定時器是win32編程中經常使用的製做動畫效果的手段。在Win32編程中,可使用::SetTimer來建立定時器,定時器消息會被會發到調用SetTimer時指定的HWND。編程
在SOUI中通常來講只有一個宿主窗口有HWND,全部的SWindow都屬於一個宿主窗口,如此一來直接使用::SetTimer建立的定時器就難以直接分發到SWindow對象了。函數
爲了可以方便的在SWindow中使用定時器,在SOUI系統中,咱們經過將定時器ID(共32位)按位進行分解:動畫
class SOUI_EXP STimerID { public: DWORD Swnd:24; //窗口句柄,若是窗口句柄超過24位範圍,則不能使用這種方式設置定時器 DWORD uTimerID:7; //定時器ID,一個窗口最多支持128個定時器。 DWORD bSwndTimer:1; //區別通用定時器的標誌,標誌爲1時,表示該定時器爲SWND定時器 STimerID(SWND hWnd,char id) { SASSERT(hWnd<0x00FFFFFF && id>=0); bSwndTimer=1; Swnd=hWnd; uTimerID=id; } STimerID(DWORD dwID) { memcpy(this,&dwID,sizeof(DWORD)); } operator DWORD &() const { return *(DWORD*)this; } };
低24位用來存儲SWindow的窗口ID(swnd)。swnd是一個SWindow建立序號,在一個應用中,一般很難產生超過0xFFFFFF(16777215)個窗口對象,所以使用低24位來存儲窗口ID在大部分狀況下都是夠用的了。this
高8位中保留最高位設置爲1,用來區別直接使用::SetTimer建立的定時器(不能夠把最高位置1)。spa
剩下7位用於SWindow中做爲定時器ID。所以在SOUI中,一個SWindow最多能夠建立0-127個定時器。code
建立定時器:對象
SWindow::SetTimer(0~127);
/** * SWindow::SetTimer * @brief 利用窗口定時器來設置一個ID爲0-127的SWND定時器 * @param char id -- 定時器ID * @param UINT uElapse -- 延時(MS) * @return BOOL * * Describe 參考::SetTimer */ BOOL SWindow::SetTimer(char id,UINT uElapse);
銷燬定時器:blog
SWindow::KillTimer;接口
/** * KillTimer * @brief 刪除一個SWND定時器 * @param char id -- 定時器ID * @return void * * Describe */ void KillTimer(char id);
響應定時器消息:開發
在消息映射表中使用MSG_WM_TIMER_EX。參見:SGifPlayer.h
SOUI_MSG_MAP_BEGIN() MSG_WM_TIMER_EX(OnTimer) //定時器消息 MSG_WM_PAINT_EX(OnPaint) //窗口繪製消息 MSG_WM_SHOWWINDOW(OnShowWindow)//窗口顯示狀態消息 SOUI_MSG_MAP_END()
若是在一個窗口中必需要建立使用32位的定時器ID,在SOUI中可使用另外一個接口來實現:
/** * SetTimer2 * @brief 利用函數定時器來模擬一個兼容窗口定時器 * @param UINT_PTR id -- 定時器ID * @param UINT uElapse -- 延時(MS) * @return BOOL * * Describe 因爲SetTimer只支持0-127的定時器ID,SetTimer2提供設置其它timerid * 可以使用SetTimer時儘可能不用SetTimer2,在Kill時效率會比較低 */ BOOL SetTimer2(UINT_PTR id,UINT uElapse); /** * KillTimer2 * @brief 刪除一個SetTimer2設置的定時器 * @param UINT_PTR id -- SetTimer2設置的定時器ID * @return void * * Describe 須要枚舉定時器列表 */ void KillTimer2(UINT_PTR id);
響應定時器:
使用SWindow::SetTimer2建立的定時器,最後會經過一個消息:WM_TIMER2來分發到SWindow。
#define WM_TIMER2 (WM_USER+5432) //定義一個與HWND定時器兼容的SOUI定時器 #define MSG_WM_TIMER2(func) \ if (uMsg == WM_TIMER2) \ { \ SetMsgHandled(TRUE); \ func(wParam); \ lResult = 0; \ if(IsMsgHandled()) \ return TRUE; \ }
前面兩種定時器都是在控件開發的時候使用定時器的方法。而在應用層,還能夠爲宿主窗口直接使用::SetTimer或者宿主窗口的基類:CSimpleWnd::SetTimer來建立定時器(注意最高位必須是0)。
在響應這類定時器時,同樣能夠在宿主窗口的消息映射表中使用MSG_WM_TIMER來響應定時器消息。可是須要注意的是,這個映射宏會截獲全部分發給宿主窗口的定時器,若是不是本身建立的定時器,則須要繼續交給基類處理。
能夠調用:SetMsgHandled(FALSE); 或者:SHostWnd::OnTimer(UINT_PTR idEvent);實現。