lccccccc 发表于 2024-2-19 13:49

为什么会有黑框呢?

本帖最后由 lccccccc 于 2024-2-20 18:50 编辑

代码:
#include <Windows.h>

bool allowDrawing = true;
POINT lastMousePos = { 0 };

#define WS_EX_LAYERED 0x80000
#define WS_EX_TRANSPARENT 0x20
#define GWL_EXSTYLE -20
#define LWA_ALPHA 0

int previousStyle;
void MakeWindowExTransparent(HWND hWnd) {
    // 获取当前窗口样式
    previousStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
    // 设置窗口样式,使窗口透明并支持鼠标穿透
    SetWindowLong(hWnd, GWL_EXSTYLE, previousStyle | WS_EX_LAYERED | WS_EX_TRANSPARENT);
    // 设置窗口透明度
    SetLayeredWindowAttributes(hWnd, 0, 100, LWA_ALPHA);
}

void RestoreWindowStyle(HWND hWnd) {
    // 恢复之前的窗口样式
    SetWindowLong(hWnd, GWL_EXSTYLE, previousStyle);
    // 将窗口透明度恢复为不透明
    SetLayeredWindowAttributes(hWnd, 0, 255, LWA_ALPHA);
}


LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
    case WM_CLOSE: {
      PostQuitMessage(0);
      return 0;
    }
    case WM_HOTKEY: {
      allowDrawing = !allowDrawing;
      if (!allowDrawing) {
            MakeWindowExTransparent(hwnd);
      }
      else {
            RestoreWindowStyle(hwnd);
      }
      return 0;
    }
    case WM_LBUTTONDOWN: {
      lastMousePos.x = LOWORD(lParam);
      lastMousePos.y = HIWORD(lParam);
      return 0;
    }
    case WM_MOUSEMOVE: {
      if (allowDrawing && wParam & MK_LBUTTON) {
            HDC hdc = GetDC(hwnd);
            HPEN hpen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0));//实线
            HPEN oldhpen = (HPEN)SelectObject(hdc, hpen);
            MoveToEx(hdc, lastMousePos.x, lastMousePos.y, NULL);
            LineTo(hdc, LOWORD(lParam), HIWORD(lParam));
            SelectObject(hdc, oldhpen);//恢复先前画笔
            DeleteObject(hpen);
            ReleaseDC(hwnd, hdc);
            lastMousePos.x = LOWORD(lParam);
            lastMousePos.y = HIWORD(lParam);
      }
      return 0;
    }
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    const wchar_t CLASS_NAME[] = L"Sample Window Class";

    WNDCLASS wc = { };
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = CLASS_NAME;
    RegisterClass(&wc);

    HWND hwnd = CreateWindowEx(NULL, CLASS_NAME, L"Paint", WS_POPUP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInstance, NULL);
    if (hwnd == NULL) {
      return 0;
    }
    // 注册热键
    RegisterHotKey(hwnd, 1, MOD_CONTROL | MOD_SHIFT, 'P');
    ShowWindow(hwnd, nCmdShow);
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
    // 注销热键
    UnregisterHotKey(hwnd, 1);
    return 0;
}

Vs编译后,运行,可以在屏幕上画画,按Ctrl+Shift+P后可以取消画画模式,用户可以像平时一样点击屏幕。但是,画画时为什么画笔后面有黑框呢?

sai609 发表于 2024-2-19 14:19

用弄好的成品,不香吗 屏幕标注工具

错的是世界 发表于 2024-2-19 15:25

大多来讲是电脑显卡性能不给力

lry123 发表于 2024-2-19 15:44

大概率是显卡不行

twyhb 发表于 2024-2-19 17:52

在给定的代码中,绘制黑色边框的原因是使用 CreatePen 函数创建画笔时,指定了 PS_SOLID 样式和宽度为 3 像素。这会导致绘制的线条具有实心的外观,并且有一个黑色的边框。

如果你想要去掉画笔后面的黑框,可以尝试以下两种方法:

1.使用 PS_NULL 样式的画笔:将 CreatePen 函数的样式参数修改为 PS_NULL,这样创建的画笔将没有实际的线条,只会绘制线条轮廓,从而去除黑色边框的显示。
HPEN hpen = CreatePen(PS_NULL, 0, RGB(255, 0, 0));

2.使用 GDI+ 绘图库:GDI+ 是 Windows 平台上的一个图形绘制库,具有更强大的图形绘制功能,并且可以绘制平滑的线条,没有黑色边框的问题。你需要添加 gdiplus.h 头文件,并链接 gdiplus.lib 库文件。
#include <gdiplus.h>
#pragma comment(lib, "gdiplus.lib")

// 在 WinMain 函数中初始化 GDI+
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

// 在 WM_MOUSEMOVE 消息处理中使用 GDI+ 绘制线条
Graphics graphics(hwnd);
Pen pen(Color(255, 255, 0, 0), 3);// 线条颜色为红色,宽度为 3 像素
graphics.DrawLine(&pen, lastMousePos.x, lastMousePos.y, LOWORD(lParam), HIWORD(lParam));

// 在程序结束前清理 GDI+
Gdiplus::GdiplusShutdown(gdiplusToken);
页: [1]
查看完整版本: 为什么会有黑框呢?