zoukankan      html  css  js  c++  java
  • MFC窗口消息PostMessage和SendMessage

    以前这些消息用得比较少,但是今天碰到了个事儿,我看非用消息不可。

    事情是这样的,我在线程中需要刷新对话框上面的内容,但是每每执行到UpdateData时就出现了断言错误。

    查了相关资料,发现这个可能是多个模块调用同一个方法出现的问题。反正照我之前的逻辑走不通。

    我现在将更新对话框信息的函数,通过线程中发窗口消息,让对话框的消息处理函数来负责处理我自定义的消息,为我刷新对话框数据。

    // http://blog.csdn.net/a8082649/article/details/7733527

    1.自定义消息ID。

    #define WM_MY_MESSAGE (WM_USER+100)         WM_USER为windows系统为非系统消息保留的ID,这里至少要用100,因为其它控件的消息会占用一部分。

    2. 定义消息处理函数。

    消息处理函数为消息目标类的成员函数。首先应该在.h 文件中声明。这里以主窗口类为例,主窗口类名 CMainDialog,则首先在CMainDialog.h声明消息处理函数。

     

    protected: 

    afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam); 

     

    3.在CMainDialog.cpp中实现消息处理函数


    LPESULT CMainDialog::OnMyMessage(WPARAM wParam, LPARAM lParam)  {  // TODO: 处理用户自定义消息  ...  return 0;  }

    4.在CMainDialog.cpp中映射消息ID和消息处理函数

    BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) 
    //{{AFX_MSG_MAP(CMainFrame) 
    ON_WM_CREATE() 
    ON_WM_TIMER() 
    ON_MESSAGE(WM_MY_MESSAGE, OnMyMessage) 
    //}}AFX_MSG_MAP 
    END_MESSAGE_MAP()

    在创建线程的时候将主窗口句柄作为参数传入线程,就可以用 PostMessage传递消息了。

    消息预处理函数

    添加消息处理函数PreTranslateMessage,此函数可以通过MFC ClassWizard添加

    1. BOOL CPreTranslateMessageDlg::PreTranslateMessage(MSG* pMsg)
    2. {
    3.     if (pMsg->message==WM_LBUTTONDOWN)
    4.     {
    5.         MessageBox("三三四四");
    6.     }
    7.     
    8.     return CDialog::PreTranslateMessage(pMsg);
    9. }

    此函数为手动添加的消息函数,可通过pMsg->message来判断是什么消息,比如WM_LBUTTONDOWN是左键单击消息,那当单击左键时就会执行此函数,同样当敲击一下键盘也会执行PreTranslateMessage函数

    // ===================================================================================================================

    SendMessage函数功能:该函数将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回。而函数PostMessage不同,将一个消息寄送到一个线程的消息队列后立即返回。

    函数原型 :

    LRESULT SendMessage(HWND hWnd,UINT wMsg,WPARAM wParam,LPARAM IParam);

    参数:

    hWnd:其窗口程序将接收消息的窗口的句柄。如果此参数为HWND_BROADCAST,则消息将被发送到系统中所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口,但消息不被发送到子窗口。

        wMsg用于区别其他消息的常量值,这些常量可以是Windows单元中预定义的常量,也可以是自定义的常量.

        wParam通常是一个与消息有关的常量值,也可能是窗口或控件的句柄

        lParam通常是一个指向内存中数据的指针。由于WParm、lParam和Pointer都是32位的,因此,它们之间可以相互转换

    返回值:返回值指定消息处理的结果,依赖于所发送的消息。

    SendMessage用例

    1.       系统消息(WM_)

    ::SendMessage(this->m_hWnd,WM_CLOSE,0,0);

    SendMessage(hWnd,WM_KEYDOWN,VK_TAB,0x000f0001);

    SendMessage(hWnd,WM_CHAR,VK_TAB,0x000f0001);

    SendMessage(hWnd,WM_KEYUP,VK_TAB,0xc00f0001);

    SendMessage(hWnd,WM_KEYDOWN,VK_TAB,0x000f0001);

    SendMessage(hWnd,WM_CHAR,VK_TAB,0x000f0001);

    SendMessage(hWnd,WM_KEYUP,VK_TAB,0xc00f0001);

    SendMessage(hWnd,WM_KEYDOWN,VK_TAB,0x000f0001);

    SendMessage(hWnd,WM_CHAR,VK_TAB,0x000f0001);

    SendMessage(hWnd,WM_KEYUP,VK_TAB,0xc00f0001);

    SendMessage(hWnd,WM_KEYDOWN,VK_RETURN,0x001c0001);

    SendMessage(hWnd,WM_CHAR,VK_RETURN,0x001c0001);

    SendMessage HWND, WM_SHOWWINDOW, SW_HIDE, vbNull '隐藏窗体

    SendMessage HWND, WM_SHOWWINDOW, SW_NORMAL, vbNull '显示窗体

    SendMessage(HWND, WM_SYSCOMMAND, SC_CLOSE, ByVal 0&)   '关闭

    SendMessage(HWND, WM_SYSCOMMAND, SC_MINIMIZE, ByVal 0&) '最小化

    SendMessage(HWND, WM_PASTE, 0, 0) '粘贴

    SendMessage(HWND, WM_COPY, 0, 0) '复制

    SendMessage(HWND, WM_UNDO, 0, 0) '撤消

    2.       通告消息

    比如:给资源ID为IDC_BUTTON2的按钮,发送点击消息:

    SendMessage(WM_COMMAND,

    MAKELONG(IDC_BUTTON2,BN_CLICKED),

    (LPARAM)(GetDlgItem(IDC_BUTTON2)-> GetSafeHwnd()));

    或:

             ::SendMessage(m_hWnd,

    WM_COMMAND,

    MAKELONG(IDC_BUTTON2,BN_CLICKED),

    (LPARAM)(GetDlgItem(IDC_BUTTON2)-> GetSafeHwnd()));

    例:给菜单ID为ID_GET的菜单项,发送消息

    ::SendMessage(AfxGetMainWnd()->m_hWnd,WM_COMMAND,ID_GET,NULL);

     

    3.       用户自定义消息

     SendMessge(WM_MYMSG,0,0);

    或:

    ::SendMessge(::AfxGetMainWnd()->m_hWnd,WM_MYMSG,0,0);

    4.       向其他应用程序发送消息

    也可以为其他应用程序发送消息,前提是找到窗体的句柄,如:与FindWindow()函数一起使用;

    如:

    CString str="360w.txt -记事本";//向窗口为str的记事本窗口发送WM_CLOSE消息

             CWnd *pWnd=CWnd::FindWindow(NULL,str);//获取目的窗口对象

             ::SendMessage(*pWnd,WM_CLOSE,0,0);

    窗口标题的获取方法:

    1.       使用VC++自带工具SPY++

    2.       编程实现,可用EnumWindows函数实现;详见“枚举所有窗体,并向打开的窗体发送关闭消息”http://download.csdn.net/detail/nuptboyzhb/4162747

     

    举例:

    HWND gameh=NULL;  gameh=::FindWindow(NULL,"窗口标题");//参看游戏的标题.可以用vc6.0自带的Spy++工具查看

     CWnd* pWnd = CWnd::FromHandle(gameh);

    //在坐标为(x,y)的点,发送鼠标按下消息//注意,x,y是客户区的坐标

     ::SendMessage(*pWnd,WM_LBUTTONDOWN,0,(y<<16)+x);

    //发送鼠标移动消息,鼠标移动到点(x,y)

    ::SendMessage(*pWnd,WM_MOUSEMOVE,0,MAKELONG(x,y));

    //发送粘贴消息

    ::SendMessage(dlg_hwnd,WM_PASTE,0,0);

    5. 发送自己注册的消息 5.1 发送端:

    本示例先通过RegisterWindowMessage函数来注册一条消息,然后用Win32 API函数SendMessage()发送。 主程序端: 建立MFC对话框,添加一个按钮 在对话框CPP文件预处理下加入下面代码: static UINT NEAR WM_RGSMSG=RegisterWindowMessage("MESSAGE");//注册一条发送MESSAGE的自己注册的消息 在按钮单击事件函数中添加后: void CMyDlg::OnButton1() {  // TODO: Add your control notification handler code here  HWND  hwnd=::FindWindow(NULL,"接受窗口");//找到我们要发送消息的窗口句柄  if(hwnd==NULL)  {   AfxMessageBox("没有找到接受窗口");   return;  }  else   ::SendMessage(hwnd,WM_RGSMSG,1,0);//发送消息 }

    5.2 接收端:

    本示例接受方,仍然是先通过RegisterWindowMessage函数来注册一条相同的消息,然后定义消息宏,绑定处理函数 接收窗口: 建立MFC对话框工程 在对话框CPP文件预处理下加入下面代码: static UINT NEAR WM_RGSMSG=RegisterWindowMessage("MESSAGE");//注册一条发送MESSAGE的自己注册的消息 在消息宏声明处 将消息声明为: afx_msg LRESULT OnRgsmsg(WPARAM wParam,LPARAM lparam);    //声明消息映射函数 在建立消息映射表的地方添加如下代码: ON_REGISTERED_MESSAGE(WM_RGSMSG,OnRgsmsg)//注册的消息宏应放在这个位置 在CPP文件中,添加函数定义,代码如下: LRESULT CMyDlg::OnRgsmsg(WPARAM wParam,LPARAM lParam) {  AfxMessageBox("接收到消息");  return TRUE; }

    // http://blog.csdn.net/nupt123456789/article/details/7370463

  • 相关阅读:
    node.js 安装后怎么打开 node.js 命令框
    thinkPHP5 where多条件查询
    网站title中的图标
    第一次写博客
    Solution to copy paste not working in Remote Desktop
    The operation could not be completed. (Microsoft.Dynamics.BusinessConnectorNet)
    The package failed to load due to error 0xC0011008
    VS2013常用快捷键
    微软Dynamics AX的三层架构
    怎样在TFS(Team Foundation Server)中链接团队项目
  • 原文地址:https://www.cnblogs.com/liflying/p/4279255.html
Copyright © 2011-2022 走看看