【问题标题】:Is there a way I can pass another parameter to use inside this window callback function?有没有办法可以传递另一个参数以在此窗口回调函数中使用?
【发布时间】:2019-11-16 18:12:38
【问题描述】:
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

因此,这是使用 Windows API (win32) 创建的某个窗口的窗口过程的函数原型。它用于处理一些窗口消息,例如当用户单击关闭按钮或调整窗口大小时。

WNDCLASSA window_class = {0};
window_class.style = CS_HREDRAW|CS_VREDRAW;
window_class.lpfnWndProc = WindowProc;
window_class.hInstance = instance;

这是使用此函数的地方,作为窗口类 WNDCLASSA 的 WNDPROC 类型,如 win32 API 中所定义。如您所见,我没有传递函数原型中定义的这四个参数中的任何一个。

我需要传递一些额外的参数以在 WindowProc 函数内部的一些消息中进行处理,但我不知道如何传递它们,我不想为此使用全局变量。我读到这是使用 WM_CREATE 消息执行此操作的一种方法,但我不确定此方法是否正是我想要做的。

有没有使用win32 API经验的人可以指导我完成这个?

【问题讨论】:

  • 该函数是由 Windows 操作系统调用的,而不是由您调用的。您不得更改其签名。但是,如果您希望变量保留其值,您可以在函数内将变量声明为静态变量。
  • 您心中有哪些具体信息?你要寄吗?
  • @DavidHeffernan 我有一个渲染缓冲区结构来绘制窗口。当窗口收到 WM_SIZE 消息时,我想更改此结构的一些值。我现在拥有的是这个结构的全局变量,每次收到 WM_SIZE 消息时都会更新。我不想把它作为一个全局变量,而只是将此结构作为回调函数中的参数传递。
  • 您不发送 WM_SIZE,系统会发送。它不会向您发送您的信息。

标签: c windows winapi functional-programming


【解决方案1】:

在创建窗口时,您可以将用户定义的值与其关联,例如对象指针。有几种方法可以实现这种关联:

  • SetWindowLongPtr(GWLP_USERDATA)

  • SetProp()

  • SetWindowSubclass()

在您的特定情况下,SetWindowSubclass() 将特别有用,因为它允许您将用户定义的值作为额外参数直接传递给您的消息过程,而不是将值存储在 HWND 中。这种方法的缺点是您的子类过程不会看到CreateWindow/Ex() 发送的任何初始设置消息,并且您无法从 HWND 本身访问值。

对于其他Set 功能,您可以手动设置关联。您可以等到CreateWindow/Ex() 退出后再调用其中一个函数,但通常最好将您的用户定义值传递给CreateWindow/Ex()lParam 参数,然后您可以在消息过程中的WM_NCCREATE 消息并使用所需的 Set 函数将其分配给 HWND,然后您可以随时从 HWND 检索值,尤其是在消息过程中的后续消息上,使用相应的 Get 函数。

【讨论】:

  • OP 正在注册一个窗口类。这允许他们通过传递一个非零的cbWndExtra 值来关联任意数量的内存供他们使用。
  • @IInspectable true,但由于窗口类已经有sizeof(void*)GWL_USERDATA 免费分配的额外字节数,因此通常不需要使用cbWndExtra,除非您需要保留更多字节,大多数人没有
  • GWLP_USERDATA 并不打算由窗口类的实现者使用。 documentation 建议:“此数据供创建窗口的应用程序使用。”
【解决方案2】:

如果您在谈论自定义消息,通常的答案是创建一个结构并将指向该结构实例的指针作为消息参数之一传递。大量现有消息都遵循此模型(几乎所有 WM_NOTIFY 消息都需要不仅仅是 NMHDR)。

如果您想要一个可用于由特定窗口类处理的所有消息的值,一种简单的方法是使用 SetWindowLongPtr 设置 GWLP_USERDATA 值,然后使用 GetWindowLongPtr 检索它,这确实有一个缺点可通过子类扩展。如果这是一个问题,我会遵循 MFC 模型并使用 CBT 挂钩将自定义数据类型的实例与 HWND 相关联。

【讨论】:

    猜你喜欢
    • 2011-02-10
    • 1970-01-01
    • 2021-06-10
    • 2021-08-15
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    相关资源
    最近更新 更多