Inquiry about the operation of GdipDrawImageRectRect

DevO 21 Reputation points
2023-02-09T05:47:37.83+00:00

Hi I'm currently working on adding images to HDC that I print.

Therefore, I have to satisfy both PCL driver and PS driver.

So I wrote the code as below.

Graphics* ImageLogoGraphices = new Graphics(hDC);
ImageLogoGraphices->ResetTransform();
ImageLogoGraphices->SetPageUnit(UnitPixel);
ImageAttributes ImgAttr;

ColorMatrix ClrMatrix = {
1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, rLogoImgDensity, 0.0f,
0.0f, 0.0f, 0.0f ,0.0f, 1.0f
};

ImgAttr.SetColorMatrix(&ClrMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap);

Image ImageLogo(PNGFormatimageFilePath);

REAL rImageWidth = ImageLogo.GetWidth();
REAL rImageHeight = ImageLogo.GetHeight();

RectF mRect(0, 0, RectnWidth, RectnHeight);

SizeF RectSize;
mRect. GetSize(&RectSize);

ImageLogoGraphices->DrawImage(&ImageLogo, mRect, 0, 0, rImageWidth, rImageHeight, UnitPixel, &ImgAttr);

After that, I checked and the resulting behavior is as follows.

         PCL     PS

32Bit O O

64Bit O X

My final question is that it doesn't work on PostScript 64Bit.

Therefore, I checked the operation in debug mode to find out why.

Other normal behavior seems to be drawing by calling StretchDIBits after calling the DrawImage API.

However, StretchDIBits was not called when using a printer using PostScript Driver of 64Bit Program.

Below is the call result using API Monitor.

[Normal case]

#	Time of Day	Thread	Module	API	Return Value	Error	Duration
1	11:42:15.725 AM	2	myModule.dll	GdipTranslateWorldTransform ( 0x0b7c1cf0, 4229.000000, 6288.000000, MatrixOrderPrepend )	Ok		0.0000025
2	11:42:17.303 AM	2	myModule.dll	GdipTranslateWorldTransform ( 0x0b7c1cf0, 512.000000, 512.000000, MatrixOrderPrepend )	Ok		0.0000020
3	11:42:22.383 AM	2	myModule.dll	GdipRotateWorldTransform ( 0x0b7c1cf0, 0.000000, MatrixOrderPrepend )	Ok		0.0000145
4	11:42:24.682 AM	2	myModule.dll	GdipTranslateWorldTransform ( 0x0b7c1cf0, -512.000000, -512.000000, MatrixOrderPrepend )	Ok		0.0000019
5	11:42:25.412 AM	2	myModule.dll	GdipDrawImageRectRect ( 0x0b7c1cf0, 		0x0b696ee8, 		0.000000, 0.000000, 1024.000000, 1024.000000, 0.000000, 0.000000, 256.000000, 256.000000, UnitPixel, 0x0b7c0560, 		 NULL, NULL )	Ok		0.0365227
6	11:42:25.412 AM	2	gdiplus.dll	GetDC ( NULL )	0x79012c11		0.0000789
7	11:42:25.412 AM	2	gdiplus.dll	GetDeviceCaps ( 0x79012c11, LOGPIXELSX )	96		0.0000055
8	11:42:25.412 AM	2	gdiplus.dll	GetDeviceCaps ( 0x79012c11, LOGPIXELSY )	96		0.0000011
9	11:42:25.412 AM	2	gdiplus.dll	ReleaseDC ( NULL, 0x79012c11 )	1		0.0000132
10	11:42:25.412 AM	2	gdiplus.dll	SaveDC ( 0x4f211de4 )	1		0.0000253
11	11:42:25.412 AM	2	gdiplus.dll	SetICMMode ( 0x4f211de4, ICM_OFF )	1		0.0000024
12	11:42:25.412 AM	2	gdi32full.dll	GetDeviceCaps ( 0x4f211de4, NUMCOLORS )	8		0.0000005
13	11:42:25.412 AM	2	gdiplus.dll	SetMapMode ( 0x4f211de4, MM_TEXT )	1		0.0000011
14	11:42:25.412 AM	2	gdiplus.dll	SetViewportOrgEx ( 0x4f211de4, 0, 0, NULL )	TRUE		0.0000009
15	11:42:25.412 AM	2	gdiplus.dll	SetWindowOrgEx ( 0x4f211de4, 0, 0, NULL )	TRUE		0.0001795
16	11:42:25.412 AM	2	gdiplus.dll	SetROP2 ( 0x4f211de4, R2_COPYPEN )	11		0.0000007
17	11:42:25.412 AM	2	gdiplus.dll	ModifyWorldTransform ( 0x4f211de4, NULL, MWT_IDENTITY )	FALSE	0 = 작업을 완료했습니다. 	0.0001101
18	11:42:25.412 AM	2	gdiplus.dll	SelectClipRgn ( 0x4f211de4, NULL )	2		0.0000212
19	11:42:25.412 AM	2	gdi32full.dll	ExtSelectClipRgn ( 0xa7212b7c, NULL, RGN_COPY )	2		0.0000058
20	11:42:25.412 AM	2	gdi32full.dll	ExtSelectClipRgn ( 0x4f211de4, NULL, RGN_COPY )	2		0.0000143
21	11:42:25.412 AM	2	gdiplus.dll	BeginPath ( 0x4f211de4 )	TRUE		0.0000190
22	11:42:25.412 AM	2	gdiplus.dll	MoveToEx ( 0x4f211de4, 4229, 6288, NULL )	TRUE		0.0000011
23	11:42:25.412 AM	2	gdiplus.dll	PolylineTo ( 0x4f211de4, 0x095caedc, 4 )	TRUE		0.0000122
24	11:42:25.412 AM	2	gdiplus.dll	CloseFigure ( 0x4f211de4 )	TRUE		0.0000051
25	11:42:25.412 AM	2	gdiplus.dll	EndPath ( 0x4f211de4 )	TRUE		0.0000023
26	11:42:25.412 AM	2	gdiplus.dll	StrokePath ( 0x4f211de4 )	TRUE		0.0003699
27	11:42:25.412 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6288, 1024, 4, 0, 0, 256, 1, 0x0b6ac910, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001621
28	11:42:25.412 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6292, 1024, 4, 0, 0, 256, 1, 0x0b6ac510, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001674
29	11:42:25.412 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6296, 1024, 4, 0, 0, 256, 1, 0x0b6ac110, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0003139
30	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6300, 1024, 4, 0, 0, 256, 1, 0x0b6abd10, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001134
31	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6304, 1024, 4, 0, 0, 256, 1, 0x0b6ab910, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001240
32	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6308, 1024, 4, 0, 0, 256, 1, 0x0b6ab510, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001042
33	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6312, 1024, 4, 0, 0, 256, 1, 0x0b6ab110, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001435
34	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6316, 1024, 4, 0, 0, 256, 1, 0x0b6aad10, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001128
35	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6320, 1024, 4, 0, 0, 256, 1, 0x0b6aa910, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001187
36	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6324, 1024, 4, 0, 0, 256, 1, 0x0b6aa510, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001080
37	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6328, 1024, 4, 0, 0, 256, 1, 0x0b6aa110, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001060
38	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6332, 1024, 4, 0, 0, 256, 1, 0x0b6a9d10, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001295
39	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6336, 1024, 4, 0, 0, 256, 1, 0x0b6a9910, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001092
40	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6340, 1024, 4, 0, 0, 256, 1, 0x0b6a9510, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001312
41	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6344, 1024, 4, 0, 0, 256, 1, 0x0b6a9110, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001137
42	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6348, 1024, 4, 0, 0, 256, 1, 0x0b6a8d10, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001162
43	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6352, 1024, 4, 0, 0, 256, 1, 0x0b6a8910, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001088
44	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6356, 1024, 4, 0, 0, 256, 1, 0x0b6a8510, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001049
45	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6360, 1024, 4, 0, 0, 256, 1, 0x0b6a8110, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001203
46	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6364, 1024, 4, 0, 0, 256, 1, 0x0b6a7d10, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001160
47	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6368, 1024, 4, 0, 0, 256, 1, 0x0b6a7910, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001269
48	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6372, 1024, 4, 0, 0, 256, 1, 0x0b6a7510, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001016
49	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6376, 1024, 4, 0, 0, 256, 1, 0x0b6a7110, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001234
50	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6380, 1024, 4, 0, 0, 256, 1, 0x0b6a6d10, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0000992
51	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6384, 1024, 4, 0, 0, 256, 1, 0x0b6a6910, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001070
52	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6388, 1024, 4, 0, 0, 256, 1, 0x0b6a6510, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001144
53	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6392, 1024, 4, 0, 0, 256, 1, 0x0b6a6110, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001241
54	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6396, 1024, 4, 0, 0, 256, 1, 0x0b6a5d10, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001074
55	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6400, 1024, 4, 0, 0, 256, 1, 0x0b6a5910, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001030
56	11:42:25.422 AM	2	gdiplus.dll	StretchDIBits ( 0x4f211de4, 4232, 6404, 1024, 4, 0, 0, 256, 1, 0x0b6a5510, 0x095cb1e4, DIB_RGB_COLORS, SRCCOPY )	1		0.0001259

[case when it doesn't work]

#	Time of Day	Thread	Module	API	Return Value	Error	Duration
1	11:42:15.725 AM	2	myModule.dll	GdipTranslateWorldTransform ( 0x0b7c1cf0, 4229.000000, 6288.000000, MatrixOrderPrepend )	Ok		0.0000025
2	11:42:17.303 AM	2	myModule.dll	GdipTranslateWorldTransform ( 0x0b7c1cf0, 512.000000, 512.000000, MatrixOrderPrepend )	Ok		0.0000020
3	11:42:22.383 AM	2	myModule.dll	GdipRotateWorldTransform ( 0x0b7c1cf0, 0.000000, MatrixOrderPrepend )	Ok		0.0000145
4	11:42:24.682 AM	2	myModule.dll	GdipTranslateWorldTransform ( 0x0b7c1cf0, -512.000000, -512.000000, MatrixOrderPrepend )	Ok		0.0000019
5	11:42:25.412 AM	2	myModule.dll	GdipDrawImageRectRect ( 0x0b7c1cf0, 		0x0b696ee8, 		0.000000, 0.000000, 1024.000000, 1024.000000, 0.000000, 0.000000, 256.000000, 256.000000, UnitPixel, 0x0b7c0560, 		 NULL, NULL )	Ok		0.0365227
6	11:42:25.412 AM	2	gdiplus.dll	GetDC ( NULL )	0x79012c11		0.0000789
7	11:42:25.412 AM	2	gdiplus.dll	GetDeviceCaps ( 0x79012c11, LOGPIXELSX )	96		0.0000055
8	11:42:25.412 AM	2	gdiplus.dll	GetDeviceCaps ( 0x79012c11, LOGPIXELSY )	96		0.0000011
9	11:42:25.412 AM	2	gdiplus.dll	ReleaseDC ( NULL, 0x79012c11 )	1		0.0000132
10	11:42:25.412 AM	2	gdiplus.dll	SaveDC ( 0x4f211de4 )	1		0.0000253
11	11:42:25.412 AM	2	gdiplus.dll	SetICMMode ( 0x4f211de4, ICM_OFF )	1		0.0000024
12	11:42:25.412 AM	2	gdi32full.dll	GetDeviceCaps ( 0x4f211de4, NUMCOLORS )	8		0.0000005
13	11:42:25.412 AM	2	gdiplus.dll	SetMapMode ( 0x4f211de4, MM_TEXT )	1		0.0000011
14	11:42:25.412 AM	2	gdiplus.dll	SetViewportOrgEx ( 0x4f211de4, 0, 0, NULL )	TRUE		0.0000009
15	11:42:25.412 AM	2	gdiplus.dll	SetWindowOrgEx ( 0x4f211de4, 0, 0, NULL )	TRUE		0.0001795
16	11:42:25.412 AM	2	gdiplus.dll	SetROP2 ( 0x4f211de4, R2_COPYPEN )	11		0.0000007
17	11:42:25.412 AM	2	gdiplus.dll	ModifyWorldTransform ( 0x4f211de4, NULL, MWT_IDENTITY )	FALSE	0 = 작업을 완료했습니다. 	0.0001101
18	11:42:25.412 AM	2	gdiplus.dll	SelectClipRgn ( 0x4f211de4, NULL )	2		0.0000212
19	11:42:25.412 AM	2	gdi32full.dll	ExtSelectClipRgn ( 0xa7212b7c, NULL, RGN_COPY )	2		0.0000058
20	11:42:25.412 AM	2	gdi32full.dll	ExtSelectClipRgn ( 0x4f211de4, NULL, RGN_COPY )	2		0.0000143
21	11:42:25.412 AM	2	gdiplus.dll	BeginPath ( 0x4f211de4 )	TRUE		0.0000190
22	11:42:25.412 AM	2	gdiplus.dll	MoveToEx ( 0x4f211de4, 4229, 6288, NULL )	TRUE		0.0000011
23	11:42:25.412 AM	2	gdiplus.dll	PolylineTo ( 0x4f211de4, 0x095caedc, 4 )	TRUE		0.0000122
24	11:42:25.412 AM	2	gdiplus.dll	CloseFigure ( 0x4f211de4 )	TRUE		0.0000051
25	11:42:25.412 AM	2	gdiplus.dll	EndPath ( 0x4f211de4 )	TRUE		0.0000023
26	11:42:25.412 AM	2	gdiplus.dll	StrokePath ( 0x4f211de4 )	TRUE		0.0003699

Please help me...

In addition, myModule, my module, uses Windows SDK 10.0 (latest version) for both 32bit and 64bit builds, and uses the v142 toolset.

Windows 10
Windows 10
A Microsoft operating system that runs on personal computers and tablets.
12,056 questions
Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,734 questions
C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,853 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Castorix31 86,976 Reputation points
    2023-02-10T15:32:20.16+00:00

    Maybe you can test if it works directly with StretchDIBits (without changing intensity in this test) =>

    #include <windows.h>
    #include <tchar.h>
    
    #include "gdiplus.h"
    using namespace Gdiplus;
    #pragma comment(lib, "gdiplus.lib")
    
    #include <Urlmon.h> // URLDownloadToCacheFile
    #pragma comment (lib, "Urlmon")
    #include <shlwapi.h> // SHCreateStreamOnFile
    #pragma comment (lib, "shlwapi")
    
    #pragma comment(linker,"\"/manifestdependency:type='win32' \
    name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
    processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
    
    HINSTANCE hInst;
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    int nWidth = 280, nHeight = 200;
    #define IDC_STATIC 10
    #define IDC_BUTTON 11
    
    //HBITMAP Create32BPPDIBSection(HDC hDC, int iWidth, int iHeight);
    HRESULT CreateNBitHBITMAP(HDC hDC, const SIZE* psize, void** ppvBits, HBITMAP* phBitmap, WORD nBitCount);
    BOOL PrintBitmap(HBITMAP hBitmap, int nOrientation);
    
    int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
    {
    	GdiplusStartupInput gdiplusStartupInput;
    	ULONG_PTR gdiplusToken;
    	GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
    
    	hInst = hInstance;
    	WNDCLASSEX wcex =
    	{
    		sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW, WndProc, 0, 0, hInst, LoadIcon(NULL, IDI_APPLICATION),
    		LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_WINDOW + 1), NULL, TEXT("WindowClass"), NULL,
    	};
    	if (!RegisterClassEx(&wcex))
    		return MessageBox(NULL, TEXT("Cannot register class !"), TEXT("Error"), MB_ICONERROR | MB_OK);
    	int nX = (GetSystemMetrics(SM_CXSCREEN) - nWidth) / 2, nY = (GetSystemMetrics(SM_CYSCREEN) - nHeight) / 2;
    	HWND hWnd = CreateWindowEx(0, wcex.lpszClassName, TEXT("Test"), WS_OVERLAPPEDWINDOW, nX, nY, nWidth, nHeight, NULL, NULL, hInst, NULL);
    	if (!hWnd)
    		return MessageBox(NULL, TEXT("Cannot create window !"), TEXT("Error"), MB_ICONERROR | MB_OK);
    	ShowWindow(hWnd, SW_SHOWNORMAL);
    	UpdateWindow(hWnd);
    	MSG msg;
    	while (GetMessage(&msg, NULL, 0, 0))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    	return (int)msg.wParam;
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	static HWND hWndButton = NULL, hWndStatic = NULL;
    	int wmId, wmEvent;
    	switch (message)
    	{
    	case WM_CREATE:
    	{
    		// hWndStatic = CreateWindowEx(0, TEXT("Static"), TEXT(""), WS_CHILD | WS_VISIBLE | SS_BITMAP, 10, 10, 200, 200, hWnd, (HMENU)IDC_STATIC, hInst, NULL);
    		hWndButton = CreateWindowEx(0, L"Button", L"Click", WS_CHILD | WS_VISIBLE | BS_PUSHLIKE, 100, 60, 60, 32, hWnd, (HMENU)IDC_BUTTON, hInst, NULL);
    		return 0;
    	}
    	break;
    	case WM_COMMAND:
    	{
    		wmId = LOWORD(wParam);
    		wmEvent = HIWORD(wParam);
    		switch (wmId)
    		{
    		case IDC_BUTTON:
    		{
    			if (wmEvent == BN_CLICKED)
    			{
    				WCHAR wsURL[MAX_PATH] = TEXT("https://image.ibb.co/buLv2e/Little_Girl3.jpg");
    				WCHAR wsFilename[MAX_PATH];
    				HRESULT hr = URLDownloadToCacheFile(NULL, wsURL, wsFilename, ARRAYSIZE(wsFilename), 0x0, NULL);
    				if (SUCCEEDED(hr))
    				{
    					IStream* pStream = NULL;
    					hr = SHCreateStreamOnFile(wsFilename, STGM_READ | STGM_SHARE_DENY_WRITE, &pStream);
    					if (SUCCEEDED(hr))
    					{
    						HBITMAP hBitmap = NULL;
    						Gdiplus::Bitmap* pBitmap = new Gdiplus::Bitmap(pStream);
    						if (pBitmap)
    						{
    							pBitmap->GetHBITMAP(Gdiplus::Color(255, 255, 255), &hBitmap);
    							PrintBitmap(hBitmap, DMORIENT_LANDSCAPE);							
    						}
    					}
    				}
    			}
    		}
    		break;
    		default:
    			return DefWindowProc(hWnd, message, wParam, lParam);
    		}
    	}
    	break;
    	case WM_PAINT:
    	{
    		PAINTSTRUCT ps;
    		HDC hDC = BeginPaint(hWnd, &ps);
    
    		EndPaint(hWnd, &ps);
    	}
    	break;
    	case WM_DESTROY:
    	{
    		PostQuitMessage(0);
    		return 0;
    	}
    	break;
    	default:
    		return DefWindowProc(hWnd, message, wParam, lParam);
    	}
    	return 0;
    }
    
    
    BOOL PrintBitmap(HBITMAP hBitmap, int nOrientation)
    {
    	HBITMAP hbm = NULL, hBitmapOld;
    	HDC hDCPrinter = NULL;
    	HDC hDCMemory, hDCMem;
    	HDC hDCScreen;
    	DOCINFO di;
    	DIBSECTION ds;
    	BITMAP bmp;
    	GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bmp);
    
    	PRINTDLG pd;
    	ZeroMemory(&pd, sizeof(PRINTDLG));
    	pd.lStructSize = sizeof(PRINTDLG);
    	pd.Flags = PD_RETURNDEFAULT | PD_RETURNDC;
    	PrintDlg(&pd);
    	hDCPrinter = pd.hDC;
    
    	if (!(GetDeviceCaps(pd.hDC, RASTERCAPS) & RC_STRETCHDIB))
    	{ 
    		MessageBox(NULL, TEXT("StretchDIBits not supported"), TEXT("Error"), MB_OK | MB_ICONSTOP);
    		return FALSE;
    	}
    
    	DEVMODE* dm = (DEVMODE*)GlobalLock(pd.hDevMode);
    	dm->dmOrientation = nOrientation;
    	ResetDC(pd.hDC, dm);
    	GlobalUnlock(pd.hDevMode);
    
    	if (!hDCPrinter)
    		return FALSE;
    	hDCScreen = GetDC(NULL);
    	hDCMem = CreateCompatibleDC(hDCScreen);
    	hBitmapOld = (HBITMAP)SelectObject(hDCMem, hBitmap);
    	//hbm = Create32BPPDIBSection(hDCMem, bmp.bmWidth, bmp.bmHeight);
    	BYTE* pbBitmap;
    	SIZE sz;
    	sz.cx = bmp.bmWidth;
    	sz.cy = bmp.bmHeight;
    	HRESULT hr = CreateNBitHBITMAP(NULL, &sz, (void**)&pbBitmap, &hbm, 32);
    	if (!hbm)
    	{
    		DeleteDC(hDCPrinter);
    		ReleaseDC(NULL, hDCScreen);
    		SelectObject(hDCMem, hBitmapOld);
    		DeleteDC(hDCMem);
    		MessageBox(NULL, TEXT("Error Creating DIB Section"), TEXT("Error"), MB_OK |MB_ICONSTOP);
    		return FALSE;
    	}
    	hDCMemory = CreateCompatibleDC(hDCScreen);
    	SelectObject(hDCMemory, hbm);
    	BitBlt(hDCMemory, 0, 0, bmp.bmWidth, bmp.bmHeight, hDCMem, 0, 0,SRCCOPY);
    	ZeroMemory(&di, sizeof(di));
    	di.cbSize = sizeof(di);
    	di.lpszDocName = TEXT("Bitmap Printing");
    	if (StartDoc(hDCPrinter, &di))
    	{
    		if (StartPage(hDCPrinter))
    		{
    			int nPrinterWidth = GetDeviceCaps(hDCPrinter, HORZRES);
    			int nPrinterHeight = GetDeviceCaps(hDCPrinter, VERTRES);
    			int nBitmapWidth = bmp.bmWidth * nPrinterWidth / GetSystemMetrics(SM_CXSCREEN);
    			int nBitmapHeight = nBitmapWidth * bmp.bmHeight / bmp.bmWidth;
    
    			GetObject(hbm, sizeof(DIBSECTION), &ds);
    			StretchDIBits(hDCPrinter,
    				0, 0, nBitmapWidth, nBitmapHeight,
    				0, 0, bmp.bmWidth, bmp.bmHeight,
    				ds.dsBm.bmBits,
    				(LPBITMAPINFO)&ds.dsBmih,
    				DIB_RGB_COLORS,
    				SRCCOPY);
    			EndPage(hDCPrinter);
    		}
    		EndDoc(hDCPrinter);
    	}
    	DeleteDC(hDCPrinter);
    	DeleteDC(hDCMemory);
    	SelectObject(hDCMem, hBitmapOld);
    	DeleteDC(hDCMem);
    	ReleaseDC(NULL, hDCScreen);
    	DeleteObject(hbm);
    	return TRUE;
    }
    
    // Adapted from MS SDK
    HRESULT CreateNBitHBITMAP(HDC hDC, const SIZE* psize, void** ppvBits, HBITMAP* phBitmap, WORD nBitCount)
    {
    	*phBitmap = NULL;
    	BITMAPINFO bmi = { 0 };
    	bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    	bmi.bmiHeader.biWidth = psize->cx;
    	bmi.bmiHeader.biHeight = psize->cy;
    	bmi.bmiHeader.biPlanes = 1;
    	bmi.bmiHeader.biBitCount = nBitCount;
    	bmi.bmiHeader.biCompression = BI_RGB;
    	HDC hDCUsed = hDC ? hDC : GetDC(NULL);
    	if (hDCUsed)
    	{
    		*phBitmap = CreateDIBSection(hDCUsed, &bmi, DIB_RGB_COLORS, ppvBits, NULL, 0);
    		if (hDC != hDCUsed)
    		{
    			ReleaseDC(NULL, hDCUsed);
    		}
    	}
    	return (NULL == *phBitmap) ? E_OUTOFMEMORY : S_OK;
    }
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.