Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++ C GDI 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;
}
Posted 14-Sep-11 12:30pm
Edited 14-Sep-11 16:13pm
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

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
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

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!
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

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;
}
  Permalink  
v2
Comments
Roland4269 at 11-May-12 10:45am
   
This works, but is incompatible with the LANDesk 9 Mirror Driver. Severe flickering occurs because the mirror driver utilizes a virtual monitor and anything that's on the primary mon will be dupe'd on top, causing flickering (overriding your paints).

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 BillWoodruff 330
1 Mathew Soji 309
2 Maciej Los 285
3 DamithSL 225
4 Afzaal Ahmad Zeeshan 207
0 OriginalGriff 6,369
1 Sergey Alexandrovich Kryukov 5,973
2 DamithSL 5,183
3 Manas Bhardwaj 4,673
4 Maciej Los 4,025


Advertise | Privacy | Mobile
Web04 | 2.8.1411019.1 | Last Updated 12 Apr 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100