我正在使用 .Net 6 和PInvoke nuget 包來訪問 Win32 API,并通過以下方式創建 Win32 視窗:
IntPtr windowHandle = User32.CreateWindowEx(User32.WindowStylesEx.WS_EX_TOOLWINDOW,
"static",
"Window Title",
User32.WindowStyles.WS_OVERLAPPEDWINDOW |
User32.WindowStyles.WS_VISIBLE,
0,
0,
800,
800,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero);
當視窗在螢屏上可見時,我的情況與此人相同。視窗渲染良好,但對用戶無回應。當我將滑鼠懸停在視窗上時,滑鼠指標變為加載圓圈。
我相信不回應是由于沒有處理視窗事件和訊息。我想以某種方式覆寫或掛鉤 Win32 視窗的 WndProc 方法來處理訊息,因為顯然User32.GetMessage() 不會回傳所有訊息。
在 WPF 中,您可以向 HwndHost 添加一個掛鉤來處理 WndProc 訊息。如何在不使用 WPF 的情況下在 .Net 6 中獲取 WndProc 訊息?
uj5u.com熱心網友回復:
TL;DR:基本上無回應是由于您的代碼沒有為有問題的視窗處理Windows 訊息泵。
正如您在“您需要獲取視窗的訊息并相應地調度它們”行中所述。即GetMessage, TranslateMessage, DispatchMessage, 都在一個while回圈中,也稱為訊息回圈。
我想以某種方式覆寫或掛鉤Win32 視窗的 WndProc 方法來處理訊息,顯然......
這不是它的作業原理。如果您在流程中創建了一個視窗,那么您有責任提供訊息回圈并對其采取行動。否則你將體驗到你現在所看到的——一個凍結的視窗。 “鉤子”在這里不是正確的術語。
例如
User32.MSG msg;
while (User32.GetMessage(msg, hWnd, null, null) > 0)
{
User32.TranslateMessage(msg);
User32.DispatchMessage(msg);
}
我懷疑您的應用程式是默認情況下不包含 Windows 訊息泵的控制臺應用程式。這就是為什么您不應該使用控制臺應用程式專案向導來創建將公開 GUI 的東西的原因之一。雖然可以使控制臺應用程式顯示 GUI,但首先選擇為 GUI 量身定制的專案向導通常更容易。[%]
在 WPF 中,您可以向 HwndHost 添加一個掛鉤來處理 WndProc 訊息...
不要忘記,WPF 使用 Direct3D 作為渲染表面,除了應用程式視窗之外,沒有子 WIN32 視窗可言。這很容易通過將Spy 等工具指向WPF 應用程式來顯示。當 Microsoft 設計 WPF 時,他們需要一種讓Microsoft UI 自動化與子元素互動的方法。它這樣做而不必擔心子視窗。
% 腳注
說到將 GUI 壓縮成今天乍一看可能看起來像控制臺應用程式的東西,這就是C在C . C 應用程式可以在單個main()入口點啟動并提供一個視窗,但是沒有出現這樣的控制臺視窗,因此控制臺比較并不完全正確。
C 應用程式沒有太多的指導。有些人可能沒有用于圖示、鍵盤加速器、字串表之類的資源表,但它們仍然是 GUI 應用程式。
Microsoft Visual C 用 MFC(幾年后又用 ATL、WTL)改變了不同的 GUI 專案型別,并封裝了來自開發人員的很多東西,特別是訊息泵代碼,此外還提供了默認圖示、鍵盤加速器、字串表。
因此,使用控制臺專案向導制作 C# GUI 應用程式類似于簡單的 C GUI 應用程式。
因此,您需要您的訊息泵。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/485988.html
