Introduction Here's a little program I wrote that shows the color under the cursor as well as the cursor's position. It's useful for grabbing colors from websites or pictures. The Code It's in Win32 C. I compile it with gcc under Dev-C++. In order to get it to compile on MSVC++ (which I've had for only two days and it seems a lot more complicated!) I had to set these project properties: Code: Configuration Properties: General Character Set: "Not Set" C/C++ Precompiled Headers Create/Use Precompiled Header: "Not Using Precompiled Headers" The C code, resource.rc, and icon are in the attachment. The C code is also here for your perusal. Code: // WhatColor.c // Shows the position and color of the point under the cursor. // To use, click on the window and drag the cursor around the screen. // Dbl-click to close (or single-click on notification-area icon). #include <windows.h> #define SIZEX 92 #define SIZEY 42 #define POSX 0 #define POSY 0 #define COLOR_BACK RGB(0,0,0) #define COLOR_FORE RGB(0,200,200) #define ID_TASKBAR_ICON 1 #define MYWM_NOTIFYICON WM_USER LRESULT CALLBACK windowProc (HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { static HDC hdcDisp; static int x, y; static COLORREF color; switch (msg) { case WM_CREATE: hdcDisp = CreateDC ("DISPLAY", NULL, NULL, NULL); break; case WM_PAINT: { HDC hdc; PAINTSTRUCT ps; char txt[32]; hdc = BeginPaint (hwnd, &ps); SetBkColor (hdc, COLOR_BACK); SetTextColor (hdc, COLOR_FORE); TextOut (hdc, 5, 5, txt, wsprintf (txt, "(%d, %d)", x, y)); TextOut (hdc, 5, 23, txt, wsprintf (txt, "%02x %02x %02x", GetRValue (color), GetGValue (color), GetBValue (color))); EndPaint (hwnd, &ps); } break; case WM_LBUTTONDOWN: SetCapture (hwnd); SendMessage (hwnd, WM_MOUSEMOVE, wp, lp); break; case WM_MOUSEMOVE: if (GetCapture() != hwnd) break; // The extra stuff here is to make it work properly // when the window is not positioned at 0,0. x = POSX + (SHORT) LOWORD (lp); y = POSY + (SHORT) HIWORD (lp); color = GetPixel (hdcDisp, x, y); InvalidateRect (hwnd, NULL, TRUE); break; case WM_LBUTTONUP: ReleaseCapture(); break; case MYWM_NOTIFYICON: switch (wp) { case ID_TASKBAR_ICON: switch (lp) { // Reacting to the button-down message seems to pass // the button-up to the next icon (after closing this one) // so instead, react to the button-up message. case WM_LBUTTONUP: PostMessage (hwnd, WM_DESTROY, 0, 0); break; } break; } break; case WM_LBUTTONDBLCLK: case WM_DESTROY: DeleteDC (hdcDisp); PostQuitMessage (0); break; default: return DefWindowProc (hwnd, msg, wp, lp); } return 0; } BOOL taskbarAddIcon (HWND hwnd, UINT id, HICON hicon) { NOTIFYICONDATA nid = { sizeof (NOTIFYICONDATA) }; nid.hWnd = hwnd; nid.uID = id; nid.uFlags = NIF_MESSAGE | NIF_ICON; nid.hIcon = hicon; nid.uCallbackMessage = MYWM_NOTIFYICON; return Shell_NotifyIcon (NIM_ADD, &nid); } BOOL taskbarDeleteIcon (HWND hwnd, UINT id) { NOTIFYICONDATA nid = { sizeof (NOTIFYICONDATA) }; nid.hWnd = hwnd; nid.uID = id; return Shell_NotifyIcon (NIM_DELETE, &nid); } void registerWindow (HINSTANCE hinst, char *appName, HBRUSH hbrBackground, WNDPROC wndproc) { WNDCLASSEX wc = { sizeof (wc) }; wc.style = CS_DBLCLKS; wc.lpfnWndProc = wndproc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hinst; wc.hIcon = LoadIcon (hinst, appName); wc.hCursor = LoadCursor (NULL, IDC_ARROW); wc.hbrBackground = hbrBackground; wc.lpszMenuName = NULL; wc.lpszClassName = appName; wc.hIconSm = LoadIcon (hinst, appName); RegisterClassEx (&wc); } int WINAPI WinMain (HINSTANCE hinst, HINSTANCE unused, PSTR cmd, int show) { char *appName = "WhatColor"; MSG msg; HWND hwnd; HBRUSH hbrBackground; HICON hIcon; hbrBackground = (HBRUSH) CreateSolidBrush (COLOR_BACK); registerWindow (hinst, appName, hbrBackground, windowProc); // Create invisible parent to keep the actual window out of the taskbar. hwnd = CreateWindow (appName, 0, 0, 0, 0, 0, 0, 0, 0, hinst, 0); hwnd = CreateWindow (appName, appName, WS_POPUP|WS_VISIBLE, POSX, POSY, SIZEX, SIZEY, hwnd, // The invisible parent 0, hinst, 0); hIcon = (HICON) LoadImage (hinst, appName, IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); taskbarAddIcon (hwnd, ID_TASKBAR_ICON, hIcon); DestroyIcon (hIcon); while (GetMessage (&msg, 0, 0, 0)) DispatchMessage (&msg); taskbarDeleteIcon (hwnd, ID_TASKBAR_ICON); DeleteObject (hbrBackground); return msg.wParam; }