SetPixel() is too slow

SetPixel() is too slow

本文关键字:too slow is SetPixel      更新时间:2023-10-16

我正在写一个类似于Windows中的"Paint"的程序。起初,我试图做一个"铅笔"函数处理WM_MOUSEMOVE消息并正确调用SetPixel()。但是当鼠标移动太快时,并不是所有的像素都显示出来(它们看起来很稀疏)。我想我必须用另一个代码替换SetPixel()函数,但我不知道。

这是因为鼠标可能在每次"更新"时移动超过一个像素,而不是SetPixel的错误。相反,您应该记住鼠标悬停的最后一个像素,并在两个像素之间画一条线(我认为正确的函数是DrawLine())。有关该方法的详细描述,请参阅ikh的回答。

  1. 捕获WM_LBUTTONDOWN,并设置捕获在您的窗口保存第一个鼠标键

  2. 捕捉WM_MOUSEMOVE,从第一帧到现在帧绘制线,然后将现在帧保存为第一帧鼠标帧

  3. 重复2 .

  4. 捕获WM_LBUTTONUP,并释放捕获

的例子:

#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);
}