大家好,又见面了,我是你们的朋友全栈君。
1.windows消息循环
代码语言:javascript复制if (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg); //消息转化
DispatchMessage(&msg); //消息派遣. 把TranslateMessage转换的消息发送到窗口的消息处理函数,此函数在窗口注册时已经指定
}
执行过程:
- 消息循环调用GetMessage()从消息队列中查找消息进行处理,如果消息队列为空,程序将停止执行并等待(程序阻塞)。
- 事件发生时导致一个消息加入到消息队列(例如系统注册了一个鼠标点击事件),GetMessage()将返回一个正值,这表明有消息需要被处理,并且消息已经填充到传入的MSG参数中;当传入WM_QUIT消息时返回0;如果返回值为负表明发生了错误。
- 取出消息(在Msg变量中)并将其传递给TranslateMessage()函数,这个函数做一些额外的处理:将虚拟键值信息转换为字符信息。这一步实际上是可选的,但有些地方需要用到这一步。
- DispatchMessage()函数将消息分发到消息的目标窗口,并且查找目标窗口过程函数,给窗口过程函数传递窗口句柄、消息、wParam、lParam等参数然后调用该函数。
- 在窗口过程函数中,检查消息和其他参数,你可以用它来实现你想要的操作。如果不想处理某些特殊的消息,你应该总是调用DefWindowProc()函数,系统将按按默认的方式处理这些消息(通常认为是不做任何操作)。
- 一旦一个消息处理完成,窗口过程函数返回,DispatchMessage()函数返回,继续循环处理下一个消息。
2. 函数定义
2.1GetMessage
代码语言:javascript复制BOOL WINAPI GetMessage(
_Out_ LPMSG lpMsg,
_In_opt_ HWND hWnd,
_In_ UINT wMsgFilterMin,
_In_ UINT wMsgFilterMax
);
- GetMessage 函数的作用是从当前线程的消息队列里获取一个消息并填入 MSG 结构 中。
- 该函数只能获取调用线程的消息,不能获得其他线程的消息。成功获取消息后,线程将从消息队列中删除该消息。
- 使用 GetMessage 函数,如果消息队列为空,函数会一直等待直到有消息到来才有返回值。
2.2 TranslateMessage
代码语言:javascript复制//BOOL TranslateMessage(CONST MSG *lpMsg);
- 参数:lpMsg 指向一个含有用GetMessage或PeekMessage函数从调用线程的消息队列中取得消息信息的MSG结构的指针
- 函数功能描述: 将虚拟键消息转换为字符消息。字符消息被送到调用线程的消息队列中,在下一次线程调用函数GetMessage或PeekMessage时被读出。 TranslateMessage函数不修改由参数lpMsg指向的消息。
2.3 DispatchMessage
代码语言:javascript复制函数原型:LONG DispatchMessage(CONST MSG*lpmsg);
- 参数: lpmsg:指向含有消息的MSG结构的指针。
- 返回值: 返回值是窗口程序返回的值。尽管返回值的含义依赖于被调度的消息,但返回值通常被忽略。
- 备注: MSG结构必须包含有效的消息值。如果参数lpmsg指向一个WM_TIMER消息,并且WM_TIMER消息的参数IParam不为NULL,则调用IPa1ram指向的函数,而不是调用窗口程序。
3. 程序实例
- 如果处理时间大于定时器时间,按照处理时间循环。
- 如果处理时间小于定时器时间,按照定时器时间。
#pragma comment(lib,"user32")
#include <stdio.h>
#include <time.h>
#include <sys/timeb.h>
#include <windows.h>
char datestr[16];
char timestr[16];
char mss[4];
void log(char *s) {
struct tm *now;
struct timeb tb;
ftime(&tb);
now = localtime(&tb.time);
sprintf(datestr, "d-d-d", now->tm_year 1900, now->tm_mon 1, now->tm_mday);
sprintf(timestr, "d:d:d", now->tm_hour, now->tm_min, now->tm_sec);
sprintf(mss, "d", tb.millitm);
printf("%s %s.%s %s", datestr, timestr, mss, s);
}
VOID CALLBACK myTimerProc1(
HWND hwnd, // handle of window for timer messages
UINT uMsg, // WM_TIMER message ************
UINT idEvent, // timer identifier
DWORD dwTime // current system time)
{
log("In myTimerProc1n");
}
VOID CALLBACK myTimerProc2(
HWND hwnd, // handle of window for timer messages
UINT uMsg, // WM_TIMER message
UINT idEvent, // timer identifier
DWORD dwTime // current system time)
{
log("In myTimerProc2n");
}
int main()
{
MSG msg;
SetTimer(NULL, 0, 4000, myTimerProc1);
SetTimer(NULL, 1, 2000, myTimerProc2);
for (int i = 0; i<20; i )
{
Sleep(1000);
log("In mainn");
if (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg); //消息处理
DispatchMessage(&msg); //消息派遣. 把TranslateMessage转换的消息发送到窗口的消息处理函数,此函数在窗口注册时已经指定
}
}
return 0;
}
代码语言:javascript复制2019-12-06 21:10:24.633 In main
2019-12-06 21:10:25.618 In myTimerProc2
2019-12-06 21:10:26.619 In main
2019-12-06 21:10:27.620 In myTimerProc1
2019-12-06 21:10:28.621 In main
2019-12-06 21:10:28.621 In myTimerProc2
2019-12-06 21:10:29.623 In main
2019-12-06 21:10:29.624 In myTimerProc2
2019-12-06 21:10:30.625 In main
2019-12-06 21:10:31.623 In myTimerProc1
2019-12-06 21:10:32.624 In main
2019-12-06 21:10:32.624 In myTimerProc2
2019-12-06 21:10:33.626 In main
2019-12-06 21:10:33.626 In myTimerProc2
2019-12-06 21:10:34.628 In main
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/129189.html原文链接:https://javaforall.cn