No title bar window movement in MFC

Source: Internet
Author: User

original link: http://blog.sina.com.cn/s/blog_6288219501015dwa.htmlThe Move standard window is implemented by clicking the window title bar with the mouse, but for a window with no title bar, you need to click outside the window title bar to move the window with the mouse. There are two ways to achieve this goal.  method One: When the window determines the mouse position, Windows sends a WM_NCHITTEST message to the window, allowing the message to be processed so that Windows considers the mouse to be on the title bar as soon as the mouse is inside the window. This requires the Onnchittest function that overloads the CWnd class to handle the WM_NCHITTEST message, calling the function of the parent class in the function, and if returning htclient, indicating that the mouse is in the window client area, so that the overloaded function returns Htcaption, Causes Windows to mistakenly assume that the mouse is on the title bar.  The following example is the actual code that uses the method:UINT cellipsewnddlg::onnchittest (CPoint point){//Get the window area where the mouse is locatedUINT nhittest = cdialog::onnchittest (point); //If the mouse is in the window client area, the title bar is returned to the Windows//Enable Windows to process the class on the title bar by mouse, click the Move windowreturn (nhittest==htclient)? Htcaption:nhittest;} method Two: When the user presses the left mouse button in the window client area, causes Windows to think that the mouse is on the title bar, that is, in the processing WM_LBUTTONDOWN message processing function OnLButtonDown send a wparam parameter is htcaption, LPARAM The Wm_nclbuttondown message for the current coordinate.  The following is the actual code that uses the method:void Cellipsewnddlg::onlbuttondown (UINT nflags, CPoint point){//Call parent class handler to complete basic OperationCdialog::onlbuttondown (nflags, point); //Send Wm_nclbuttondown message//Make Windows think the mouse is on the title barPostMessage (Wm_nclbuttondown,Htcaption,Makelparam (Point.x, Point.y));   or SendMessage (wm_syscommand,0xf012,0); 0xf012 = Sc_move | Htcaption}    first, look at how the system moves the program window under normal circumstances. When the user presses the left mouse button within the program window's title bar area (non-work area), the following things occur: the system sends a WM_NCLBUTTONDOWN message to the window procedure function.  The Wm_nclbuttondown message is eventually routed to the DefWindowProc () function in the window procedure function.  The DefWindowProc () function performs the default action of the message by pressing and moving the left mouse button, as well as the htcaption identifies the position of the mouse when it is pressed, which is the action that the window moves with the mouse cursor.  to test this as an exercise, first set the following statement in the window callback function (that is, the window procedure function):   Casewm_nclbuttondown return 0;   then, the same time in the window title bar hold the left mouse button and move the mouse, but the window does not move with the mouse, this is how it? This is because the "return 0" statement is provided in the above statement. This statement causes the Wm_nclbuttondown message to be passed to the DefWindowProc () function, which is returned early in the window procedure function, and the operation of the moving window is not possible. This, in turn, confirms the fact that the last operation to complete the mobile window will be done by the DefWindowProc () function.  The above analysis can be ticked off such an operation process: that is, the user in the window title bar pressing the left mouse button → system send Wm_nclbuttondown message →defwindowproc () function receive message → User mobile mouse →defwindowproc () The function executes the action that the window moves with the mouse.  The conclusion is that in order to realize the operation of the mobile window, there must be two conditions: one is to press the left mouse button and move (the DefWindowProc () function will detect this condition), and the second is to send wm_ when the left mouse button is pressed. Nclbuttondown the message and returns the Htcaption identity.  according to the above analysis, in the absence of the window title bar, the Way to cheat DefWindowProc () function, to achieve the non-title bar window entity movement operation.    1. Actively send Wm_nclbuttondown messagesIn the absence of a title bar in the window, when the left mouse button is pressed on the window entity, the system does not send the Wm_nclbuttondown message, because the mouse cursor is pressed in the window's workspace, and the system sends the WM_LBUTTONDOWN message.  but through the above analysis, you can know that the DefWindowProc () function does not care about who sent the Wm_nclbuttondown message, but just whether the message is sent. So as long as we press the left mouse button in the event, the initiative to send the Wm_nclbuttondown message, will not be able to meet both conditions at the same time! The following code is designed according to this idea.  Casewm_lbuttondown: SendMessage (hwnd,wm_nclbuttondown,htcaption,0); Break ;   when the message is sent, a message is given to the DefWindowProc () function via the htcaption parameter, telling it that the left mouse button is pressed at the title bar in the non-working area of the window. This is, of course, a false intelligence, but the DefWindowProc () function will believe it and perform the corresponding operation based on that information.    2. Actively send Wm_syscommand messages  Casewm_lbuttondown: SendMessage (hwnd,wm_syscommand,sc_dragmove,0); Break ;   the ability to use Wm_syscommand messages to move windows, thanks to a recently expanded Sc_dragmove style flag, is literally the meaning of "drag and move." This flag is not found in the lower version of the compiler (not in VC 6.0), so it should be stated in advance when referencing the flag:   #define Sc_dragmove 0xf012   You can also use its constant value directly:   SendMessage (hwnd,wm_syscommand,0xf012,0);   The mechanism for moving a form above the Untitled Bar window is similar to a window with a title bar, and the same is done by the DefWindowProc () function at the end, where the message is sent in different ways, one is implied by the system, and the other is sent publicly by the program.  The above two methods to move the window, with the title bar to move the window's visual effect is the same, that is, when moving, the first move the indicator box (a dashed box), and so on to determine the new position after the form moved, when releasing the left mouse button when the window's body is actually moved to the location pointed to by the dashed box. Can you move the window entities directly without a dashed box? The answer is yes.  in fact, the operating system prepares two ways to move windows, one with a dashed box, the other without a dashed box, and the default for Windows system is a dashed box. However, if we add the following statement in the example code above:   SystemParametersInfo (spi_setdragfullwindows,true,null,0);   namely:   Casewm_lbuttondown: SystemParametersInfo (spi_setdragfullwindows,true,null,0); SendMessage (hwnd,wm_nclbuttondown,htcaption,0); Break ;   this way, when you move the window, the dashed indicator box does not appear. Note that the position order of the above statements cannot be wrong, otherwise the dashed box appears when you move.  However, the system defaults to moving the window by the way the dotted line indicates the box is through the pros and cons. This is because a dashed box moves the window and does not actually move the window at the beginning, but instead uses a wireframe to specify where the window will arrive, and then moves the window to the specified position (redrawn at the specified location) one time. That is, in the process of moving a window, the window entity only needs to be redrawn once. If you do not use the dashed box, but directly move the window entity, in the process of moving the window, will form N times to draw the window, increase the burden of the system processing graphics, and make the window drawing quality seriously reduced, resulting in bad visual effects.  To this end, in the programming practice can be arranged in this way: the special-shaped window in order to reflect the special-shaped visual effects, you can use a non-dashed box to move the window, and for the general rectangular window can be a dashed box to move the window, in order to ensure that the window redraw quality.  It is true that the code set above can make the irregular window move without a dashed box, but since the SystemParametersInfo () function is system-level, the call to it will affect all program windows on the computer desktop to be moved in a no-dashed box, if so. The overall visual effect of the desktop will be greatly compromised. If you do not want to affect the movement of other windows, but only to require that the special window when moving the box does not appear, you can add the following code in the window procedure function:   Case Wm_mousemove: SystemParametersInfo (Spi_setdragfullwindows,false, null,0); Break ;   3. Self -codingThe first two methods are defective, changing the message flow so that the onlbuttondown,onlbuttonup does not respond self-coding can also be implemented without the title bar window mobile operation, and more flexible and diverse. For example, the operation can be done by the left mouse button or the right mouse button. Here is the actual code to complete the window movement through the right mouse button, adding the following code to the procedure function of the program window:   static Point pt, PE; static RECT RT, re;   Case Wm_rbuttondown: setcapture (HWND); Set mouse capture (prevent the cursor from running out of the window and lose the mouse hotspot) GetCursorPos (&PT); Gets the current position of the mouse cursor pointer GetWindowRect (HWND,&RT); Get window position and size Re.right=rt.right-rt.left; Save window width re.bottom=rt.bottom-rt.top;//Save window Height Break ;   Case Wm_rbuttonup: releasecapture (); Release mouse capture to restore normal state Break ;   Case Wm_mousemove: GetCursorPos (&PE); Gets the new position of the cursor pointer if (Wparam==mk_rbutton)//When the right mouse button is pressed     { re.left=rt.left+ (pe.x-pt.x); New horizontal position of window re.top =rt.top+ (PE.Y-PT.Y);//new vertical position of window MoveWindow (hwnd,re.left,re.top,re.right,re.bottom,true);//Mobile Window     } Break ;  or: in OnLButtonDown ():setcapture ();CRect RW;GetWindowRect (RW);CPoint PtW = point;ClientToScreen (&PTW);m_ptcursoroffset.x = ptw.x-rw.left; in OnMouseMove ():if ((Nflags & Mk_lbutton) && this = = GetCapture ()){CPoint PtW = point;ClientToScreen (&PTW);ptw.x-= m_ptcursoroffset.x;ptw.y-= M_ptcursoroffset.y;:: SetWindowPos (M_hwnd, 0,ptw.x,ptw.y,0,0,swp_nosize); }m_ptcursoroffset.y = ptw.y-rw.top;in OnLButtonUp ():releasecapture ();

No title bar window movement in MFC

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.