gpt4 book ai didi

c++ - 如何在 GUI 窗口中使用 WinApi (GDI) 在 C++ 中设置鼠标单击像素?

转载 作者:可可西里 更新时间:2023-11-01 13:51:33 26 4
gpt4 key购买 nike

我尝试通过鼠标点击来设置像素,但点击时没有任何反应。这是我的部分代码。

首先,我在 WM_SIZE 中控制窗口大小的变化。比起第一次,当我想通过鼠标设置像素时,我得到窗口的宽度和高度,然后将窗口的内容复制到内存 HDC 和 HBITMAP(在存储窗口中)(HBITMAP 大小等于(宽度,高度))。事实上,我只复制到内存中的清除窗口。

在任何情况下,我都将像素设置为内存 DC。在下一个 WM_PAINT 消息处理中,我将内存 DC 绘制到屏幕。

.....
case WM_SIZE:
{
CheckWidthHeight();
break;
}
case WM_MBUTTONDOWN:
{
if (firstTimeDraw)
{
CheckWidthHeight();
StoreWindow();
firstTimeDraw = false;
}
SetPixel(memoryDC, LOWORD(lParam), HIWORD(lParam), RGB(0,0,0));
break;
}
case WM_PAINT:
{
RestoreWindow();
break;
}
.....

我的函数和变量在哪里:

HDC memoryDC;
HBITMAP memoryBitmap;
int width = 0, height = 0;
bool firstTimeDraw = true;

void CheckWidthHeight()
{
RECT clientRect;
GetClientRect(hwnd, &clientRect);
width = clientRect.right - clientRect.left;
height = clientRect.bottom - clientRect.top;
}

//Copy real window content to memory window
void StoreWindow()
{
HDC hDC = GetDC(hwnd);
memoryDC = CreateCompatibleDC(hDC);
memoryBitmap = CreateCompatibleBitmap(hDC, width, height);
SelectObject(memoryDC, memoryBitmap);
BitBlt(memoryDC, 0, 0, width, height, hDC, 0, 0, SRCCOPY);
ReleaseDC(hwnd, hDC);
}

//Copy memory windows content to real window at the screen
void RestoreWindow()
{
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hwnd, &ps);
memoryDC = CreateCompatibleDC(hDC);
SelectObject(memoryDC, memoryBitmap);
BitBlt(hDC, 0, 0, width, height, memoryDC, 0, 0, SRCCOPY);
EndPaint(hwnd, &ps);
}

我做错了什么?

更新:

A shot in the dark: You're handling the middle button click. Are you by any chance clicking on the left or right mouse buttons? :)

好的。现在我使用 WM_LBUTTONUP 或 WM_LBUTTONDOWN。什么也没有发生。

UPD2:

  1. When you change the memory DC, you'll also want to invalidate the part of the window that is affected so that Windows will generate a WM_PAINT message for it. InvalidateRect would be a good place to start.

我放置了这段代码

RECT rect;
GetClientRect(hwnd, &rect);
InvalidateRect(hwnd, &rect, true);

在 EndPaint 之前。没有什么。比我在 EndPaint 之后移动它。什么都没有。

  1. In the WM_PAINT handler, you need to use a DC provided by BeginPaint and call EndPaint when you're done with it.

我在 RestoreWindow() 中执行此操作。

我还不知道是什么问题...

UPD3:

InvalidateRect() needs to happen in the WM_?BUTTONDOWN handler after the SetPixel (not in RestoreWindow())- it's what tells windows that you want to get a WM_PAINT in the first place.

好的。在你写这条消息之前我已经完成了。还是不行。

UPD4:

非常感谢你,雷米!谢谢大家。现在好了!!

最佳答案

两件事。

  1. 当您更改内存 DC 时,您还需要使受影响的窗口部分无效,以便 Windows 为其生成 WM_PAINT 消息。 InvalidateRect 将是一个很好的起点。

  2. 在 WM_PAINT 处理程序中,您需要使用 BeginPaint 提供的 DC,并在完成后调用 EndPaint。

关于c++ - 如何在 GUI 窗口中使用 WinApi (GDI) 在 C++ 中设置鼠标单击像素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7558595/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com