Dynamic drag of Win98 special window

Source: Internet
Author: User

 

Dynamic drag of Win98 special window

Song Libo

The Untitled window on top of Win98 is a special window. Typical instances include the ime Input Method Application, ucwin platform, various floating toolbox, and office desktop toolbar.

I. Command detection and Dynamic Cursor prompt

This type of window dragging is generally divided into two types: the specific customer command area and the non-specific customer command area. The specific customer command area refers to the special stator rectangular area defined by "rect"; the non-specific customer command area refers to the window customer area not explicitly defined, that is, all parts outside the specified customer command area. The primary issue for implementing this function is how to detect and process mouse commands in specific customer command areas and non-specific customer command areas, and how to use the mouse and cursor to dynamically prompt users when to drag the window.

1. Check mouse commands for specific customer command Areas

To set the icon command button to implement the drag function in the window, you must define the specific customer area of the command button in the resource file. This area is generally the rectangular area of the command button icon, this area is defined as "rect dragrt", where dragrt is the rectangular area defined for detecting the mouse command. It uses dragrt. left, dragrt. top, dragrt. right and dragrt. the bottom parameter is used to describe the relative coordinate value of the rectangular area relative to the upper left corner of the window client area. It can also be filled with the "setrect" function.

When processing the mouse message wm_lbuttondown, the window function converts the mouse position parameter lparam received by the system to the window coordinate value through the makepoint () function, then, use the ptinrect () function to determine whether a coordinate point is located in a specific rectangle, and determine whether the mouse pointer is clicked within the drag command button.

2. Non-specific client command area detection mouse command

When the Window application adopts the non-specific client command area drag method, you must determine the rectangular coordinates of each specific customer command area in the resource file in advance, in this case, the custom command area is irregular. It must be determined based on the actual application window and the rectangular area of each command button, that is, the "Non" subset of the rectangle area of each command button relative to the window rectangle area. When processing the mouse message wm_lbuttondown, the window function first uses the ptinrect () function to determine whether the current mouse pointer is clicked in the rectangle of each command button. If it is not clicked in any command button area, you can click the mouse in the unspecified customer command area to start the window dragging function.

3. cursor prompt for window dragging

Before implementing the mouse and cursor dynamic prompt function, you need to customize the mouse and cursor shape. The window dragging function dynamically prompts that the cursor shape is generally a four arrow pattern, this can be achieved by using the resource editor "image edit" in Microsoft sdks, fpt3.0, VC ++ 4.1, and other advanced development software. The cursor resource file is generally a 32x32 2-or 16-color. cur graphic file. After creating your own mouse cursor resource file, you must first define the mouse cursor in the application's resource file, and then use loadcursor () to call in the application, and set in the class: WC. hcursor = hcurm.

When the mouse cursor needs to be dynamically prompted in a specific customer command button area of the window or in a non-specific customer command area, the above definition method cannot be used, when the window function is used to process the wm_mousemove message, it must first determine whether the current position of the mouse pointer is in the drag command button or the unspecified client command area, if the cursor position meets the requirements of the function area of the window to be dragged, the API function setcursor () is used to change the mouse cursor pattern, prompting you to drag the window at this time, the mouse enters control to the current window, and sets the changed mouse cursor flag. When the mouse pointer is removed from the drag window command to start the area, restore the original mouse cursor pattern while releasing the mouse input focus control, and clear the mouse cursor dynamic prompt flag unit.

Ii. Dynamic drag box Customization

The key issue before dragging a window is the implementation of the drag box display and erase function during the dragging of the window. The drag dotted box of a window is a box showing the size of the dragged window in the entire Windows screen area. Its size must be determined based on the size of the rectangular area of the dragged window and actual needs, it is generally the size of the rectangular area of the dragged window.

In Windows, the drawing method is implemented by displaying the device description table. Drawing operations require a certain amount of GDI resources. The GDI resources in Windows 95 are much larger than those in Windows 3.x, so the system can allocate enough GDI resources for Windows, menus, dialogs, fonts, and various drawing functions. In Windows, there are two ways to display the device descriptor table: the update window displays the customer region and the direct operation window displays the customer region. The client area displayed in the update window is directly targeted at the application window rectangular area. When the window function responds to the wm_paint message, the graphic operation command is used to update the window:

Invalidaterect (hwnd, & winrect, true); // winrect is the region to be updated

Updatewindow (hwnd );

When a window is initially created, all the areas of the update window are used by default. When the rectangular area to be updated is null, all the rectangular areas of the update window are updated. The updatewindow () function notifies the system to send the wm_paint message to the window in which the rectangle is to be updated. After receiving the wm_paint message, the window function first obtains the device descriptor table using the beginpaint () function, then, the graphic command is used to directly update the display device, and the endpaint () function is used to notify the System of the update operation.

Update the window rectangle area directly using the Screen paint brush defined in the window class, even if you use the SelectObject () function to select the corresponding Screen paint brush is invalid, and update the rectangle area range through invalidaterect () the updatewindow () function notifies the system to update the window. The entire process is scheduled by the system. Therefore, this method cannot be used to draw and operate windows by dragging virtual boxes.

You can use the getdc () function to directly obtain the display device handle and use various graphic operation commands to directly plot the display device. It uses the paint brush and paint brush currently set on the screen to draw various images. Without passing any message to the system, it can update and plot the screen window in real time. The procedure is to first obtain the display device descriptor handle HDC = getdc (hwnd). When the hwnd parameter is null, the device descriptor table handle of the entire screen is obtained, and then the SelectObject () the function sets the paint brush and paint brush of the current screen. It uses various painting functions to draw the screen. Finally, it releases the device description table obtained by using the releasedc () function. If you use the rectangle () function to draw a rectangle to implement a virtual box, you must use SelectObject (HDC, getstockobject (null_brush) to block any Screen paint brush while setting the current Screen paint brush, otherwise, the windows program will soon swallow all the GDI resources, which is equivalent to adding numerous Rectangular areas to the screen device resources.

For the erase operation of the window drag box, you only need to set the image brush operation mode on the screen to r2_xorpen exclusive or mode, that is, setrop2 (hdc2, r2_xorpen ). Pay attention to restoration when drawing in the drag box. Before moving the drag box in the window to the next position, call the draw function again at the original position to erase the original drag box (see program 1 ).

// Use the rectangle function to drag the solid frame (because the space draw line and point function are omitted)

Void drawmoverect (INT xx1, int YY1, int xx2, int yy2, int xy)

{HDC;

Int oldrop2, M, K;

HDC = getdc (null); // get the full screen device description handle

Oldrop2 = getrop2 (HDC); // gets the original Screen Drawing Method

Setrop2 (HDC, r2_xorpen); // you can specify an exclusive or screen drawing method.

SelectObject (HDC, getstockobject (null_brush); // screen the paint brush

SelectObject (hdc2, getstockobject (white_pen); // select the paint brush

For (k = 0; k Xx1-= 1; xx2 + = 1;

YY1-= 1; yy2 + = 1;

Rectangle (hdc2, xx1, YY1, xx2, yy2 );

}

Setrop2 (hdc2, oldrop2); // restore the original drawing method

Releasedc (null, hdc2); // release the device descriptor table

}

(Procedure 1)

3. dynamically drag the window "Three Steps"

After you have completed the judgment of the client area drag command for Windows Advanced window, the mouse and cursor dynamic prompt for the drag function, and the custom window drag box function, you need to implement the three-step process of starting the drag process, moving the window drag box, and dragging the End Process in the entire drag scheme. Therefore, wm_lbuttondown, wm_mousemove, and wm_lbuttonup messages must be processed directly in the window function. The following describes the details of the above three steps.

Step 1: In the window function, you can click the wm_lbuttondown message to judge the message. This allows you to obtain the start-up message generated by pressing the left mouse button when the window is dragged. Its functional code is as follows:

Case wm_lbuttondown:

PT = makepoint (lparam );

If (ptinrect (& dragrt, pt )){

Dragbegin (lprect) & winrt, lparam, hwnd, 2); // Startup Process

} Else {// perform other processing ;}

The above dragbegin () function is the development of the window drag start function. Because an advanced Window application usually has many windows, it is treated as a separate function. Here, winrt is the rectangle area of the advanced window, which is passed as the rectangle area parameter of the drag box. lparam is the long integer of the mouse pointer, and hwnd is the handle of the currently dragged window, 2 is the width of the drag box. In this case, you need to give control of the mouse to the currently dragged window, set the drag window unit, save the position of the current mouse on the screen, and display the drag box of the dragged window. The source code of the drag function startup function is as follows:

Void dragbegin (lprect winrect, // drag the rectangular area of the box

Lparam, // cursor current pointer

Hwnd, // current window handle

Unsigned int KK) // The width of the drag box.

{Setcapture (hwnd); // when dragging, the window must have the right of mouse input

Moveflag = true; // you can specify the drag flag.

Oldmx = loword (lparam); // records the coordinates of the current mouse screen x

Oldmy = hiword (lparam); // record the current mouse screen coordinate Y

Drawmoverect (winrect-> left, winrect-> top, // display the drag box

Winrect-> right, winrect-> bottom, KK );

}

Step 2: You need to move the drag box when dragging the window with the mouse. This requires wm_mousemove message processing in the window function. The movement of the drag box includes two steps: Clear the last displayed drag box and show the current drag box. Because the drag box painting function re-sets the current painting method, the exclusive or mode allows you to clear the drag box by calling the function again at the original screen coordinate position, you only need to call the drag box draw function twice to display and clear the drag box when you move the mouse in the window. In addition, the method for calculating the position of the drag box on the screen is also very simple, that is, the mouse movement offset obtained from the current screen position coordinate value minus the saved previous screen position coordinate value, add this offset to the coordinate value in the upper left corner of the original window screen to determine the coordinate value of the new screen position in the dragged window and drag box.

Case wm_mousemove:

If (moveflag = true ){

Dragmove (lprect) & winrt, winwt, winhi, lparam, 2 );

} Else {// perform other processing ;}

In view of the fact that the advanced Window application generally has multiple subwindows, the process of moving the drag box is compiled into a function separately, in addition, the window cannot be completely located in the visible area of the screen when you move the mouse over the window. Developers can adjust their positions as needed so that the dragged window can be fully displayed in the visible area of the screen. The source code of the function is as follows:

Void dragmove (lprect rcwin, // drag the rectangular area of the box

Unsigned int WI, // The width of the dragged window

Unsigned int hi, // The height of the dragged window

Lparam, // pointer to the mouse position

Unsigned int KK) // drag the Border width of the box

{Drawmoverect (rcwin-> left, rcwin-> top,

Rcwin-> right, rcwin-> bottom, KK); // clear the last draw drag box

Rcwin-> left + = loword (lparam)-simeg. oldmx; // computing window

Rcwin-> top + = hiword (lparam)-simeg. oldmy; // new location

Simeg. oldmx = loword (lparam); // Save the current coordinate value

Simeg. oldmy = hiword (lparam );

If (rcwin-> left <0) rcwin-> left = 0; // The window goes beyond the screen.

If (rcwin-> left> simeg. xscrwi-WI) // visible area Processing

Rcwin-> left = simeg. xscrwi-wi;

II = simeg. yscrhi-hi-(simeg. winver <0x35f? 0: botoff );

If (rcwin-> top <0) rcwin-> Top = 0; // bottom of Win95

If (rcwin-> top> II) rcwin-> Top = II; // special reserved processing

Rcwin-> right = rcwin-> left + wi-1;

Rcwin-> bottom = rcwin-> top + hi-1;

Drawmoverect (rcwin-> left, rcwin-> top,

Rcwin-> right, rcwin-> bottom, KK); // draw a new position drag box

}

Step 3: When the mouse is dragged to the end of the window, the actual movement of the window is required. Therefore, when processing the wm_lbuttonup message, the movewindow () command is used for actual movement. In addition, for Multi-Window reasons, you still need to separate the processing process into a function, and you also need to use the drawing function to clear the drag box drawn on the screen before moving the window. If the window is not completely visible to the screen, you must adjust it so that the dragged window can be completely visible to the screen, release the mouse control, and clear the drag window cell. The descriptive code of the end process is as follows:

Case wm_lbuttonup:

If (simeg. moveflag = true) {// The drag flag is valid.

Dragend (lprect) & winrt, winwt, winhi, hwnd );}

The source code of the drag-and-stop processing function is as follows:

Void dragend (lprect rcwin, // drag the rectangular area of the box

Unsigned int WI, // The width of the dragged window

Unsigned int hi, // The height of the dragged window

Unsigned int KK) // drag the Border width of the box

{Drawmoverect (rcwin-> left, rcwin-> top,

Rcwin-> right, rcwin-> bottom, 1); // clear the drag box

If (rcwin-> left <0) rcwin-> left = 0; // The window goes beyond the screen.

If (rcwin-> left> simeg. xscrwi-WI) // visible area Processing

Rcwin-> left = simeg. xscrwi-wi;

II = simeg. yscrhi-hi-(simeg. winver <0x35f? 0: botoff );

If (rcwin-> top <0) rcwin-> Top = 0; // bottom of Win95

If (rcwin-> top> II) rcwin-> Top = II; // special reserved processing

Rcwin-> right = rcwin-> left + wi-1;

Rcwin-> bottom = rcwin-> top + hi-1;

Movewindow (hwnd, rcwin-> left, rcwin-> top,

WI, hi, true); // move the window to a new location

Simeg. moveflag = false; // clear the drag Cell

Releasecapture (); // release control of the mouse

}

Now, the entire window is dragged dynamically. If you are interested, you can download the recommended software on the "bobosong.yeah.net" Homepage to see how this function works.

(Author's address: Office of Tieling municipal committee, Liaoning Province 112000, China)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.