Click here to Skip to main content
15,887,596 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I need to draw an image each on two dialogue boxes of my application. I chose to use a memory dc. Unfortunately, instead of drawing the image, it drew a black box. What could be wrong? The relevant codes are shown below.

C++
//Top of dialogue box procedure

static HDC hmemDC = nullptr;
    static HBITMAP hbitmap = nullptr;
    static HBITMAP hOldbitmap = nullptr;



C++
case WM_INITDIALOG:

  HDC hdc = GetDC(hDlg);
        
        hmemDC = CreateCompatibleDC(hdc);
        hbitmap = CreateCompatibleBitmap(hmemDC,iPicWidth,iPicHeight);
        hOldbitmap = (HBITMAP)SelectObject(hmemDC, hbitmap);

        ReleaseDC(hDlg, hdc);




C++
//The drawing code

 std::string stPicPath;
            if (UpdateStudentInfoControls(hDlg, llSessionID, llArmID, eUseMode, stPicPath))
            {
               DrawAppImage(hmemDC, iPicLeft,iPicTop,iPicWidth, iPicHeight, stPicPath);
            }
            else
            {
                HPEN hPen = (HPEN)GetStockObject(BLACK_PEN);
                HPEN hOldPen = (HPEN)SelectObject(hmemDC, hPen);

                MoveToEx(hmemDC, 0, 0, NULL);
                LineTo(hmemDC,iPicWidth, 0);
                LineTo(hmemDC, iPicWidth,iPicHeight);
                LineTo(hmemDC,0,iPicHeight);
                LineTo(hmemDC,0,0);

                SelectObject(hmemDC, hOldPen);
            }




C++
case WM_PAINT:
   {
       PAINTSTRUCT ps;
       HDC hdc = BeginPaint(hDlg, &ps);

       BitBlt(hdc, iPicLeft, iPicTop, iPicWidth, iPicHeight, hmemDC, 0, 0, SRCCOPY);

       EndPaint(hDlg, &ps);

   }
   return (INT_PTR)TRUE;




C++
<


void DrawAppImage(HDC hdc, int iLeft, int iTop, int iWidth, int iHeight, string stImagePath)
{
	string stImageFullPath = stDBImageDirectory;
	stImageFullPath += '\\';
	stImageFullPath += stImagePath;

	wstring wstImagePath = utf8_decode(stImageFullPath);

	// Create an Image object.
	Gdiplus::Image image(wstImagePath.c_str());


	Gdiplus::Graphics graphics(hdc);

	// Draw the original source image.
	graphics.DrawImage(&image, iLeft, iTop, iWidth, iHeight);
}



/pre>

What I have tried:

I have spent sustantial time debugging the code.
Posted
Updated 18-Jan-24 5:26am
v2

1. Be sure that you have initialize the GDI+ library by calling GdiplusStartup API.
2. Check whatever image successfully loaded by using GetLastStatus method of the Image class after loading the file.
3. Check last status of the Graphics operation by using GetLastStatus method of the Graphics class after drawing the image.
4. make sure that you are performing drawing in correct call sequence for example you can call drawing and after call invalidating background of the control which cause erasing background. You can first test drawing on the graphics object created from the GDI+ bitmap object and save resulted bitmap to the file.

Regards,
Maxim.
 
Share this answer
 
Comments
Gbenbam 18-Jan-24 8:27am    
The thing is that when I draw the image directly during WM_PAINT, it gets drawn but flickers. Problem arose when I drew to the memeory dc first. What do you think?
Maxim Kartavenkov 18-Jan-24 8:37am    
You may return value which cause default painting after your method. Or you can call invalidate for entire control which cause erasing background (this may be done also from the parent - you call invalidate it and it fallback to children which are on view port), or some controls may need to have flags to have owned draw and not fallback to default drawing. Also you may need to disable erasing background by handling it WM_ and skip erasing by return value.
Gbenbam 18-Jan-24 11:12am    
I was drawing on the dialogue box window not on a control.
Maxim Kartavenkov 19-Jan-24 2:54am    
It the same - check whatever you return from paint handler and disable erasing background.
neobugs 24-Feb-24 0:39am    
If a new project is created in Visual Studio(for me 2022), Graphics library will not work as expected. It will compile, but no image will be shown. I fix with #1(of 4(GdiplusStartup)) in this solution by adding these 3 lines in my WinMain:

GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

Get from:
https://learn.microsoft.com/en-us/windows/win32/api/gdiplusinit/nf-gdiplusinit-gdiplusstartup

After that, Graphics library work !!!

How do i vote for this, 1 to 5 stars?

I use the only #1(on 4 suggestion)
See Dialog Box Programming Considerations - Win32 apps | Microsoft Learn[^], especially the section headed: The WM_INITDIALOG Message.
 
Share this answer
 
Comments
Gbenbam 18-Jan-24 11:28am    
Sorry, I made a mistake in my post. The memory dc was created during WM_INITDIALOG and not during WM_CREATE as I previously wrote. Do have any other possible solution idea?
Richard MacCutchan 18-Jan-24 12:10pm    
Sorry, I cannot see anything obvious. I suggest you put breakpoints at each part of this code that builds and displays the image, and check exactly what is happening.
Richard MacCutchan 18-Jan-24 12:48pm    
I just tried a simple test of dreawing a box on a dialog and it works fine.

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900