定义和发送自定义消息

来源:互联网 发布:安祖赛弗的数据任务 编辑:程序博客网 时间:2024/05/29 15:24

自定义消息 

ClassWizard不允许增加用户自定义消息,所以你必须手工输入。输入后,ClassWizard就可以象处理其它消息一样处理你自定义的消息了。

下面是增加自定义消息的步骤:

第一步:定义消息。开发Windows95应用程序时,Microsoft推荐用户自定义消息至少是WM_USER+100,因为很多新控件也要使用WM_USER消息。

第二步:实现消息处理函数。该函数使用WPRAM和LPARAM参数并返回LPESULT。

LPESULT CMainFrame::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
// TODO: 处理用户自定义消息
...
return 0;
}
第三步:在类头文件的AFX_MSG块中说明消息处理函数:

class CMainFrame:public CMDIFrameWnd
{
...
// 一般消息映射函数
protected:
// {{AFX_MSG(CMainFrame)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnTimer(UINT nIDEvent);
afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
}
第四步:在用户类的消息块中,使用ON_MESSAGE宏指令将消息映射到消息处理函数中。

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()
如果用户需要一个整个系统唯一的消息,可以调用SDK函数RegisterWindowMessage并使用ON_REGISTER_MESSAGE宏指令取代ON_MESSAGE宏指令,其余步骤同上。

 

 

三、同一进程里发送消息

1.发送消息

 

void CSendMessageDlg::OnBnClickedButtonSend()
{
 CString* msg = new CString("发送的字符串");
 ::SendMessage(m_hWnd,WM_USER+1,0,(LPARAM)msg);
 delete msg; 
}

2.添加消息响应函数

(1)SendMessageDlg.h 添加

 

afx_msg HRESULT OnClickBtn1(WPARAM,LPARAM);

(2)SendMessageDlg.cpp

BEGIN_MESSAGE_MAP

END_MESSAGE_MAP()中间

 

ON_MESSAGE(WM_USER+1,OnClickBtnSend)   

(3)实现函数

 

HRESULT CSendMessageDlg::OnClickBtn1(WPARAM wParam,LPARAM lParam)
  {
   CString* rmsg = (CString*)lParam;
   MessageBox(*rmsg);
   return TRUE;
  }

3.点击发送,响应消息

四、不同进程发送消息传递字符串

1.两个进程间

(1)两个不同的进程不能用上面的方法,当然只发送消息是可以的。

(2)两个进程由于使用的是相互独立的两个虚拟内存空间,同一地址对不同的进程来说并不一定指向同一物理内存,内容也就不一定一样,因此不同进程无法通过传地址的方式传递字符串(但是同一进程下的不同线程是可以的)

2.解决办法

发送WM_COPYDATA消息在进程间传送数据

(1)发送消息

The exchange of data is performed by finding the other application (using FindWindow) and sending a WM_COPYDATA message to that window

使用FindWindow找到窗口,然后发送WM_COPYDATA消息,字符串附加到COPYDATASTRUCT 结构体

 

  LRESULT copyDataResult;
  CWnd *pOtherWnd = CWnd::FindWindow(NULL, strWindowTitle);
  if (pOtherWnd)
  {
    COPYDATASTRUCT cpd;
    cpd.dwData = 0;
    cpd.cbData = strDataToSend.GetLength();
    cpd.lpData = (void*)strDataToSend.GetBuffer(cpd.cbData);
    copyDataResult = pOtherWnd->SendMessage(WM_COPYDATA,
                                                (WPARAM)AfxGetApp()->m_pMainWnd->GetSafeHwnd(),
                                                (LPARAM)&cpd);
    strDataToSend.ReleaseBuffer();
    // copyDataResult has value returned by other app
    
  } 
  else 
  {
    AfxMessageBox("Unable to find other app.");
  }

(2)添加消息

The other app should handle the WM_COPYDATA message in the following manner

 

BEGIN_MESSAGE_MAP(CMyWnd, CWnd)
  //{{AFX_MSG_MAP(CMyWnd)
  ...
  ON_WM_COPYDATA()
  ...
  //}}AFX_MSG_MAP
END_MESSAGE_MAP()

(3)消息处理

 

BOOL CMyWnd::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) 
{
  CString strRecievedText = (LPCSTR) (pCopyDataStruct->lpData);
  return CMyWnd::OnCopyData(pWnd, pCopyDataStruct);
}


五、PostMessage  和SendMessage的区别

1.队列

PostMessage  和SendMessage的区别主要在于是否等待其他程序消息处理。

PostMessage只是把消息放入队列,不管其他程序是否处理都返回,然后继续执行

2.返回

SendMessage必须等待其他程序处理消息后才返回,继续执行。这两个函数的返回值也不同,SendMessage的返回值表示其他程序处理消息后的返回值

PostMessage的返回值表示PostMessage函数执行是否正确

 

 

原创粉丝点击