2012-12-31 116 views
1

我想要做的是在我的進程內的窗口上捕獲並等待WM_TIMER消息(儘管我無法控制這個消息)。在NativeWindow中等待消息

我正在嘗試使用AutoResetEvent以等待消息。

WaitForMaterialUpdate方法連接NativeWindow到窗口,並阻塞,直到它收到一條消息。

這是我使用的代碼:

public class MaterialEditorWindow : NativeWindow 
{ 
    private const int WM_TIMER = 0x0113; 

    private AutoResetEvent waiter; 

    public void WaitForMaterialUpdate(IntPtr handle) 
    { 
     waiter = new AutoResetEvent(false); 
     AssignHandle(handle); 
     waiter.WaitOne(5000); 
     ReleaseHandle(); 
    } 

    protected override void WndProc(ref Message m) 
    { 
     if (m.Msg == WM_TIMER) waiter.Set(); 
     base.WndProc(ref m); 
    } 
} 

我在一個非常調試的環境是沒有,但我一直在使用MessageBox該窗口實際上是在等待期間接收WM_TIMER的消息,但WaitOne證實在返回之前始終等待完整的5000毫秒超時時間。

任何想法,我要去哪裏錯了?

+0

是否在UI線程中運行? – SLaks

+0

@SLaks是的。我應該從另一個線程調用'WaitOne'嗎?如果是這樣,爲什麼即使在這種狀態下,我仍然可以得到'MessageBox'彈出窗口? – Rotem

+0

'MessageBox'泵用戶界面消息。 – SLaks

回答

1

WaitOne()是一個阻塞呼叫。
直到WaitOne()返回,UI線程纔會收到任何消息。由於您在UI線程收到消息時設置了等待句柄,因此會出現死鎖。

您需要在後臺線程上執行此操作,或者只需在收到消息時調用回調函數。

+0

我明白了。謝謝。由於環境的具體情況需要同步完成,所以我可能會使用'while(!msgReceived)Application.DoEvents()'來自己抽取消息,而不是'AutoResetEvent'。 – Rotem

+0

這是不準確的,當在UI線程上調用WaitOne()時,CLR抽取消息循環。見http://stackoverflow.com/questions/4540244/how-is-this-possible-onpaint-processed-while-in-waitone –