Windows程序通訊 -- WM_COPYDATA 訊息
來自:https://blog.csdn.net/u012104827/article/details/102914600
關於 WM_COPYDATA 訊息說明:https://docs.microsoft.com/zh-cn/windows/win32/dataxchg/wm-copydata
COPYDATASTRUCT有三個成員變數,如下所示:
typedef struct tagCOPYDATASTRUCT { ULONG_PTR dwData; DWORD cbData; PVOID lpData; } COPYDATASTRUCT, *PCOPYDATASTRUCT;
注意:
1、dwData為自定義資料,按照自己習慣設定就好,不影響物件的傳輸;
2、cbData,MSDN解釋為:The size, in bytes, of the data pointed to by the lpData member.即lpData指向的資料的長度,要是這個變數的值設定錯誤,就會導致WM_COPYDATA傳輸資料失敗;
3、lpData,傳輸的資料。使用簡單的資料最好,例如char陣列。本人在程式中使用了string物件,發現在子程序不能接收到正常的資料,使用char陣列卻很正常。有可能跟string物件不能跨程序訪問有關,讀者如果知道原因的話請在評論區告訴我,謝謝;
4、使用WM_COPYDATA時要用SendMessage而不能使用PostMessage
5、由於使用SendMessage,所以不應該在WM_COPYDATA中處理資料,可以在訊息響應窗體的WM_COPYDATA中先把COPYDATASTRUCT物件中的資料複製出來,通過自定義訊息傳送到訊息響應窗體,然後立即返回,來減少父程序的阻塞時間。這樣就把處理資料的程式碼放在自定義訊息處了。
在另一篇文章中 https://blog.csdn.net/syb1295306116/article/details/104155986,有這麼一段:
這裡注意要分配全域性記憶體,否則另一程序接受訊息時,訊息被釋放,接受的是亂碼,無法解析。
const UINT messageID = RegisterWindowMessage("SingletonApplication"); char szTemp[1024] = { 0 }; sprintf(szTemp, "LayeredWindow_%d", iWndID);//視窗名 HWND hTemp = ::FindWindow(NULL, szTemp);//視窗控制代碼 BYTE* pGlobal = (BYTE*)::GlobalAlloc(GMEM_FIXED, str.length());//全域性記憶體 if (!pGlobal) { return; } else { ZeroMemory(pGlobal, str.length()); memcpy(pGlobal, str.c_str(), str.length()); } COPYDATASTRUCT copyData = {0}; copyData.dwData = messageID; copyData.cbData = (DWORD)(str.length()+1); copyData.lpData = pGlobal; SendMessage(hTemp, WM_COPYDATA, 0, (LPARAM)©Data); ::GlobalFree((HGLOBAL)pGlobal);//釋放全域性記憶體
不過,我測試的時候,使用 malloc() 沒使用GlobalAlloc() ,倒也沒問題,不知何故?