当前位置: 首页 > news >正文

最大的网站建设北京十大app开发公司排名

最大的网站建设,北京十大app开发公司排名,管理系统平台,建筑设计有哪些专业本文讲解SendMessage、PostMessage两个函数的实现原理#xff0c;分为三个步骤进行讲解#xff0c;分别适合初级、中级、高级程序员进行理解#xff0c;三个步骤分别为#xff1a; 1、SendMessage、PostMessage的运行机制。 2、SendMessage、PostMessage的运行内幕。 3、…本文讲解SendMessage、PostMessage两个函数的实现原理分为三个步骤进行讲解分别适合初级、中级、高级程序员进行理解三个步骤分别为 1、SendMessage、PostMessage的运行机制。 2、SendMessage、PostMessage的运行内幕。 3、SendMessage、PostMessage的内部实现。 注理解这篇文章之前必须先了解Windows的消息循环机制。 1、SendMessage、PostMessage的运行机制 我们先来看最简单的。 SendMessage可以理解为SendMessage函数发送消息等待消息处理完成后SendMessage才返回。稍微深入一点是等待窗口处理函数返回后SendMessage就返回了。 PostMessage可以理解为PostMessage函数发送消息不等待消息处理完成立刻返回。稍微深入一点PostMessage只管发送消息消息有没有被送到则并不关心只要发送了消息便立刻返回。 对于写一般Windows程序的程序员来说能够这样理解也就足够了。但SendMessage、PostMessage真的是一个发送消息等待、一个发送消息不等待吗具体细节下面第2点将会讲到。 2、SendMessage、PostMessage的运行内幕 在写一般Windows程序时如上第1点讲到的足以应付其实我们可以看看MSDN来确定SendMessage、PostMessage的运行内幕。 在MSDN中SendMessage解释如为The SendMessage function sends the specified message to a window or windows. It calls the window procedure for the specified window and does not return until the window procedure has processed the message. 翻译成中文为SendMessage函数将指定的消息发到窗口。它调用特定窗口的窗口处理函数并且不会立即返回直到窗口处理函数处理了这个消息。 再看看PostMessage的解释The PostMessage function places (posts) a message in the message queue associated with the thread that created the specified window and returns without waiting for the thread to process the message. 翻译成中文为PostMessage函数将一个消息放入与创建这个窗口的消息队列相关的线程中并立刻返回不等待线程处理消息。 仔细看完MSDN解释我们了解到SendMessage的确是发送消息然后等待处理完成返回但发送消息的方法为直接调用消息处理函数即WndProc函数按照函数调用规则肯定会等消息处理函数返回之后SendMessage才返回。而PostMessage却没有发送消息PostMessage是将消息放入消息队列中然后立刻返回至于消息何时被处理PostMessage完全不知道此时只有消息循环知道被PostMessage的消息何时被处理了。 至此我们拨开了一层疑云原来SendMessage只是调用我们的消息处理函数PostMessage只是将消息放到消息队列中。下一节将会更深入这两个函数看看Microsoft究竟是如何实现这两个函数的。 3、SendMessage、PostMessage的内部实现 Windows内部运行原理、机制往往是我们感兴趣的东西而这些东西又没有被文档化所以我们只能使用Microsoft提供的工具自己研究了。 首先在基本Win32工程代码中我们可以直接看到消息处理函数、消息循环所以建立一个基本Win32工程本篇文章使用VS2005为了看到更多信息我们需要进行设置让VS2005载入Microsoft的Symbolpdb文件[1]。为了方便去除了一些多余的代码加入了两个菜单ID分别为IDM_SENDMESSAGE、IDM_POSTMESSAGE。如下列出经过简化后的必要的代码。 消息循环 Ln000while (GetMessage(msg, NULL, 0, 0)) Ln001{ Ln002    TranslateMessage(msg); Ln003    DispatchMessage(msg); Ln004} 消息处理函数 Ln100LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) Ln101{ Ln102    int wmId, wmEvent; Ln103    switch (message) Ln104    { Ln105    case WM_COMMAND: Ln106        wmId LOWORD(wParam); Ln107        wmEvent HIWORD(wParam); Ln108        switch (wmId) Ln109        { Ln110        case IDM_EXIT: Ln111            DestroyWindow(hWnd); Ln112            break; Ln113        case IDM_SENDMESSAGE: Ln114            SendMessage(hWnd, WM_SENDMESSAGE, 0, 0); Ln115            break; Ln116        case IDM_POSTMESSAGE: Ln117            PostMessage(hWnd, WM_POSTMESSAGE, 0, 0); Ln118            break; Ln119        default: Ln120            return DefWindowProc(hWnd, message, wParam, lParam); Ln121        } Ln122        break; Ln123 Ln124    case WM_SENDMESSAGE: Ln125        MessageBox(hWnd, LSendMessage, LPrompt, MB_OK); Ln126        break; Ln127 Ln128    case WM_POSTMESSAGE: Ln129        MessageBox(hWnd, LPostMessage, LPrompt, MB_OK); Ln130        break; Ln131 Ln132    case WM_DESTROY: Ln133        PostQuitMessage(0); Ln134 Ln135    default: Ln136        return DefWindowProc(hWnd, message, wParam, lParam); Ln137    } Ln138    return 0; Ln139} 下面一步步分析这两个函数的内部情况先讨论 SendMessage。 第一步在DispatchMessageLn003函数处下个断点F5进行调试当程序运行到断点后查看 CallStack 窗口可得如下结果 #003MyProj.exe!wWinMain(HINSTANCE__ * hInstance0x00400000, HINSTANCE__ * hPrevInstance0x00000000, wchar_t * lpCmdLine0x000208e0, int nCmdShow0x00000001)  Line 49   C #002MyProj.exe!__tmainCRTStartup()  Line 589 0x35 bytes C #001MyProj.exe!wWinMainCRTStartup()  Line 414 C #000kernel32.dll!_BaseProcessStart4()  0x23 bytes  我们可以看到进程先调用 kernel32.dll 中的 BaseProcessStart 函数然后调用的 Startup Code 的函数 wWinMainCRTStartup然后调用 _tmainCRTStartup 函数最终调用我们的 wWinMain 函数我们的程序就运行起来了。 第二步去除第一步下的断点在 WndProcLn101 函数入口处下个断点F5 继续运行运行到新下的断点处查看 CallStack 窗口可得如下结果 #008MyProj.exe!WndProc(HWND__ * hWnd0x00050860, unsigned int message0x00000101, unsigned int wParam0x00000074, long lParam0xc03f0001)  Line 122    C #007user32.dll!_InternalCallWinProc20()  0x28 bytes    #006user32.dll!_UserCallWinProcCheckWow32()  0xb7 bytes    #005user32.dll!_DispatchMessageWorker8()  0xdc bytes   #004user32.dll!_DispatchMessageW4()  0xf bytes #003MyProj.exe!wWinMain(HINSTANCE__ * hInstance0x00400000, HINSTANCE__ * hPrevInstance0x00000000, wchar_t * lpCmdLine0x000208e0, #000int nCmdShow0x00000001)  Line 49 0xc bytes C #002MyProj.exe!__tmainCRTStartup()  Line 589 0x35 bytes C #001MyProj.exe!wWinMainCRTStartup()  Line 414 C #000kernel32.dll!_BaseProcessStart4()  0x23 bytes  #000~#003 跟第一步相同不再解释。在 #004、#005可以看到函数运行到 DispatchMessage 的内部了DispatchMessageW、DispatchMessageWorker 是 user32.dll 中到处的函数而且函数前部字符串相等在此猜想应该是 DispatchMessage 的内部处理。#008 为我们消息处理函数所以推想而知#006、#007 是为了调用我们的消息处理函数而准备的代码。 第三步去除第二步下的断点在Ln003、Ln114、Ln115、Ln125 处分别下一个断点在菜单中选择对应项使程序运行至 Ln114F10下一步可以看到并没有运行到 breakLn115直接跳到了 Ln125 处由此可知目前 SendMessage 已经在等待了查看 CallStack 窗口可得如下结果 #013MyProj.exe!WndProc(HWND__ * hWnd0x00050860, unsigned int message0x00000500, unsigned int wParam0x00000000, long lParam0x00000000)  Line 147    C #012user32.dll!_InternalCallWinProc20()  0x28 bytes    #011user32.dll!_UserCallWinProcCheckWow32()  0xb7 bytes    #010user32.dll!_SendMessageWorker20()  0xc8 bytes  #009user32.dll!_SendMessageW16()  0x49 bytes   #008MyProj.exe!WndProc(HWND__ * hWnd0x00050860, unsigned int message0x00000111, unsigned int wParam0x00008003, long lParam0x00000000)  Line 136 0x15 bytes   C #007user32.dll!_InternalCallWinProc20()  0x28 bytes    #006user32.dll!_UserCallWinProcCheckWow32()  0xb7 bytes    #005user32.dll!_DispatchMessageWorker8()  0xdc bytes   #004user32.dll!_DispatchMessageW4()  0xf bytes #003MyProj.exe!wWinMain(HINSTANCE__ * hInstance0x00400000, HINSTANCE__ * hPrevInstance0x00000000, wchar_t * lpCmdLine0x000208e0, #000int nCmdShow0x00000001)  Line 49 0xc bytes C #002MyProj.exe!__tmainCRTStartup()  Line 589 0x35 bytes C #001MyProj.exe!wWinMainCRTStartup()  Line 414 C #000kernel32.dll!_BaseProcessStart4()  0x23 bytes  #000~#008 跟上面的相同不再解释。在 #009、#010可以看到函数调用到 SendMessage 内部了在此猜想应该是 SendMessage 的内部处理。#011、#012 跟第二步中的 #006、#007 一样在第二部中这两个函数是为了调用消息处理函数而准备的代码#013 也是我们的消息处理函数所以此两行代码的功能相等。 至此我们证明了 SendMessage 的确是直接调用消息处理函数的在消息处理函数返回前SendMessage 等待。在所有的操作中Ln003 断点没有去到证明 SendMessage 不会将消息放入消息队列中在 PostMessage 分析中此断点将会跑到接下来讲述。 第四步F5继续运行此时弹出对话框点击对话框中的确定后运行到断点 Ln115 处。查看 CallStack 窗口可得如下结果 #008MyProj.exe!WndProc(HWND__ * hWnd0x00050860, unsigned int message0x00000111, unsigned int wParam0x00008003, long lParam0x00000000)  Line 137    C #007user32.dll!_InternalCallWinProc20()  0x28 bytes    #006user32.dll!_UserCallWinProcCheckWow32()  0xb7 bytes    #005user32.dll!_DispatchMessageWorker8()  0xdc bytes   #004user32.dll!_DispatchMessageW4()  0xf bytes #003MyProj.exe!wWinMain(HINSTANCE__ * hInstance0x00400000, HINSTANCE__ * hPrevInstance0x00000000, wchar_t * lpCmdLine0x000208e0, int nCmdShow0x00000001)  Line 49 0xc bytes   C #002MyProj.exe!__tmainCRTStartup()  Line 589 0x35 bytes C #001MyProj.exe!wWinMainCRTStartup()  Line 414 C #000kernel32.dll!_BaseProcessStart4()  0x23 bytes  #000~008 跟第二步的完全相同此时 SendMessage 也已经返回所调用的堆栈也清空了。 至此我们彻底拨开了 SendMessage 的疑云了解了 SendMessage 函数的运行机制综述为SendMessage 内部调用 SendMessageW、SendMessageWorker 函数做内部处理然后调用 UserCallWinProcCheckWow、InternalCallWinProc 来调用我们代码中的消息处理函数消息处理函数完成之后SendMessage 函数便返回了。 SendMessage 讨论完之后现在讨论 PostMessage将上面的所有断点删除关闭调试。 第一步在DispatchMessageLn003函数处下个断点F5进行调试此处结果跟 SendMessage 一样不再说明。 第二步去除第一步下的断点在 WndProcLn101 函数入口处下个断点F5 继续运行此处结果跟 SendMessage 一样不再说明。 第三步去除第二步下的断点在 Ln003、Ln117、Ln118、Ln129 处分别下一个断点在菜单中选择对应项使程序运行至 Ln117F10 下一步可以看到已经运行到 breakPostMessage 函数返回了此时 CallStack 没有变化。 第四步F5 继续运行此时程序运行到 Ln003CallStack 跟第一步刚起来时一样。 第五步F5 继续运行由于有多个消息可能要按多次让程序运行到 Ln129此时 CallStack 跟第二步相同为了方便说明再次列举如下 #008MyProj.exe!WndProc(HWND__ * hWnd0x00070874, unsigned int message0x00000501, unsigned int wParam0x00000000, long lParam0x00000000)  Line 151    C #007user32.dll!_InternalCallWinProc20()  0x28 bytes    #006user32.dll!_UserCallWinProcCheckWow32()  0xb7 bytes    #005user32.dll!_DispatchMessageWorker8()  0xdc bytes   #004user32.dll!_DispatchMessageW4()  0xf bytes #003MyProj.exe!wWinMain(HINSTANCE__ * hInstance0x00400000, HINSTANCE__ * hPrevInstance0x00000000, wchar_t * lpCmdLine0x000208e0, int nCmdShow0x00000001)  Line 49 0xc bytes   C #002MyProj.exe!__tmainCRTStartup()  Line 589 0x35 bytes C #001MyProj.exe!wWinMainCRTStartup()  Line 414 C #000kernel32.dll!_BaseProcessStart4()  0x23 bytes  由此可以看到此调用是从消息循环中调用而来DispatchMessageW、DispatchMessageWorker 是 DispatchMessage 的内部处理UserCallWinProcCheckWow、InternalCallWinProc是为了调用我们的消息处理函数而准备的代码。 至此我们再次彻底拨开了 PostMessage 的疑云了解了 PostMessage 函数的运行机制综述为PostMessage 将消息放入消息队列中自己立刻返回消息循环中的 GetMessagePeekMessage 也可本例中为演示处理到我们发的消息之后便按照普通消息处理方法进行处理。
http://www.sadfv.cn/news/298970/

相关文章:

  • 宁波网站优化软件乔拓云微信小程序官网
  • 舟山网站网站建设后台网站开发文档
  • 地方网站程序wordpress页面模板怎么做
  • 做金融必看网站网站开发项目流程设计
  • 现在市面网站做推广好旅游网页设计模板图及代码
  • 明年做哪个网站致富wordpress如何制作网页
  • 网站建设知识论文简历设计网官网
  • 低面效果在哪个网站做建立公司网站多少钱
  • 蓝色系网站优化wordpress访问速度
  • 直播网站建设模板网页设计提升班
  • 做网站费用需要分摊吗舞蹈培训东莞网站建设
  • 芙蓉区营销型网站建设定制优秀网页设计网站
  • 网站建设话术开场白网站排名怎么弄
  • 网站建设不用虚拟主机夜狼seo
  • wordpress 股票主题搜索引擎优化的核心及内容
  • 杭州网站建设公司联系方式php怎么做搭建网站
  • 网站制作教程手机如何在各个购物网站之间做差价
  • 网站开发所涉及的技术海南网络广播电视台开学第一课
  • 南宁企业网站建站模板striking wordpress
  • 无极网站成都网站设计成功柚v米科技
  • 解决设计网站问题制作公众号的编辑器
  • 网站速度慢的原因北京网站推广公司排名
  • 淄博网站制作公司深圳企业网站建设服务公司
  • 做服装店网站的素材深圳宝安做网站的公司
  • 推广型网站建设机构网页设计与网站开发的实践目的
  • 荷城网站设计有关大学生做兼职的网站
  • 自己做图片的网站链接上海网站seo
  • 系统网站建设方案郑州网站建设哪里好
  • 保亭整站优化手机互动网站建设
  • 凡科网站建设公司临沂谁会做网站