将GetDeviceCaps获得的纸张的可打印区域转换为RectF [英] Convert printable area of the paper, obtained by GetDeviceCaps, into RectF

查看:96
本文介绍了将GetDeviceCaps获得的纸张的可打印区域转换为RectF的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习使用打印属性表,所以我可以通过在纸上画一个矩形来开始学习打印。



我的问题是我没有打印机,并通过打印到 XPS 文件和 MS Office OneNote 2007 来测试结果。我正在使用此代码片段绘制矩形:

I am learning to use print property sheet so I can start learning printing by drawing a rectangle on the paper.

My problem is that I do not have a printer, and am testing the results by printing to XPS file and MS Office OneNote 2007. I am drawing the rectangle with this code snippet :

// hWnd is the window that owns the property sheet.
HRESULT DisplayPrintPropertySheet(HWND hWnd)
{
    HRESULT hResult;
    PRINTDLGEX pdx = {0};
    LPPRINTPAGERANGE pPageRanges = NULL;

    // Allocate an array of PRINTPAGERANGE structures.
    pPageRanges = (LPPRINTPAGERANGE) GlobalAlloc( GPTR, 
        10 * sizeof(PRINTPAGERANGE) );

    if (!pPageRanges)
        return E_OUTOFMEMORY;

    //  Initialize the PRINTDLGEX structure.
    pdx.lStructSize = sizeof(PRINTDLGEX);
    pdx.hwndOwner = hWnd;
    pdx.hDevMode = NULL;
    pdx.hDevNames = NULL;
    pdx.hDC = NULL;
    pdx.Flags = PD_RETURNDC;
    pdx.Flags2 = 0;
    pdx.ExclusionFlags = 0;
    pdx.nPageRanges = 0;
    pdx.nMaxPageRanges = 10;
    pdx.lpPageRanges = pPageRanges;
    pdx.nMinPage = 1;
    pdx.nMaxPage = 1000;
    pdx.nCopies = 1;
    pdx.hInstance = 0;
    pdx.lpPrintTemplateName = NULL;
    pdx.lpCallback = NULL;
    pdx.nPropertyPages = 0;
    pdx.lphPropertyPages = NULL;
    pdx.nStartPage = START_PAGE_GENERAL;
    pdx.dwResultAction = 0;

    //  Invoke the Print property sheet.

    hResult = PrintDlgEx(&pdx);

    if ( ( hResult == S_OK )    
        && ( pdx.dwResultAction == PD_RESULT_PRINT ) )
    {

        // User clicked the Print button, 
        // so use the DC and other information returned in the 
        // PRINTDLGEX structure to print the document.

        DOCINFO diDocInfo = {0};
        diDocInfo.cbSize = sizeof( DOCINFO ); 
        diDocInfo.lpszDocName = L"Testing printing...";

        if( StartDoc( pdx.hDC, &diDocInfo ) > 0 )
        {
            if( StartPage( pdx.hDC ) > 0 )
            {
                // get paper dimensions
                int pageWidth, pageHeight;

                pageWidth = GetDeviceCaps( pdx.hDC, HORZRES );
                pageHeight = GetDeviceCaps( pdx.hDC, VERTRES );

                // graphics object for rendering text, grid lines, bitmaps ...
                Graphics g( pdx.hDC );

                /************ draw a testing rectangle***************/

                g.DrawRectangle( &Pen( Color::Red, 4 ), 0, 0, 
                    pageWidth, pageHeight );

                /************************************************/

                if( EndPage( pdx.hDC ) < 0 )
                    // for now pop a message box saying something went wrong
                    MessageBox( hWnd, L"EndDoc failed!", L"Error", MB_OK );
            }

            EndDoc( pdx.hDC );

        }
    }

    if (pdx.hDevMode != NULL) 
        GlobalFree(pdx.hDevMode); 
    if (pdx.hDevNames != NULL) 
        GlobalFree(pdx.hDevNames); 
    if (pdx.lpPageRanges != NULL)
        GlobalFree(pPageRanges);
    if (pdx.hDC != NULL) 
        DeleteDC(pdx.hDC);

    return hResult;
}





我遇到的问题 [ ^ ]是未正确计算右下坐标。预期结果应该像这个 [ ^ ]。



显然,我没有获得右下角的正确矩形坐标。



因此我要求一个可以计算纸张的正确矩形坐标的解决方案,所以我可以像上面第二张图片一样绘制红色矩形。



The problem I get[^] is that right and bottom coordinates are not properly calculated. The expected result should be like this[^].

Apparently, I do not obtain the proper rectangle coordinates for the bottom right.

Therefore I ask for a solution that can calculate proper rectangle coordinates for paper, so I can draw the red rectangle like in the second picture above.

推荐答案

查看 GDI绘图和打印 [ ^ ]。


我发现问题与Graphics类中的默认单位设置有关,如 http://msdn.microsoft.com/en-us/library/ms535812( v = vs.85).aspx [ ^ ]

您需要使用以下代码行将其设置为像素。

I have discovered that the issue is to do with the default unit settings in the Graphics class, as described in http://msdn.microsoft.com/en-us/library/ms535812(v=vs.85).aspx[^]
You need to use the following line of code to set it to pixels.
g.SetPageUnit(UnitPixel);



现在可以在XPS和真正的打印机上使用。





[edit]

使用旧式GDI而不是GDI +,以下代码工作正常:


That now works in XPS and on the real printer.


[edit]
Using old-style GDI rather than GDI+, the following code works fine:

HANDLE hPen = CreatePen(PS_SOLID, 60, RGB(255, 0, 0)); // pen width 1/10th inch
SelectObject(pdx.hDC, hPen);
Rectangle(pdx.hDC, 0, 0, pageWidth, pageHeight);



[/ edit]


[/edit]


这篇关于将GetDeviceCaps获得的纸张的可打印区域转换为RectF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆