#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <stdio.h>
HWND main_wnd;
HHOOK mouseHook;
COLORREF color = 0xffffffff;
VOID WINAPIvoid CopyToClipboard(HWND hwnd)
{
if (!OpenClipboard(hwnd))
return;
EmptyClipboard();
int len = 10;
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);
if (!hMem) return;
char* buffer = GlobalLock(hMem);
if (!buffer) return;
sprintf_s(buffer, len, "#%02x%02x%02x",
GetRValue(color), GetGValue(color), GetBValue(color));
GlobalUnlock(buffer);
SetClipboardData(CF_TEXT, hMem);
CloseClipboard();
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
const int TEXT_LINE_HEIGHT = 30;
if ((GetKeyState(VK_LBUTTON) & 0x8000) == 0)//mouse is up
{
POINT pt;
GetCursorPos(&pt);
HDC hdc_desktop = GetDC(0);
COLORREF clr = GetPixel(hdc_desktop, pt.x, pt.y);
ReleaseDC(0, hdc_desktop);
color = clr;
}
RECT rect;
GetClientRect(hwnd, &rect);
rect.bottom -= TEXT_LINE_HEIGHT;
HBRUSH brush = CreateSolidBrush(color);
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);
wchar_t buffer[20];
wsprintf(buffer, L"#%02x%02x%02x",
GetRValue(color), GetGValue(color), GetBValue(color));
SetTextColor(hdc, RGB(0, 0, 0));
HFONT hFont = CreateFont(30, 0, 0, 0, FW_BOLD, 0, 0, 0,
0, 0, 0, ANTIALIASED_QUALITY, 0, 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_KEYDOWN:
//Ctrl+C:
if ((GetKeyState(VK_CONTROL) & 0x8000) == 0x8000 && wParam == 'C')
CopyToClipboard(hwnd);
return 0;
case WM_SIZE:
InvalidateRect(hwnd, NULL, FALSE);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (wParam == WM_MOUSEMOVE)
{
int is_mouse_down = (GetKeyState(VK_LBUTTON) & 0x8000) != 0;
if(!is_mouse_down)
InvalidateRect(main_wnd, 0, 0);
}
return CallNextHookEx(mouseHook, nCode, wParam, lParam);
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prev, PWSTR cmd, int show)
{
const wchar_t CLASS_NAME[] = L"GrabPixlMainWndw";
WNDCLASSEX wc = { 0 };
wc.cbSize = sizeof(wc);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClassEx(&wc);
int screenWidth = GetSystemMetrics(SM_CXFULLSCREEN);
int screenHeight = GetSystemMetrics(SM_CYFULLSCREEN);
const int w = 300;
const int h = 200;
main_wnd = CreateWindowEx(0, CLASS_NAME, L"GrabPixel 1.6",
WS_OVERLAPPEDWINDOW, (screenWidth - w) / 2, (screenHeight - h) / 2,
w, h, NULL, NULL, hInstance, NULL);
ShowWindow(main_wnd, show);
UpdateWindow(main_wnd);
mouseHook = SetWindowsHookEx(WH_MOUSE_LL, LowLevelMouseProc, hInstance, 0);
MSG msg = { 0 };
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <stdio.h>
HWND main_wnd;
HHOOK mouseHook;
COLORREF color = 0xffffffff;
VOID WINAPI CopyToClipboard(HWND hwnd)
{
if (!OpenClipboard(hwnd))
return;
EmptyClipboard();
int len = 10;
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);
if (!hMem) return;
char* buffer = GlobalLock(hMem);
if (!buffer) return;
sprintf_s(buffer, len, "#%02x%02x%02x",
GetRValue(color), GetGValue(color), GetBValue(color));
GlobalUnlock(buffer);
SetClipboardData(CF_TEXT, hMem);
CloseClipboard();
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
const int TEXT_LINE_HEIGHT = 30;
if ((GetKeyState(VK_LBUTTON) & 0x8000) == 0)//mouse is up
{
POINT pt;
GetCursorPos(&pt);
HDC hdc_desktop = GetDC(0);
COLORREF clr = GetPixel(hdc_desktop, pt.x, pt.y);
ReleaseDC(0, hdc_desktop);
color = clr;
}
RECT rect;
GetClientRect(hwnd, &rect);
rect.bottom -= TEXT_LINE_HEIGHT;
HBRUSH brush = CreateSolidBrush(color);
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);
wchar_t buffer[20];
wsprintf(buffer, L"#%02x%02x%02x",
GetRValue(color), GetGValue(color), GetBValue(color));
SetTextColor(hdc, RGB(0, 0, 0));
HFONT hFont = CreateFont(30, 0, 0, 0, FW_BOLD, 0, 0, 0,
0, 0, 0, ANTIALIASED_QUALITY, 0, 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_KEYDOWN:
//Ctrl+C:
if ((GetKeyState(VK_CONTROL) & 0x8000) == 0x8000 && wParam == 'C')
CopyToClipboard(hwnd);
return 0;
case WM_SIZE:
InvalidateRect(hwnd, NULL, FALSE);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (wParam == WM_MOUSEMOVE)
{
int is_mouse_down = (GetKeyState(VK_LBUTTON) & 0x8000) != 0;
if(!is_mouse_down)
InvalidateRect(main_wnd, 0, 0);
}
return CallNextHookEx(mouseHook, nCode, wParam, lParam);
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prev, PWSTR cmd, int show)
{
const wchar_t CLASS_NAME[] = L"GrabPixlMainWndw";
WNDCLASSEX wc = { 0 };
wc.cbSize = sizeof(wc);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClassEx(&wc);
int screenWidth = GetSystemMetrics(SM_CXFULLSCREEN);
int screenHeight = GetSystemMetrics(SM_CYFULLSCREEN);
const int w = 300;
const int h = 200;
main_wnd = CreateWindowEx(0, CLASS_NAME, L"GrabPixel 1.6",
WS_OVERLAPPEDWINDOW, (screenWidth - w) / 2, (screenHeight - h) / 2,
w, h, NULL, NULL, hInstance, NULL);
ShowWindow(main_wnd, show);
UpdateWindow(main_wnd);
mouseHook = SetWindowsHookEx(WH_MOUSE_LL, LowLevelMouseProc, hInstance, 0);
MSG msg = { 0 };
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <stdio.h>
HWND main_wnd;
HHOOK mouseHook;
COLORREF color = 0xffffffff;
void CopyToClipboard(HWND hwnd)
{
if (!OpenClipboard(hwnd))
return;
EmptyClipboard();
int len = 10;
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);
if (!hMem) return;
char* buffer = GlobalLock(hMem);
if (!buffer) return;
sprintf_s(buffer, len, "#%02x%02x%02x",
GetRValue(color), GetGValue(color), GetBValue(color));
GlobalUnlock(buffer);
SetClipboardData(CF_TEXT, hMem);
CloseClipboard();
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
const int TEXT_LINE_HEIGHT = 30;
if ((GetKeyState(VK_LBUTTON) & 0x8000) == 0)//mouse is up
{
POINT pt;
GetCursorPos(&pt);
HDC hdc_desktop = GetDC(0);
COLORREF clr = GetPixel(hdc_desktop, pt.x, pt.y);
ReleaseDC(0, hdc_desktop);
color = clr;
}
RECT rect;
GetClientRect(hwnd, &rect);
rect.bottom -= TEXT_LINE_HEIGHT;
HBRUSH brush = CreateSolidBrush(color);
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);
wchar_t buffer[20];
wsprintf(buffer, L"#%02x%02x%02x",
GetRValue(color), GetGValue(color), GetBValue(color));
SetTextColor(hdc, RGB(0, 0, 0));
HFONT hFont = CreateFont(30, 0, 0, 0, FW_BOLD, 0, 0, 0,
0, 0, 0, ANTIALIASED_QUALITY, 0, 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_KEYDOWN:
//Ctrl+C:
if ((GetKeyState(VK_CONTROL) & 0x8000) == 0x8000 && wParam == 'C')
CopyToClipboard(hwnd);
return 0;
case WM_SIZE:
InvalidateRect(hwnd, NULL, FALSE);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (wParam == WM_MOUSEMOVE)
{
int is_mouse_down = (GetKeyState(VK_LBUTTON) & 0x8000) != 0;
if(!is_mouse_down)
InvalidateRect(main_wnd, 0, 0);
}
return CallNextHookEx(mouseHook, nCode, wParam, lParam);
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prev, PWSTR cmd, int show)
{
const wchar_t CLASS_NAME[] = L"GrabPixlMainWndw";
WNDCLASSEX wc = { 0 };
wc.cbSize = sizeof(wc);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClassEx(&wc);
int screenWidth = GetSystemMetrics(SM_CXFULLSCREEN);
int screenHeight = GetSystemMetrics(SM_CYFULLSCREEN);
const int w = 300;
const int h = 200;
main_wnd = CreateWindowEx(0, CLASS_NAME, L"GrabPixel 1.6",
WS_OVERLAPPEDWINDOW, (screenWidth - w) / 2, (screenHeight - h) / 2,
w, h, NULL, NULL, hInstance, NULL);
ShowWindow(main_wnd, show);
UpdateWindow(main_wnd);
mouseHook = SetWindowsHookEx(WH_MOUSE_LL, LowLevelMouseProc, hInstance, 0);
MSG msg = { 0 };
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
The lag in resizing is caused byUse InvalidateRect
, instead of PostMessage(hwndmain_wnd, WM_PAINT, color0, color0);
in mouse procto update paint. Each time the windowWM_PAINT
message is resizednot for sending messages, the mouse procit is sending additional paint requestused for processing the message. This, and the resource leaks, are likely the cause of lag in resizing.
Error handling for functions such as GetCursorPos
is not necessary. This function fails only if the parameter is incorrect, or there is something seriously wrong, in which case the program will crash anyway.
WM_PAINT
is received by window for processing, it cannot be sent using PostMessage(main_wnd, WM_PAINT, 0, 0);
Use We can also handle InvalidateRectWM_SIZE
insteadto update the window on resizing.
Other suggestions:Error handling for functions such as GetCursorPos
is not necessary. This function fails only if the parameter is incorrect, or there is something seriously wrong, in which case the program will crash anyway.
Add a separate functionMake sure process is DPI aware, for exampleotherwise mouse position will be off, and updateGetPixel
, to get returns the pixelwrong color and draw it.
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <stdio.h>
HWND main_wnd;
HHOOK mouseHook;
COLORREF save_colorcolor = 0xffffffff;
VOID WINAPI CopyToClipboard(HWND hwnd)
{
if (!OpenClipboard(GetDesktopWindow()hwnd))
return;
EmptyClipboard();
int len = 10;
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);
if (!hMem) return;
char* buffer = (char*)GlobalLock(hMem);
if (!buffer) return;
sprintf_s(buffer, len, "#%02x%02x%02x",
GetRValue(save_colorcolor), GetGValue(save_colorcolor), GetBValue(save_colorcolor));
GlobalUnlock(hMembuffer);
SetClipboardData(CF_TEXT, hMem);
CloseClipboard();
}
voidLRESULT updateCALLBACK WindowProc(HWND hwnd, HDCUINT hdcuMsg, WPARAM wParam, LPARAM lParam)
{
constswitch int(uMsg) TEXT_LINE_HEIGHT
= 30;
{
POINTcase pt;WM_PAINT:
GetCursorPos(&pt);{
HDC hdc_desktop = GetDC(0);
PAINTSTRUCT ps;
COLORREF color = GetPixel(hdc_desktop, pt.x, pt.y);
HDC hdc = ReleaseDCBeginPaint(0hwnd, hdc_desktop&ps);
const int is_mouse_downTEXT_LINE_HEIGHT = 30;
if ((GetKeyState(VK_LBUTTON) & 0x8000) !=== 0;0)//mouse is up
if {
POINT pt;
GetCursorPos(!is_mouse_down&pt);
{ HDC hdc_desktop = GetDC(0);
if COLORREF clr = GetPixel(colorhdc_desktop, ==pt.x, save_colorpt.y);
return;ReleaseDC(0, hdc_desktop);
save_color color = color;clr;
}
RECT rect;
GetClientRect(hwnd, &rect);
rect.bottom -= TEXT_LINE_HEIGHT;
HBRUSH brush = CreateSolidBrush(save_colorcolor);
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);
wchar_t buffer[20];
wsprintf(buffer, L"#%02x%02x%02x",
GetRValue(save_colorcolor), GetGValue(save_colorcolor), GetBValue(save_colorcolor));
SetTextColor(hdc, RGB(0, 0, 0));
HFONT hFont = CreateFont(30, 160, 0, 0, FW_BOLD, FALSE, FALSE0, FALSE0, ANSI_CHARSET0,
OUT_DEFAULT_PRECIS 0, CLIP_DEFAULT_PRECIS0, 0, ANTIALIASED_QUALITY, FF_MODERN0, L"Monospaced");
SetTextColor(hdc, RGB(0, 0, 0));
HFONT oldfont = (HFONT)SelectObject(hdc, hFont);
TextOut(hdc, 5, rect.bottom - TEXT_LINE_HEIGHT, buffer, 7);
SelectObject(hdc, oldfont);
DeleteObject(hFont);
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAMEndPaint(hwnd, lParam&ps)
{;
switch (uMsg)
return {0;
case WM_DESTROY:}
PostQuitMessage(0);
case WM_KEYDOWN:
return 0;
case WM_KEYDOWN//Ctrl+C:
if ((GetKeyState(VK_CONTROL) & 0x8000) == 0x8000 && wParam == 'C')
CopyToClipboard(hwnd);
break;return 0;
case WM_SIZE:
InvalidateRect(hwnd, NULL, TRUEFALSE);
return 0;
case WM_PAINTWM_DESTROY:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
update(hwnd, hdc);
EndPaintPostQuitMessage(hwnd, &ps0);
return 0;
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (wParam == WM_MOUSEMOVE)
{
int is_mouse_down = (GetKeyState(VK_LBUTTON) & 0x8000) ==!= 00;
&& wParam == WM_MOUSEMOVE && lParam if(!is_mouse_down)
InvalidateRect(main_wnd, 0, 0);
}
return CallNextHookEx(mouseHook, nCode, wParam, lParam);
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstanceprev, PWSTR pCmdLinecmd, int nCmdShowshow)
{
const wchar_t CLASS_NAME[] = L"GrabPixlMainWndw";
WNDCLASSEX wc = { 0 };
wc.cbSize = sizeof(wc);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClassEx(&wc);
int screenWidth = GetSystemMetrics(SM_CXFULLSCREEN);
int screenHeight = GetSystemMetrics(SM_CYFULLSCREEN);
const int WIDTHw = 300;
const int HEIGHTh = 200;
main_wnd = CreateWindowEx(0, CLASS_NAME, L"GrabPixel 1.6",
WS_OVERLAPPEDWINDOW, (screenWidth - WIDTHw) / 2, (screenHeight - HEIGHTh) / 2,
WIDTHw, HEIGHTh, NULL, NULL, hInstance, NULL);
ShowWindow(main_wnd, nCmdShowshow);
UpdateWindow(main_wnd);
mouseHook = SetWindowsHookEx(WH_MOUSE_LL, LowLevelMouseProc, hInstance, 0);
MSG msg = { 0 };
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
The lag in resizing is caused by PostMessage(hwnd, WM_PAINT, color, color);
in mouse proc. Each time the window is resized, the mouse proc is sending additional paint request.
Error handling for functions such as GetCursorPos
is not necessary. This function fails only if the parameter is incorrect, or there is something seriously wrong, in which case the program will crash anyway.
WM_PAINT
is received by window for processing, it cannot be sent using PostMessage(main_wnd, WM_PAINT, 0, 0);
Use InvalidateRect
instead.
Other suggestions:
Add a separate function, for example update
, to get the pixel color and draw it.
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <stdio.h>
HWND main_wnd;
HHOOK mouseHook;
COLORREF save_color = 0xffffffff;
VOID WINAPI CopyToClipboard(HWND hwnd)
{
if (!OpenClipboard(GetDesktopWindow()))
return;
EmptyClipboard();
int len = 10;
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);
if (!hMem) return;
char* buffer = (char*)GlobalLock(hMem);
if (!buffer) return;
sprintf_s(buffer, len, "#%02x%02x%02x",
GetRValue(save_color), GetGValue(save_color), GetBValue(save_color));
GlobalUnlock(hMem);
SetClipboardData(CF_TEXT, hMem);
CloseClipboard();
}
void update(HWND hwnd, HDC hdc)
{
const int TEXT_LINE_HEIGHT = 30;
POINT pt;
GetCursorPos(&pt);
HDC hdc_desktop = GetDC(0);
COLORREF color = GetPixel(hdc_desktop, pt.x, pt.y);
ReleaseDC(0, hdc_desktop);
int is_mouse_down = (GetKeyState(VK_LBUTTON) & 0x8000) != 0;
if (!is_mouse_down)
{
if (color == save_color)
return;
save_color = color;
}
RECT rect;
GetClientRect(hwnd, &rect);
rect.bottom -= TEXT_LINE_HEIGHT;
HBRUSH brush = CreateSolidBrush(save_color);
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);
wchar_t buffer[20];
wsprintf(buffer, L"#%02x%02x%02x",
GetRValue(save_color), GetGValue(save_color), GetBValue(save_color));
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");
SetTextColor(hdc, RGB(0, 0, 0));
HFONT oldfont = (HFONT)SelectObject(hdc, hFont);
TextOut(hdc, 5, rect.bottom - TEXT_LINE_HEIGHT, buffer, 7);
SelectObject(hdc, oldfont);
DeleteObject(hFont);
}
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);
break;
case WM_SIZE:
InvalidateRect(hwnd, NULL, TRUE);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
update(hwnd, hdc);
EndPaint(hwnd, &ps);
return 0;
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if ((GetKeyState(VK_LBUTTON) & 0x8000) == 0 && wParam == WM_MOUSEMOVE && lParam)
InvalidateRect(main_wnd, 0, 0);
return CallNextHookEx(mouseHook, nCode, wParam, lParam);
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
const wchar_t CLASS_NAME[] = L"GrabPixlMainWndw";
WNDCLASSEX wc = { 0 };
wc.cbSize = sizeof(wc);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClassEx(&wc);
int screenWidth = GetSystemMetrics(SM_CXFULLSCREEN);
int screenHeight = GetSystemMetrics(SM_CYFULLSCREEN);
const int WIDTH = 300;
const int HEIGHT = 200;
main_wnd = CreateWindowEx(0, CLASS_NAME, L"GrabPixel 1.6",
WS_OVERLAPPEDWINDOW, (screenWidth - WIDTH) / 2, (screenHeight - HEIGHT) / 2,
WIDTH, HEIGHT, NULL, NULL, hInstance, NULL);
ShowWindow(main_wnd, nCmdShow);
UpdateWindow(main_wnd);
mouseHook = SetWindowsHookEx(WH_MOUSE_LL, LowLevelMouseProc, hInstance, 0);
MSG msg = { 0 };
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
Use InvalidateRect
, instead of PostMessage(main_wnd, WM_PAINT, 0, 0);
to update paint. WM_PAINT
message is not for sending messages, it is used for processing the message. This, and the resource leaks, are likely the cause of lag in resizing.
We can also handle WM_SIZE
to update the window on resizing.
Error handling for functions such as GetCursorPos
is not necessary. This function fails only if the parameter is incorrect, or there is something seriously wrong, in which case the program will crash anyway.
Make sure process is DPI aware, otherwise mouse position will be off, and GetPixel
returns the wrong color.
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <stdio.h>
HWND main_wnd;
HHOOK mouseHook;
COLORREF color = 0xffffffff;
VOID WINAPI CopyToClipboard(HWND hwnd)
{
if (!OpenClipboard(hwnd))
return;
EmptyClipboard();
int len = 10;
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);
if (!hMem) return;
char* buffer = GlobalLock(hMem);
if (!buffer) return;
sprintf_s(buffer, len, "#%02x%02x%02x",
GetRValue(color), GetGValue(color), GetBValue(color));
GlobalUnlock(buffer);
SetClipboardData(CF_TEXT, hMem);
CloseClipboard();
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
const int TEXT_LINE_HEIGHT = 30;
if ((GetKeyState(VK_LBUTTON) & 0x8000) == 0)//mouse is up
{
POINT pt;
GetCursorPos(&pt);
HDC hdc_desktop = GetDC(0);
COLORREF clr = GetPixel(hdc_desktop, pt.x, pt.y);
ReleaseDC(0, hdc_desktop);
color = clr;
}
RECT rect;
GetClientRect(hwnd, &rect);
rect.bottom -= TEXT_LINE_HEIGHT;
HBRUSH brush = CreateSolidBrush(color);
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);
wchar_t buffer[20];
wsprintf(buffer, L"#%02x%02x%02x",
GetRValue(color), GetGValue(color), GetBValue(color));
SetTextColor(hdc, RGB(0, 0, 0));
HFONT hFont = CreateFont(30, 0, 0, 0, FW_BOLD, 0, 0, 0,
0, 0, 0, ANTIALIASED_QUALITY, 0, 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_KEYDOWN:
//Ctrl+C:
if ((GetKeyState(VK_CONTROL) & 0x8000) == 0x8000 && wParam == 'C')
CopyToClipboard(hwnd);
return 0;
case WM_SIZE:
InvalidateRect(hwnd, NULL, FALSE);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (wParam == WM_MOUSEMOVE)
{
int is_mouse_down = (GetKeyState(VK_LBUTTON) & 0x8000) != 0;
if(!is_mouse_down)
InvalidateRect(main_wnd, 0, 0);
}
return CallNextHookEx(mouseHook, nCode, wParam, lParam);
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prev, PWSTR cmd, int show)
{
const wchar_t CLASS_NAME[] = L"GrabPixlMainWndw";
WNDCLASSEX wc = { 0 };
wc.cbSize = sizeof(wc);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClassEx(&wc);
int screenWidth = GetSystemMetrics(SM_CXFULLSCREEN);
int screenHeight = GetSystemMetrics(SM_CYFULLSCREEN);
const int w = 300;
const int h = 200;
main_wnd = CreateWindowEx(0, CLASS_NAME, L"GrabPixel 1.6",
WS_OVERLAPPEDWINDOW, (screenWidth - w) / 2, (screenHeight - h) / 2,
w, h, NULL, NULL, hInstance, NULL);
ShowWindow(main_wnd, show);
UpdateWindow(main_wnd);
mouseHook = SetWindowsHookEx(WH_MOUSE_LL, LowLevelMouseProc, hInstance, 0);
MSG msg = { 0 };
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
WM_PAINT
is received by window for processing, it cannot be sent using PostMessage(main_wnd, WM_PAINT, 0, 0);
Use InvalidateRect
instead.
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <stdio.h>
#include "w32.h"
const int WIDTH =HWND 300;main_wnd;
const int HEIGHT =HHOOK 200;mouseHook;
const intCOLORREF TEXT_LINE_HEIGHTsave_color = 30;
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);0xffffffff;
LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam);
VOID WINAPI CopyToClipboard(HWND hwnd);
HWND hwnd;{
BOOL ctrlKeyDown = FALSE;
POINT prevPoint;
HHOOK mouseHook;
#define WM_USER1if (WM_USER + 1!OpenClipboard(GetDesktopWindow()
))
COLORREF save_color = 0;
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,return;
PWSTR pCmdLine, int nCmdShowEmptyClipboard() ;
{
prevPoint.x = -1;
int prevPoint.ylen = -1;10;
const wchar_tHGLOBAL CLASS_NAME[]hMem = L"GrabPixlMainWndw";
WNDCLASSEX wc =GlobalAlloc(GMEM_MOVEABLE, {0}len);
wc.cbSize =if sizeof(wc!hMem); return;
wc.hCursorchar* buffer = LoadCursor(NULL, IDC_ARROWchar*)GlobalLock(hMem);
wc.lpfnWndProcif =(!buffer) WindowProc;return;
wc.hInstancesprintf_s(buffer, =len, hInstance;"#%02x%02x%02x",
wc.lpszClassName = CLASS_NAME;
RegisterClassExGetRValue(&wcsave_color);
int screenWidth, =GetGValue(save_color), GetSystemMetricsGetBValue(SM_CXFULLSCREENsave_color));
int screenHeight = GetSystemMetricsGlobalUnlock(SM_CYFULLSCREENhMem);
hwnd = CreateWindowExSetClipboardData(0, CLASS_NAMECF_TEXT, L"GrabPixel 1.6",hMem);
WS_OVERLAPPEDWINDOW, CloseClipboard(screenWidth - WIDTH);
}
void /update(HWND 2hwnd, (screenHeight -HDC HEIGHThdc) / 2,
{
const int TEXT_LINE_HEIGHT = WIDTH,30;
HEIGHT, NULL, NULL, hInstance,POINT NULL);
pt;
if GetCursorPos(hwnd == NULL&pt) ;
HDC hdc_desktop return= 0;
GetDC(0);
mouseHookCOLORREF color = SetWindowsHookExGetPixel(WH_MOUSE_LL, LowLevelMouseProchdc_desktop, hInstancept.x, 0pt.y);
ShowWindowReleaseDC(hwnd0, nCmdShow);
UpdateWindow(hwndhdc_desktop);
MSGint msgis_mouse_down = {0};
while (GetMessageGetKeyState(&msg, NULL, 0, 0)VK_LBUTTON) {
& 0x8000) != 0;
if TranslateMessage(&msg!is_mouse_down);
DispatchMessage(&msg);{
}
return 0;
}
voidif update(HDCcolor hdc== save_color)
{
POINT pt;
GetCursorPos(&pt);
return;
HDC hdc_desktop = GetDC(0);
save_color = GetPixel(hdc_desktop, pt.x, pt.y);color;
ReleaseDC(0, hdc_desktop);}
RECT rect;
GetClientRect(hwnd, &rect);
rect.bottom -= TEXT_LINE_HEIGHT;
HBRUSH brush = CreateSolidBrush(save_color);
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[20];
wsprintf(buffer, L"#%02x%02x%02x",
GetRValue(save_color), GetGValue(save_color), GetBValue(save_color));
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");
SetTextColor(hdc, RGB(0, 0, 0));
HFONT oldfont = (HFONT)SelectObject(hdc, hFont);
TextOut(hdc, 5, rect.bottom - TEXT_LINE_HEIGHT, buffer, 7);
SelectObject(hdc, oldfont);
DeleteObject(hFont);
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_USER1:
{
HDC hdc = GetDC(hwnd);
update(hdc);
ReleaseDC(hwnd, hdc);
return 0;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_KEYDOWN:
if ((GetKeyState(VK_CONTROL) & 0x8000) == 0x8000)
if&& (wParam == 'C')
CopyToClipboard(hwnd);
break;
case WM_SIZE:
InvalidateRect(hwnd, NULL, TRUE);
return 0;
case WM_KEYUP:
if (wParam == VK_CONTROL)
ctrlKeyDown = FALSE;
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
update(hwnd, hdc);
EndPaint(hwnd, &ps);
return 0;
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if ((GetKeyState(VK_LBUTTON) & 0x8000) == 0 && wParam == WM_MOUSEMOVE && lParam)
PostMessageInvalidateRect(hwnd, WM_USER1main_wnd, 0, 0);
return CallNextHookEx(mouseHook, nCode, wParam, lParam);
}
VOIDint WINAPI CopyToClipboardwWinMain(HWNDHINSTANCE hwnd)hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
ifconst (!OpenClipboard(GetDesktopWindow()))wchar_t CLASS_NAME[] = L"GrabPixlMainWndw";
WNDCLASSEX wc = { return;0 };
EmptyClipboardwc.cbSize = sizeof(wc);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpfnWndProc = WindowProc;
intwc.hInstance r= hInstance;
wc.lpszClassName = GetRValueCLASS_NAME;
RegisterClassEx(save_color&wc);
int gscreenWidth = GetGValueGetSystemMetrics(save_colorSM_CXFULLSCREEN);
int bscreenHeight = GetBValueGetSystemMetrics(save_colorSM_CYFULLSCREEN);
const int lenWIDTH = 10;300;
HGLOBALconst hMemint HEIGHT = GlobalAlloc200;
main_wnd = CreateWindowEx(GMEM_MOVEABLE0, len);CLASS_NAME, L"GrabPixel 1.6",
if WS_OVERLAPPEDWINDOW, (!hMemscreenWidth - WIDTH) return;/ 2, (screenHeight - HEIGHT) / 2,
char* buffer = (char* WIDTH, HEIGHT, NULL, NULL, hInstance, NULL)GlobalLock;
ShowWindow(hMemmain_wnd, nCmdShow);
if UpdateWindow(!buffermain_wnd) return;;
sprintf_s(buffer,mouseHook len,= "#%02x%02x%02x"SetWindowsHookEx(WH_MOUSE_LL, rLowLevelMouseProc, ghInstance, b0);
GlobalUnlock(hMem)MSG msg = { 0 };
SetClipboardDatawhile (CF_TEXTGetMessage(&msg, hMemNULL, 0, 0)) {
TranslateMessage(&msg);
CloseClipboard DispatchMessage(&msg);
}
return 0;
}
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <stdio.h>
#include "w32.h"
const int WIDTH = 300;
const int 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;
BOOL ctrlKeyDown = FALSE;
POINT prevPoint;
HHOOK mouseHook;
#define WM_USER1 (WM_USER + 1)
COLORREF save_color = 0;
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
prevPoint.x = -1;
prevPoint.y = -1;
const wchar_t CLASS_NAME[] = L"GrabPixlMainWndw";
WNDCLASSEX wc = {0};
wc.cbSize = sizeof(wc);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
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",
WS_OVERLAPPEDWINDOW, (screenWidth - WIDTH) / 2, (screenHeight - HEIGHT) / 2,
WIDTH, HEIGHT, NULL, NULL, hInstance, NULL);
if (hwnd == NULL)
return 0;
mouseHook = SetWindowsHookEx(WH_MOUSE_LL, LowLevelMouseProc, hInstance, 0);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
MSG msg = {0};
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
void update(HDC hdc)
{
POINT pt;
GetCursorPos(&pt);
HDC hdc_desktop = GetDC(0);
save_color = GetPixel(hdc_desktop, pt.x, pt.y);
ReleaseDC(0, hdc_desktop);
RECT rect;
GetClientRect(hwnd, &rect);
rect.bottom -= TEXT_LINE_HEIGHT;
HBRUSH brush = CreateSolidBrush(save_color);
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[20];
wsprintf(buffer, L"#%02x%02x%02x",
GetRValue(save_color), GetGValue(save_color), GetBValue(save_color));
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");
SetTextColor(hdc, RGB(0, 0, 0));
HFONT oldfont = (HFONT)SelectObject(hdc, hFont);
TextOut(hdc, 5, rect.bottom - TEXT_LINE_HEIGHT, buffer, 7);
SelectObject(hdc, oldfont);
DeleteObject(hFont);
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_USER1:
{
HDC hdc = GetDC(hwnd);
update(hdc);
ReleaseDC(hwnd, hdc);
return 0;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_KEYDOWN:
if ((GetKeyState(VK_CONTROL) & 0x8000) == 0x8000)
if (wParam == 'C')
CopyToClipboard(hwnd);
break;
case WM_SIZE:
InvalidateRect(hwnd, NULL, TRUE);
return 0;
case WM_KEYUP:
if (wParam == VK_CONTROL)
ctrlKeyDown = FALSE;
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
update(hdc);
EndPaint(hwnd, &ps);
return 0;
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if ((GetKeyState(VK_LBUTTON) & 0x8000) == 0 && wParam == WM_MOUSEMOVE && lParam)
PostMessage(hwnd, WM_USER1, 0, 0);
return CallNextHookEx(mouseHook, nCode, wParam, lParam);
}
VOID WINAPI CopyToClipboard(HWND hwnd)
{
if (!OpenClipboard(GetDesktopWindow()))
return;
EmptyClipboard();
int r = GetRValue(save_color);
int g = GetGValue(save_color);
int b = GetBValue(save_color);
int len = 10;
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);
if (!hMem) return;
char* buffer = (char*)GlobalLock(hMem);
if (!buffer) return;
sprintf_s(buffer, len, "#%02x%02x%02x", r, g, b);
GlobalUnlock(hMem);
SetClipboardData(CF_TEXT, hMem);
CloseClipboard();
}
WM_PAINT
is received by window for processing, it cannot be sent using PostMessage(main_wnd, WM_PAINT, 0, 0);
Use InvalidateRect
instead.
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <stdio.h>
HWND main_wnd;
HHOOK mouseHook;
COLORREF save_color = 0xffffffff;
VOID WINAPI CopyToClipboard(HWND hwnd)
{
if (!OpenClipboard(GetDesktopWindow()))
return;
EmptyClipboard();
int len = 10;
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);
if (!hMem) return;
char* buffer = (char*)GlobalLock(hMem);
if (!buffer) return;
sprintf_s(buffer, len, "#%02x%02x%02x",
GetRValue(save_color), GetGValue(save_color), GetBValue(save_color));
GlobalUnlock(hMem);
SetClipboardData(CF_TEXT, hMem);
CloseClipboard();
}
void update(HWND hwnd, HDC hdc)
{
const int TEXT_LINE_HEIGHT = 30;
POINT pt;
GetCursorPos(&pt);
HDC hdc_desktop = GetDC(0);
COLORREF color = GetPixel(hdc_desktop, pt.x, pt.y);
ReleaseDC(0, hdc_desktop);
int is_mouse_down = (GetKeyState(VK_LBUTTON) & 0x8000) != 0;
if (!is_mouse_down)
{
if (color == save_color)
return;
save_color = color;
}
RECT rect;
GetClientRect(hwnd, &rect);
rect.bottom -= TEXT_LINE_HEIGHT;
HBRUSH brush = CreateSolidBrush(save_color);
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);
wchar_t buffer[20];
wsprintf(buffer, L"#%02x%02x%02x",
GetRValue(save_color), GetGValue(save_color), GetBValue(save_color));
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");
SetTextColor(hdc, RGB(0, 0, 0));
HFONT oldfont = (HFONT)SelectObject(hdc, hFont);
TextOut(hdc, 5, rect.bottom - TEXT_LINE_HEIGHT, buffer, 7);
SelectObject(hdc, oldfont);
DeleteObject(hFont);
}
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);
break;
case WM_SIZE:
InvalidateRect(hwnd, NULL, TRUE);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
update(hwnd, hdc);
EndPaint(hwnd, &ps);
return 0;
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if ((GetKeyState(VK_LBUTTON) & 0x8000) == 0 && wParam == WM_MOUSEMOVE && lParam)
InvalidateRect(main_wnd, 0, 0);
return CallNextHookEx(mouseHook, nCode, wParam, lParam);
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
const wchar_t CLASS_NAME[] = L"GrabPixlMainWndw";
WNDCLASSEX wc = { 0 };
wc.cbSize = sizeof(wc);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClassEx(&wc);
int screenWidth = GetSystemMetrics(SM_CXFULLSCREEN);
int screenHeight = GetSystemMetrics(SM_CYFULLSCREEN);
const int WIDTH = 300;
const int HEIGHT = 200;
main_wnd = CreateWindowEx(0, CLASS_NAME, L"GrabPixel 1.6",
WS_OVERLAPPEDWINDOW, (screenWidth - WIDTH) / 2, (screenHeight - HEIGHT) / 2,
WIDTH, HEIGHT, NULL, NULL, hInstance, NULL);
ShowWindow(main_wnd, nCmdShow);
UpdateWindow(main_wnd);
mouseHook = SetWindowsHookEx(WH_MOUSE_LL, LowLevelMouseProc, hInstance, 0);
MSG msg = { 0 };
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}