将GetDeviceCaps获得的纸张的可打印区域转换为RectF [英] Convert printable area of the paper, obtained by GetDeviceCaps, into 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屋!