Color Take


This program gets the color of pixels from the desktop, displays them in a window, and has a 4x1 magnifier by default. 2x or 8x can be selected from the menu. The color value can later be copied to the Clipboard.


The selected colors fill the five boxes. The associated button copies its color to the copy window in the format selected by the Select Format option. The buttons are initially disabled; otherwise, the background color of the dialog window would be copied. Press Copy to sent this value to the Clipboard.

Using the Code

The elements:

  • A menu
  • Window to display the color of the pixel
  • Zoom window (4x1 magnifier)
  • Display HEX, HTML, or RGB
  • Mouse coordinates
  • Five boxes to show the last five selected colors
  • Copy to Clipboard
  1. The Menu, no biggie, used the resource editor. Here is the first challenge: ON_UPDATE_COMMAND_UI does not work for non-system menus. This function toggles menu items. Call it with ToggleMenuItem(0, 1). I hand coded the menu items and sub items; this call sets a check mark on Options menu, Stay on Top.
  2. void CColorTakeDlg::ToggleMenuItem(int nMenu, int nPos)
       // Onupdate command UI doesn't work in a non-system menu
       CMenu *pMenu = GetMenu();
       CMenu *pSubMenu = pMenu->GetSubMenu(nMenu);
       UINT nID = pSubMenu->GetMenuItemID(nPos);
       UINT nState = pSubMenu->GetMenuState(nID, MF_BYCOMMAND);
       ASSERT(nState != 0xFFFFFFFF);
       if(nState & MF_CHECKED)
          pSubMenu->CheckMenuItem(nID, MF_UNCHECKED |
          pSubMenu->CheckMenuItem(nID, MF_CHECKED |
  3. Display current color.
  4. CDC *pSDC = m_current.GetDC();
    CRect sRect;
    pSDC->FillSolidRect(&sRect, m_colCurrent);
  5. Zoom window.
  6. if (bEnableZoom)
        CDC *pDC = m_zoom.GetDC();
        CRect m_rect;
        InflateRect(&m_rect, -1, 0);
        // stretch the 20 x 20 to the 81 x 81 window, close to
        // 4 to 1 magnifier
        pDC->StretchBlt(m_rect.left,, m_rect.Width(),
                        m_rect.Height(), pDesktopDC,
                        pt.x - m_nOffset, pt.y - m_nOffset,
                        m_nWidth, m_nWidth, SRCCOPY);
       pen.CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
       CPen *pOldPen = pDC->SelectObject(&pen);
       CPoint point;
       // draw a red line at the mid point of the x and y axis
       point.x = m_rect.Width()/2;
       point.y =;
       point.y = m_rect.bottom;
       point.x = m_rect.left;
       point.y = m_rect.Height()/2;
       point.x = m_rect.right;
  7. Display HEX, HTML, or RGB.
  8. switch (m_nSelect)
       case 0:    // Hex
          str.Format("%02X, %02X, %02X", rVal, gVal, bVal);
       case 1:    // HTML
          str.Format("#%02X%02X%02X", rVal, gVal, bVal);
       case 2:    // RGB
          str.Format("%d, %d, %d", rVal, gVal, bVal);
  9. Mouse coordinates. This was quite a challenge. I used SetCapture() to get the cursor from the desktop. In the previous version, that was an error.
  10. void CColorTakeDlg::OnTimer(UINT nIDEvent)
       // TODO: Add your message handler code here and/or
       // call default
       HWND m_hwnd = ::GetDesktopWindow();
       CString str;
       POINT pt;
       pt.x = pt.y = 0;
       //  =====================================================
       //  Get the mouse pointer position and display it
       //  =====================================================
       str.Format("X: %d, Y: %d", pt.x, pt.y);
  11. Five boxes to show the last five selected colors.
  12. // Store the current selected color in the left most of
    // five boxes, shifting the old ones right.
    void CColorTakeDlg::CopyColor()
       m_nColor[4] = m_nColor[3];
       m_nColor[3] = m_nColor[2];
       m_nColor[2] = m_nColor[1];
       m_nColor[1] = m_nColor[0];
       m_nColor[0] = m_colCurrent;
  13. Copy to the Clipboard.
  14. void CColorTakeDlg::OnCopy()
       // TODO: Add your control notification handler code here
       m_edit1.SetSel(0, -1);
       // Copy selected color to the Clipboard

Points of Interest

This program uses a CHotKeyCtrl class to copy the selected color to the list and the first box. The void GetHotKey( WORD &wVirtualKeyCode, WORD &wModifiers ) const; function is used to get the hot key from the control. wVirtualKeyCode is the keyboard key (A–Z) pressed and wModifiers are the control keys (Shift, Ctrl, Alt, and the Windows key). The modifier flags defined in CommCtrl.h can be a combination of the following values:

#define HOTKEYF_SHIFT           0x01
#define HOTKEYF_CONTROL         0x02
#define HOTKEYF_ALT             0x04
#define HOTKEYF_EXT             0x08

Then, the hot key has to be registered by using:

BOOL RegisterHotKey(
   HWND hWnd,           // handle to window
   int id,              // hot key identifier
   UINT fsModifiers,    // key-modifier options
   UINT vk              // virtual-key code

The values for fsModifiers are defined in WinUser.h.

#define MOD_ALT         0x0001
#define MOD_CONTROL     0x0002
#define MOD_SHIFT       0x0004
#define MOD_WIN         0x0008

As you can see, the values are not the same, so I have:

void CColorTakeDlg::OnNewHotkey()
   // TODO: Add your control notification handler code here
   UnregisterHotKey(m_hWnd, HOTKEYID);
   m_hotkey1.GetHotKey(wVirtualKeyCode, wModifiers);
      fsModifiers = MOD_SHIFT;
      fsModifiers = MOD_CONTROL;
   case HOTKEYF_ALT:
      fsModifiers = MOD_ALT;
   case HOTKEYF_EXT:
      fsModifiers = MOD_WIN;
   RegisterHotKey(m_hWnd, HOTKEYID, fsModifiers,

These are only four combinations. I didn't want to allow all 16, so I used SetRules().

m_hotkey1.SetHotKey(0x43, HOTKEYF_ALT);
m_hotkey1.SetRules(HKCOMB_CA | HKCOMB_SA | HKCOMB_SC |
                   HKCOMB_SCA | HKCOMB_NONE, HOTKEYF_ALT);
RegisterHotKey(m_hWnd, HOTKEYID, MOD_ALT, 0x43);
wVirtualKeyCode = 0x43;
wModifiers = HOTKEYF_ALT;
fsModifiers = MOD_ALT;

You want something zany, position the cursor in the magnifier window. When you get close to the cross-hairs that are 1 pixel wide, you will see in the window they are 4 pixels wide. If you get closer, they appear 16 pixels wide. About the time they get to be 64 pixels wide, the window will turn red.


If you use this program on older versions of Windows, Win95/Win98, and the zoom window fails to function, you have a problem. The GDI resource causes StretchBlt(...) to return FALSE. Please see the MSDN Knowledge Base article.



  • Nice tool

    Posted by kirants on 12/14/2005 08:34pm

    One suggestion. Most websites and most GUIs these days have different images for hover state. So, as soon as you move mouse over those places the appearance is changed.. So, you see, as soon as you have moved your mouse over the button to find the color, the appearance has changed. It would be cool to have a feature in your application to be able to provide co-ordinates and find the color from that spot

    • Not exactly

      Posted by Roger65 on 12/22/2005 05:21pm


    • Not exactly

      Posted by kirants on 12/22/2005 12:52pm

      What I mean to say is this: Say you have colortake up. Now, you see a cool image on a webpage and you like the color. You move your mouse over the image and suddenly the image has changed to a hover image. So, you see, you won't be able to capture the previous color since the mouse move spoils the image that you wanted to capture. Basically, what I am saying is to be able to capture non-hover color

    • hover color

      Posted by Roger65 on 12/15/2005 06:04am

      My program does this. The five buttons are initially disabled, try a normal button or select a color first then check button 1.

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

Top White Papers and Webcasts

  • Moving from an on-premises environment to Office 365 does not remove the need to plan for disruptions or reduce the business risk requirements for protecting email services. If anything, some risks increase with a move to the cloud. Read how to ease the transition every business faces if considering or already migrating to cloud email. This white paper discusses: Setting expectations when migrating to Office 365 Understanding the implications of relying solely on Exchange Online security Necessary archiving …

  • Enterprises are increasingly looking to platform as a service (PaaS) to lower their costs and speed their time to market for new applications. Developing, deploying, and managing applications in the cloud eliminates the time and expense of managing a physical infrastructure to support them. PaaS offerings must deliver additional long-term benefits, such as a lower total cost of ownership (TCO), rapid scalability, and ease of integration, all while providing robust security and availability. This report …

Most Popular Programming Stories

More for Developers

RSS Feeds

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