gpt4 book ai didi

c++ - WndProc调用机制(WinAPI)

转载 作者:可可西里 更新时间:2023-11-01 11:06:05 25 4
gpt4 key购买 nike

我正在尝试了解 Windows 应用程序的工作原理。

有一个 WndProc 函数,其中发生消息处理。

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {   
switch (msg) {
case WM_KEYDOWN:
if (wParam == VK_ESCAPE) {
if (MessageBox(0, L"Are you sure?", L"Exit?", MB_YESNO | MB_ICONQUESTION) == IDYES)
//Release the windows allocated memory
DestroyWindow(hwnd);
}
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}

这个函数可以在两种情况下调用:

A) 在消息循环周期中由 DispatchMessage(&msg) 函数调用:

while (true){                       
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

B) 在接收到非队列消息时由 Windows 调用。

这是如何运作的? Windows如何在不使用并行的情况下立即调用WndProc函数?能否请您详细描述一下函数调用的机制?

MSDN 官方文档说:

Nonqueued messages are sent immediately to the destination window procedure, bypassing the system message queue and thread message queue. The system typically sends nonqueued messages to notify a window of events that affect it. For example, when the user activates a new application window, the system sends the window a series of messages, including WM_ACTIVATE, WM_SETFOCUS, and WM_SETCURSOR. These messages notify the window that it has been activated, that keyboard input is being directed to the window, and that the mouse cursor has been moved within the borders of the window. Nonqueued messages can also result when an application calls certain system functions. For example, the system sends the WM_WINDOWPOSCHANGED message after an application uses the SetWindowPos function to move a window.

原来非队列消息只在窗口初始化的时候出现,后面的所有非队列消息都只能是我程序调用WinAPI函数的结果?

最佳答案

没有什么特别魔法,如果 SendMessage 从创建窗口的同一线程调用,则窗口过程直接由 SendMessage 调用, 否则请求被排队并且 SendMessage() 等待直到消息循环处理请求。这是记录在案的行为:

SendMessage function

If the specified window was created by the calling thread, the window procedure is called immediately as a subroutine. If the specified window was created by a different thread, the system switches to that thread and calls the appropriate window procedure. Messages sent between threads are processed only when the receiving thread executes message retrieval code. The sending thread is blocked until the receiving thread processes the message.

PeekMessage function

Dispatches incoming sent messages, checks the thread message queue for a posted message, and retrieves the message (if any exist).

...

During this call, the system delivers pending, nonqueued messages, that is, messages sent to windows owned by the calling thread using the SendMessage, SendMessageCallback, SendMessageTimeout, or SendNotifyMessage function. Then the first queued message that matches the specified filter is retrieved. The system may also process internal events.

GetMessage function

Retrieves a message from the calling thread's message queue. The function dispatches incoming sent messages until a posted message is available for retrieval.

...

During this call, the system delivers pending, nonqueued messages, that is, messages sent to windows owned by the calling thread using the SendMessage, SendMessageCallback, SendMessageTimeout, or SendNotifyMessage function. Then the first queued message that matches the specified filter is retrieved. The system may also process internal events.

唯一的魔力是:

  • 有些消息并非“真正”排队,而是在没有更好的事情可做(→ 重绘、鼠标移动消息、计时器等)时由 GetMessage 合成;
  • 消息分发处理系统“知道”的消息的 Unicode 转换;窗口是“Unicode”还是“ANSI”取决于它是通过 RegisterWindowW 还是 RegisterWindowA 注册的,发送的消息是“Unicode”还是“ANSI”取决于它是通过 RegisterWindowW 还是 RegisterWindowA它是通过 SendMessageW/PostMessageW/... 或 SendMessageA/PostMessageA/... 发送的。如果两个不匹配系统适本地转换消息。

不涉及并行性,窗口过程的好处是它们总是从创建窗口的线程调用。

关于c++ - WndProc调用机制(WinAPI),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35248676/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com