WM_COPYDATA消息,在win32中用來進行進程間的數據傳輸。
typedef struct tagCOPYDATASTRUCT { // cds DWORD dwData; DWORD cbData; PVOID lpData; } COPYDATASTRUCT;
其中dwData為32位的自定義數據, lpData為指向數據的指針,cbData為lpData指針指向數據的大小(字節數)。
一般推薦用SendMessage函數進行發送,這樣就能確保在接收方復制數據前避免發送方能修改或刪除數據;
LRESULT SendMessage( HWND hWnd, // handle of destination window UINT Msg, // message to send WPARAM wParam, // first message parameter LPARAM lParam // second message parameter );
這裡:
hWnd:為接收進程的窗體句柄;
Msg:WM_COPYDATA;
wParam:為發送進程的窗體句柄;
lParam:為指向COPYDATASTRUCT數據結構的指針;
這裡需要注意的:傳輸的COPYDATA數據在發送後要避免被發送進程中的其他線程修改,其次要確保被傳輸的數據中沒有包含接收進程無法訪問的對象的指針或引用。比如:發送進程自身的HDC、HBITMAP之類的東西,它們對於接收進程來說是無效的。另外,接收進程窗體句柄可以通過FindWindow函數獲取:
const char szDlgTitle[] = "ReceiveProcess"; HWND hRecvWindow = ::FindWindow(NULL, szDlgTitle);
這裡的“ReceiveProcess”為接收進程的名字;
同時,接收數據的進程中,首先在消息映射表中增加WM_COPYDATA消息映射,然後定義消息映射函數,其函數的格式為:
BOOL CCanCollectorDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) { .... }
主要代碼如下:(這裡發送進程發送當前的時間給接收進程)
發送進程:
void CProcessCommDlg::OnBTNStart1() { const char szDlgTitle[] = "ReceiveProcess"; HWND hSendWindow =this->GetSafeHwnd(); HWND hRecvWindow = ::FindWindow(NULL, szDlgTitle); COPYDATASTRUCT CopyData; char szSendBuf[100]; time_t timenow; time(&timenow); sprintf(szSendBuf, "%s", ctime(&timenow));//注意,ctime()返回的字符串後面帶了'\n' CopyData.dwData = 0; CopyData.cbData = strlen(szSendBuf); szSendBuf[CopyData.cbData - 1] = '\0'; CopyData.lpData = szSendBuf; ::SendMessage(hRecvWindow, WM_COPYDATA, (WPARAM)hSendWindow, (LPARAM)&CopyData); printf("%s\n", szSendBuf); }
接收進程:
BEGIN_MESSAGE_MAP(CCanCollectorDlg, CDialog) //{{AFX_MSG_MAP(CCanCollectorDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_COPYDATA() //}}AFX_MSG_MAP END_MESSAGE_MAP() ........ BOOL CCanCollectorDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) { char szBuffer[300]; memset(szBuffer, 0, sizeof(szBuffer)); sprintf(szBuffer, "dwData:%d cbData:%d\r\nlpData:0x%08x = %s\r\n\r\n", pCopyDataStruct->dwData, pCopyDataStruct->cbData, (PVOID)pCopyDataStruct->lpData, (char*)pCopyDataStruct->lpData); return CDialog::OnCopyData(pWnd, pCopyDataStruct); }
哈哈,選我吧!1、剪貼板CliPBoard:在16位時代常使用的方式,CWnd中提供支持
2、窗口消息標准的Windows消息以及專用的WM_COPYDATA消息SENDMESSAGE()接收端必須有一個窗口
3、使用共享內存方式(SharedMemory)
a.設定一塊共享內存區域
HANDLECreateFileMapping(HANDLE,LPSECURITY_ATTRIBUTES,DWORD,DWORD,DWORD,LPCSTR)
產生一個file-mapping核心對象
LPVOIDMapViewOfFile(
HANDLEhFileMappingObject,
DWORDdwDesiredAcess,
DWORDdwFileOffsetHigh,
DWORDdwFileOffsetLow,
DWORDdwNumberOfBytesToMap
);
得到共享內存的指針
b.找出共享內存
決定這塊內存要以點對點(peertopeer)的形式呈現每個進程都必須有相同的能力,產生共享內存並將它初始化。每個進程
都應該調用CreateFileMapping(),然後調用GetLastError().如果傳回的錯誤代碼是ERROR_ALREADY_EXISTS,那麼進程就可以假設這一共享內存區域已經被別的進程打開並初始化了,否則該進程就可以合理的認為自己排在第一位,並接下來將共享內存初始化。
還是要使用client/server架構中只有server進程才應該產生並初始化共享內存。所有的進程都應該使用
HANDLEOpenFileMapping(DWORDdwDesiredAccess,
BOOLbInheritHandle,
LPCTSTRlpName);
再調用MapViewOfFile(),取得共享內存的指針
c.同步處理(Mutex)
d.清理(Cleaningup)BOOLUnmapViewOfFile(LPCVOIDlpBaseAddress);
CloseHandle()
4、動態數據交換(DDE)通過維護全局分配內存使的應用程序間傳遞成為可能
其方式是再一塊全局內存中手工放置大量的數據,然後使用窗口消息傳遞內存指針.這是16位WIN時代使用的方式,因為在WIN32下已經沒有全局和局部內存了,現在的內存只有一種就是虛存。
5、消息管道(MessagePipe)
用於設置應用程序間的一條永久通訊通道,通過該通道可以象自己的應用程序訪問一個平面文件一樣讀寫數據。
匿名管道(AnonymousPipes)
單向流動,並且只能夠在同一電腦上的各個進程之間流動。
命名管道(NamedPipes)
雙向,跨網絡,任何進程都可以輕易的抓住,放進管道的數據有固定的格式,而使用ReadFile()只能讀取該大小的倍數。
可以被使用於I/OCompletionPorts
6、郵件槽(Mailslots)
廣播式通信,在32系統中提供的新方法,可以在不同主機間交換數據,在WIN9X下只支持郵件槽客戶
7、Windows套接字(WindowsSocket)
它具備消息管道所有的功能,但遵守一套通信標准使的不同操作系統之上的應用程序之間可以互相通信。
8、Internet通信它讓應用程序從Internet地址上載或下載文件
9、RPC:遠程過程調用,很少使用,因其與UNIX的RPC不兼容。
10、串行/並行通信(Serial&#......余下全文>>
進程間通信的幾種方式:
.
進程間通信IPC------Inter-Process Communication
由於內存管理的一些機制,導致兩個進程間並不能直接的進行通信(在獨立的用戶空間),因此我們需要利用一些介質來完成兩個進程之間的通信。以下是常用的進程間通信方式。
# 管道( pipe ):管道是一種半雙工的通信方式,數據只能單向流動,而且只能在具有親緣關系的進程間使用。進程的親緣關系通常是指父子進程關系。
# 有名管道 (named pipe) : 有名管道也是半雙工的通信方式,但是它允許無親緣關系進程間的通信。
# 信號量( semophore ) : 信號量是一個計數器,可以用來控制多個進程對共享資源的訪問。它常作為一種鎖機制,防止某進程正在訪問共享資源時,其他進程也訪問該資源。因此,主要作為進程間以及同一進程內不同線程之間的同步手段。
# 消息隊列( message queue ) : 消息隊列是由消息的鏈表,存放在內核中並由消息隊列標識符標識。消息隊列克服了信號傳遞信息少、管道只能承載無格式字節流以及緩沖區大小受限等缺點。
# 信號 ( sinal ) : 信號是一種比較復雜的通信方式,用於通知接收進程某個事件已經發生。
# 共享內存( shared memory ) :共享內存就是映射一段能被其他進程所訪問的內存,這段共享內存由一個進程創建,但多個進程都可以訪問。共享內存是最快的 IPC 方式,它是針對其他進程間通信方式運行效率低而專門設計的。它往往與其他通信機制,如信號兩,配合使用,來實現進程間的同步和通信。
# 套接字( socket ) : 套解口也是一種進程間通信機制,與其他通信機制不同的是,它可用於不同及其間的進程通信。
.
參考資料: Windows下進程通信的幾種方式
.
wenku.baidu.com/...kpVUy3