Файл: Методические указания к курсовому проектированию по дисциплине Методы программирования и прикладные алгоритмы для студентов специальности 075400.doc

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 05.12.2023

Просмотров: 43

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.


Функция закрашивает текущей кистью прямоугольник lpRect или (x1,y1; x2,y2) со скругленными углами, которые задаются эллипсом шириной x3 и высотой y3
void FillSolidRect( LPCRECT lpRect, COLORREF clr );

или

void FillSolidRect( int x, int y, int cx, int cy, COLORREF clr );

Функция закрашивает прямоугольник lpRect; (x,y; cx,cy – ширина, высота) цветом clr.

[ ЭЛЛИПС ]

BOOL Ellipse( int x1, int y1, int x2, int y2 );

или

BOOL Ellipse( LPCRECT lpRect );

Функция изображает текущим пером и закрашивает текущей кистью эллипс внутри прямоугольника: lpRect или (x1,y1; x2,y2).
[ Закрашенный СЕКТОР]

BOOL Pie( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 );

или

BOOL Pie( LPCRECT lpRect, POINT ptStart, POINT ptEnd );

Функция рисует текущим пером и закрашивает текущей кистью сектор (против ч.с) внутри прямоугольника: lpRect или (x1,y1; x2,y2) от начальной точки ptStart; (x3,y3) до конечной точки ptEnd; (x4,y4).
[ ЗакрашеннАЯ ЗАМКНУТАЯ ОБЛАСТЬ ]

BOOL Polygon( LPPOINT lpPoints, int nCount );

Функция рисует текущим пером и закрашивает текущей кистью замкнутую область, ограниченную отрезками, которые задаются точками массива lpPoints, количеством nCount.
Пример использования графических функций класса CClientDC.

CClientDC MyDC(GetDlgItem(IDC_STATIC1));

// создали объект класса CClientDC, который инициализирует графическое

//окно в элементе диалога приложения с идентификатором IDC_STATIC1.
CRect Rect; // объявили объект класса CRect
CWnd *pWnd = MyDC.GetWindow();

// инициализировали pWnd как указатель на окно, закрепленное за объектом

//MyDC(с идентификатором IDC_STATIC1)
pWnd->GetClientRect(&Rect);

// передали объекту Rect координаты этого окна, т.е. определили область

//экрана, где будем выводить графику.
MyDC.FillSolidRect( &Rect, RGB(50,100,150) );

// закрасили прямоугольник Rect
int w, h;

w = Rect.Width()/3;

// определили ширину прямоугольника Rect и уменьшили ее в 3 раза

h = Rect.Height()/4;

// определили высоту прямоугольника Rect и уменьшили ее в 4 раза
CRect SmallRect = Rect;

//инициализировали малый прямоугольник, объявили его равным

//прямоугольнику Rect
SmallRect.DeflateRect( w, h );

// уменьшили ширину и высоту малого прямоугольника до значений w и h

//соответственно, сохраняя координаты центральной точки прямоугольника.
CBrush Br (RGB(100,0,150)); // инициализировали кисть

MyDC.SelectObject(&Br); // выбрали ее
MyDC.Ellipse( &SmallRect );

// изобразили закрашенный эллипс выбранной кистью, вписанный в малый

//прямоугольник.


Рис. 1. Полученное изображение

3. Работа с файлами в C / C++.
FILE *fopen(const char * filename, const char *mode);

Функция fopen() открывает файл и инициализирует связанный с ним поток данных. Аргумент mode устанавливает режим открытия файла (табл. 2).

• Спецификация режима может быть дополнена символами t или b, указывающими, в текстовом или двоичном режиме от­крывается файл.

Возвращаемое значение: Функция возвращает указатель на структуру типа FILE (см. 8). Этот указатель затем передается в качестве аргумента следующим функциям, работающим с потоком. Если файл не может быть открыт, возвращается NULL-указатель.

Таблица 2

Режимы открытия файлов

Ре­жим

Описание

r

Файл открывается только для чтения

w

Файл открывается только для записи с усечением. Если файл не существует, он создается в каталоге, заданном в параметре filename. Указатель записи-чтения устанавливается в нуль. После закрытия файл имеет новый размер, соответствующий текущему положению указателя записи-чтения

а

Файл открывается для пополнения, т.е. после его открытия указатель записи-чтения устанавливается на позицию конца файла

r+

Файл открывается для обновления. Он доступен для чтения и записи, но после закрытия не происходит усечения файла. Сразу после открытия указатель записи-чтения устанавливается в начало файла

W+

Файл открывается для обновления, т.е. доступен для чтения и записи. Если файл не существует, он создается в каталоге, заданном в параметре filename. Указатель записи-чтения устанавливается в нуль. После закрытия файл имеет новый размер, соответствующий текущему положению указателя записи-чтения

а+

Файл открывается для обновления, т.е. доступен для чтения и записи. После его открытия указатель записи-чтения устанавливается в позицию конца файла. После закрытия файла не происходит его усечения

int fprintf (FILE *stream, const char *format...);

Функция формирует по заданным аргументам символьную стро­ку, которая записывается в поток stream. Форматирование сим­вольной строки происходит таким же образом, как и в функции

printf().

Параметр Описание

stream Указатель на структуру FILE потока данных
format Символьная строка формата (см. printf())
... Переменное число аргументов

• Возвращаемое значение: число записанных в поток символов. В случае ошибки возвращается отрицательное значение (чаще всего EOF (WEOF)).

__________________________________________________________________

int fscanf (FILE *stream, const char *format, ...);

Функция считывает данные из потока данных stream. Она исполь­зует аргумент format для преобразования считыва­емых символов по заданному формату. Следующие аргументы яв­ляются указателями на переменные, которым присваиваются вводимые значения.

Возвращаемое значение: число успешно преобразованных и присвоенных полей либо EOF в случае попытки считывания конца файла.

__________________________________________________________________

int fputc(int character, FILE *stream);

Функция выводит отдельный символ из потока ввода-вывода.

Возвращаемое значение: записанный в поток символ или EOF в случае ошибки.

__________________________________________________________________

int fputs(const char*string, FILE *stream);

Функция записывает символьную строку в поток данных. Перенос завершается при достижении символа конца строки '\0'. Сам нуль-терминатор в файл не передается и не заменяется симво­лом '\n'.

Возвращаемое значение: код последнего записанного в файл символа. В случае ошибки возвращается EOF.

__________________________________________________________________

int fgetc(FILE*stream);

Функция считывает символ из потока stream. После считывания указатель записи-чтения файла устанавливается в новую пози­цию.

Возвращаемое значение: считанный символ в виде целого беззнакового значения типа int; EOF означает ошибку или конец файла.

__________________________________________________________________

char*fgets(char *string, int n, FILE*stream);
Функция считывает строку из потока stream до тех пор, пока не будут считаны nсимволов, либо символ конца строки '\n', либо символ конца файла. Символ '\n' не передается в считанную строку. Функция автоматически дополняет полученную строку нуль-терминатором '\0'.

Возвращаемое значение: указатель на string, а в случае ошибки или при получении символа конца файла — NULL-указатель.

__________________________________________________________________
size_t fread(void*buffer, size_t size, size_t nelem, FILE* stream);

Функция считывает nelem элементов размером size байт каждый в область памяти, на которую указывает buffer, из откры­того потока stream.

Возвращаемое значение: количество безошибочно считан­ных элементов данных.


__________________________________________________________________

size_t fwrite(const void *buffer, size_t size, size_t nelem, FILE *stream);
Функция записывает в поток stream nelem элементов дан­ных размером size байтов каждый из области памяти, на которую указывает buffer. После записи указатель записи-чтения потока устанавливается на новое место. Если поток открыт в текстовом режиме, то каждый символ '\n' преобразуется в пару символов: перевода строки и возврата каретки.

Возвращаемое значение: число фактически записанных элементов данных.

__________________________________________________________________
int fseek(FILE *stream, long offset, int from_where);

Функция передвигает указатель записи-чтения файла на заданное аргумен­том offset количество байтов. Аргумент from_where задает точку отсчета для сдвига.

• Для файлов, открытых в двоичном режиме, количество байтов смещения указателя соответствует числу символов, на которые должен передвинуться указатель записи-чтения файла (может быть также и отрицательным).

• Для файлов, открытых в текстовом режиме, количество байтов смещения должно вычисляться с помощью функции ftell(), причем аргумент from_where должен быть равен SEEK_SET. Для аргумента from_where могут быть заданы три различные константы.

SEEK_CUR сдвиг выполняется от текущей позиции
указателя чтения-записи файла

SEEK_END сдвиг выполняется от конца файла
SEEK_SET сдвиг выполняется от начала файла

Возвращаемое значение: нуль в случае успеха, в противном случае — любое ненулевое значение.

__________________________________________________________________

long ftell(FILE *stream);

Функция возвращает текущее значение указателя записи-чтения файла, связанного с потоком stream.

Возвращаемое значение: текущая позиция указателя запи­си-чтения файла.

• Если файл открыт в двоичном режиме, функция возвращает число байтов от начала файла до текущей позиции.

• Если файл открыт в MS DOS текстовом режиме, то каждый символ '\n' преобразуется в пару символов: перевода стро­ки и возврата каретки (CR/LF). В этом случае значение, воз­вращаемое ftell(), не соответствует физическому байтово­му смещению. В случае ошибки возвращаемым значением является 1L.

__________________________________________________________________


Пример использования приведенных выше функций работы с файлами.

#include

#include

void main( void )

{

FILE *file;

char* file_name = "file.txt";

char load_string[50] = "none";

file = fopen( file_name, "w" );

//открываем файл с именем file.txt на запись

fputs( "string", file ); // записываем в него слово string

fclose( file ); //закрываем файл

file = fopen( file_name, "r" );

// открываем этот же файл на чтение
if( file != 0 )

//если файл был действительно открыт, т.е. указатель file содержит адрес

//открываемого файла и, следовательно, не равен 0, то

{

fgets( load_string, 50 , file );

//считываем из файла строку длиной 50 в переменную load_string символов

// из открытого файла (указатель на него file)

cout << "load_string = " << load_string << endl;

// выводим считанную строку на экран

}

else

cout << "File not found !!!" << endl;

// иначе (если файл не был открыт) – сообщаем об ошибке
fclose(file); // закрываем файл

}
4. Работа с файлами с помощью MFC (классы CFile, CStdioFile, ... ) и стандартный класс MFC CFileDialog.

В библиотеку MFC включено несколько классов для обеспечения работы с файлами. Рассматриваемые ниже классы наследуются от базового класса CFile.

Класс CFile

Класс CFile предназначен для обеспечения работы с файлами. Он позволяет упростить использование файлов, представляя файл как объект, который можно создать, читать, записывать и т.д.

Чтобы получить доступ к файлу, сначала надо создать объект класса CFile. Конструктор класса позволяет сразу после создания такого объекта открыть файл.

Открытие и создание файлов

После создания объекта класса CFile можно открыть файл, вызвав метод Open. Методу надо указать путь к открываемому файлу и режим его использования. Прототип метода Open имеет следующий вид:

virtual BOOL Open(LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError=NULL);

В качестве параметра lpszFileName надо указать имя открываемого файла. Можно указать только имя файла или полное имя файла, включающее полный путь к нему.

Второй параметр nOpenFlags определяет действие, выполняемое методом Open с файлом, а также атрибуты файла. Ниже представлены некоторые возможные значения параметра nOpenFlags:

  • CFile::modeCreate – Создается новый файл. Если указанный файл существует, то его содержимое стирается и длина файла устанавливается равной нулю.

  • CFile::modeNoTruncate – Этот файл предназначен для использования совместно с файлом CFile::modeCreate. Если создается уже существующий файл, то его содержимое не будет удалено.

  • CFile::modeRead – Файл открывается только для чтения.

  • CFile::modeReadWrite – Файл открывается для записи и для чтения.

  • CFile::modeWrite – Файл открывается только для записи.

  • CFile::typeText – Используется классами, порожденными от класса CFile, например CStdioFile, для работы с файлами в текстовом режиме. Текстовый режим обеспечивает преобразование комбинации символа возврата каретки и символа перевода строки.

  • CFile::Binary – Используется классами, порожденными от класса CFile, например, CStdioFile, для работы с файлами в двоичном режиме.

Необязательный параметр pError, который является указателем на объект класса CFileException, используется только в том случае, если выполнение операции с файлом вызовет ошибку. При этом в объект, указываемый pError, будет записана дополнительная информация.

Метод Open возвращает не нулевое значение, если файл открыт и нуль в случае ошибки. Ошибка при открытии файла может случиться, например, если методу Open указан для чтения несуществующий файл.

Идентификатор открытого файла

В состав класса CFile входит элемент данных m_hFile типа UINT. В нем хранится идентификатор открытого файла. Если объект класса CFile уже создан, но файл еще не открыт, то в переменной m_hFile записана константа hFileNull. Обычно идентификатор открытого файла непосредственно не используется. Методы класса CFile позволяют выполнять практически любые операции с файлами и не требуют указывать идентификатор файла. Так как m_hFile является элементом класса, то реализация его методов всегда имеет свободный доступ к нему.

Закрытие файлов

После завершения работы с файлом, его надо закрыть. Класс CFile имеет для этого специальный метод Close. Нужно заметить, что если был создан объект класса CFile и открыт файл, а затем объект удаляется, то связанный с ним файл закрывается автоматически с помощью деструктора.
Чтение и запись файлов

Для доступа к файлам предназначено несколько методов класса CFile: Read, ReadHuge, Write, WriteHuge, Flush. Методы Read и ReadHuge предназначены для чтения данных из предварительно открытого файла. В 32-разрядных операционных системах оба метода могут одновременно считать из файла больше 65535 байт. Спецификация ReadHuge считается устаревшей и оставлена только для совместимости с 16-разрядными операционными системами.

Данные, прочитанные из файла, записываются в буфер lpBuf. Параметр nCount определяет количество байт, которое надо считать из файла. Фактически из файла может быть считано меньше байт, чем запрошено параметром nCount. Это происходит, если во время чтения достигнут конец файла. Методы возвращают количество байт, прочитанных из файла.

Для записи в файл предназначены методы Write и WriteHuge. В 32-разрядных операционных системах оба метода могут одновременно записывать в файл больше 65535 байт. Методы записывает в открытый файл nCount байт из буфера lpBuf. В случае возникновения ошибки записи, например переполнения диска, методы вызывает обработку исключения.

Метод Flush

Когда используется метод Write или WriteHuge для записи данных на диск, они некоторое время могут находиться во временном буфере. Чтобы убедиться, что необходимые изменения внесены в файл на диске, нужно воспользоваться методом Flush.

Операции с файлами

В состав класса входят методы, позволяющие выполнять над файлами различные операции, например копирование, переименование, удаление, изменение атрибутов.

Для изменения имени файла класс CFile включает статический метод Rename, выполняющий функции этой команды. Метод нельзя использовать для переименования каталогов. В случае возникновения ошибки метод вызывает исключение.

Для удаления файлов в классе CFile включен статический метод Remove, позволяющий удалить указанный файл. Этот метод не позволяет удалять каталоги. Если удалить файл невозможно, то метод вызывает исключение.

Чтобы определить дату и время создания файла, его длину и атрибуты, предназначен статический метод GetStatus. Существует две разновидности метода – первый определен как виртуальный, а второй – как статический метод.

Виртуальная версия метода GetStatus определяет состояние открытого файла, связанного с данным объектом класса CFile. Этот метод вызывается только тогда, когда объект класса CFile создан и файл открыт.

Статическая версия метода GetStatus позволяет определить характеристики файла, не связанного с объектом класса CFile. Чтобы воспользоваться этим методом, необязательно предварительно открывать файл.

Блокировка

В состав класса включены методы LockRange и UnlockRange, позволяющие заблокировать один или несколько фрагментов данных файла для доступа из других процессов. Если приложение пытается повторно блокировать данные, уже заблокированные раньше этим или другим приложением, вызывается исключение. Блокировка представляет собой один из механизмов, позволяющих нескольким приложениям или процессам одновременно работать с одним файлом, не мешая друг другу.

Установить блокировку можно с помощью метода LockRange. Чтобы снять установленные блокировки, надо воспользоваться методом UnlockRange. Если в одном файле установлены несколько блокировок, то каждая из них должна сниматься отдельным вызовом метода UnlockRange.

Позиционирование

Чтобы переместить указатель текущей позиции файла в новое положение, можно воспользоваться одним из следующих методов класса CFileSeek, SeekToBegin, SeekToEnd. В состав класса CFile также входят методы, позволяющие установить и изменить длину файла, – GetLength, SetLength.

При открытии файла указатель текущей позиции файла находится в самом начале файла. Когда порция данных прочитана или записана, то указатель текущей позиции перемещается в сторону конца файла и указывает на данные, которые будут читаться или записываться очередной операцией чтения или записи в файл.

Чтобы переместить указатель текущей позиции файла в любое место, можно воспользоваться универсальным методом Seek. Он позволяет переместить указатель на определенное число байт относительно начала, конца или текущей позиции указателя.

Чтобы переместить указатель в начало или конец файла, наиболее удобно использовать специальные методы. Метод SeekToBegin перемещает указатель в начало файла, а метод SeekToEnd – в его конец.

Но для определения длины открытого файла совсем необязательно перемещать его указатель. Можно воспользоваться методом GetLength. Этот метод также возвращает длину открытого файла в байтах. Метод SetLength позволяет изменить длину открытого файла. Если при помощи этого метода размер файла увеличивается, то значение последних байт не определено.

Текущую позицию указателя файла можно определить с помощью метода GetPosition. Возвращаемое методом GetPosition 32-разрядное значение определяет смещение указателя от начала файла.

Характеристики открытого файла

Чтобы определить расположение открытого файла на диске, надо вызвать метод GetFilePath. Этот метод возвращает объект класса CString, в котором содержится полный путь файла, включая имя диска, каталоги, имя файла и его расширение.

Если требуется определить только имя и расширение открытого файла, можно воспользоваться методом GetFileName. Он возвращает объект класса CString, в котором находится имя файла. В случае, когда нужно узнать только имя открытого файла без расширения, пользуются методом GetFileTitle.

Следующий метод класса CFile позволяет установить путь файла. Это метод не создает, не копирует и не изменяет имени файла, он только заполняет соответствующий элемент данных в объекте класса CFile.

Класс CMemFile

В библиотеку MFC входит класс CMemFile, наследуемый от базового класса CFile. Класс CMemFile представляет файл, размещенный, в оперативной памяти. С объектами класса CMemFile так же, как и с объектами класса CFile. Отличие заключается в том, что файл, связанный с объектом CMemFile, расположен не на диске, а в оперативной памяти компьютера. За счет этого операции с таким файлом происходят значительно быстрее, чем с обычными файлами.

Работая с объектами класса CMemFile, можно использовать практически все методы класса CFile, которые были описаны выше. Можно записывать данные в такой файл или считывать их. Кроме этих методов в состав класса CMemFile включены дополнительные методы.

Для создания объектов класса CMemFile предназначено два различных конструктора. Первый конструктор CMemFile имеет всего один необязательный параметр nGrowBytes:

CMemFile(UINT nGrowBytes=1024);

Этот конструктор создает в оперативной памяти пустой файл. После создания файл автоматически открывается (не нужно вызывать метод Open).

Когда начинается запись в такой файл, автоматически выделяется блок памяти. Для получения памяти методы класса CMemFile вызывают стандартные функции malloc, realloc и free. Если выделенного блока памяти недостаточно, его размер увеличивается. Увеличение блока памяти файла происходит по частям по nGrowBytes байт. После удаления объекта класса CMemFile используемая память автоматически возвращается системе.

Второй конструктор класса CMemFile имеет более сложный прототип. Это конструктор используется в тех случаях, когда программист сам выделяет память для файла:

CMemFile(BYTE* lpBuffer, UINT nBufferSize,

UINT nGrowBytes=0);

Параметр lpBuffer указывает на буфер, который будет использоваться для файла. Размер буфера определяется параметром nBufferSize.

Необязательный параметр nGrowBytes используется более комплексно, чем в первом конструкторе класса. Если nGrowBytes содержит нуль, то созданный файл будет содержать данные из буфера lpBuffer. Длина такого файла будет равна nBufferSize.

Если nGrowBytes больше нуля, то содержимое буфера lpBuffer игнорируется. Кроме того, если в такой файл записывается больше данных, чем помещается в отведенном буфере, то его размер автоматически увеличивается. Увеличение блока памяти файла происходит по частям по nGrowBytes байт.

Класс CMemFile позволяет получить указатель на область памяти, используемую файлом. Через этот указатель можно непосредственно работать с содержимым файла, не ограничивая себя методами класса CFile. Для получения указателя на буфер файла можно воспользоваться методом Detach. Перед этим полезно определить длину файла (и соответственно размер буфера памяти), вызвав метод GetLength.

Метод Detach закрывает данный файл и возвращает указатель на используемый им блок памяти. Если опять потребуется открыть файл и связать с ним оперативный блок памяти, нужно вызвать метод Attach.

Нужно отметить, что для управления буфером файла класс CMemFile вызывает стандартные функции malloc, realloc и free. Поэтому, чтобы не нарушать механизм управления памятью, буфер lpBuffer должен быть создан функциями malloc или calloc.

Класс CStdioFile

Тем, кто привык пользоваться функциями потокового ввода/вывода из стандартной библиотеки C и C++, следует обратить внимание на класс CStdioFile, наследованный от базового класса CFile. Этот класс позволяет выполнять буферизированный ввод/вывод в текстовом и двоичном режиме. Для объектов класса CStdioFile можно вызывать практически все методы класса CFile.

В класс CStdioFile входит элемент данных m_pStream, который содержит указатель на открытый файл. Если объект класса CStdioFile создан, но файл еще не открыт, либо закрыт, то m_pStream содержит константу NULL.

Класс CStdioFile имеет три различных конструктора. Первый конструктор класса CStdioFile не имеет параметров. Этот конструктор только создает объект класса, но не открывает никаких файлов. Чтобы открыть файл, надо вызвать метод Open базового класса CFile.

Второй конструктор класса CStdioFile можно вызвать, если файл уже открыт и нужно создать новый объект класса CStdioFile и связать с ним открытый файл. Этот конструктор можно использовать, если файл был открыт стандартной функцией fopen. Параметр метода должен содержать указатель на файл, полученный вызовом стандартной функции fopen.

Третий конструктор можно использовать, если надо создать объект класса CStdioFile, открыть новый файл и связать его с только что созданным объектом.

Для чтения и записи в текстовый файл класс CStdioFile включает два новых метода: ReadString и WriteString. Первый метод позволяет прочитать из файла строку символов, а второй метод – записать.

Примеры записи и чтения из файла

Приведем фрагменты кода, в которых демонстрируется использование стандартных диалоговых панелей выбора файла и процедуры чтения и записи в файл.
Открытие файла и чтение из него

CString m_Text;

CFileDialog DlgOpen(TRUE,(LPCSTR)"txt",NULL,

OFN_HIDEREADONLY,(LPCSTR)"Text Files (*.txt) |*.txt||");

// создание стандартной панели выбора файла Open
if(DlgOpen.DoModal()==IDOK) {

// отображение стандартной панели выбора файла Open
CStdioFile File(DlgOpen.GetPathName(),

CFile::modeRead|CFile::typeBinary);

// создание объекта и открытие файла для чтения
CString& ref=m_Text;

// чтение из файла строки

File.ReadString(ref);

// передается ссылка на строку m_Text }
Открытие файла и запись из него

CString m_Text;

CFileDialog DlgSaveAs(FALSE,(LPCSTR)"txt",NULL,

OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,

(LPCSTR)" Text Files (*.txt) |*.txt||");

// создание стандартной панели выбора файла SaveAs


if(DlgSaveAs.DoModal()==IDOK) {

// отображение стандартной панели выбора файла SaveAs

CStdioFile File(DlgSaveAs.GetPathName(),

CFile::modeCreate|CFile::modeWrite|

CFile::typeBinary);

// создание объекта и открытие файла для записи
File.WriteString((LPCTSTR)m_Text); } // запись в файл строки
5. Использование таймера.

Во многих программах требуется следить за временем или выполнять какие-либо периодические действия.

Операционная система Windows позволяет для каждого приложения создать несколько виртуальных таймеров. Все эти таймеры работают по прерываниям одного физического таймера.

Так как работа Windows основана на передаче сообщений, логично было бы предположить, что и работа виртуального таймера также основана на передаче сообщений. И в самом деле, приложение может заказать для любого своего окна несколько таймеров, которые будут периодически посылать в функцию окна сообщение с кодом WM_TIMER.

К сожалению, точность виртуального таймера оставляет желать лучшего. Сообщения таймера проходят через очередь приложения, к тому же другое приложение может блокировать на некоторое время работу вашего приложения. Поэтому сообщения от таймера приходят в общем случае нерегулярно. Кроме того, несмотря на возможность указания интервалов времени в миллисекундах, реальная дискретность таймера определяется периодом прерываний, посылаемых таймером. Этот период (то есть длительность одного такта таймера) можно узнать с помощью функции GetTimerResolution:

DWORD WINAPI GetTimerResolution(void);

Нерегулярность прихода сообщений таймера не вызывает особых проблем, если речь не идет о работе в режиме реального времени.
1   2   3   4