Overcome Window Flicker While Dragging | CodeGuru

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 […]

Written By
CodeGuru Staff
CodeGuru Staff
Jun 17, 2009
1 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

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!

CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.