[VC] dialog achieves a magnetic adsorption form (Dock) similar to Winamp and listen)

Source: Internet
Author: User

Keywords:Dock form, magnetic form, and sticky form

 

Version:Visual c ++ 6.0 or above

 

Principle:

1. determine whether the adsorption conditions are met. Intercept the sub-form wm_windowposchanging message, convert lparam to pwindowpos, and compare it with the rect of the main form, when the condition is met (for example, the left gap between the subform right and the main form is less than 10px), modify the subform status to "adsorbed ", record the edge (left, right, top, and bottom) of the main form, and record the gap between the edge and X and Y of the main form.

 

2. when you drag the main form and move all the child forms that have been adsorbed, you need to send the wm_move and wm_size messages of the corresponding main form. When these messages are triggered, after the new coordinates are calculated, move the subform Based on the border adsorption of the subform and the gap between the subform and the main form X and Y.

 

The above are the simplest conditions. In fact, the "main form" and "subform" mentioned above do not mean the pparent parent level in DLG. Create (idd_xx, pparent. It is relative to the adsorption and adsorption objects.

 

And 10px is written directly in the function. You can change it as needed.

 

 

 

Code to be implemented in the child form:

In my code, it inherits the cdialog object (vs2008 ↑ can inherit the cdialogex object) as the cmagnetdialog

Create a private variable: cwnd * m_pmaindlg; carray <cwnd *, cwnd * &> m_pmagnetismlist;

 

· If m_pmaindlg is not null, it indicates that the form is a child form of m_pmaindlg, and the corresponding function of m_pmaindlg is setmaindlg (cwnd * pwnd );.

· M_pmagnetismlist.getsize ()> 0 indicates that many subforms exist under this form.

 

 

Assume that three new forms A, B, and C are created. A is the main form, and B and C are all subforms of.

Written in initdialog of B and C:

This-> setmaindlg ();

In this way, a is set as a subform of B and C.

 

 

Intercept message:

 

Bool cmagnetdialog: onwndmsg (uint message, wparam, lparam, lresult * presult) // process the moved <br/>{< br/> If (Message = wm_size | message = wm_move) <br/>{< br/> If (m_pmagnetismlist.getsize ()> 0) // magnetism parent <br/> moveallmagnetismdlg (); // after the main form is moved, sub-windows are moved <br/>}< br/> return cdialog: onwndmsg (message, wparam, lparam, presult); <br/>}< br/> lresult cmagnetdialog:: windowproc (uint mess Age, wparam, lparam) <br/>{< br/> MSG; <br/> MSG. message = message; <br/> MSG. lparam = lparam; <br/> MSG. wparam = wparam; <br/> If (Message = wm_lbuttondown) <br/> {<br/> releasecapture (); <br/> sendmessage (wm_syscommand, SC _move | htcaption, null); <br/>}< br/> If (Message = wm_windowposchanging) <br/>{< br/> If (m_pmaindlg! = NULL &&! M_pmaindlg-> isiconic () // do not check when minimized <br/>{< br/> childcheckmagnetism (& MSG ); <br/>}< br/> return cdialog: windowproc (MSG. message, MSG. wparam, MSG. lparam); <br/>}< br/> // The following are some implementation functions: <br/>/* move all the adsorbed sub-Windows */<br/> void cmagnetdialog: moveallmagnetismdlg () <br/> {<br/> crect rme; <br/> getwindowrect (& RME); <br/> for (INT I = 0; I <m_pmagnetismlist.getsize (); ++ I) <br/> {<br/> cwnd * pwnd = m_pmagnet Ismlist. getat (I); <br/> If (! Iswindow (pwnd-> m_hwnd) <br/> continue; <br/> cmagnetdialog * pdlg = (cmagnetdialog *) pwnd; <br/> pdlg-> magnetismrerect (RME ); <br/>}< br/>/* determine how to move sub-forms */<br/> void cmagnetdialog: magnetismrerect (crect & rparent) <br/>{< br/> If (m_bisadsorption) <br/>{< br/> crect rcld; <br/> getwindowrect (& rcld ); <br/> int L = rcld. left, t = rcld. top; <br/> switch (m_imagnetismtype) <br/> {<br/> case cmagne Tdialog: magnetism_left: <br/> L = rparent. left-rcld. width (); <br/> T = rparent. top + m_imagnetismrectdelta; <br/> break; <br/> case cmagnetdialog: magnetism_top: <br/> L = rparent. left + m_imagnetismrectdelta; <br/> T = rparent. top-rcld. height (); <br/> break; <br/> case cmagnetdialog: magnetism_right: <br/> L = rparent. right; <br/> T = rparent. top + m_imagnetismrectdelta; <br/> break; <br/> C ASE cmagnetdialog: magnetism_bottom: <br/> L = rparent. left + m_imagnetismrectdelta; <br/> T = rparent. bottom; <br/> break; <br/>}< br/> // movewindow (L, t, rcld. width (), rcld. height (); <br/> setwindowpos (null, L, t, 0, swp_nozorder | swp_nosize | swp_nosendchanging ); <br/>}< br/>/* determine whether the subform can be adsorbed to the main form when there is a windowsposchange message */<br/>/* this is the most relative complicated functions, this function will also be modified in future versions */<br/> bool cmagnetdialog: childc Heckmagnetism (MSG * PMSG) <br/>{< br/> int imindisparitypixel = 10; // adsorption when approaching +-10 pixels <br/> crect rparent; <br/> m_pmaindlg-> getwindowrect (& rparent); <br/> pwindowpos PPOs = (windowpos *) PMSG-> lparam; <br/> crect rcld (cpoint (PPOs-> X, PPOs-> Y), csize (PPOs-> CX, PPOs-> CY )); <br/> // trace (_ T ("child moving/sizing % d x = % d; y = % d/R/N"), PPOs-> flags, rcld. left, rcld. top); <br/> crect rcur; getwindowrect (& rcur); <br/> If (rcld. isrectnull ()&&! Rcur. isrectnull () <br/>{< br/> return isadsorption (); <br/>}< br/> bool bissizing = rcur. Width ()! = Rcld. Width () | rcld. Height ()! = Rcur. height (); <br/> m_imagnetismtype = cmagnetdialog: magnetism_null; <br/> m_imagnetismrectdelta = 0; <br/> setadsorption (false ); <br/> int iothesidemagnetismtype = cmagnetdialog: magnetism_null; <br/> int iothesidemagnetismtype1 = cmagnetdialog: magnetism_null; <br/> If (rcld. top> rparent. top-rcld. height () & rcld. top <rparent. bottom) // y range limit <br/>{< br/> bool bisadsorption = false; <br/> If (ABS (rcld. right-rparent. left) <imindisparitypixel) // left adsorption <br/>{< br/> m_imagnetismtype = cmagnetdialog: magnetism_left; <br/> If (bissizing) <br/> PPOs-> Cx = rparent. left-PPOs-> X; // left unchanged when moving <br/> else <br/> PPOs-> X = rparent. left-rcld. width (); <br/> setadsorption (true); <br/> bisadsorption = true; <br/>} else if (ABS (rcld. left-rparent. right) <imindisparitypixel) // right adsorption <br/> {<br/> m_imagnetismtype = cmagnetdialog: magnetism_right; <br/> If (bissizing) {// when moving, keep right unchanged <br/> PPOs-> X = rparent. right; <br/> PPOs-> Cx = rcld. right-rparent. right; <br/>}else <br/> PPOs-> X = rparent. right; <br/> setadsorption (true); <br/> bisadsorption = true; <br/>}< br/> If (bisadsorption) <br/>{< br/> If (ABS (rcld. top-rparent. top) <imindisparitypixel) <br/>{< br/> If (bissizing) <br/>{// when moving, keep bottom unchanged <br/> PPOs-> Y = rparent. top; <br/> PPOs-> Cy = rcld. bottom-rparent. top; <br/>}else <br/> PPOs-> Y = rparent. top; <br/>}< br/> If (ABS (rcld. bottom-rparent. bottom) <imindisparitypixel) <br/>{< br/> If (bissizing) // move, the top is unchanged <br/> PPOs-> Cy = rparent. bottom-PPOs-> Y; <br/> else <br/> PPOs-> Y = rparent. bottom-rcld. height (); <br/>}< br/> m_imagnetismrectdelta = PPOs-> Y-rparent. top; <br/>}< br/> If (rcld. left> rparent. left-rcld. width () & rcld. left <rparent. right) // X range restriction <br/>{< br/> bool bisadsorption = false; <br/> If (ABS (rcld. bottom-rparent. top) <imindisparitypixel) // adsorption <br/>{< br/> m_imagnetismtype = cmagnetdialog: magnetism_top; <br/> If (bissizing) // move, keep top unchanged <br/> PPOs-> Cy = rparent. top-PPOs-> Y; <br/> else <br/> PPOs-> Y = rparent. top-rcld. height (); <br/> setadsorption (true); <br/> bisadsorption = true; <br/>} else if (ABS (rcld. top-rparent. bottom) <imindisparitypixel) // bottom adsorption <br/>{< br/> m_imagnetismtype = cmagnetdialog: magnetism_bottom; <br/> If (bissizing) {// when moving, keep bottom unchanged <br/> PPOs-> Y = rparent. bottom; <br/> PPOs-> Cy = rcld. bottom-rparent. bottom; <br/>}else <br/> PPOs-> Y = rparent. bottom; <br/> setadsorption (true); <br/> bisadsorption = true; <br/>}< br/> If (bisadsorption) <br/>{< br/> If (ABS (rcld. left-rparent. left) <imindisparitypixel) <br/>{< br/> If (bissizing) {// when moving, keep the right unchanged <br/> PPOs-> X = rparent. left; <br/> PPOs-> Cx = rcld. right-rparent. left; <br/>}else <br/> PPOs-> X = rparent. left; <br/>}< br/> If (ABS (rcld. right-rparent. right) <imindisparitypixel) <br/>{< br/> If (bissizing) // move, left unchanged <br/> PPOs-> Cx = rparent. right-PPOs-> X; <br/> else <br/> PPOs-> X = rparent. right-rcld. width (); <br/>}< br/> m_imagnetismrectdelta = PPOs-> X-rparent. left; <br/>}< br/> return isadsorption (); <br/>}< br/> 

 

 

The above code is not complete, but implements some processes.

 

Download the complete code here:

Http://download.csdn.net/source/2710558

 

 

 

 

This is the first version. It is enabled in windows"Display window content when dragging"The effect is quite obvious, so it is not limited by" dragging is the display of window content "because it does not have a title bar, and then some code is rewritten, you can drag the form after clicking any part of the form. Currently, this code is just a simple method to send the hit_test message spoofing after clicking the mouse, which is similar to clicking the title bar. I will try again later to drag the form after clicking the mouse, mainly in the smooth way. I think many examples on the Internet are very simple. You can pull the form after clicking it.

 

 

Some details:

When the child form and one side of the main form are within the 10px gap, the function of moving the child form will be smooth (always sticking to the side of the main form)

When the child form has been adsorbed, resize the child form, when the child form has two adjacent sides of the adsorption will have magnetic function with the two sides of the main form, please try it yourself

 

In the second version, the following functions will be implemented:

1. After clicking any part of the form, you can drag the form (in this way, you can ignore "Show window content when dragging)

2. When subform B is adsorbed on the main form, other subform C can also be adsorbed on this subform B. Until B loses its adsorption (moving or resize beyond the 10px range)

3. The magnetic properties are enhanced. When the sub-form moves to an edge of any sub-form, the adsorption and resize are also magnetic. 2

 

 

Download the complete code here:

Http://download.csdn.net/source/2710558

 

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.