以前竟然没有做过打印的程序(为了省事,曾经使用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; wndclass.cbSize = sizeof(wndclass); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = NULL; wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "PrintDemo"; wndclass.hIconSm = NULL; RegisterClassEx (&wndclass); hwMain=CreateWindow (wndclass.lpszClassName,NULL,WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,500,568,NULL,NULL,hInstance,NULL); hMenu=CreateMenu(); hMenuA=CreateMenu(); AppendMenu(hMenuA,MF_STRING,ID_FILE_PRINT,"Print"); AppendMenu(hMenu,MF_POPUP,(UINT)hMenuA,"File"); SetMenu(hwMain,hMenu); ShowWindow (hwMain,iCmdShow); UpdateWindow (hwMain); while (GetMessage (&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam ; }
/* This function is called by the Windows function DispatchMessage() */ LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; static PRINTDLG pd; static DOCINFO dci; static LPTSTR lpszDocName="Print Test"; switch (iMsg) { case WM_CREATE: pd.lStructSize=sizeof(pd); pd.hwndOwner=hwnd; pd.hDevMode=NULL; pd.hDevNames=NULL; pd.Flags=PD_RETURNDC|PD_HIDEPRINTTOFILE |PD_RETURNDEFAULT; pd.nFromPage=1; pd.nToPage=1; pd.nMinPage=1; pd.nMaxPage=1; pd.nCopies=1; dci.cbSize=sizeof(dci); dci.lpszDocName=lpszDocName; dci.lpszOutput=NULL; dci.lpszDatatype=NULL; dci.fwType=0; return 0; case WM_COMMAND: switch (LOWORD(wParam)) { case ID_FILE_PRINT: if (!PrintDlg(&pd)) return 0; hdc=pd.hDC; StartDoc(hdc,&dci); StartPage(hdc); draw(hdc); EndPage(hdc); EndDoc(hdc); break; } return 0; case WM_PAINT: hdc=BeginPaint(hwnd,&ps); draw(hdc); EndPaint(hwnd,&ps); return 0; case WM_DESTROY : PostQuitMessage(0); return 0; } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; } 
|