如何使用 GDIPLUS 绘制第二个显示器

Posted

技术标签:

【中文标题】如何使用 GDIPLUS 绘制第二个显示器【英文标题】:How to draw over second monitor with GDIPLUS 【发布时间】:2015-05-28 09:25:26 【问题描述】:

我想在桌面上画一些文字和线条。

我正在使用 gdiplus.h 打印带有函数 DrawString 的文本。

但它只在主屏幕监视器上打印文本。

如果在演示模式下使用 2 个显示器,我需要在第二个显示器上打印文本。

#define _WIN32_WINNT 0x500
#include <windows.h>
#include <gdiplus.h>

using namespace Gdiplus;

#pragma comment (lib,"Gdiplus.lib")

int main() 

    HWND desktop = GetDesktopWindow();
    HDC hdc = GetWindowDC(desktop); 

    ULONG_PTR m_gdiplusToken;
    // Initialize GDI+
    GdiplusStartupInput gdiplusStartupInput;
    GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);

    while (true)
    

        HPEN newpen;
        LPPOINT point = NULL;
        newpen = CreatePen(PS_COSMETIC, 20, RGB(255, 0, 0));
        SelectObject(hdc, newpen);
        MoveToEx(hdc, 1500, 500, point);
        LineTo(hdc, 1600, 550 ); 
        //this block works for draw line in second monitor

        TextOut(hdc, 1500, 300, TEXT("Text of text out"), 17); // this works too


    //But if I'm use gdiplus only print things on the primary screen
    Gdiplus::Graphics g(hdc);

    Pen      pen(Gdiplus::Color(0, 0, 255), 2);

    g.DrawLine(&pen, 1500, 0, 1700, 600);// dont work

    g.DrawLine(&pen, 0, 0, 1200, 600);//  work, but is in the primary screen

    FontFamily  fontFamily(L"Times New Roman");
    Font        font(&fontFamily, 24, FontStyleRegular, UnitPixel);
    SolidBrush  brush(Color(255, 0, 0, 255));

    g.DrawString(TEXT("test of GDI+"), 13, &font, PointF(1600.0f, 300.0f), &brush); // dont work

    g.DrawString(TEXT("test of GDI+"), 13, &font, PointF(500.0f, 300.0f), &brush); // work, but is in the primary screen
    

    Gdiplus::GdiplusShutdown(m_gdiplusToken);

    return 0;

【问题讨论】:

【参考方案1】:

是的,这非常困难。 GetWindowDC 的帮助确实警告我们它仅适用于主显示监视器(这显然只对了一半,因为您示例中的常规 GDI 位确实有效):

要获取其他显示监视器的设备上下文,请使用 EnumDisplayMonitors 和 CreateDC 函数。

这不是什么提示,但我想这个工作示例(基于您的代码)的内容是有意的:

#define _WIN32_WINNT 0x500
#include <windows.h>
#include <gdiplus.h>

using namespace Gdiplus;

#pragma comment (lib,"Gdiplus.lib")

BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)

    MONITORINFOEXW info;
    info.cbSize = sizeof(info);
    ::GetMonitorInfoW(hMonitor, &info);

    HDC hdc = ::CreateDCW(NULL, info.szDevice, NULL, NULL);

    
        Gdiplus::Graphics graphics(hdc);

        FontFamily  fontFamily(L"Times New Roman");
        Font        font(&fontFamily, 24, FontStyleRegular, UnitPixel);
        SolidBrush  brush(Color(255, 0, 0, 255));

        graphics.DrawString(
                    info.szDevice,
                    wcslen(info.szDevice),
                    &font,
                    PointF(0.0f, 0.0f),
                    &brush);
    

    ::DeleteDC(hdc);

    return TRUE;


int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int)

    ULONG_PTR m_gdiplusToken;
    GdiplusStartupInput gdiplusStartupInput;
    Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);

    while (true)
    
        ::EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, NULL);
    

    Gdiplus::GdiplusShutdown(m_gdiplusToken);

    return 0;

【讨论】:

以上是关于如何使用 GDIPLUS 绘制第二个显示器的主要内容,如果未能解决你的问题,请参考以下文章

在 OpenGL 4 中创建第二个 VAO 并绘制两个形状

如何绘制多个形状

如何告诉 Matplotlib 创建第二个(新)图,然后在旧图上绘制?

如何更新第二个绘图轴 plotly Scatter3D subplots

如何使用Javascript根据先前的下拉值显示第二个下拉列表

在不使用导航控制器的情况下转到第二个视图时如何显示动画?