Overcome Window Flicker While Dragging

While I use the CImageList control for dragging, I found it flickers in the owner window while draging and redraw the client region. I tried Google to find a solution, but there were no result, so I try to solve it myself.

Here's my solution, which I'm very glad share with you!

First, you should register a new window class and create a new top most tool window, and move it's position far off screen(I take 99000), so it's not visible. The code would look like this:

BOOL CImageDragWrapper::Initialize()
{
   if(m_hDragWnd)
   {
      return TRUE;
   }

   WNDCLASSEX wcex;
   wcex.cbSize = sizeof(WNDCLASSEX); 

   if(!::GetClassInfoEx(AfxGetInstanceHandle(), POPWINDOWCLASSNAM, &wcex))
   {   
      wcex.style           = CS_HREDRAW | CS_VREDRAW;
      //specifies default window procedure 
      wcex.lpfnWndProc     = (WNDPROC)DefWindowProc;
      wcex.cbClsExtra      = 0;
      wcex.cbWndExtra      = 0;
      wcex.hInstance       = AfxGetInstanceHandle();
      wcex.hIcon           = LoadIcon(0, IDI_INFORMATION);
      wcex.hCursor         = LoadCursor(NULL, IDC_ARROW);
      wcex.hbrBackground   = (HBRUSH)(COLOR_WINDOW+1);
      wcex.lpszMenuName    = 0;
      wcex.lpszClassName   = POPWINDOWCLASSNAM;
      wcex.hIconSm         = LoadIcon(0, IDI_INFORMATION);   
      RegisterClassEx(&wcex);
   }

   m_hDragWnd = CreateWindowEx(WS_EX_TOPMOST | WS_EX_TOOLWINDOW, POPWINDOWCLASSNAM,
                        _T(""),WS_POPUP | WS_DISABLED |  WS_CLIPSIBLINGS,99000, 
                        0, 6, 6, 0,   0,
                        AfxGetInstanceHandle(),   0   );

   if(m_hDragWnd)
   {
      SetLayeredWindowAttributes(RGB(255,255,255), 100,   /*0x00000001|*/0x0000002);

      ShowWindow(m_hDragWnd, SW_SHOW);
      UpdateWindow(m_hDragWnd);
   }
   return m_hDragWnd != 0;
}

Second, move the window to properly position and paint it's client. The code would look like this:

BOOL CImageDragWrapper::DragBegin(HWND hDragWndOwner,int cxWnd, int cyWnd, 
                int cxHotSpotOffset, int cyHotSpotOffset,
                const POINT& ptCurrentMousePos, HBITMAP hBack, 
				int cxBackOffset, int cyBackOffset)
{
   if(m_hDragWnd)
   {   
      m_hDragWndOwner = hDragWndOwner;
      m_cxHotSpotOffset = cxHotSpotOffset;
      m_cyHotSpotOffset = cyHotSpotOffset;

      POINT ptDest = ptCurrentMousePos;
      ClientToScreen(m_hDragWndOwner, &ptDest);

      ::MoveWindow(m_hDragWnd,
                ptDest.x - m_cxHotSpotOffset, 
                ptDest.y - m_cyHotSpotOffset, 
                cxWnd,
                cyWnd, TRUE);

      //Draw background image for dragging support window
      if(hBack)
      {
         HDC hDC = ::GetDC(m_hDragWnd);
         HDC hMemDC = ::CreateCompatibleDC(hDC);
            
         HBITMAP hbmpOldMem = (HBITMAP)::SelectObject(hMemDC, hBack);
         
         ::BitBlt(hDC, 0, 
               0, 
               cxWnd, 
               cyWnd, 
               hMemDC, 
               cxBackOffset, 
               cyBackOffset, 
               SRCCOPY);         

         ::SelectObject(hMemDC, hbmpOldMem);
         ::DeleteDC(hMemDC);

         ::ReleaseDC(m_hDragWnd, hDC);
      }
   }
   return m_hDragWnd != 0;
}

Third, changes the position and dimensions for dragging support window by calling MoveWindow

Forth, move dragging to support the window's postion far to screen. The code would look like this:

BOOL CImageDragWrapper::DragEnd()
{
   if(m_hDragWnd && m_hDragWndOwner)
   {
      m_hDragWndOwner = 0;
      ::MoveWindow(m_hDragWnd,
                   99000, 
                   0, 
                   6,
                   6, TRUE);
   }
   return m_hDragWnd != 0;
}

Using the Code:

First, in the InitInstance method of CWinApp's subclass add code like this:

   CImageDragWrapper::Initialize();
   CTestDragDialogDlg dlg;
   m_pMainWnd = &dlg;
   int nResponse = dlg.DoModal();
   if (nResponse == IDOK)
   {
      // TODO: Place code here to handle when the dialog is
      //  dismissed with OK
   }
   else if (nResponse == IDCANCEL)
   {
      // TODO: Place code here to handle when the dialog is
      //  dismissed with Cancel
   }

   CImageDragWrapper::Destroy();

Then in dragging the owner window's OnMouseMove, OnLButtonUp method calls DragBegin, DragMove, and DragEnd method of CImageDragWrapper, It's very simple.

Note: you can compare CImageDragWrapper with CImageList by using my sample code!



About the Author

Jehhry23 Lv

I'm come from china, very glad to make friend with you!

Downloads

Comments

  • Is Penis Enlargement an Option to Erectile Dysfunction?

    Posted by anueffifielm on 06/21/2013 12:54am

    Erectile Dysfunction - Is it Psychological? It is also widely spread and well known in many countries [url=http://rxhealth.pw ] how long will an erection last with viagra [/url] read far more Erectile Malfunction and Impotence, Avoid Taboo See How

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • You've managed to piece together the "DREAM TEAM." Your tech staff works like a well-oiled machine, keeping your company humming and thriving. And then it happens: dissension. For whatever reason, your employees have grown unhappy and you find out they're searching for new employment or losing productivity. What did you do wrong? Did you hire the wrong people? Did your company push them away? Or is it a combination of numerous factors? Read this white paper to learn how to build an environment that fosters …

  • Salesforce has been recognized by Gartner as a leader in this report for three years in a row. This graphic was published by Gartner, Inc. as part of a larger research document and should be evaluated in the context of the entire document. The Gartner document is available upon request from Salesforce.com. Gartner does not endorse any vendor, product or service depicted in its research publications, and does not advise technology users to select only those vendors with the highest ratings. Gartner research …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date