Windows application window generally includes two: normal windows and end-free high-end windows in the top floor. The former is customized by Windows internal features, which has all normal features of the Windows application window: Title strips, window borders, maximize buttons, minimization buttons, and system default shortcuts and mouse support functions, using the left mouse button Drag the title strip of this window can move any window on the screen, and you can change the window size when the mouse cursor stops on the window border; the latter is a custom advanced window, which does not have any properties of the normal window, the whole The control of the window must be determined by the programmer. The typical examples of this window have IME input method applications in Windows, UCWIN 4.0 platforms, various floating toolboxes, desktop toolbars in office, and third-party development Chinese character input platform, etc.
One Significant Features of Windows None Title Situke Top-level Advanced windows is that there is no need to change the window size but must have a window-wide customer area drag function. Since the drag function of the normal window is done by the system, preparing a normal application is difficult to encounter this problem according to the problem of not considering the customer area, and therefore, it is difficult to encounter this problem. Developers often hope that their software has developed with window customers in classic software, the author used to use the imitation system mouse click the title bar to drag the window and the API send function provided within the Windows system to send the internal drag command to achieve no The title of the header is often the top-level high-level window, and the results are not ideal. Later, in the window function, by direct processing of WM_LBUTTONDOWN, WM_MOUSEMOVE, and WM_LBUTTONUP messages, the self-control window dragged, drag start, window movement, drag and virtual fax draw, virtual frame move, and drag the end, etc. Realize the customer area drag scheme of the advanced top window. The following is a detailed introduction to the specific methods and main techniques of this program on our practical experience.
I. Implementation of Windows Detects Customer Dynamic Tips and Mouse Cursor Dynamic Tips
WINDOWS No headlines The customer area of the Top-level advanced window is generally divided into two: specific customer command areas and non-specific customer command areas. The specific customer command area refers to the specific sub-rectangular area defined by "RECT", and the window function detects and processes the mouse command that occurs within the area; non-specific customer command area means part of the window customer area that is not clearly defined, All parts other than a particular customer command area, the window function determines whether the mouse command that occurs within the region is processed according to actual needs. Realizing the primary issue of the top-level advanced window drag function, how to detect and process the mouse command within the specific customer command area and the non-specific customer command area, and how to use the mouse cursor to dynamically prompt users to drag the window at this time operating.
1. Method for detecting the mouse command in a particular customer area
When the icon command button that implements the drag function is set, the specific customer area of the command button must be defined in the resource file, which is typically the rectangular area of the icon in the command button. The definition method of this area is " Rect DragRT ", where DraGRT defines the defined mouse command rectangular area, which uses DraGrt.LAGRT.TOP, DRAGRT.RIGT, DRAGRT.TOP, four parameters to describe the relative coordinate values of the rectangular area relative to the upper left corner of the window customer area. These four parameters must define specific values in advance, or use the "SETRECT" function to fill directly.
When the window function is handled by the mouse message WM_LButtondown, after the mouse position parameter LPARAM passed by the system, convert it to the window coordinate value by the makepoint () function, using the function PtinRect () that determines whether a certain coordinate point is located within a particular rectangular area. You can determine whether the mouse pointer is clicked within the drag command button to complete the startup task of the window drag function. The descriptive function code example is, for example:
Case WM_LBUTTONDOWN: // Mouse Cursor Click Processing
Point pt; // mouse on the screen position pointer, including Pt.x and Pt.y parameters, // The pointer value is converted by the MakePoint through the LPARAM parameter
Pt = makepoint (lparam); // Get the current screen position pointer
IF (PtinRect (& DragRT, PT)) {// Judging whether the mouse is click on the drag button
/ / Realize the startup function of the mouse drag window scheme
} else {
// Other specific or non-specific commands customer area judgment processing
}
Break;
2. Method for detecting mouse commands in non-specific customer regions
When a non-specific customer area drag method is taken in the window application, the rectangular coordinates of each particular customer area must be determined in advance, at this time, the non-specific customer area is an irregular area, which requires the actual application. The window and each command button rectangular area are determined, that is, the "non" subset of each command button relative to the window rectangular area. When the window function is handled by the mouse message WM_LButtondown, first use the function PtinRect () to determine if the current mouse pointer is clicked in the rectangular area of each command button, if not clicked in any command button area, you can determine that the mouse click within the non-specific customer area. Thus, the start of the window drag function. The descriptive function code example is, for example:
Case WM_LBUTTONDOWN: // Mouse Cursor Click Processing
Point pt; // Defines the position pointer on the screen on the screen
Pt = makepoint (lparam); // get the mouse cursor current position pointer
For (i = 0; i
IF (PtinRect (& DragRT [i], pt) {// DraGRT [i] is a button rectangular array
Break; // mouse click to interrupt on other buttons
}
}
IF (i
// Mouse click to handle other button features in other specific customer zones
} else {
// The mouse click to complete the start of the window drag scheme in the non-customer area.
}
Break;
3, the mouse cursor dynamic prompt method for window drag function
In the headlines of the headline, the normal window application can be used to use a method of dragging a specific customer area as a command button, or a method of dragging commands in a non-specific customer area detection window, or two ways to use . When using the first method, the function of the user can prompt the user's command button with a specific icon or text in the command button, and the latter method can be prompted because the rectangular area cannot be determined to be prompted with icon or text, or simply cannot be displayed. Icon and text (such as non-specific customer areas are window boundaries, etc.), the user can't know that the non-specific customer area has drag window function, and only makes full use of the dynamic prompt function of the mouse cursor, just like the WINDOWS ordinary window mouse When the cursor stops on the window frame, the mouse cursor becomes a double arrow shape to prompt the user to change the window size, this function is very important in the high-level window interface design.
Realizing the mouse cursor shape before the mouse cursor dynamic prompt function, the dynamic prompt of the window drag function is generally four arrow patterns, which can use Microsoft's SDK, FPT3.0, and VC 4.1 and other advanced development software. Resource editor "image edit", etc. The cursor resource file is typically 32x32 2 color or 16-color .cur graphic file, the cursor pattern can be specifically determined according to the implementation function or directly using the cursor resource file provided in the Windows system, and then use the resource editor to draw the cursor pattern, You also need to use the debug. EXE program to modify the mouse cursor display offset coordinates in the cursor resource file so that the cursor pattern can be used as the dynamic prompt cursor in the Windows system, the center of the cursor pattern is just in the current position of the screen. This offset coordinate value is located in the double-byte position of 10 and 12 in the light file, such as dynamic prompt cursor resource file name mousem.cur, to make 32x32 (2 color) cursor graphic display time pattern center point It is in the current screen position, and its modification is as follows:
C> Debug Mousem.cur-e 10a
XXXX: 10A 00.10 00.00 00.10 00.00
-W
After establishing your own mouse cursor resource file, you first need to define the mouse cursor in the application's resource file, the definition method in the resource file is:
IMecurm Cursor Mousem.cur
The mouse cursor resource file is only available in the application to use the loadcursor () function in the application, and its calling method is:
Hcursor hcurm; // Turn mouse cursor resource file data into memory
Hcurm = loadingcursor (Hinstance, IMecurm ");
When a client area that needs to dynamically change the shape of the mouse spectroids is the entire customer area of the entire window or a sub-window, the corresponding mouse cursor resource handle is defined when the client application window class is registered, and the mouse light is changed to the corresponding window. The shape of the cursor is automatically restored when the corresponding window is removed. The definition method of realizing this dynamic prompt function of the mouse cursor is as follows:
Wc.hcursor = hcurm;
When the mouse cursor needs to perform dynamic prompts in the specific customer command button area of the window or in a non-specific customer command area, it is necessary to use the above definition method to handle the WM_MOUSEMOVE message when the window function is handled: first determine the mouse cylinder pointer. Whether the location moves in the drag command button or a non-specific customer area, if the mouse pointer position meets the requirements of the drag window function area, use the API function setCursor () to change the mouse cursor pattern, prompting users to perform window drag operations. And handle the mouse input control to the current window, and set the mouse cursor mark; when the mouse pointer moves out the drag window to start the command area, restore the original mouse cursor pattern simultaneously release the mouse input focus control, and clear the mouse cursor dynamic prompt Flag unit. Its functional code is described as follows:
Bool Dragflag; // Dynamic Tips Cursor Sign
Case WM_MOUSEMOVE: // Mouse Cursor Mobile Processing
Pt = makepoint (lparam); // mouse cursor current location pointer
IF (PtinRect (& DragRT, PT)) {// mouse pointer inside the drag command area
SetCursor (HCURM); // Dynamically change the shape of the mouse cursor
SetCapture (hwnd); // Enter the mouse to control the right window
Iflag = true; // Set the mouse cursor shape change flag
} else if (iflag == true) {// mouse pointer is not in the drag command area
SetCursor (LoadCursor (NULL, IDC_ARROW); // Restore the original shape
ReleaseCapture () // Release mouse input control
Iflag = false; // Restore mouse cursor shape change sign
}
Break;
Second, the customer customization method of the drag box in the Windows Advanced window dragging scheme
The above-described mouse cursor dynamic prompt method for the window dragging the front mouse cursor position detection and the customer command area, when the user meets the drag window condition by the mouse cursor dynamic prompt function, start the drag by clicking the left mouse button. The most critical technical problem at this time is that the drag box display and erase function are implemented during the mouse drag window movement. Window Drag Download Square is displaying a wire frame that describes the drag window size in the entire screen area of Windows. Its size needs to be determined according to the rectangular area and actual needs of the drag window, generally dragged The rectangular area of the window is in size.
The drawing method in the Windows system is implemented by displaying the device description table, the drawing operation needs to occupy a certain GDI resource, the system is allocated to all GDI resources, the GDI in Windows 95 Resources is much larger than GDI resources in Windows3.x. There are two ways to use the display device descriptor table in Windows: Update the window displays the client area and the direct operation window to display the customer area. Update Window Display Customer Area is Direct to the application window rectangle area, using the graphic operation command when the window function responds to the WM_PAINT message: InvalIDateRect (hwnd, & winRect, true); // WinRect is to update the area
UpdateWindow (HWND);
When the window is initially established, the full area of the default update window, when the rectangular area to update is NULL, indicating all rectangular areas of the update window. Function updateWindow () Notification System Sends a WM_PAINT message to the window to update the rectangular area, and the window function receives the WM_PAINT message first use the beginpaint () function to obtain the device descriptor table, then use the graphic command to update the display device directly, and finally Endpaint () function notification system update operation ends. The descriptive function code is as follows:
Case WM_Paint:
Paintstruct PS;
HDC = BeginPaint (HWND, & PS); // acquire device descriptor table
SetBKMode (HDC, Opaque); // Device Update
Setbkcolor (HDC, 0x00C0C0);
/ / Update the graphical operation in the rectangular area
Endpaint (hwnd, & ps); // End Update Operation
Break;
Update Window Rectangular Area Directly Using the Screen Demand Defined in the Window Class, even if you use the SelectObject () function to select the corresponding screen painting brush, the update rectangular area range is accumulated by the invalidateRect () function, by UpdateWindow () function notification system Start a window update operation, the entire process is scheduled by the system, so use this method unable to implement the window of the window to draw and real-time operation.
The method of direct operation window customer area is to use the getDc () function to directly obtain the display device handle, and draw the display device directly with the various graphics operation commands, which use the screen of the screen to implement various graphics drawings, You can update and draw an operation on the screen window in real time without any system. Its operational process is first acquired a display device descriptor handle:
HDC HDC;
HDC = getdc (hwnd); // get hWnd window device descriptor table handle
When the HWND parameter is NULL, the device descriptor table handle is obtained throughout the screen, and then uses the SelectObject () function to set the brush and brush of the current screen, you can use various drawing functions to complete the screen's drawing operation, and finally take advantagedc. ) The function releases the acquired display device description table. Since this method can directly control the brush and brush of the current screen, and without system scheduling, you can perform the screen device directly, so this method can be used to fully implement the window drag and dashed box. The window of the window is used to describe the dotted frame and solid box to move the window size. When the rectangular drag is dashed, you need to use the drawpoint or the picture line function through a certain algorithm, which requires the current Screen brush; When the window's dragbox is a solid box, if you use the drawing function to set the screen brush, if you use the drawing rectangular function Rectangle (), you must use SelectObject while setting the current screen brush (HDC, GetStockObject (null_brush)) Shields any screen painting, otherwise the Windows program will quickly swallow all GDI resources, which is equivalent to adding countless rectangular areas in the screen device resources.
For the erase operation of the window drag box, simply set the screen's graphic brush mode to R2_xorpen or mode in the drag box drawing function, that is, setrop2 (HDC2, R2_Xorpen), pay attention to recovery at the end of the drag box Then, then move the drawing function at the original screen position again in the window drag box to move the original drag box. Below, the user uses the drag box function implemented by the drawing rectangle, the drawing line, and the drawpoint function, and the user can select the solid line or dashed drag box function you like when using the user. Function 1 is a drag real zone implemented using a rectangular function, which is characterized by the function of the function. The drag frame is fast; the function 2 is the drag box implemented by the drawing function, which is characterized by setting different Picture of line types can also be drawn, and the function 3 is the drag fashion function that utilizes the drawing function. It is characterized by the flexibility of dragging the virtual box pattern. It is not enough to function. The function can select different drag type or density by parameters. The function 3 parameter XY is 1 when drag the default default flyer as the Windows 3.x window, and if the XY parameter is 2, drag the virtual box as a reducing border. Different drag-duplicate frame patterns and corresponding brushes and paintings can also be selected as needed to achieve different effects.
// Function 1: Drag the stream using the rectangle function
Void DrawMoveRect (int XX1, int yy1, int xx2, int yy2, int xy)
{
HDC HDC;
INT OLDROP2, M, K;
HDC = getdc (null); // acquire full screen device description handle
Oldrop2 = getrop2 (HDC); // Get the original screen drawing method
SETROP2 (HDC, R2_Xorpen); // Setting the same or screen picture mode
SelectObject (HDC, getStockObject (null_brush)); // Mask Painting Brush
SelectObject (HDC2, getStockObject (White_pen)); // Select Brush
For (k = 0; k
XX1- = 1;
XX2 = 1;
YY1- = 1;
YY2 = 1;
Rectangle (HDC2, XX1, YY1, XX2, YY2);
}
SETROP2 (HDC2, Oldrop2); // Restore original mapping
ReleaseDC (NULL, HDC2); // Release Device Descriptor Table
}
// Function 2: Drag Bravings or Dirty Frame Using Paint Functions
Void DrawMoveRect (int XX1, int yy1, int xx2, int yy2, int xy)
{HDC HDC2;
INT OLDROP2, M, K;
HDC = getdc (null); // acquire full screen device description handle
Oldrop2 = getrop2 (HDC); // Get the original screen drawing method
SETROP2 (HDC, R2_Xorpen); // Setting the same or screen picture mode
SelectObject (HDC, getStockObject (null_brush)); // Mask Painting Brush
SelectObject (HDC2, getStockObject (White_pen)); // Select Brush
For (k = 0; K
XX1- = 1;
XX2 = 1;
YY1- = 1;
YY2 = 1;
MoveTo (HDC2, XX1, YY1);
LINETO (HDC2, XX2, YY1);
MoveTo (HDC2, XX1, YY1);
LINETO (HDC2, XX2, YY1);
}
SETROP2 (HDC2, Oldrop2); // Restore original mapping
ReleaseDC (NULL, HDC2); // Release Device Descriptor Table
}
// Function 3: Use the drawpoint function to achieve the drag of different patterns
Void DrawMoveRect (int XX1, int yy1, int xx2, int yy2, int xy)
{HDC HDC2; int OLDROP2, I, J, X1, X2, Y1, Y2;
HDC = getdc (null); // acquire full screen device description handle
Oldrop2 = getrop2 (HDC); // Get the original screen drawing method
SETROP2 (HDC, R2_Xorpen); // Setting the same or screen picture mode
SelectObject (HDC, getStockObject (null_brush)); // Mask Painting Brush
SelectObject (HDC2, getStockObject (White_pen)); // Select Brush
For (j = 0; J
X1 = XX1-J; // The annotation portion is another pattern
X2 = xx2 j;
Y1 = yy1-j;
Y2 = yy2 j;
FOR (i = x1; i
SetPixel (HDC, I, Y1, RGB (255, 0, 0));
// if (i
For (i = y1; i
Setpixel (HDC, X2, I, RGB (255, 0, 0));
// if (i
For (i = x2; i> x1; i- = 2)
SetPixel (HDC, I, Y2, RGB (255, 0, 0));
// if (i> x1 2) setpixel (HDC, I-1, Y2-1, RGB (255, 0, 0));
For (i = y2; i> y1; i- = 2)
SetPixel (HDC, X1, I, RGB (255, 0, 0));
// if (i> Y1 2) setpixel (HDC, X1 1, I-1, RGB (255, 0, 0));
}
SETROP2 (HDC2, Oldrop2); // Restore original mapping
ReleaseDC (NULL, HDC2); // Release Device Descriptor Table
}
Third, the "three steps" implemented by the Windows Advanced Window Customer Area
The customer area of the Windows Advanced window is judged that the mouse cursor dynamual prompt and custom window dragging the box function, the drag process is started, the window drag box moves and dragging the drag frame. End the process of three steps. The WM_LBUTTONDOWN, WM_MOUSEMOVE, and WM_LBUTTONUP messages must be processed directly in the window function to specifically process the details of the above three steps.
In the first step, the mouse click on the message WM_LBUTTONDOWN in the window function to process the user when obtaining the window drag condition by the mouse cursor dynamic prompt function, press the start-up drag process message generated by the left mouse button, its functionality code show as below:
Point Pt;
Bool moveflag = false;
Case WM_LBUTTONDOWN:
Pt = makepoint (lparam); // Get mouse cursor pointer
IF (PtinRect (& DragRT, PT)) {// DraGRT is the drag command area
Dragbegin ((LPRECT) & WinRT, LPARAM, HWND, 2);
// Start window dragging process
} else {other processing}
Break;
The above Dragbegin () function drags the startup function for the window developed by the author. Since there are often many windows in a advanced window application, it is handled as a single function. Where WinRT is a high-grade window rectangular area, here as the drag frame rectangular area parameter, LPARAM is the mouse spectrum pin long integer, HWnd is the handle of the current drag window, 2 is the drag frame width. At the same time, the mouse control will be given to the current drag window, set the drag window flag unit, save the current mouse on the screen and display the dragbum of the drag window. The original code of the drag function start function is as follows:
Void Dragbegin
LPRECT WINRECT, / / Drag Box Rectangle
Lparam lparam, // mouse cursor current pointer
HWND HWND, // Current window handle
UNSIGNED INT KK) / / Drag Box Display Width {
SetCapture (hwnd); / / When dragging the window must have the right mouse input
MoveFlag = true; // Set the drag sign
Oldmx = loword (lparam); // Record