Reputation: 449
I'm writing a program similar to "Paint" in Windows. At first I tried to make a "pencil" function handling WM_MOUSEMOVE message and calling SetPixel() properly. But when mouse moves too fast, not all pixels are appearing (they look like sparse). I think I must replace that SetPixel() function with another code, but I don't know what.
Upvotes: 1
Views: 1543
Reputation: 10417
Catch WM_LBUTTONDOWN
, and set capture on your window saving the first mouse coord.
Catch WM_MOUSEMOVE
, and draw line from first coord to now coord. Then, save the now coord into first mouse coord.
repeat 2.
Catch WM_LBUTTONUP
, and release capture.
Example:
#include <windows.h>
#include <windowsx.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int)
{
WNDCLASS wc;
HWND hWnd;
MSG msg;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = L"adf";
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
RegisterClass(&wc);
hWnd = CreateWindow(L"adf", NULL, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInst, NULL);
ShowWindow(hWnd, SW_NORMAL);
while (GetMessage(&msg, 0, 0, NULL))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
static int prevx, prevy;
switch (iMsg)
{
case WM_LBUTTONDOWN:
prevx = GET_X_LPARAM(lParam);
prevy = GET_Y_LPARAM(lParam);
SetCapture(hWnd);
return 0;
case WM_LBUTTONUP:
ReleaseCapture();
return 0;
case WM_MOUSEMOVE:
if (GetCapture() == hWnd)
{
HDC hdc = GetDC(hWnd);
MoveToEx(hdc, prevx, prevy, NULL);
LineTo(hdc, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
prevx = GET_X_LPARAM(lParam);
prevy = GET_Y_LPARAM(lParam);
ReleaseDC(hWnd, hdc);
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, iMsg, wParam, lParam);
}
Upvotes: 3
Reputation: 863
This is because the mouse may move more than one pixel on each 'update', and is not a fault in SetPixel. Instead, you should remember the last pixel that had a mouseover, and draw a line between the two pixels (I think the correct function is DrawLine()
). See ikh's answer for a detailed description of that method.
Upvotes: 6