首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >关闭仅消息窗口时出现问题- C++

关闭仅消息窗口时出现问题- C++
EN

Stack Overflow用户
提问于 2011-04-27 06:05:53
回答 1查看 945关注 0票数 1

我的应用程序有一个从新创建的线程启动的纯消息窗口。线程函数创建仅限消息的窗口并运行消息泵。我遇到的问题是消息泵似乎永远不会收到WM_CLOSE消息。为了简化发布的代码,我删除了错误处理。有人知道我做错了什么吗?

构造函数:

代码语言:javascript
运行
复制
this->m_hInstance = ::GetModuleHandle( NULL );

this->m_wcx.cbSize = sizeof(WNDCLASSEX);  // size of structure
this->m_wcx.style = CS_HREDRAW | CS_VREDRAW; // initially minimized
this->m_wcx.lpfnWndProc = &WndProc;       // points to window procedure
this->m_wcx.cbClsExtra = 0;               // no extra class memory
this->m_wcx.cbWndExtra = 0;               // no extra window memory
this->m_wcx.hInstance = m_hInstance;      // handle to instance
this->m_wcx.hIcon = ::LoadIcon( NULL, IDI_APPLICATION ); // default app icon
this->m_wcx.hCursor = ::LoadCursor( NULL, IDC_ARROW ); // standard arrow cursor
this->m_wcx.hbrBackground = NULL;         // no background to paint
this->m_wcx.lpszMenuName = NULL;          // no menu resource
this->m_wcx.lpszClassName = s_pwcWindowClass; // name of window class
this->m_wcx.hIconSm = NULL;               // search system resources for sm icon

this->m_atom = ::RegisterClassEx( &m_wcx );

this->m_hNotifyWindowThread = ::CreateThread(
    NULL,                           // no security attributes
    0,                              // use default initial stack size
    reinterpret_cast<LPTHREAD_START_ROUTINE>(NotifyWindowThreadFn), // function to execute in new thread
    NULL,                           // thread parameters
    0,                              // use default creation settings
    NULL                            // thread ID is not needed
    );

析构函数:

代码语言:javascript
运行
复制
::DestroyWindow( this->m_hWnd );
::WaitForSingleObject( this->m_hNotifyWindowThread, NW_DEFAULT_TIMEOUT ); // <-- Seems to get stuck here.
::UnregisterClass( s_pwcWindowClass, this->m_hInstance );

线程函数:

代码语言:javascript
运行
复制
s_ptInterface->pobjNotifyWindow->m_hWnd = ::CreateWindow(
    s_pwcWindowClass,               // window class name
    s_pwcWindowName,                // window name
    WS_ICONIC,                      // window style is minimized
    0,                              // initial horizontal position
    0,                              // initial vertical position
    CW_USEDEFAULT,                  // window width
    0,                              // window height
    NULL,                           // no parent window
    NULL,                           // no menu
    s_ptInterface->pobjNotifyWindow->GetInstanceHandle(), // associated instance
    NULL                            // no additional info for WM_CREATE
    );

::ShowWindow( s_ptInterface->pobjNotifyWindow->GetWindowHandle(), SW_HIDE );
::UpdateWindow( s_ptInterface->pobjNotifyWindow->GetWindowHandle();

dbt.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
dbt.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
dbt.dbcc_classguid = s_guidForCP210xDevices;

m_hNotify = RegisterDeviceNotification( m_hWnd, &dbt, DEVICE_NOTIFY_WINDOW_HANDLE );

while ( (blRetVal = ::GetMessage(
    &msg,                           // message structure
    NULL,                           // retrieve messages for all windows on this thread
    0,                              // lowest message value to retrieve
    0                               // highest message value to retrieve
    )) != 0 )
{
    if ( blRetVal == -1 )
    {
        return ::GetLastError();
    }
    else
    {
        ::TranslateMessage( &msg );
        ::DispatchMessage( &msg );
    }
}

窗口过程:

代码语言:javascript
运行
复制
switch ( uMsg )
{
case WM_CLOSE:
    if ( m_hNotify != NULL )
    {
        ::UnregisterDeviceNotification( m_hNotify );
        m_hNotify = NULL;
    }

    ::DestroyWindow( hWnd );
    break;

case WM_DESTROY:
    ::PostQuitMessage( 0 );
    break;

case WM_DEVICECHANGE:
    if ( pHeader != NULL )
    {
        if ( pHeader->dbch_devicetype == DBT_DEVTYP_PORT )
        {
            switch ( wParam)
            {
            case DBT_DEVICEREMOVECOMPLETE:      // Device is gone
                ::EnterCriticalSection( &(s_ptInterface->csSerialPort) );
                s_ptInterface->pobjSerialPort->Close();
                ::LeaveCriticalSection( &(s_ptInterface->csSerialPort) );
                break;

            case DBT_DEVICEARRIVAL:             // System detected device
                ::EnterCriticalSection( &(s_ptInterface->csSerialPort) );
                s_ptInterface->pobjSerialPort->Open();
                ::LeaveCriticalSection( &(s_ptInterface->csSerialPort) );
                break;

            default:
                // Do nothing.
                break;
            }
        }
    }
    break;

default:
    // Do nothing.
    break;
}

return ::DefWindowProc( hWnd, uMsg, wParam, lParam );
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-04-27 07:35:37

当Windows要求你的应用程序关闭窗口时,会发送WM_CLOSE。例如,当用户单击右上角的Close按钮或按下Alt+F4时。这些都不会发生,您调用了DestroyWindow()。您需要改用WM_DESTROY。这很好,不需要否决关闭请求。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5797032

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档