如何使用 GDIPLUS 绘制第二台显示器
How to draw over second monitor with GDIPLUS
我想在桌面上画一些文字和线条。
我正在使用 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;
}
是的,这出奇地困难。 GetWindowDC 的帮助确实警告我们它仅适用于主显示器(这显然只对了一半,因为您示例中的常规 GDI 位确实有效):
To get the device context for other display monitors, use the
EnumDisplayMonitors and CreateDC functions.
这不是什么暗示,但我想这个工作示例(基于您的代码)的意思是:
#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.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;
}
是的,这出奇地困难。 GetWindowDC 的帮助确实警告我们它仅适用于主显示器(这显然只对了一半,因为您示例中的常规 GDI 位确实有效):
To get the device context for other display monitors, use the EnumDisplayMonitors and CreateDC functions.
这不是什么暗示,但我想这个工作示例(基于您的代码)的意思是:
#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;
}