2017-01-30 51 views
0

1つのスレッドから、ウィンドウプロシージャのメインスレッドにメッセージを送信します。 しかし、それは失敗です。同じスレッドからメッセージを送信するとすべてOKです。SendNotifyMessageは正しいメッセージを送信しません

include "stdafx.h" 
#include <Windows.h> 
#include <atlbase.h> 


#define MAX_THREADS 1 

HWND m_wnd; 

enum 
{ 
    EVENT_CALL = (WM_APP + 0x30), 
}; 


static LRESULT CALLBACK function_call() 
{ 
    //some code 
    int test = 0; 
    return 0; 
} 

static LRESULT CALLBACK http_message_proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
     switch (uMsg) 
     { 
     case EVENT_CALL: 
      function_call(); 
      return 0; 
     } 
    return ::DefWindowProc(hWnd, uMsg, wParam, lParam); 
} 

void CreateNotifyWnd() 
{ 
    WNDCLASSEX w = { 0 }; 
    w.cbSize = sizeof(w); 
    w.hInstance = (HINSTANCE)&__ImageBase; 
    w.lpszClassName = L"uistone_http_event_wnd"; 
    w.lpfnWndProc = http_message_proc; 
    ::RegisterClassEx(&w); 
    int error = GetLastError(); 
    m_wnd = ::CreateWindowEx(0, w.lpszClassName, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, w.hInstance, 0); 
    error = GetLastError(); 
} 


DWORD WINAPI SendThread(void* request_param) 
{ 
    ::SendNotifyMessage(m_wnd, EVENT_CALL, 11, 12); 
    int error = GetLastError(); 
    return 0; 
} 


int main() 
{ 
    CreateNotifyWnd(); 
    HANDLE hThreadArray[MAX_THREADS]; 

    hThreadArray[0] = CreateThread(nullptr, 0, SendThread, nullptr, 0, nullptr); 
    //::SendNotifyMessage(m_wnd, EVENT_CALL, 11, 12); 

    WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE); 

    return 0; 
} 

他のスレッドからメッセージをキャッチできないのはなぜですか?おかげさまで

+0

あなたは) https://en.wikipedia.org/wiki/Message_loop_in_Microsoft_Windows – UKMonkey

+0

1 ...メッセージループを持っていないように見えますどこのメッセージループがありますか? 2)あなたのコードがメッセージをキャッチするかどうかを確認する方法は? –

+0

http_message_procはプログラム内のループの関数です –

答えて

1

これは文書化された動作です。ウィンドウが呼び出し元のスレッドによって作成された場合、SendNotifyMessageは、ウィンドウのウィンドウプロシージャを呼び出し、ウィンドウプロシージャがメッセージを処理するまで戻らない

:これはSendNotifyMessageドキュメントから関連する部分です。 ウィンドウが別のスレッドによって作成された場合、SendNotifyMessageはメッセージをウィンドウプロシージャに渡し、すぐに戻ります。ウィンドウプロシージャがメッセージの処理を終了するのを待つことはありません。

同じスレッドで作成されたウィンドウで使用した場合、あなたがSendNotifyMessageを呼び出すときに、関数は同期返す前にターゲットウィンドウに関連付けられたウィンドウプロシージャを呼び出すので、これは、動作しているように見えます。コールがスレッドを横切る場合

は、他の一方で、あなたはのためのメッセージループを実行する必要があるだろう - 今、キューに入れられた - メッセージがウィンドウプロシージャ1)をピックアップし渡さ取得します。アプリケーションはメッセージループを実行せず、メッセージがターゲットウィンドウに到達する前に終了します。

これを修正するには、メッセージループを実行する必要があります。これはあなたの問題に対する正しいアプローチであるかもしれません。私たちはわからないので、あなたが解決しようとしている問題は、潜在的に優れたアプローチと解決策を提案することはできません。


1) About Messages and Message Queues: Message Routingを参照してください。

+0

' CreateNotifyWnd'でウィンドウのメッセージループを作成しました。 –

+0

@MartinJuin:あなたが投稿したコードにありません。 [ウィンドウプロシージャ](https://msdn.microsoft.com/en-us/library/windows/desktop/ms632593.aspx)を登録しましたが、メッセージキューを廃棄したり、メッセージをディスパッチするループはありません。 – IInspectable

+0

これは私のエラーです。ループはありません。しかし、私はこのループを書く必要がありましたか? –

関連する問題