以前竟然没有做过打印的程序(为了省事,曾经使用word automation打印过)。突然要打印文字和图片,而且不能再使用word了,就花了一点时间理解map mode和打印,或许这些内容对您也有点用,原理很简单,能省一些您打字的功夫也不错:-)
//author: onega
#include <windows.h>
#include <stdio.h>
lpctstr bmp_filename = "c:\\test\\printdemo\\res\\toolbar.bmp";
lresult callback wndproc (hwnd hwnd, uint imsg, wparam wparam, lparam lparam) ;
hwnd hwmain;
handle hbmp = null;
const int id_file_print = __line__;
int get_line_height(hdc hdc)
{ //return text line height
//return value < 0 if map mode is not mm_text, so that you can always use
//y+= line_height when drawing to device.
int map_mode = getmapmode(hdc);
textmetric tm;
gettextmetrics(hdc,&tm);
int h = tm.tmheight + tm.tmexternalleading;
if(mm_text != map_mode)
h = 0 - h;
return h;
}
double get_screen_pixel_width(int map_mode)
{ //purpose: a pixel displayed in mm_text mode should be about the same size
//when displayed in other map mode.
hdc hdc = getdc(null);
double hroz_size = getdevicecaps(hdc,horzsize);//width, in millimeters, of the physical screen.
double horz_res = getdevicecaps(hdc, horzres);//width, in pixels, of the screen.
double pixel_width = hroz_size / horz_res; // width, in millimeters
// 1 inch = 25.4 mm
const double inch_to_mm = 25.4;
const double inch_to_twip = 1440;
switch(map_mode)
{
case mm_lometric:
pixel_width *= 10;
break;
case mm_himetric:
pixel_width *= 100;
break;
case mm_text:
break;
case mm_loenglish: //each logical unit is mapped to 0.01 inch
pixel_width = pixel_width / inch_to_mm * 100;
break;
case mm_hienglish: //each logical unit is mapped to 0.001 inch
pixel_width = pixel_width / inch_to_mm * 1000;
break;
case mm_twips: //each logical unit is mapped to one twentieth of a printer's point (1/1440 inch, also called a twip).
pixel_width = pixel_width / inch_to_mm * inch_to_twip;
break;
default:
break;
}
return pixel_width;//width, in logical units according to the map_mode
}
void draw(hdc hdc)
{
if(hbmp == null)
{
hbmp = (handle)loadimage( null,bmp_filename ,
image_bitmap, 0,0,lr_loadfromfile);
}
int map_mode = mm_twips;
lpctstr map_name = "mm_twips";
setmapmode(hdc,map_mode); //each logical unit is mapped to 0.1 millimeter.
int x = 0;
int y = 0;
int line_h = get_line_height(hdc);
selectobject(hdc,getstockobject(black_pen));
setbkmode(hdc, transparent);
textout(hdc,x, y,map_name,strlen(map_name));
y += line_h;
if( null != hbmp)
{
bitmap bm;
getobject( hbmp, sizeof(bitmap), &bm );
long width=bm.bmwidth;
long height=bm.bmheight;
hdc memdc = createcompatibledc(hdc);
hgdiobj oldbmp = selectobject(memdc,hbmp);
double pixel_size = get_screen_pixel_width(map_mode);
int bmp_draw_width = (int)(width * pixel_size) ;
int bmp_draw_height = (int)(height * pixel_size) ;
stretchblt(hdc,x,y, bmp_draw_width ,-bmp_draw_height, memdc, 0,0,width,height,srccopy);
selectobject(memdc,oldbmp);
deletedc(memdc);
}
else
{
lpctstr error_msg = "failed to load bitmap from file";
textout(hdc,x,y,error_msg,strlen(error_msg));
}
}
int winapi winmain(hinstance hinstance, hinstance hprevinstance,
pstr szcmdline, int icmdshow)
{
msg msg;
wndclassex wndclass ;
hmenu hmenu,hmenua;