Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Winapi 显示窗口后执行代码_Winapi_Event Loop - Fatal编程技术网

Winapi 显示窗口后执行代码

Winapi 显示窗口后执行代码,winapi,event-loop,Winapi,Event Loop,我正在开发一个windows应用程序,我正在自己实现整个事件循环和类似的一切(这是有原因的)。在一个地方,我需要在显示窗口后执行一些代码。通常,在创建窗口时,我会在收到WM_CREATE消息时进行一些初始化。WM_SHOWWINDOW在窗口显示之前发送。但是,我需要在第一次显示窗口之后立即执行一些代码。我似乎找不到在显示窗口后发送的通知消息。难道没有一个吗 当然,我可以保留一个布尔值-FirstRun-指示我是否执行了逻辑,然后在收到WM_ACTIVATE时执行代码,前提是布尔值为TRUE,然后

我正在开发一个windows应用程序,我正在自己实现整个事件循环和类似的一切(这是有原因的)。在一个地方,我需要在显示窗口后执行一些代码。通常,在创建窗口时,我会在收到WM_CREATE消息时进行一些初始化。WM_SHOWWINDOW在窗口显示之前发送。但是,我需要在第一次显示窗口之后立即执行一些代码。我似乎找不到在显示窗口后发送的通知消息。难道没有一个吗

当然,我可以保留一个布尔值-FirstRun-指示我是否执行了逻辑,然后在收到WM_ACTIVATE时执行代码,前提是布尔值为TRUE,然后将FirstRun设置为FALSE,以便下次收到WM_ACTIVATE时不会执行代码,但这对我来说似乎有点不自然


我已经很久没有在这个级别上进行win32编程了,所以记不太清楚了。这里最好的方法是什么?

没有,因为这就是WM_SHOWWINDOW的用途。将该消息传递到默认消息处理过程后,将显示该窗口。你能做的最好的事情就是通过某种定时器进行投票


你的程序设计似乎有缺陷,尽管你不得不依赖这样的东西。你想做什么?

没有,因为这就是WM_SHOWWINDOW的用途。将该消息传递到默认消息处理过程后,将显示该窗口。你能做的最好的事情就是通过某种定时器进行投票


你的程序设计似乎有缺陷,尽管你不得不依赖这样的东西。您想做什么?

没有特别通知,但在许多情况下,您可以使用以下技巧:

LRESULT CALLBACK MainWndProc(
HWND hwnd,        // handle to window
UINT uMsg,        // message identifier
WPARAM wParam,    // first message parameter
LPARAM lParam)    // second message parameter
{ 
switch (uMsg) 
{ 
    case WM_USER + 100:
        //window is just displayed, do some actions
        return DefWindowProc(hwnd, uMsg, wParam, lParam); 
    case WM_CREATE:
        PostMessage(hwnd, WM_USER + 100, 0, 0);
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    default: 
        return DefWindowProc(hwnd, uMsg, wParam, lParam); 
}
return 0;
}

没有特殊通知,但在许多情况下,您可以使用以下技巧:

LRESULT CALLBACK MainWndProc(
HWND hwnd,        // handle to window
UINT uMsg,        // message identifier
WPARAM wParam,    // first message parameter
LPARAM lParam)    // second message parameter
{ 
switch (uMsg) 
{ 
    case WM_USER + 100:
        //window is just displayed, do some actions
        return DefWindowProc(hwnd, uMsg, wParam, lParam); 
    case WM_CREATE:
        PostMessage(hwnd, WM_USER + 100, 0, 0);
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    default: 
        return DefWindowProc(hwnd, uMsg, wParam, lParam); 
}
return 0;
}

只要您自己实现整个事件循环以及类似的一切,就可以在WinMain()中直接处理它,如下所示:

HWND hWnd = CreateWindow(...);

if (!hWnd) return 0;

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

OnWindowJustDisplayed();    // here

MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

只要您自己实现整个事件循环以及类似的一切,就可以在WinMain()中直接处理它,如下所示:

HWND hWnd = CreateWindow(...);

if (!hWnd) return 0;

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

OnWindowJustDisplayed();    // here

MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

您是否可以侦听
WM_WINDOWPOSCHANGED
消息并测试
SWP_SHOWWINDOW
标志?这不会起作用,因为窗口可以在整个应用程序中显示和隐藏多次-但此代码只需要在第一次“显示”时执行。好的,记录你是否对此做出过反应,并且只做出一次反应。是的,这就是我在第二段中写的。我希望有更好的方法。你能监听
WM_WINDOWPOSCHANGED
消息并测试
SWP_SHOWWINDOW
标志吗?这不会起作用,因为窗口可以在整个应用程序中显示和隐藏多次-但这段代码只需要在第一次“显示”时执行。嗯,记录你是否对此做出过反应,并且只做出一次反应。是的,这就是我在第二段中写的。我希望有更好的办法。+1:我过去成功地做到了这一点。尽管从理论上讲,我们应该记住,WM是使用一些优先级从队列中拉出的。IIRC WM_油漆的优先级较低。但是这个把戏还是管用的。+1:我过去已经成功地做到了这一点。尽管从理论上讲,我们应该记住,WM是使用一些优先级从队列中拉出的。IIRC WM_油漆的优先级较低。但不管怎样,这个技巧还是有效的。