Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
каркас.doc
Скачиваний:
58
Добавлен:
03.06.2015
Размер:
1.6 Mб
Скачать

3.6. Генерация сообщений таймера

Последним сообщением, которое мы обсудим в этой главе, будет WM_TIMER. В Windows-программах можно устанавливать таймер, который с заданной периодич­ностью будет посылать программе сообщение WM_TIMER. Использование таймера является хорошим способом время от времени «будить» Вашу программу. Это может быть полезным в том случае, если Ваша программа выполняется как фоновое приложение.

Основные функции. Для установки таймера нужно использовать функцию API SetTimer():

UINT SetTimer(HWND hwnd, UINT nID, UINT wLength,

TIMEPROC lpTFunc);

Параметр hwnd является дескриптором окна, которое собирается использовать таймер. Параметр nID – идентификатор устанавливаемого таймера (одновременно могут использоваться несколько таймеров). Параметр wLength задает временной интервал для таймера в миллисекундах. Функция, указатель на которую задается параметром lpTFunc, является процедурой, определенной в программе и вызываемой при об­работке прерываний таймера. Эта функция должна быть определена как VOID CALLBACK и имеет такие же параметры, как и оконная функция. Однако, если значение lpTFunc равно NULL, как это чаще всего и бывает, для обработки сообще­ний таймера будет вызываться оконная функция. В этом случае каждый раз по истечении заданного временного интервала в очередь сообщений программы будет помещаться сообщение WM_TIMER, а оконная функция программы должна будет обрабатывать его так же, как и остальные сообщения. Такой подход используется в следующем примере. Функция SetTimer() в случае успешного завершения возвращает значение nID, в противном случае возвращается 0.

Будучи установлен, таймер будет посылать сообщения до тех пор, пока программа не завершится или не вызовет функцию API KillTimer():

BOOL KillTimer(HWND hwnd, UINT nID);

Здесь hwnd является дескриптором окна, использующего таймер, а nID – идентификатором этого таймера.

Каждый раз при поступлении сообщения WM_TIMER параметр wParam содер­жит идентификатор таймера, a lParam – адрес функции таймера (если он был задан при установке таймера). В следующем примере значение IParam будет NULL.

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

struct tm *newtime,

адрес которой помещается в указатель newtime.

Кроме того, нужна переменная t типа time_t:

time_t t.

Функция time(NULL)позволяет получить новое время, которое имеет тип time_t:

t = time(NULL).

Новое время можно поместить в структуру типа tm (в соответствующее её поле), адрес которой помещен в указатель newtime, с помощью функции localtime :

newtime=localtime(&t).

Единственным аргументом функции localtime является адрес переменной t типа time_t.

Из структуры типа tm время можно поместить в буфер вывода, используя функции strcpy и asctime:

strcpy(str,asctime(newtime)).

Следует учесть, что в конце этой информации Windows поместит символы «возврат каретки» \r и «новая строка» \n . Эти символы желательно удалить, поставив в конце информации обычный символ «конец строки»:

str[strlen(str)-1] = '\0' .

Пример 3-5. Приведенная ниже программа использует таймер для создания часов. Для полу­чения текущей даты и времени она вызывает стандартные функции «C» или «C++». Каждый раз при получении сообщения таймера – примерно раз в секунду – изображение, отображающее время, обновляется. Таким образом, время указывается с точностью до одной секунды.

// Программа-часы

#include <Windows.h>

#include <String.h>

#include <Stdio.h>

#include <Time.h>

LRESULT CALLBACK WindowFunc(HWND, UINT,

WPARAM, LPARAM);

char szWinName[]="МоеОкно"; // Имя класса окна

char str[80]=""; // Буфер для строки вывода

int X=1, Y=1; // Координаты строки на экране

int WINAPI WinMain(HINSTANCE hThisInst,

HINSTANCE hPrevInst,

LPSTR lpszArgs,

int nWinMode)

{

HWND hwnd;

MSG msg;

WNDCLASS wcl; // Определить класс окна

wcl.hInstance=hThisInst; // Дескриптор приложения

wcl.lpszClassName=szWinName; // Имя класса окна

wcl.lpfnWndProc=WindowFunc; // Функция окна

wcl.style=0; // Стиль по умолчанию

wcl.hIcon=LoadIcon(NULL,IDI_APPLICATION);// Иконка

wcl.hCursor=LoadCursor(NULL,IDC_ARROW); // Курсор

wcl.lpszMenuName=NULL; // Без меню

wcl.cbClsExtra=0; // Без дополнительной информации

wcl.cbWndExtra=0;

wcl.hbrBackground=

(HBRUSH)GetStockObject(WHITE_BRUSH); //Белый фон

if(!RegisterClass(&wcl)) // Регистрируем класс окна

return 0;

hwnd=CreateWindow(szWinName, // Создать окно

"Программа-часы",

WS_OVERLAPPEDWINDOW, // Стиль окна

CW_USEDEFAULT, // x-координата

CW_USEDEFAULT, // y-координата

CW_USEDEFAULT, // Ширина

CW_USEDEFAULT, // Высота

HWND_DESKTOP, // Нет родител. окна

NULL, // Нет меню

hThisInst,// Дескриптор приложения

NULL); // Нет дополнит. аргументов

ShowWindow (hwnd, nWinMode); // Показать окно

SetTimer(hwnd,1,1000,NULL); // Устан. таймер 1 сек.

UpdateWindow(hwnd); // Перерисовать содержимое

while(GetMessage(&msg,NULL,0,0)) // Запустить цикл

{ // обработки сообщений

TranslateMessage(&msg); //Разреш. исп-е клавиатуры

DispatchMessage (&msg); // Вернуть управл. Windows

}

KillTimer(hwnd,1); // Освободить таймер

return msg.wParam;

}

// Следующая функция вызывается операционной

// системой Windows и получает в качестве

// параметров сообщения из очереди сообщений

// данного приложения

LRESULT CALLBACK WindowFunc(HWND hwnd,

UINT message,

WPARAM wParam,

LPARAM lParam)

{

HDC hdc;

PAINTSTRUCT paintstruct;

struct tm *newtime;

time_t t;

switch(message)

{

case WM_PAINT: // Перерисовка рабочей области

hdc=BeginPaint(hwnd,&paintstruct);// Получить DC

TextOut(hdc,X,Y,str,strlen(str));//Вывести буфер

EndPaint(hwnd, &paintstruct); // Освободить DC

break;

case WM_TIMER: // Очередной временной интервал

t = time(NULL); // Получить новое время

newtime=localtime(&t); // Новое время - в буфер

strcpy(str,asctime(newtime));

str[strlen(str)-1] = '\0'; // Удалить \r\n

InvalidateRect(hwnd,NULL,1); // Перерисов. экран

break;

case WM_DESTROY: // Завершение программы

PostQuitMessage(0);

break;

default:

// Все сообщения, не обрабатываемые в

// данной функции, направляются на обработку

// по умолчанию

return DefWindowProc(hwnd,message,

wParam,lParam);

}

return 0;

}

Пример вывода этой программы показан на рис. 3.3.