Windows Programming/界面
鍵盤
編輯光標(Cursor) 對 插入位置(Caret)
編輯光標(Cursor)是指鼠標所指示的屏幕上的位置的圖形表示。插入位置(Caret)是插入文本的位置點在屏幕上的閃爍表示。當從鍵盤輸入字符時,字符插入到「插入位置」(Caret),插入位置自動向右移動1個字符的空間。
按鍵消息
編輯大部分按鍵消息無需特別處理。
- WM_KEYDOWN
- 表示某個鍵被按下。如果按鍵後一直不鬆手,那麼作業系統會產生一系列的WM_KEYDOWN消息。 LPARAM 參數的含義:
Bits of LPARAM Purpose 0-15 Key Count 16-23 Scan Code 29 Context Code 30 Previous State 31 Key Transition
- 鍵盤上所有鍵都有自己的scan code,包括動作按鍵如Shift, ALT, CTRL。Context Code確定是否ALT鍵被按下。Previous State是在消息發送前的按鍵狀態。Key Transition確定鍵是否按下或釋放。WM_KEYDOWN消息的大部分信息都可以忽略,除非關注連續擊鍵(Type-Matic)功能。
- WM_KEYUP
- 按鍵被釋放。大部分編程者可以忽略這一消息。
加速鍵
編輯一些按鍵組合被定義為特定動作。這些按鍵組合稱為加速鍵(Accelerators)。應用程式的資源中有加速鍵表(accelerator table)。當加速鍵被按下,應用程式將接收到WM_COMMAND消息。這需要API函數TranslateAccelerator來翻譯加速鍵:
while(GetMessage(&msg, NULL, 0, 0)) { if(!TranslateAccelerator(&msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } }
TranslateAccelerator函數自動分派WM_COMMAND消息到相應的窗口過程。
使用插入位置
編輯每個程序只有1個活動的插入位置(caret)。整個系統在屏幕上也只有1個活動的插入位置。這需要編程者創建插入位置、摧毀不用的插入位置。可通過消息WM_SETFOCUS message (當窗口被激活)與WM_KILLFOCUS、WM_DESTROY。
鼠標
編輯鼠標比鍵盤有更多種類的消息。
鼠標消息
編輯- WM_NCHITTEST
- 作業系統判斷鼠標事件屬於當前窗口,然後發出此消息來獲取鼠標命中了窗口的哪個部位,消息響應函數的返回值指出了部位,例如HTCAPTION,或者HTCLIENT等等。當窗體是WS_POP時,如果再給窗體添加上WS_SYSMENU類型,那麼就無法響應WM_NCHITTEST消息。如果用SetCapture函數捕獲了鼠標,那麼SendMessage(hWnd,WM_NCLBUTTONDOWN,HTCAPTION,0)將會無效,即這時不能有非客戶區的鼠標消息。這個消息只能由窗體自身響應,不能讓父窗體響應。
- WM_LBUTTONDBLCLK
- WM_LBUTTONDOWN
- WM_LBUTTONUP
- WM_MBUTTONDOWN
- WM_MBUTTONUP
- WM_MOUSEMOVE
- 用戶在窗口客戶區上移動鼠標
- WM_MOUSEWHEEL
- 用戶滾動或按下鼠標滾輪
- WM_RBUTTONDOWN
- WM_RBUTTONUP
鼠標移動時,系統需要在新位置重新繪製鼠標的光標。這時發送WM_SETCURSOR消息。在窗口客戶區,默認使用窗口類登記時的光標形狀;在非客戶區默認使用箭頭光標。
API函數
編輯- SetCapture: 在屬於當前線程的指定前景窗口里設置鼠標捕獲。如果鼠標在窗口的前景可見區域上,或者在在窗口的前景可見區域上按下了鼠標button且一直沒有鬆手,所有鼠標輸入事件都回發給該窗口。同一時刻只能有一個窗口捕獲鼠標。如果鼠標光標在另一個線程創建的窗口上,當鼠標鍵按下時系統將鼠標輸入發給這個窗口。ReleaseCapture函數釋放被捕獲的鼠標。
定時器
編輯使用API函數SetTimer啟動一個定時器。 KillTimer函數摧毀定時器。
UINT_PTR SetTimer( HWND hWnd, //Handle of the window associated to the timer UINT nIDEvent, //an identifier for the timer UINT uElapse, //the time-out value, in ms TIMERPROC lpTimerFunc //the address of the time procedure (see below) ); BOOL KillTimer( HWND hWnd, // Handle of the window associated to the timer UINT_PTR uIDEvent // the identifier of the timer to destroy );
如果重置定時器,那麼第一個參數為NULL, 第二個參數為已存在的定時器ID.
消息WM_TIMER有兩種處理方式:
- 通過窗口過程。
- 通過定時器的回調函數