2014-04-23 93 views
1

使用VB.NET/C# - .Net Framework 3.5。我目前處於WinForms事件的處理程序中(例如)。在處理程序中,我希望將自己的事件放入窗口消息泵中,但在隊列末尾(假設它泵送消息FIFO)。我希望我的處理程序和任何其他處理程序能夠執行當前事件,並且隨後拿起我插入隊列並調用處理程序的自定義事件。關於如何將事件插入Windows事件隊列(不關心什麼語言)的示例代碼?如何將事件添加到Windows消息泵隊列中?

+0

可能重複[?如何更新從C#另一個線程的GUI(http://stackoverflow.com/questions/661561/how-to-更新-gui-from-another-thread-in-c) – Servy

+0

@Servy我不明白這是如何重複的? – Stijn

+0

這是如何重複? – Denis

回答

3

如果你想添加一條消息到隊列中,那麼你只需要P/Invoke PostMessage function。正如文檔所述,此功能:

在與創建指定窗口的線程關聯的消息隊列中放置消息,並返回而無需等待線程處理消息。

樣品的P/Invoke聲明:

[return: MarshalAs(UnmanagedType.Bool)] 
[DllImport("user32", SetLastError = true)] 
static extern bool PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); 
  • hWnd是一個句柄到你的窗口,其窗口過程應該接收消息的一個。在WinForms中,這可以使用Handle屬性進行檢索。

  • msg是您要發佈的訊息。當然,你需要弄清楚在這裏使用哪一個。如果其中一條標準信息適用於您的目的,那麼您可以使用它。否則,只需定義一個用戶定義的消息。用戶定義的消息的值範圍> = WM_USER。所以:

    const uint WM_USER = 0x0400; 
    const uint UWM_MYGREATMESSAGE = WM_USER + 1; 
    const uint UWM_MYOTHERMESSAGE = WM_USER + 2; 
    
  • 顯然,wParamlParam包含特定消息的信息。如果您使用的是標準消息之一,他們的文檔將告訴您在這裏指定的內容。如果您使用用戶定義的消息,那麼您幾乎可以通過任何您想要的東西,包括IntPtr.Zero,如果您不需要任何自定義數據。

+0

@CodyGray的+1在長時間缺席後回到SO。現在我有人要再次戰鬥:P –

+0

這是不必要的複雜的程序。目前已經建成張貼到消息隊列框架多種工具,也沒有必要程序複雜化,減少維修,或在這裏明確地使用非託管代碼增加了出錯的機會。 – Servy

+0

@Servy我知道這是一個古老的問題,但這個答案對我很有用。如果你知道一種方法來實現沒有PostMessage的延遲UI線程執行,你能否創建一個答案?請注意'Control.Invoke'是不夠的(它同步運行)...也許'BeginInvoke'會工作,但它不是顯然是正確的。 –

2

我真的很喜歡@CodyGray給出的工程示例。 自從我在Delphi中使用Win32的東西已經有一段時間了:)。

儘管如此,我仍然無法保持我的手指,並不得不分享這個想法,因爲我認爲這可能會更簡單。

假設您有一段代碼。我們稱之爲A。 假設它由10條語句組成。我們稱它們爲a0a9。 因此,我們的代碼塊看起來是這樣的:

{ 
    a0; 
    a1; 
    ... 
    a4; 
    a5; 
    ... 
    a8; 
    a9; 
} 

現在說你寫出來這個塊作爲一個Windows事件處理程序窗體控件:

void button1_Click(object sender, EventArgs e) { 
    a0; 
    a1; 
    ... 
    a8; 
    a9; 
} 

突然你意識到你想立即執行a0至a4,並延遲執行a5至a9。後來的意思是儘快但消息泵閒置後。

所有你需要做的是:

void button1_Click(object sender, EventArgs e) { 
    a0; 
    a1; 
    a2; 
    a3; 
    a4; 

    this.BeginInvoke(() => { 
     a5; 
     a6; 
     a7; 
     a8; 
     a9; 
    }); 
} 
相關問題