使用EnumDisplayMonitors的屏幕保护程序仅在第二个监视器上绘制黑色矩形 [英] Screensaver using EnumDisplayMonitors only draws black rectanlge on 2nd monitor

查看:145
本文介绍了使用EnumDisplayMonitors的屏幕保护程序仅在第二个监视器上绘制黑色矩形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试了以下代码,但除了第二个监视器上的黑色矩形(使用GDI +)外,我什么都没得到.有人听说过这个问题吗?我在第二个监视器上所做的任何绘图(位图或文本)都呈现为黑色矩形.谢谢!

I tried the following code but I am getting nothing but black rectangles where my drawing images should be (using GDI+) on my 2nd monitor. Has anyone heard of this issue? Any drawing I do (bitmap or text) on the second monitor renders as a black rectangle. Thanks!

LRESULT WINAPI ScreenSaverProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)  
{
   static UINT         uTimer;   // timer identifier

   // Handles screen saver messages  
   switch(message)  
   { 
      // <snip>
      case WM_PAINT:   //  Sent when the system or another application makes a request to paint a portion of an application's window (e.g., UpdateWindow/RedrawWindow)
      {
         PAINTSTRUCT lpPaint = {0};
         HDC hdc = BeginPaint(hwnd, &lpPaint );
            EnumDisplayMonitors(hdc, NULL, MonitorNumProcPaint, 0);  // For every monitor attached, call the passed in function
         EndPaint(hwnd, &lpPaint);
         return true;
      }
      // <snip>
   }
}
 
BOOL CALLBACK MonitorNumProcPaint(HMONITOR hMonitor, HDC hdc, LPRECT lprcMonitor, LPARAM data)
{
   // If the coordinates of the top left corner are 0,0, then we're rendering on the primary monitor, otherwise we're not.
   if (lprcMonitor->left == 0 && lprcMonitor->top == 0)
      return (PaintPrimaryDisplay(hMonitor, hdc, lprcMonitor, data));
   else
      return (PaintNonPrimaryDisplay(hMonitor, hdc, lprcMonitor, data));
}
 
bool PaintNonPrimaryDisplay(HMONITOR hMonitor, HDC hdc, LPRECT lprcMonitor, LPARAM data)
{
   Gdiplus::Graphics * pGraphics = Gdiplus::Graphics::FromHDC(hdc);
 
   if (gpBitmapMotivation2)
   {
      pGraphics->DrawImage(gpBitmapMotivation2, lprcMonitor->left, lprcMonitor->top, lprcMonitor->right - lprcMonitor->left, lprcMonitor->bottom - lprcMonitor->top);
   }
 
   int sizeX = (int) ceil( (lprcMonitor->right - lprcMonitor->left) * SS_SCREEN_PERCENTAGE);
   int sizeY = (int) ceil( (lprcMonitor->bottom- lprcMonitor->top)  * SS_SCREEN_PERCENTAGE);
   DrawMyText(lprcMonitor, sizeX, sizeY, pGraphics, "MyText"); // This custom function sets up the font, etc and renders the text.

   BitBlt(hdc, lprcMonitor->left, lprcMonitor->top, lprcMonitor->right - lprcMonitor->left, lprcMonitor->bottom - lprcMonitor->top, hdc, lprcMonitor->left, lprcMonitor->top, SRCCOPY);
 
   return true;
}

推荐答案

您通过的HWND在所有监视器上都已最大化...

如果您要单独绘制图形,最好在WM_CREATE调用期间为每个监视器创建一个子窗口
the HWND you get passed is maximised over all monitors ...

you''re probably better off creating a child window per monitor during the WM_CREATE call if you want separate draw images


barneyman,
如果您在进入ScreenSaverProc时是指HWND,那么我不确定您说什么.应该为我拥有的每个监视器调用MonitorNumProcPaint,并且其参数包括LPRECT lprcMonitor,这是调用该函数的特定监视器的位置和大小.

因此,如果我在lprcMonitor-> left处绘制一个矩形,那将是我所使用的任何监视器的左侧.我已经通过在该值上加上和减去数字来验证了这一点,黑色矩形向左或向右移动.第二个监视器上的黑色矩形一定是由于我对PaintNonPrimaryDisplay的回调.如果我删除该呼叫,则第二个监视器说的是同样的话..屏幕保护程序没有任何内容.

我确实想绘制单独的图像.一组用于主监视器,然后每个监视器具有不同的图像.但是无论我做什么,渲染都是一个黑色的矩形.就像设置了画布一样,但没有任何渲染.我尝试使用坐标来查看我的绘图坐标是否已关闭,但它们似乎还可以.

感谢任何人可以提供的任何帮助,谢谢!
Hi barneyman,
If you mean the HWND when entering the ScreenSaverProc, then I''m not sure what your saying. MonitorNumProcPaint should be called for every monitor I have, and its params include LPRECT lprcMonitor which is the location and size of the particular monitor the function was called for.

So if I draw a rectangle at lprcMonitor->left, that will be the left side of whatever monitor I''m on. And I''ve verified this by adding and subtracting numbers to that value, and the black rectangle moves left or right. The black rectangle on my 2nd monitor is definately due to my callback of PaintNonPrimaryDisplay. if I remove that call then the 2nd monitor says the same.. nothing via the screensaver gets painted to it.

I do want to draw seperate images. One set for the Primary Monitor and then different images for each monitor thereafter. But no matter what I do the rendering is a black rectangle. Its like the canvas is being set but nothing renders on it. I''ve tried playing with coordinates to see if my drawing coordinates were off but they seem OK.

I appreciate any assistance anyone can give, thanks!


我不久前解决了这个问题.我尝试使用lprcMonitor的方式,但最终使用dwData对其进行了修复,如下所述:

I resolved this a while ago. The way I was trying to use the lprcMonitor, but ended up using the dwData to fix it, as commented below:

gHdc = BeginPaint(hwnd, &gPaintStruct);   // Get Device Context handle from canvas
   // For every monitor attached, call the passed in function
   EnumDisplayMonitors(gHdc, NULL, MonitorNumProcPaint, (LPARAM)&gHdc); 
EndPaint(hwnd, &gPaintStruct);            // Painting is done

BOOL PaintNonPrimaryDisplay(HMONITOR hMonitor, LPRECT lprcMonitor, LPARAM dwData)
{
   HDC *pdc = (HDC*)dwData;
//From http://www.realtimesoft.com/multimon/forum/messages.asp?Topic=3760&tmpl=UltraMon)

   // Create an "off screen" DC (double buffer) to avoid flickering
   HDC hdcMem = CreateCompatibleDC(*pdc);
   HBITMAP hbmMem = CreateCompatibleBitmap(*pdc, lprcMonitor->right - lprcMonitor->left, lprcMonitor->bottom - lprcMonitor->top);
   HGDIOBJ hOld = SelectObject(hdcMem, hbmMem);

   // Paint everything into the double buffer
   Gdiplus::Graphics  *gpGraphics = Gdiplus::Graphics::FromHDC(hdcMem);
   if (gpGraphics == NULL)
      return false;

   if (gpBitmapMotivations[1])
   {
      gpGraphics->DrawImage(gpBitmapMotivations[1], 0, 0, lprcMonitor->right - lprcMonitor->left, lprcMonitor->bottom - lprcMonitor->top);
   }

   DrawOverlay(0, 0, lprcMonitor->right - lprcMonitor->left, lprcMonitor->bottom - lprcMonitor->top, gpGraphics);

   // Transfer the "off screen" (double buffer) DC (Device Context) to the screen
   // BitBlt Specs: http://msdn.microsoft.com/en-us/library/dd183370(v=VS.85).aspx
   BitBlt(*pdc, lprcMonitor->left, lprcMonitor->top, lprcMonitor->right - lprcMonitor->left, lprcMonitor->bottom - lprcMonitor->top, hdcMem, 0, 0, SRCCOPY);
   
   // Free the "off screen" DC
   delete gpGraphics;
   SelectObject(hdcMem, hOld);
   DeleteObject(hbmMem);
   DeleteDC(hdcMem);

   return TRUE;
}


这篇关于使用EnumDisplayMonitors的屏幕保护程序仅在第二个监视器上绘制黑色矩形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆