Click here to Skip to main content
15,921,179 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
How can I write from a memory device context to a printer device context using StretchBlt considering differences in resolution between the printer and the window that the memory device context is compatible with.

What I have tried:

I have been searching on-line for this for months.
Posted
Updated 23-May-24 6:13am
Comments
Rick York 23-May-24 12:25pm    
That is a rather curious design if that is what you have to do. I have written a lot of programs that do rendering both 2D (usually GDI+) and 3D (OpenGL, see my profile) and they are almost always double buffered and I have never had a persistent memory DC. It is always drawn to, written to the device, and then automatically deleted. That means this topic has never come up for me because I always do printing from the device. Why do you need to print from the memory context? Also - the printer and device (nearly) always have different resolutions so why does that make a difference in this case?
Gbenbam 23-May-24 14:19pm    
I currently write write to window dc using double buffering, but write direct to printer. But the printed version vision is not a replica of the window version. Users might be displeased. So, i am thinking to use double buffering for printing too, but I want to know how to handle difference in resolution issues. I felt using stretch but to write from a window compatible dc to printer using a scale factor that factors in resolution might work. What do you think?
Richard MacCutchan 23-May-24 12:26pm    
The same way that you write to the screen. You need to look into the use of the different MAPMODES that are used in order to map the image onto the printer.
Gbenbam 23-May-24 14:20pm    
I sure know about mapping modes. See my response to Rick York above.
Richard MacCutchan 24-May-24 5:09am    
I have some code that may help you, but it is too long to post here. If you go to Re: rfcomm ? - Linux Programming Discussion Boards[^] and click on the Email link below my message, you can send me a private message. I can then reply to that and send you my code as a complete VS project.

The concept of the device context DC is the abstraction of the peripheral device attached to the computer. You draw or print in exactly same way to all of them. So, if you have function say like in MFC OnDraw(CDC* pDC) - if you pass the screen CDC it will draw onto the screen. If you pass Printer CDC it will draw to your printer. Same goes for plotter, fax or whatever is supported by windows.
 
Share this answer
 
Comments
Gbenbam 23-May-24 21:35pm    
What about resolution? Of course my function wires successfully . to printer. The issue is that what was printed is not a replica of what was displayed on the screen because of differences in resolution.

For instance, I use the GDI+- function which draws the images as desired to windows without hassles but the exact same function drew something way way bigger on printer. I had to read documentation long enough to find out that GDI+ graphics function can be set to draw u device units like millimetre . Setting display unit of graphics class resolved the issue, but not completely. The position of the images were not a exact replica of what was displayed in that they were not drawn to perspective in terms of positioning. I had to add printer specific codes.
steveb 24-May-24 21:49pm    
If I remember correctly you need to call GetDeviceCaps with X and Y parameter and this should be applied to rectangles, coordinates, etc. For screen those usually always equal 1 but for printers depends. I saw 9 for printer. If you have MFC installed peek inside CPreviewView (They use those methods everywhere)
Below is a sample code.

C++
void PrintDocument(
	HDC	hPrinterDC,
	HDC hMemoryDC,
	int iSourceWidth,
	int iSourceHeight

	)
{
	POINT destSize{};
	destSize.x = iSourceWidth;
	destSize.y = iSourceHeight;

	double dMemoryDCX = GetDeviceCaps(hMemoryDC, LOGPIXELSX);	// and the dimensions of the memoryDC
	double dMemoryDCY = GetDeviceCaps(hMemoryDC, LOGPIXELSY);
	double dDeviceX = GetDeviceCaps(hPrinterDC, LOGPIXELSX);		// and the target device
	double dDeviceY = GetDeviceCaps(hPrinterDC, LOGPIXELSY);

	//Calculate scale factor
	double dScaleFactorX = dDeviceX / dMemoryDCX;
	double dScaleFactorY = dDeviceY / dMemoryDCY;

	destSize.x = static_cast<int>(destSize.x * dScaleFactorX);
	destSize.y = static_cast<int>(destSize.y * dScaleFactorY);
	DPtoLP(hPrinterDC, &destSize, 1);

	// Blit it on to the printerDC, stretching or compressing as necessary
	StretchBlt(hPrinterDC,
		0,	// destination X position
		0,		// destination Y position
		destSize.x,			// destination width
		destSize.y,			// destination height
		hMemoryDC, 0,0,		// source start
		iSourceWidth		// source image width
		iSourceHeight,	//       ..     height
		SRCCOPY);			// how to blit

}
 
Share this answer
 
Comments
jeron1 10-Jun-24 10:03am    
Sample code that works?
Gbenbam 11-Jun-24 8:06am    
It works like charm.
Gbenbam 11-Jun-24 8:09am    
I hae used it to do uncountable printing already.
jeron1 11-Jun-24 10:05am    
Does this solve your issue or is this an addition to the original question?
Gbenbam 11-Jun-24 11:12am    
My question was on how to print from memory dc using stretchBlt because that handles differences in resolution issue. I know it is possible because I have done it before but only could not remember exactly how.

The above code perfectly does want I wanted to do. So, yes, this solves my issue.

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