1. 程式人生 > >message-only 視窗及其操作

message-only 視窗及其操作

工程中想通過視窗進行IPC,而不需要視覺化的視窗,於是建立如下視窗型別,其中呼叫CreateWindow 時父視窗傳入了HWND_MESSAGE 以表示這是一個message-only 的視窗。

工程中想通過視窗進行IPC

#include <windows.h>
#include <stdio.h>
#define WINDOW_CLASS_NAME TEXT("DemoClass")
#define WINDOW_CAPTION_NAME TEXT("DemoCaption")


LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    printf("hWnd:%x\tMssage:%x\twParam:%x\tlParam:%x\n"
, hWnd, message, wParam, lParam); return ::DefWindowProc(hWnd, message, wParam, lParam); } BOOL CreateDemoWindow() { WNDCLASSEX wc = { 0 }; ATOM ret; HWND hwnd; wc.cbSize = sizeof(WNDCLASSEX); wc.lpfnWndProc = (WNDPROC)WndProc; wc.hInstance = GetModuleHandle(NULL); wc.
lpszClassName = WINDOW_CLASS_NAME; ret = RegisterClassEx(&wc); if (ret == NULL && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) { printf("RegisterClassEx Fail:%d\r\n", GetLastError()); return FALSE; } hwnd = CreateWindow(WINDOW_CLASS_NAME, WINDOW_CAPTION_NAME, 0
, 0, 0, 0, 0, HWND_MESSAGE, 0, GetModuleHandle(NULL), 0); printf("hwnd:%x\r\n", hwnd); if (!::IsWindow(hwnd)) return FALSE; ::UpdateWindow(hwnd); return TRUE; } int main() { MSG msg; printf("CreateDemoWindow:%s", CreateDemoWindow() ? "TRUE" : "FALSE"); while (::GetMessage(&msg, NULL, 0, 0)) { // 轉化鍵盤訊息 ::TranslateMessage(&msg); // 將訊息傳送到相應的視窗函式 ::DispatchMessage(&msg); } getchar(); getchar(); return 0; }

關鍵點說明:

  • WndProc 訊息處理函式中,對於我們不處理的訊息一定要呼叫:DefWindowProc 否則CreateWindow 失敗,且返回:126
    這裡寫圖片描述
    通過上圖我們可以看到,其實在呼叫CreateWindow 的時候,已經開始呼叫我們的WndProc 函數了,只是因為我們沒有正確處理一些視窗訊息,因此呼叫失敗,當我們增加DefWindowProc 函式的呼叫後,CreateWindow 返回成功

  • 如何找到我們的視窗
    剛開始視窗這個視窗後,通過FindWindow 函式以及spy++均找不到我們的視窗標題以及類,但是通過指定的控制代碼卻可以收發訊息。
    後來看到如下網址:
    https://msdn.microsoft.com/en-us/library/windows/desktop/ms632599(v=vs.85).aspx#message_only
    這裡寫圖片描述
    由此可得到查詢message-obly 型別的視窗的方法:

FindWindowExA(HWND_MESSAGE, NULL, "類名", "視窗名");

至此我們可以通過視窗訊息正常通訊了

  • 不要忘了main 函式中的訊息迴圈,什麼都不是憑空而來的,Windows 訊息機制的核心也就是這一個迴圈了

  • 以上