Translatemessage函数(Windows编程中消息处理函数的问题)

2024-05-05 20:50:05 :39

translatemessage函数(Windows编程中消息处理函数的问题)

其实translatemessage函数的问题并不复杂,但是又很多的朋友都不太了解Windows编程中消息处理函数的问题,因此呢,今天小编就来为大家分享translatemessage函数的一些知识,希望可以帮助到大家,下面我们一起来看看这个问题的分析吧!

本文目录

Windows编程中消息处理函数的问题

是个挺复杂的问题啊!1)从消息机制角度讲,WINDOWS里有两类线程。一种是可以接受消息的线程,一种是不接受消息的线程。区别在于,WINDOWS系统会为接受消息的线程开辟一个内存块,在其中维护一个数据结构,而不接受消息的线程则没有这样的数据结构。触发WINDOWS为线程添加这样的数据结构的条件基本上有2种情况:一是在我们的程序里调用了涉及窗口的API,像创建了一个窗口如使用了CREATEWINDOW,或显示一个窗口如SHOWWINDOW;二是调用了涉及消息的API,如GETMESSAGE,PEEKMESSAGE。2)线程中有关处理消息的这个数据结构中集中了几个队列,按优先处理顺序是1.发送消息队列2.投送消息队列3.虚拟输入队列4.屏幕重画队列5.定时器队列。在程序中调用SENDMESSAGE就把消息发送到了发送消息队列中,通过POSTMESSAGE就把消息发送到了投送消息队列中,键盘按键(分按下和弹起2个动作,因此按一个键时总是先把WM_(SYS)KEYDOWN发送到虚拟消息队列中,然后再将WM_(SYS)KEYUP消息发到虚拟消息队列中)和鼠标按键消息被发送到虚拟消息队列中。3)对应于每一个队列有一个标志变量,譬如,如果在发送消息队列里有一个WM_CREATE的消息时,发送消息标志变量是打开的(代码理解为标识变量--》a=0表示关闭,a=1表示打开)。当调用GETMESSAGE或PEEKMESSAGE时会首先检查发送消息标志变量,从而能确定在发送消息队列中是否有消息,如果有消息,GETMESSAGE和PEEKMESSAGE直接在它们函数体中调用对应该消息的窗口处理函数来处理该消息(GETMESSAGE和带PM_REMOVE参数的PEEKMESSAGE在发现该消息时,还要把该消息从队列中给删除,否则像不带PM_REMOVE参数的PEEKMESSAGE就会重复去处理该消息)。当该消息处理完后,GETMESSAGE和PEEKMESSAGE是不会结束的,在它们的函数体中是通过WHILE来保持循环检查消息队列的。因此当刚才列举的WM_CREATE消息处理完后,它会重新再检查发送消息队列标识变量,直到发送消息队列中没有消息为止。然后它再去按顺序检查投送消息队列,如果里面发现了一个WM_COMMAND消息,那GETMESSAGE和PEEKMESSAGE就会终止运行,调用RETURN,返回到我们的程序中,返回值为TRUE(看下GETMESSAGE和PEEKMESSAGE的函数声明)。还记得我们再调用这两个函数时,需要传递一个LPMSG的消息结构吗,当GETMESSAGE和PEEKMESSAGE返回前,它会把它在投送消息队列和虚拟输入消息队列中发现的消息复制到这个LPMSG的变量中。4)当GETMESSAGE和PEEKMESSAGE返回时,如果再调用TRANSLATEMESSAGE时,TRANSLATEMESSAGE会检查参数LPMSG(看TRANSLATEMESSAGE函数声明,它需要接受一个LPMSG类型的参数,该参数是在前面调用GETMESSAGE和PEEKMESSAGE时已经被填充了内容了)。如果在LPMSG发现了WM_(SYS)KEYDOWN消息,TRANSLATEMESSAGE会把该消息处理成为WM_CHAR消息,然后再调用POSTMESSAGE,把该WM_CHAR消息投送到线程的投送消息队列中,当以后再调用GETMESSAGE和PEEKMESSAGE时,该消息才会被这两个函数填充进LPMSG中。5)TRANSLATEMESSAGE返回后,需要调用DISPATCHMESSAGE。它的作用是对LPMSG中的消息进行处理,譬如当它发现LPMSG中有个WM_CHAR时,它会调用对应于该消息的窗口处理函数进行处理,处理完后该函数返回。以上是消息机制的一部分(基本上针对了你的问题回答了)WINDOWS的消息处理机制是非常复杂的,而且当你看有关消息的API以及窗口过程时,会很茫然。初学者是这样的,不要心急,慢慢来。如同七龙珠一般,慢慢搜集,把所有龙珠凑齐了,才能看到神秘的神龙!

请问mfc组件中如何使PreTranslateMessage函数有作用,望给个明确易懂的步骤

PreTranslateMessage是标准窗口的消息预处理响应函数,在任何标准窗口有效。DLL中窗口的创建是在一个导出函数中,并在调用CWnd::Create这前调用了AFX_MANAGE_STATE(AfxGetStaticModuleState())来切换模块线程状态,导致该窗口所在的模块线程状态和MFC调用CWinApp::PreTranslateMessage时的不同,所以DLL中的窗口就无法响应PreTranslateMessage函数了。解决方案:1.dll导出一条函数 DllPreTranslateMessageBOOL PASCAL DllPreTranslateMessage(MSG *pMsg){ AFX_MANAGE_STATE(AfxGetStaticModuleState()); return theApp.PreTranslateMessage(pMsg);}2.在主程序的CWinApp的PreTranslateMessage中直接调用DLL的DllPreTranslateMessage函数。但记住要先调用DLL中的函数。BOOL CMyApp::PreTranslateMessage(MSG* pMsg){ // TODO: Add your specialized code here and/or call the base class if(DllPreTranslateMessage(pMsg)) return TRUE; return CWinApp::PreTranslateMessage(pMsg);}经过以上两步,DLL中的窗口就可以响应PreTranslateMessage了。

Win32项目中,不可或缺的两个函数是什么

按照我的理解,非要说两个不可或缺的函数话,应该是(1)WinMain() //入口函数,相当于c语言的main()函数,函数原型为int WINAPI WinMain (HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow);(2)WndProc()//窗口处理函数,用来处理各种消息,因为Window程序设计是事件驱动的。函数原型为LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);另外,你说的创建win32应用程序的基本过程,概括起来就是 先 注册窗口类,然后创建窗口,显示窗口,进入消息循环。。用简单代码表示如下(例子取自《Windows程序设计》一书):#include 《windows.h》LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName = TEXT ("HelloWin") ; HWND hwnd ; MSG msg ; WNDCLASwndclass ;wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground= (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuNam = NULL ; wndclass.lpszClassName= szAppName ;if (!RegisterClass (&wndclass)) { MessageBox ( NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow( szAppName, // window class name TEXT ("The Hello Program"), // window caption WS_OVERLAPPEDWINDOW, // window style CW_USEDEFAULT,// initial x position CW_USEDEFAULT,// initial y position CW_USEDEFAULT,// initial x size CW_USEDEFAULT,// initial y size NULL, // parent window handle NULL, // window menu handle hInstance, // program instance handle NULL) ; // creation parametersShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ;while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; }LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc ; PAINTSTRUCT ps ; RECT rect ;switch (message) { case WM_CREATE: PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ; return 0 ;case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ;GetClientRect (hwnd, ▭) ;DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, ▭, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; EndPaint (hwnd, &ps) ; return 0 ;case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }

VC PreTranslateMessage 解释

关于PreTranslateMessage(MSG* pMsg) 这个函数,msdn上这样说的:CWinApp类使用这个函数以在消息被分派到Windows的TranslateMessage和DispatchMessage函数之前进行转换。

C++ 时间延时 函数,时间不准,求解

你的意思是说为什么delay的时间并不是你传进去的mis。原因应该是如下:你循环体本身执行的时候就是要时间的。比如mis 传进来是 2000忽略到GetCurrentTime等的执行时间COleDateTime start_time = COleDateTime::GetCurrentTime(); COleDateTimeSpan end_time = COleDateTime::GetCurrentTime() - start_time; while(end_time.GetTotalSeconds() 《= (mis/1000)) end_time为0{ MSG msg; GetMessage(&msg,NULL,0,0); 假设执行时间 100ms TranslateMessage(&msg); 假设执行时间100ms DispatchMessage(&msg); 假设执行时间是3000ms end_time = COleDateTime::GetCurrentTime() - start_time; 此时end_time就为3200ms}所以此时就是一个等待时间久违3200ms,四舍五入的话3seconds这样就跟你传入的参数2秒不对了。。关键你是要考虑一些函数的执行时间,同时DispatchMessage是一个同步函数。当前GetMessage得到一个WM_TIMER消息,而窗口处理函数在处理onTimer的时候sleep了5秒,那么这个函数要等5秒才返回。所以你这个delay函数时间肯定是不精确的。

关于translatemessage函数到此分享完毕,希望能帮助到您。

translatemessage函数(Windows编程中消息处理函数的问题)

本文编辑:admin
Copyright © 2022 All Rights Reserved 威海上格软件有限公司 版权所有

鲁ICP备20007704号

Thanks for visiting my site.