如何正确处理Win32 GUI消息循环?

用户名

我正在做一个简单的文本编辑器win32应用程序,很有趣。我的程序有一个特殊的问题。看来我的程序退出时没有返回零。相反,它返回1385929。当我的主GUI窗口被破坏时,我使用PostQuitMessage( 0 ),但似乎不是在主函数的中返回的东西message.wParam到目前为止,这是我的代码,

#define WIDTH 500
#define HEIGHT 400

#define EDIT_ID 10

LRESULT CALLBACK windowProc( HWND window, UINT message, WPARAM wParam, LPARAM lParam )
{
    static HDC deviceContext = INVALID_HANDLE_VALUE;
    static HWND editControl = INVALID_HANDLE_VALUE;

    switch ( message )
    {
        case WM_CREATE :
            deviceContext = GetDC( window );

            if ( !deviceContext )
            {
                showWindowsError( "Creating Device Context", FALSE );
                DestroyWindow( window );
            }

            editControl = CreateWindow(
                                       "EDIT",
                                       NULL,
                                       WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_LEFT |
                                       ES_MULTILINE | ES_AUTOVSCROLL | ES_NOHIDESEL,
                                       0,
                                       0,
                                       0,
                                       0,
                                       window,
                                       ( HMENU )EDIT_ID,
                                       ( HINSTANCE )GetWindowLong( window, GWL_HINSTANCE ),
                                       NULL
                                      );

            if ( !editControl )
            {
                showWindowsError( "Creating Edit Control", TRUE );
                DestroyWindow( window );
            }

            return 0;
        break;

        case WM_COMMAND :
            switch ( wParam )
            {
                case WM_UNDO :
                    SendMessage( editControl, WM_UNDO, 0, 0 );
                break;

                case WM_CUT :
                    SendMessage( editControl, WM_CUT, 0, 0 );
                break;

                case WM_COPY :
                    SendMessage( editControl, WM_COPY, 0, 0 );
                break;

                case WM_PASTE :
                    SendMessage( editControl, WM_PASTE, 0, 0 );
                break;

                case WM_CLEAR :
                    SendMessage( editControl, WM_CLEAR, 0, 0 );
                break;

                default:
                    return DefWindowProc( window, message, wParam, lParam );
            }

        case WM_SIZE :
            MoveWindow( editControl, 0, 0, LOWORD( lParam ), HIWORD( lParam ), TRUE );

            return 0;
        break;

        case WM_DESTROY :
            ReleaseDC( window, deviceContext );
            DestroyWindow( editControl );
            PostQuitMessage( 0 );

            return 0;
        break;
    }

    return DefWindowProc( window, message, wParam, lParam );
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR CmdArgs, int nCmdShow )
{
    WNDCLASSEX windowClass = { 0 };
    HWND window = INVALID_HANDLE_VALUE;

    MSG message = { 0 };
    HBRUSH windowColor = CreateSolidBrush( GetSysColor( COLOR_WINDOW ) );

    windowClass.cbSize = sizeof( windowClass );
    windowClass.style = CS_HREDRAW | CS_VREDRAW;
    windowClass.lpfnWndProc = windowProc;
    windowClass.hInstance = hInstance;
    windowClass.hCursor = LoadCursor( NULL, IDC_ARROW );
    windowClass.hIcon = LoadIcon( NULL, IDI_APPLICATION );
    windowClass.hbrBackground = windowColor;
    windowClass.lpszClassName = "TextEditorWindow";

    if ( !RegisterClassEx( &windowClass ) )
    {
        DeleteObject( windowColor );
        showWindowsError( "Registering Windows Class", TRUE );
    }

    window = CreateWindow(
                           "TextEditorWindow",
                           "Text Editor",
                           WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
                           CW_USEDEFAULT,
                           CW_USEDEFAULT,
                           WIDTH,
                           HEIGHT,
                           NULL,
                           NULL,
                           hInstance,
                           NULL
                        );

    if ( !window )
    {
        DeleteObject( windowColor );
        showWindowsError( "Creating GUI", TRUE );
    }

    ShowWindow( window, SW_SHOW );
    UpdateWindow( window );

    do
    {
        TranslateMessage( &message );
        DispatchMessage( &message );
    } while ( GetMessage( &message, window, 0, 0 ) > 0 );

    DeleteObject( windowColor );
    return message.wParam;
}
伊尔卡

您的调用GetMessage()将第二个参数设置为窗口的HWND,这将接收到的消息仅限制为发送到该窗口的消息-请参阅API函数的文档

WM_QUIT另一方面,消息是发送到运行消息泵的线程的消息,没有任何特定的窗口。由于存在该过滤器,因此您不会收到它,message.wParam也永远不会将其设置为0

但是,为什么循环结束并且程序仍然关闭?由于HWNDinwindow在窗口关闭后变为in无效,因此GetMessage()以错误结束并返回-1


此外,您当前正在调用TranslateMessage()DispatchMessage()并且message在第一次迭代之前用正确的数据填充之前。循环应该是这样的:

while ( GetMessage( &message, NULL, 0, 0 ) > 0 )
{
    TranslateMessage( &message );
    DispatchMessage( &message );
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何处理Win32错误消息的占位符?

来自分类Dev

适用于OpenGL的Win32主消息循环

来自分类Dev

用“无限”循环正确处理QtConcurrent

来自分类Dev

如何在一行命令中正确处理 FOR 循环中的重定向?

来自分类Dev

如何正确处理 foreach 循环以及数组中递增的动态内容

来自分类Dev

什么是Win32消息编组?

来自分类Dev

未定义的WIN32消息

来自分类Dev

为什么在线程化时win32消息循环停止工作?

来自分类Dev

如何在Gui win32编程中使用静态标签和按钮

来自分类Dev

如何将Win32鼠标消息转换为WPF鼠标事件?

来自分类Dev

如何使屏幕阅读器阅读WPF消息的方式类似于阅读Win32 MessageBox?

来自分类Dev

foreach循环可以正确处理列表长度的变化吗?

来自分类Dev

foreach循环能正确处理列表长度的变化吗?

来自分类Dev

Win32应用程序是否有一个消息循环?还是每个窗口一个消息循环?

来自分类Dev

Poco C ++库和Win32 GUI集成

来自分类Dev

如何正确处理httpClient?

来自分类Dev

如何正确处理scanf()

来自分类Dev

如何正确处理并发?

来自分类Dev

如何正确处理导航

来自分类Dev

win32可执行资源如何处理?

来自分类Dev

Win32可执行资源如何处理?

来自分类Dev

如何使用for循环的实时结果更新GUI?

来自分类Dev

如何使用无限for循环连续显示消息?

来自分类Dev

如何使用循环显示多个错误消息

来自分类Dev

如何循环播放并在中途显示消息

来自分类Dev

正确使用Win32线程

来自分类Dev

Flask下的fork如何正确处理?

来自分类Dev

如何正确处理Visual Studio关闭?

来自分类Dev

OCaml:如何正确处理总和类型?