码迷,mamicode.com
首页 > 其他好文 > 详细

第13章 使用打印机_13.2 打印图形和文字

时间:2015-08-02 10:11:38      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:

第13章 使用打印机_13.2 打印图形和文字

13.2 打印图形和文字

(1)注册打印异常终止过程 SetAbortProc(hdcPrn,AbortProc);//在StartDoc前注册

(2)异常终止过程——取消打印

    ①调用时间:当调用EndPage之前,程序每次调用一个GDI函数时,GDI模块会把另一个记录追加到磁盘上的图元文件。当调用EndPage时(也就是把图元文件送设备驱动程序和创建临时打印文件时),GDI会频繁地调用异常终止过程。(如生成临时文件导致磁盘空间不足,会调用该过程,并传入iCode为SP_OUTOFDISK的参数)

    ②异常终止过程

BOOL CALLBACK AbortProc(HDC hdcPrn, int iCode)
{
   MSG msg;

   while(!bUserAbort && PeekMessage(&msg,NULL,0,0,PM_REMOVE))
   {
         if(!hDlgPrint || !IsDialogMessage(hDlgPrint,&msg))
         {
              TranslateMessage(&msg);//本例主窗口被Disable,收不到键盘和鼠标消息,该句可省略

              DispatchMessage(&msg);
         }
  }

  return !bUserAbort;
}

说明:

     A、因本例开始打印时,会出现产生自定义的“取消对话框”(非模态的),为了在GDI模块将图元文件送给设备驱动程序时,用户能随时点击“取消”按钮终止打印,得在异常终止过程中用“消息循环”(因为这时程序己进入异常中止过程的处理,要在这个过程中能处理对话框的消息,这时就必须从消息队列中获取消息,并分配出去!),如果用户点击了“取消”,则会把全局变量bUserAbort设为TRUE,从而退出打印。

     B、PeekMessage查看消息,可立即返回,而不用等待消息的出现。

     C、异常处理过程中当返回TRUE时,继续打印,返回FALSE时终止打印。

     D、为防止用户在打印作业开始以后,又选择主菜单中的“Print”菜单项,甚至选择退
 出程序,这种情况下程序的所有窗口都被销毁了,但当程序从异常中止过程中返回的时候,会
 找出现不到窗口错误。所以在打印作业开始前,要禁用掉主窗口(EnableWindow函数,参数为
  FALSE)。但主窗口仍可以收到WM_PAINT等消息。

                   

 ③打印结束不必去除异常终止过程 

【获取打印机设备环境——程序】

/*----------------------------------------------------------------------------------
GETPNTDC.C ——GetPrinterDC function
----------------------------------------------------------------------------------*/
//#pragma warning(disable: 4996)  //win8.1以上GetVersion己过时,加上这句关闭句
#include <windows.h>
#include <VersionHelpers.h>  //VS2013用来判断系统版本的头文件
HDC GetPrinterDC(void)
{
    DWORD  dwNeeded, dwReturned;
    HDC    hdc;
    PRINTER_INFO_4   *pinfo4;
    PRINTER_INFO_5   *pinfo5;

    if (!IsWindowsXPOrGreater())
        //  if (GetVersion() && 0x80000000)   //Windows98
    {
        EnumPrinters(PRINTER_ENUM_DEFAULT, NULL, 5, NULL, 0, &dwNeeded, &dwReturned); //获取所需缓冲区的字节数和所需结构体的数量
        pinfo5 = malloc(dwNeeded); //分配所需的字节数
        EnumPrinters(PRINTER_ENUM_DEFAULT, NULL, 5, (PBYTE)pinfo5, dwNeeded, &dwNeeded, &dwReturned);
        hdc = CreateDC(NULL, pinfo5->pPrinterName, NULL, NULL); //pinfo5为打1个打印机,pinfo5+1为第2个打印机
        free(pinfo5);
    } else
    {
        EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4, NULL, 0, &dwNeeded, &dwReturned);
        pinfo4 = malloc(dwNeeded);
        EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4, (PBYTE)pinfo4, dwNeeded, &dwNeeded, &dwReturned);
        hdc = CreateDC(NULL, pinfo4->pPrinterName, NULL, NULL);
        free(pinfo4);
    }
    return hdc;
}
//#pragma warning (default : 4996)

【打印程序框架】

/*------------------------------------------------------------
PRINT.C -- Common routines for Print1,Print2,and Print3
(c) Charles Petzold, 1998
------------------------------------------------------------*/
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL PrintMyPage(HWND);
extern HINSTANCE hInst;
extern TCHAR     szAppName[];
extern TCHAR     szCaption[];
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   PSTR szCmdLine, int iCmdShow)
{
    HWND         hwnd;
    MSG          msg;
    WNDCLASSEX     wndclass;
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.cbSize = sizeof(WNDCLASSEX);
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(hInstance, szAppName);
    wndclass.hIconSm = LoadIcon(hInstance, szAppName);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;
    if (!RegisterClassEx(&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"),
                   szAppName, MB_ICONERROR);
        return 0;
    }
    hInst = hInstance;
    hwnd = CreateWindow(szAppName,                  // window class name
                        szCaption, // window caption
                        WS_OVERLAPPEDWINDOW,        // window style
                        CW_USEDEFAULT,              // initial x position
                        CW_USEDEFAULT,              // initial y position
                        CW_USEDEFAULT,              // initial x size
                        CW_USEDEFAULT,              // initial y size
                        NULL,                       // parent window handle
                        NULL,                       // window menu handle
                        hInstance,                  // program instance handle
                        NULL);                     // creation parameters

    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
void PageGDICalls(HDC hdcPrn, int cxPage, int cyPage)
{
    static TCHAR szTextStr[] = TEXT("Hello Printer!");
    //画边框
    Rectangle(hdcPrn, 0, 0, cxPage, cyPage);
    //画对角线
    MoveToEx(hdcPrn, 0, 0, NULL);
    LineTo(hdcPrn, cxPage, cyPage);
    MoveToEx(hdcPrn, cxPage, 0, NULL);
    LineTo(hdcPrn, 0, cyPage);
    SaveDC(hdcPrn);
    SetMapMode(hdcPrn, MM_ISOTROPIC);//各向同性
    //将坐标系改为坐标系原点在客户区中心,y向上为正,x、y均为范围(-1000,1000)
    SetWindowExtEx(hdcPrn, 1000, 1000, NULL);
    SetViewportExtEx(hdcPrn, cxPage / 2, -cyPage / 2, NULL); //y轴向上为正
    SetViewportOrgEx(hdcPrn, cxPage / 2, cyPage / 2, NULL);

    //画圆(因为是各向同性的)
    Ellipse(hdcPrn, -500, 500, 500, -500);

    SetTextAlign(hdcPrn, TA_BASELINE | TA_CENTER); //对齐的基准点要对准基线
    TextOut(hdcPrn, 0, 0, szTextStr, lstrlen(szTextStr));
    RestoreDC(hdcPrn, -1);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC         hdc;
    PAINTSTRUCT ps;
    static int  cxClient, cyClient;
    HMENU       hMenu;
    switch (message)
    {
    case WM_CREATE:
        //在系统菜单中增加"Print"菜单项,菜单ID为1;
        hMenu = GetSystemMenu(hwnd, FALSE);
        AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
        AppendMenu(hMenu, 0, 1, TEXT("&Print"));  //菜单ID=1;
        return 0;
    case WM_SIZE:
        cxClient = LOWORD(lParam);
        cyClient = HIWORD(lParam);
        return 0;
    case WM_SYSCOMMAND: //wParam为菜单ID
        if (wParam == 1)
        {
            if (!PrintMyPage(hwnd))
                MessageBox(hwnd, TEXT("Could not print page!"),
                szAppName, MB_OK | MB_ICONEXCLAMATION);
            return 0;
        }
        break;
    case WM_PAINT:
        hdc = BeginPaint(hwnd, &ps);

        PageGDICalls(hdc, cxClient, cyClient);

        EndPaint(hwnd, &ps);
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

【Print1程序】

技术分享

/*------------------------------------------------------------------
PRINT1.C —— Bare Bones Printing
(c) Charles Petzold, 1998
-------------------------------------------------------------------*/
#include <windows.h>
HDC  GetPrinterDC(void);              // in GETPRNDC.C
void PageGDICalls(HDC, int, int);     // in PRINT.C
HINSTANCE hInst;
TCHAR  szAppName[] = TEXT("Print1");
TCHAR  szCaption[] = TEXT("Print Program 1");
BOOL PrintMyPage(HWND hwnd)
{
    static DOCINFO di = { sizeof(DOCINFO), TEXT("Print1:Printing"), TEXT("Print1.prn") };
    BOOL           bSuccess = TRUE;
    HDC            hdcPrn;
    int            xPage, yPage;
    if (NULL == (hdcPrn = GetPrinterDC()))
    {
        return FALSE;
    }
    xPage = GetDeviceCaps(hdcPrn, HORZRES); //水平像素规模
    yPage = GetDeviceCaps(hdcPrn, VERTRES); //垂直像素规模
    if (StartDoc(hdcPrn, &di)>0) //打印作业开始
    {
        if (StartPage(hdcPrn)>0)  //一页的开始
        {
            PageGDICalls(hdcPrn, xPage, yPage); //打印内容

            if (EndPage(hdcPrn) > 0) //一页的结束
                EndDoc(hdcPrn);      //作业完成
            else
                bSuccess = FALSE;

        }
    } else
        bSuccess = FALSE;

    DeleteDC(hdcPrn);
    return TRUE;
}

【Print2程序】

/*-------------------------------------------
PRINT2.C -- Printing with Abort Procedure
(c) Charles Petzold, 1998
-------------------------------------------*/
#include <windows.h>
HDC GetPrinterDC(void);             //in GETPRNDC.C
void PageGDICalls(HDC, int, int);   //in PRINT.C
HINSTANCE hInst;
TCHAR szAppName[] = TEXT("Print2");
TCHAR szCaption[] = TEXT("Print Program 2(Abort Procedure)");
BOOL CALLBACK AbortProc(HDC hdcPrn, int iCode)
{
    MSG msg;
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return TRUE;
}
BOOL PrintMyPage(HWND hwnd)
{
    static DOCINFO di = { sizeof(DOCINFO), TEXT("Print2:Printing") };
    HDC  hdcPrn;
    BOOL bSuccess = TRUE;
    short xPage, yPage;
    if (NULL == (hdcPrn = GetPrinterDC()))
    {
        return FALSE;
    }
    xPage = GetDeviceCaps(hdcPrn, HORZRES);
    yPage = GetDeviceCaps(hdcPrn, VERTRES);
    EnableWindow(hwnd, FALSE);
    SetAbortProc(hdcPrn, AbortProc);
    if (StartDoc(hdcPrn, &di) > 0)
    {
        if (StartPage(hdcPrn) > 0)
        {
            PageGDICalls(hdcPrn, xPage, yPage);
            if (EndPage(hdcPrn) > 0)
                EndDoc(hdcPrn);
            else
                bSuccess = FALSE;
        }
    } else
        bSuccess = FALSE;
    EnableWindow(hwnd, TRUE);
    DeleteDC(hdcPrn);
    return bSuccess;
}

 

第13章 使用打印机_13.2 打印图形和文字

标签:

原文地址:http://www.cnblogs.com/5iedu/p/4695175.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!