Win32屏幕保护程序多显示器与主显示器不是最左边
Win32 Screensaver multiple monitors with main display not leftmost
我做了一个屏幕保护程序,它可以简单地从右向左滚动用户定义的文本,如果超过左边界就自动跳转回右。
它可以完美地与多个显示器一起工作,除非有一个例外:如果"主显示器"在右边(即监视器#2是主要的),那么我就不会得到滚动文本,但是监视器被代码黑掉了。如果主显示为#1,则没有问题。
我花了几个小时研究代码,但无法确定问题出现在哪个阶段;我可以确认文本在正确的位置(我插入了验证其当前位置的日志代码),但就好像其中一个API调用只是擦除它一样。我已经阅读了它们的文档,看起来都很好。
我在WM_CREATE中创建一个自定义DC:
if (( hDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL)) == NULL )
为了防止闪烁,我创建了兼容的对象来更新:
void
TickerScreensaver::Paint_Prep(HDC hDC)
{
_devcon_mem = CreateCompatibleDC(hDC);
_devcon_orig = hDC;
_bmp_mem = CreateCompatibleBitmap(hDC, _width, _height);
}
和在WM_PAINT中绘制时(在BeginPaint等之后),做一个位块传输到实际的设备上下文:
void
TickerScreensaver::Paint(HDC hDC, RECT rect)
{
_bmp_orig = (HBITMAP)SelectObject(_devcon_mem, _bmp_mem);
FillRect(_devcon_mem, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH));
if ( _gdiplus_token != NULL )
{
Graphics graphics(_devcon_mem);
SolidBrush brush(cfg.display.font_colour);
FontFamily font_family(cfg.display.font_family.c_str());
Font font(&font_family, cfg.display.font_size, FontStyleRegular, UnitPixel);
PointF point_f((f32)cfg.display.text_pos.x, (f32)cfg.display.text_pos.y);
RectF layout_rect(0, 0, 0, 0);
RectF bound_rect;
graphics.SetTextRenderingHint(TextRenderingHintAntiAlias);
graphics.MeasureString(cfg.display.text.c_str(), cfg.display.text.length(), &font, layout_rect, &bound_rect);
cfg.display.offset.x = (DWORD)(0 - bound_rect.Width);
cfg.display.offset.y = (DWORD)(bound_rect.Height / 2);
graphics.DrawString(cfg.display.text.c_str(), cfg.display.text.length(), &font, point_f, &brush);
}
BitBlt(hDC, 0, 0, _width, _height, _devcon_mem, 0, 0, SRCCOPY);
SelectObject(_devcon_mem, _bmp_orig);
}
我这样计算尺寸:
void
TickerScreensaver::GetFullscreenRect(HDC hDC, RECT *rect)
{
RECT s = { 0, 0, 0, 0 };
if ( EnumDisplayMonitors(hDC, NULL, EnumMonitorCallback, (LPARAM)&s) )
{
CopyRect(rect, &s);
s.left < 0 ?
_width = s.right + (0 + -s.left) :
_width = s.right;
s.top < 0 ?
_height = s.bottom + (0 + -s.top) :
_height = s.bottom;
}
}
请注意,计算出的宽度、高度等都是100%准确的;这纯粹是绘图代码,似乎没有在主显示器上工作,只有当它在右边时(它将原点设置为{0,0},监视器#1然后为负值)。它也可以在三屏显示器上再现,主体在中间。
好吧,事实证明这是很好的和简单的-在Paint()
,我们应该使用一个矩形使用实际的宽度和高度,而不是一个检索到的包含负值(一个实际从API函数检索):
RECT r = { 0, 0, _width, _height };
_bmp_orig = (HBITMAP)SelectObject(_devcon_mem, _bmp_mem);
FillRect(_devcon_mem, &r, (HBRUSH)GetStockObject(BLACK_BRUSH));
相关文章:
- 如何创建一个QTableWidgetItem,用长文本右对齐,左边有省略号
- 如何在qt中同步应用程序和显示器的刷新率?
- C++列出屏幕以在第二台显示器中显示图像
- 使用多个显示器 - XOpenDisplay(NULL) 有时无法获取窗口的当前显示吗?
- '.expression'左边必须有类/结构/联合
- 自由过剩(某些东西):无法打开显示器
- 获取数字最左边两个位的值的最便宜的方法是什么?
- 管理多个显示器
- 如何在一行中找到数字的最左边位
- 为什么我的串行串行在Arduino IDE上通过串行显示器进行两次打印
- 如何使用OpenCV在不同的显示器中显示不同的窗口
- 获取有关 X11 中离鼠标光标最近的显示器的信息
- 显示器在 Ubuntu 上使用 OpenGL 闪烁
- 如何在液晶显示器上显示粗体字
- 如何处理 KDE5 等离子体中第二个显示器的连接
- 如何拆分在多个8位显示器上显示的值
- Allegro 5:在大分辨率显示器中处理小精灵尺寸
- 如何在2D中构建显示器
- 如何区分外接显示器和笔记本电脑屏幕本身?
- Win32屏幕保护程序多显示器与主显示器不是最左边