Flu*_*ike 0 c# winapi wndproc .net-6.0
我使用 .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);
Run Code Online (Sandbox Code Playgroud)
当窗口在屏幕上可见时,我的情况与此人相同窗口呈现良好,但对用户没有响应。当我将鼠标悬停在窗口上时,鼠标指针变为加载圆圈。
我认为无响应是由于窗口事件和消息未得到处理。我想以某种方式覆盖或挂钩 Win32 窗口的 WndProc 方法来处理消息,因为显然User32.GetMessage() 不会返回所有消息。
在 WPF 中,您可以向 HwndHost 添加一个挂钩来处理 WndProc 消息。如何在不使用 WPF 的情况下获取 .Net 6 中的 WndProc 消息?
小智 5
TL;DR:本质上,无响应是由于您的代码没有处理有问题的窗口的Windows 消息泵。
正如您的行中提到的“您需要获取窗口的消息并相应地分派它们”。即GetMessage,,,,全部在一个循环内TranslateMessage,也称为消息循环。DispatchMessagewhile
我想以某种方式覆盖或挂钩Win32 窗口的 WndProc 方法来处理消息,显然......
事情不是这样的。如果您在流程中创建一个窗口,那么您有责任提供消息循环并对其采取行动。否则,您将体验到您现在所看到的一切 - 冻结的窗口。 “钩子”在这里不是正确的术语。
例如
User32.MSG msg;
while (User32.GetMessage(msg, hWnd, null, null) > 0)
{
User32.TranslateMessage(msg);
User32.DispatchMessage(msg);
}
Run Code Online (Sandbox Code Playgroud)
我怀疑您的应用程序是一个控制台应用程序,默认情况下不包含 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 应用程序。
因此,您需要消息泵。
| 归档时间: |
|
| 查看次数: |
1076 次 |
| 最近记录: |