WM_COPYDATA实现进程间数据通信
当我们软件已经打开,并且读取了一份文档后,如果我们再次双击打开另外一份文档(前提是文档类型已经与我们的软件建立了关联,双击文档可以打开我们软件并读取文档)时,我们不应该再次打开软件,而是应该重新呈现已经打开的该软件,并显示当前双击的文档。
已经打开的软件如何读取此次双击的文档呢?这就需要进程间通信了,将此次双击的文档的路径传递给已经打开的软件。这里我们通过发送WM_COPYDATA消息来实现该功能。
首先,我们需要定义一个COPYDATASTRUCT类型的成员变量:
COPYDATASTRUCT m_copyData;
我们可以在CTestApp::InitInstance()函数中如下实现:
CTestApp::InitInstance() { /*1、通过增加mutex互斥来防止再次启动程序*/ HANDLE hMutex = CreateMutex( NULL, TRUE, _T("TestApp_Mutex") ); if (GetLastError()==ERROR_ALREADY_EXISTS ) { /*通过窗口名称找到已经打开的该应用程序窗口指针*/ CWnd *pWnd = CWnd::FindWindow(NULL, _T("TestApp")); if (NULL == pWnd) { return 0; } /*通过命令行获取双击的文档的名称*/ CString fineName = m_lpCmdLine; HWND h = pWnd->GetSafeHwnd(); pWnd->ShowWindow(SW_SHOW); TChar fullName[ 1024] = { ‘\0’ }; /*拷贝数据*/ HRESULT hResult = StringCbCopy(fullName, sizeof(fullName), m_lpCmdLine); if (hResult == S_OK) { m_copyData.dwData = NULL; m_copyData.cbData = sizeof(fullName); m_copyData.lpData = fullName; /*发送数据m_copyData到已经打开的应用程序窗口*/ ::SendMessage(h, WM_COPYDATA, (WPARAM)(HWND)pWnd, (LPARAM)(LPVOID)& m_copyData); }
}
ReleaseMutex(hMutex); CloseHandle( hMutex ); /*这里直接return后,*/ return 0; }
至此,数据是发到已经打开的应用程序窗口了,下面,我们来实现接收该数据。
在CMainFrm类中添加对WM_ COPYDATA消息的响应函数,在函数中如下实现:
BOOL CMainFrame::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) { CString pathname = ( TCHAR* ) ( pCopyDataStruct->lpData ); if ( pathname != _T(“”) ) { //TODO:读取文件、解析文件、呈现内容 } }