Chapter 3, Keyboard and Mouse
Essence concentration:
The keyboard and mouse are probably the most two things that use the computer (especially), except DIYERs), but it is impressive, it is not difficult to understand them. In Windows, the keyboard and mouse input are in the form of a message. First, the device driver receives and processes the mouse and the keyboard interrupt, and the initial electrical pulse signal is converted into the system message queue by the Interrupt Processing (ISR). The operating system core has a dedicated thread (which should be user32.dll) to monitor the system message queue, distribute the message into each application thread message queue. In the future, the application's search processing of the message is in the MFC development, the message mapping mechanism told by the first chapter. Learning how to respond to keyboards and mouse settings To understand which message of this processing and some MFCs and API functions related to processing. The mouse message is first divided into two categories, namely customer area messages, and non-client messages. Press different input actions, and subdivided into left (right, medium) keys, double-click, and press, bounce, and mouse move messages. For example, WM_LBUTTONDOWN, indicating that this is the left button to press the message, while WM_ncmbuttonup, indicating that this is the NOT Client mouse button bomb. Details of the mouse event and the corresponding message can be referred to MSDN.
In the MFC, the prototype of the client area mouse message processing function is: AFX_MSG Void OnMSGName (uint nflags, cpoint point) where Point indicates the current cursor position, this position coordinate is in the upper left corner of the window customer area. . If necessary, use CDC :: DPTOLP () to convert it to logical coordinates. The NFLAGS parameter indicates the state of the mouse button and the state of Shift and Ctrl when the message is generated. Usually used to determine the mouse or keyboard status, such as if (nflags & mk_lbutton) .... The processing function prototype of non-client messages is: AFX_MSG Void OnMSgname (uint nhittest, cpoint point) where the point indicates the event that occurs in the window, but this location is the screen coordinate. The screen coordinates can be converted to the customer area coordinate with CWnd :: ScreenToClient (). The NHitTest parameter contains a hit test code that identifies the went of non-customer area events. Such as HTCAPTION, HTClose, HTSYSMENU, etc. A list of full hit test code can be found in the WM_NCHITTEST or CWND: ONNCHITTEST () help document. Actual application is similar to NFLAGS. The mouse cursor is an interface between the mouse and the user. We know that each window has corresponding WNDCLASS, which is defined in the WNDCLASS structure. The HCURSOR field holds the handle of the window type cursor, which is an image on the window client area. When the mouse moves, Windows clears the cursor from the old position by the background of the redraw cursor. Then, it sends a WM_SETCURSOR message containing the hit test code under the cursor. The default response to this message system is called: SetCursor () API function. If the hit test code is HTClient (ie, in the client area), the set type cursor is displayed, otherwise the default arrow cursor is displayed. The cursor will automatically update the test code based on the mouse moving time period. This trick can also be applied to other image processing. Method for setting the cursor summary: 1. Register WNDCLASS (how to register, there is a summary in the back knowledge point), and specify the desired cursor type as window cursor; 2. Call API function in the ONSETCURSOR message processing function :: setCursor ) Respond to WM_SETCURSOR messages. The Windows application understands the way the keyboard event is the same as the mouse event: all through the message. The keyboard message is only three, that is, the WM_KEYDOWN keyboard Press the WM_KEYUP keyboard to raise the WM_CHAR Trim Character key Press or raise (this is to simplify the character processing) Windows always sent the keyboard message to the window with input focus. It is notified that the WM_SETFOCUS and WM_KILLFOCUS messaging will notify the notification to receive or lose the input focus. CWnd :: setFocus () Transfer the input focus to another window; CWnd :: getFocus () is used to find the window currently used to enter the focus, and its return type is CWnd. A keyboard processing function receives a lot of messages for keystrokes, including one code to identify key values pressed or released. The prototype is as follows: AFX_MSG Void OnMSGName (uint nchar, uint nrepcnt, uint nflags) where nchar is a virtual key value of the button pressed or released, and nREPCNT is a repetition number, usually 1. The NFLAGS parameter contains the scan code of the key and some bit flags (for details, refer to MSDN). Like the mouse, the system resources related to the keyboard are inserts. However, the cursor is a global shared resource, and the insert is a single-threaded shared resource, which is shared all windows on the same thread.
The use of the insert has some simple rules: 1. The insertion is created when the input focus is received, and "destroy" when the input focus is lost. Related functions include CreateCaret, Creategraycaret, :: DestroyCaret, etc .; 2. To call ShowCaret to make the created insert, call hidecaret can hide; 3. Call setCareTPOS to move insert, always remember, control insert Mobile is your own work. Retrieval of the insert position can be available with GetCareTPOS. Some knowledge points: 1. Custom window type: In the MFC, you can use the global function AFXRigisterWndClass to register the window type. This requires the fields in the WNDCLASS structure. AfxrigisterWndClass has automatically populated most of the fields, you usually need to care about 4 values. AfxRigisterWndClass function prototype is: LPCTSTR AfxRigisterWndClass (UINT nClassStyle, HCURSOR hCursor = 0, HBRUSH hbrBackground = 0, HICON hIcon = 0) wherein, nClassStyle specified window type style (not the display type), but the window allows certain operating characteristics. Such as cs_owndc, indicating that the window created by WNDCLASS has its own device descriptive table (DC); Hcursor is the "Type Cursor" created by WNDCLASS. You can get through AFXGetApp () -> LoadStandardCursor (IDC_XXX); HBRBACKGROUND parameter defines the default background color of the window; the last parameter HICON specifies that Windows is used on the desktop, the taskbar and other places represent the big, small icon of the application. In the MFC, call this function usually completes by overwriting the PrecreateWindow virtual function.
2. Some non-mainstream mouse messages: 1) WM_NCHITTEST message: The window first receives the screen coordinates and WM_NCHITTEST messages of the cursor before accepting a client area or non-client mouse message. Windows generally handles it by default. A skill using the onnchittest handler is to use the HTCAPTION hit test code instead of HTClient to create a window that can be dragged in the client area: uint cmainwindow :: ONNCHITTEST (CPOINT) {uint nhittest = cframewnd :: ONNCHITTEST (POINT); if (nhittest == htclient) NHittest = Hicaption; return nhittest;} 2) WM_MouseLeave and WM_Mousehover Message: These two messages allow you to know when the mouse moves into the window or moves in the window. The API function associated with this is: TRACKMOUSEEVENT (), by it, a program can register, receive the WM_MouseEleave message when the cursor leaves the window, and the cursor is stopped in the window to receive the WM_Mousehover message. :: TrackMouseEvent () function has only one parameter, a pointer to the TRACKMOUSEEVENT structure. . 3) WM_MOUSEWHEEL message: windows of ON_WM_MOUSEWHEEL macro mapping WM_MOUSEWHEEL message to the message processing function OnMouseWheel, the prototype is: BOOL OnMouseWheel (UINT nFlags, short zDelta, CPoint point) where, nFlags and point to other mouse handler the same meaning, zDelta of The value is equal to WHEEL_DELTA (a incremental increment) or -wheel_delta (scrolling an increment afterward). 3. Capture of the mouse: This is usually used in the "rubber band" drawing operation. Capture the mouse with CWnd :: SetCapture, the corresponding use: ReleaseCapture releases it.