有一个窗口,您可以在其中使用鼠标进行绘制。
我需要在它旁边放置相同的区域,其中将有在第一个区域中绘制的图片的缩小版本。
也就是我例如在第一个区域画出字母A,大小为300x300,然后,例如按下“压缩”按钮后,在第二个区域出现一个压缩的图片A,大小为64x64。
这是窗口代码:
#include <Windows.h>
#include <vector>
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 800
#define WINDOW_XPOS (GetSystemMetrics(SM_CXSCREEN) >> 1) - (WINDOW_WIDTH >> 1)
#define WINDOW_YPOS (GetSystemMetrics(SM_CYSCREEN) >> 1) - (WINDOW_HEIGHT >> 1)
#define CHILD_WIDTH 300
#define CHILD_HEIGHT 300
#define PADDING_L 50
#define PADDING_B 50
HINSTANCE hInst;
RECT clientRect;
HBRUSH WINDOW_BACKGROUND = CreateSolidBrush(RGB(41, 49, 51));
HBRUSH CHILD_BACKGROUND = CreateSolidBrush(RGB(76, 81, 74));
HBRUSH BRUSH_COLOR = CreateSolidBrush(RGB(213, 213, 213));
HPEN hPen = CreatePen(PS_NULL, 0, NULL);
HDC child_hdc;
HDC hdc;
std::vector<std::vector<bool>> pixels = {};
LRESULT CALLBACK ChildProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
static int x = 0, y = 0, x_prev = 0, y_prev = 0, N = 10;
static BOOL fDrawEllipse;
static HBITMAP hBMP;
static HDC hMemDC;
switch (msg) {
case WM_CREATE: {
child_hdc = GetDC(hwnd);
hMemDC = CreateCompatibleDC(child_hdc);
hBMP = CreateCompatibleBitmap(child_hdc, CHILD_WIDTH, CHILD_HEIGHT);
SelectObject(hMemDC, hBMP);
SelectObject(hMemDC, hPen);
SelectObject(hMemDC, BRUSH_COLOR);
FillRect(hMemDC, &clientRect, CHILD_BACKGROUND);
return 0;
}
case WM_LBUTTONDOWN: {
x = LOWORD(lParam);
y = HIWORD(lParam);
fDrawEllipse = true;
Ellipse(hMemDC, x - 5, y - 5, x + 5, y + 5);
BitBlt(child_hdc, 0, 0, CHILD_WIDTH, CHILD_HEIGHT, hMemDC, 0, 0, SRCCOPY);
return 0;
}
case WM_PAINT: {
BitBlt(child_hdc, 0, 0, CHILD_WIDTH, CHILD_HEIGHT, hMemDC, 0, 0, SRCCOPY);
return 0;
}
case WM_MOUSEMOVE: {
if (fDrawEllipse) {
x_prev = x;
y_prev = y;
x = LOWORD(lParam);
y = HIWORD(lParam);
for (int i = 0; i < N; ++i) {
int px = x_prev + (x - x_prev) * i / N;
int py = y_prev + (y - y_prev) * i / N;
Ellipse(hMemDC, px - 5, py - 5, px + 5, py + 5);
BitBlt(child_hdc, 0, 0, CHILD_WIDTH, CHILD_HEIGHT, hMemDC, 0, 0, SRCCOPY);
}
}
return 0;
}
case WM_LBUTTONUP: {
fDrawEllipse = false;
x_prev = 0; y_prev = 0; x = 0; y = 0;
StretchBlt(hdc, 0, 0, 64, 64, child_hdc, 0, 0, CHILD_WIDTH, CHILD_HEIGHT, SRCCOPY);
return 0;
}
case WM_DESTROY: {
ReleaseDC(hwnd, child_hdc);
DeleteObject(WINDOW_BACKGROUND);
DeleteObject(CHILD_BACKGROUND);
DeleteObject(BRUSH_COLOR);
DeleteObject(hPen);
DeleteDC(hMemDC);
DeleteDC(child_hdc);
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
static HBITMAP hBMP;
switch (msg) {
case WM_CREATE: {
hdc = GetDC(hwnd);
GetClientRect(hwnd, &clientRect);
WNDCLASSEX wc{};
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = ChildProc;
wc.hInstance = hInst;
wc.hbrBackground = CHILD_BACKGROUND;
wc.lpszClassName = "ChildClass";
wc.hCursor = LoadCursor(nullptr, IDC_CROSS);
RegisterClassEx(&wc);
HWND child = CreateWindowEx(0, wc.lpszClassName, (LPCTSTR)nullptr, WS_CHILD | WS_BORDER | WS_VISIBLE,
clientRect.left + PADDING_L, clientRect.bottom - CHILD_HEIGHT - PADDING_B, CHILD_WIDTH, CHILD_HEIGHT,
hwnd, nullptr, hInst, nullptr);
ShowWindow(child, SW_NORMAL);
UpdateWindow(child);
return 0;
}
case WM_DESTROY: {
ReleaseDC(hwnd, hdc);
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE,
_In_ LPSTR lpCmdLine, _In_ int nShowCmd) {
HWND hwnd{};
MSG msg{};
WNDCLASSEX wc;
hInst = hInstance;
wc.cbSize = sizeof(WNDCLASSEX);
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = WINDOW_BACKGROUND;
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
wc.hIconSm = nullptr;
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = "WindowClass";
wc.lpszMenuName = nullptr;
wc.style = CS_VREDRAW | CS_HREDRAW;
if (!RegisterClassEx(&wc))
return EXIT_FAILURE;
hwnd = CreateWindowEx(WS_EX_WINDOWEDGE | WS_EX_TOPMOST, wc.lpszClassName, "Окно windows",
WS_OVERLAPPEDWINDOW, WINDOW_XPOS, WINDOW_YPOS, WINDOW_WIDTH, WINDOW_HEIGHT,
nullptr, nullptr, hInstance, nullptr);
if (hwnd == INVALID_HANDLE_VALUE)
return EXIT_FAILURE;
ShowWindow(hwnd, nShowCmd);
UpdateWindow(hwnd);
BOOL bRet;
while (bRet = GetMessage(&msg, nullptr, 0, 0)) {
if (bRet == -1)
return EXIT_FAILURE;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
我知道这个功能StretchBlt
,但是当我试图弄清楚时,出现了很多问题。
这是我需要的完整工作代码。
当您在一个大矩形中绘制时,它会立即以截断的形式更新为一个小矩形。此外,在调整大小、折叠等时,字段保持不变。
它可能看起来像拐杖,如果是这样,请提供一个好的代码示例作为答案。我会很高兴!)如果它的工作方式相同,我会选择你的答案作为正确的答案。