基於訊息,事件驅動的點滴感悟
阿新 • • 發佈:2019-02-06
在入門windows程式設計時,我們總會聽到這麼一句:Message Based,Event Driven。
今天在解決Bug00173911 TL2.6:合併視窗,滑動滑鼠使得右上角的收縮按鈕展開,拖動視窗至最大化,關閉按鈕顯示為還原按鈕 時有點感觸。
在解決該bug後,除錯過程中發現,視窗的最大化和還原狀態與右上角的Button狀態偶爾對應不上,後面跟蹤發現因為win7系統有針對桌面視窗自動排列的功能,當我們拖動一個視窗移動到桌面右邊邊緣時,系統會將視窗自動鋪滿半個螢幕。而xp中沒有此功能,因此我們在處理雙擊標題欄是否最大化/還原問題時用了以下的程式碼。
LRESULT CChatDlgWnd::HandleMessage( UINT message, WPARAM wParam, LPARAM lParam )
{
if ( message == WM_NCLBUTTONDBLCLK && wParam == HTCAPTION )
{
if ( m_bMaxShow )
{
::GetWindowRect( m_hWnd, &m_rcWnd );
m_btnMax->SetVisible( true );
m_btnRestore->SetVisible( false );
m_bMaxShow = false;
}
else
{
::GetWindowRect( m_hWnd, &m_rcWnd );
m_btnMax->SetVisible( false );
m_btnRestore->SetVisible( true );
m_bMaxShow = true;
}
}
// ...
}
但按以上的操作讓系統對視窗進行自動排列後,此時窗口占半個螢幕大小,並非最大化狀態,雙擊視窗的標題欄,會發現系統的行為並非是將視窗置為Max狀態,還是Restored狀態。
當時覺得在雙擊最大化或是還原的時候,視窗應該會收到系統發來的調整視窗位置的訊息,
後用SPY++抓了一下視窗訊息,發現在雙擊標題欄時會收到WM_SIZE 訊息。
,wParam為相應的
#define SIZE_RESTORED 0 #define SIZE_MINIMIZED 1 #define SIZE_MAXIMIZED 2 #define SIZE_MAXSHOW 3 #define SIZE_MAXHIDE 4
因此果斷用WM_SIZE替代了原先的程式碼。
用這樣的方式同樣在響應最大化/還原按鈕時無需進行額外的操作將m_btnMax和m_btnRestore切換顯示隱藏。bool CChatDlgWnd::OnBnClickedMax( TNotifyUI& msg )
{
SendMessage( WM_SYSCOMMAND, SC_MAXIMIZE, 0 );
// m_btnMax->SetVisible( false );
// m_btnRestore->SetVisible( true );
}
這個案例很細微,但是在一定程度上卻反應了一些問題,在WINDOWS