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有两种处理方式:
- 通过窗口过程。
- 通过定时器的回调函数