1. 程式人生 > >基於訊息,事件驅動的點滴感悟

基於訊息,事件驅動的點滴感悟

在入門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_btnMaxm_btnRestore切換顯示隱藏。
bool CChatDlgWnd::OnBnClickedMax( TNotifyUI& msg )
{
	SendMessage( WM_SYSCOMMAND, SC_MAXIMIZE, 0 );
// 	m_btnMax->SetVisible( false );
// 	m_btnRestore->SetVisible( true );	
}

這個案例很細微,但是在一定程度上卻反應了一些問題,在WINDOWS
平臺下,依據其自身的規則,基於訊息去程式設計,往往程式碼更簡練高效得多,維護成本也低。可能在社會生存也是如此,順勢而為,更容易成功。