(See the previous question.)
Now I have incorporated some suggestions by Barmak Shemirani.
See what I have:
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <stdio.h>
const int DEFAULT_WINDOW_WIDTH = 300;
const int DEFAULT_WINDOW_HEIGHT = 200;
const int TEXT_LINE_HEIGHT = 30;
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam);
VOID WINAPI CopyToClipboard(HWND hwnd);
HWND hwnd;
COLORREF prevColor = 0xffffffff;
HHOOK mouseHook;
int WINAPI wWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PWSTR pCmdLine,
int nCmdShow) {
prevColor = RGB(0, 0, 0);
const wchar_t CLASS_NAME[] = L"GrabPixlMainWndw";
WNDCLASSEX wc = {};
wc.cbSize = sizeof(wc);
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClassEx(&wc);
int screenWidth = GetSystemMetrics(SM_CXFULLSCREEN);
int screenHeight = GetSystemMetrics(SM_CYFULLSCREEN);
hwnd = CreateWindowEx(
0,
CLASS_NAME,
L"GrabPixel 1.6 (by rodde)",
WS_OVERLAPPEDWINDOW,
(screenWidth - DEFAULT_WINDOW_WIDTH) / 2,
(screenHeight - DEFAULT_WINDOW_HEIGHT) / 2,
DEFAULT_WINDOW_WIDTH,
DEFAULT_WINDOW_HEIGHT,
NULL,
NULL,
hInstance,
NULL);
if (hwnd == NULL) {
return 0;
}
mouseHook =
SetWindowsHookExA(
WH_MOUSE_LL,
LowLevelMouseProc,
hInstance,
0);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE);
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_KEYDOWN:
if ((GetKeyState(VK_CONTROL) & 0x8000) == 0x8000 && wParam == 'C') {
CopyToClipboard(hwnd);
}
return 0;
case WM_PAINT:
case WM_SHOWWINDOW:
{
if (uMsg == WM_SHOWWINDOW && !wParam) {
return 0;
}
RECT rect;
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
if ((GetKeyState(VK_LBUTTON) & 0X80000) == 0) {
// Here, the mouse left button is up.
// Not resizing.
POINT pt;
GetCursorPos(&pt);
HDC hdcDesktop = GetDC(NULL);
COLORREF clr = GetPixel(hdcDesktop, pt.x, pt.y);
ReleaseDC(NULL, hdcDesktop);
prevColor = clr;
// Make sure that the cursor is not the resize cursor
// when changing the window size by dragging the
// window corner:
HCURSOR cursor = LoadCursor(NULL, IDC_ARROW);
SetCursor(cursor);
}
GetClientRect(hwnd, &rect);
rect.bottom -= TEXT_LINE_HEIGHT;
// Fill the actual client area:
HBRUSH brush = CreateSolidBrush(prevColor);
FillRect(hdc, &rect, brush);
DeleteObject(brush);
// Draw the RGB rectangle:
brush = CreateSolidBrush(RGB(255, 255, 255));
rect.top = rect.bottom;
rect.bottom += TEXT_LINE_HEIGHT;
FillRect(hdc, &rect, brush);
DeleteObject(brush);
// Print the RGB value of the current pixel:
wchar_t buffer[10];
wsprintf(buffer,
L"#%02x%02x%02x",
GetRValue(prevColor),
GetGValue(prevColor),
GetBValue(prevColor));
SetTextColor(hdc, RGB(0, 0, 0));
HFONT hFont = CreateFont(30,
16,
0,
0,
FW_BOLD,
FALSE,
FALSE,
FALSE,
ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
ANTIALIASED_QUALITY,
FF_MODERN,
L"Monospaced");
HFONT oldFont = (HFONT) SelectObject(hdc, hFont);
TextOut(hdc,
5,
rect.bottom - TEXT_LINE_HEIGHT,
buffer,
7);
SelectObject(hdc, oldFont);
DeleteObject(hFont);
EndPaint(hwnd, &ps);
return 0;
}
case WM_SIZE:
InvalidateRect(hwnd, NULL, FALSE);
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (wParam == WM_MOUSEMOVE) {
BOOL isMouseDown = (GetKeyState(VK_LBUTTON) & 0x8000) != 0;
if (!isMouseDown) {
InvalidateRect(hwnd, NULL, FALSE);
return 0;
}
}
return CallNextHookEx(mouseHook, nCode, wParam, lParam);
}
VOID WINAPI CopyToClipboard(HWND hwnd) {
HGLOBAL hglbCopy;
LPSTR lpstrCopy;
if (!OpenClipboard(GetDesktopWindow())) {
return;
}
EmptyClipboard();
POINT point;
if (GetCursorPos(&point)) {
int x = point.x;
int y = point.y;
COLORREF color = GetPixel(GetDC(NULL), x, y);
int r = GetRValue(color);
int g = GetGValue(color);
int b = GetBValue(color);
char buffer[10];
sprintf_s(buffer, "#%02x%02x%02x", r, g, b);
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, 10);
if (!hGlobal) {
CloseClipboard();
return;
}
memcpy(GlobalLock(hGlobal), buffer, 10);
GlobalUnlock(hGlobal);
SetClipboardData(CF_TEXT, hGlobal);
CloseClipboard();
GlobalFree(hGlobal);
}
}
What's new
- The resize lag bug seems to be fixed.
- The app works on scaled desktops too.
Critique request
Is there anything to improve?