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有两种处理方式:

- 通过窗口过程。

- 通过定时器的回调函数

定时器模式编辑

下一章编辑