初学打印文字和位图

以前竟然没有做过打印的程序(为了省事,曾经使用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) ;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值