Articles   Members Online:
-Article/Tip Search
-News Group Search over 21 Million news group articles.
-Delphi/Pascal
-CBuilder/C++
-C#Builder/C#
-JBuilder/Java
-Kylix
Member Area
-Home
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Login/Logout
-Become a Member
-Why sign up!
-Newsletter
-Chat Online!
-Indexes NEW!!
Employment
-Build your resume
-Find a job
-Post a job
-Resume Search
Contacts
-Contacts
-Feedbacks
-Link to us
-Privacy/Disclaimer
Embarcadero
Visit Embarcadero
Embarcadero Community
JEDI
Links
Using SetMapMode during printing Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
23-Sep-03
Category
Reporting /Printing
Language
Delphi 3.x
Views
86
User Rating
No Votes
# Votes
0
Replies
0
Publisher:
DSP, Administrator
Reference URL:
DKB
			Author: Eugene Mayevski

Printing something is relatively easy with Delphi. But there are times, when you 
need to use the same functions for drawing on screen canvas and on printer. Did you 
ever try to? And you got the printer image much smaller, than on the screen, right? 
That's because you have to change coordinates passed to GDI functions or use 
SetMapMode function. The article is about how to use this function and a bit more. 

Answer:

Suppose you need to draw a rectangle with coordinates ((0,0),(300,300)). On the 
screen such rectangle will be a bit bigger than one inch (at least on 1024*768 
resolution on 15' monitor). But when you call Printer.Canvas.FrameRect(Rect(0, 0, 
300, 300)), you get a tiny rectangle with side length of .39 inch. 
So, you need to perform transformation of coordinate system before printing. 
Open MSDN, see SetMapMode, feel happy. You find, that MM_ANISOTROPIC mode is what 
you need (remember, that printers have different vertical and horizontal resolution 
and page size, so you need to use MM_ANISOTROPIC parameter). 

SetMapMode(TmpDC, MM_ANISOTROPIC);
// we use TmpDC to prepare an image, that will be later copied to printer
// canvas.

But then you need to call a couple of other functions to do the job. 
These functions are SetWindowExtEx and SetViewPortExtEx. As described in 
documentation, these functions let you set logical and "physical" coordinate 
systems for device context. What parameters do you have to pass to it? 
Logical coordinates is the size of the screen part needed to display an image in 
WYSIWYG mode (to get the same size as on the screen). 
Physical coordinates define the size in pixels of the device media (paper in our 
case). 

We will find the real size of the paper in 0.01 mm. It will be used in further 
calculations: 
1   
2   // find the width of the printer page
3   MMWidth := MulDiv(GetDeviceCaps(PrinterDC, PHYSICALWIDTH), 2540,
4     GetDeviceCaps(PrinterDC, LOGPIXELSX));
5   // find the height of the printer page
6   MMHeight := MulDiv(GetDeviceCaps(PrinterDC, PHYSICALHEIGHT), 2540,
7     GetDeviceCaps(PrinterDC, LOGPIXELSY));


Now you have to set logical coordinates using SetWindowExtEx and physical 
dimensions of device context (actually, paper size) using SetViewPortExtEx. 

8   SetWindowExtEx(TmpDC, LogExtX, LogExtY, nil);
9   SetViewPortExtEx(TmpDC, PhExtX, PhExtY, nil);


How do we calculate LogExt* parameters? 
10  
11  ScreenDC := GetDC(0);
12  // now find logical width of the screen space, needed to display the image in 
13  WYSIWYG mode
14  // Scale parameter is used to provide scaling during printing.
15  LogExtX := MulDiv(MMWidth, 100 * GetDeviceCaps(ScreenDC, LOGPIXELSX), 2540 * Scale);
16  // now find logical height of the screen space, needed to display the image in 
17  WYSIWYG mode
18  // Scale parameter is used to provide scaling during printing.
19  LogExtY := MulDiv(Printer.PageHeight, 100 * GetDeviceCaps(DC, LOGPIXELSY), 2540 *
20    Scale);
21  ReleaseDC(0, screenDC);
22  
23  //How do we calculate PhExt* parameters? 
24  
25  PhExtX := MulDiv(Printer.PageWidth, GetDeviceCaps(Printer.PrinterDC, LOGPIXELSX),
26    2540);
27  PhExtY := MulDiv(Printer.PageHeight, GetDeviceCaps(Printer.PrinterDC, LOGPIXELSY),
28    2540);


That's all, folks :). Now you can safely draw the rectangle. 
Remember to restore MapMode after you finished drawing (you can save MapMode using GetMapMode function).

			
Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10

 

Advertisement
Share this page
Advertisement
Download from Google

Copyright © Mendozi Enterprises LLC