2016-09-26 11 views
0

편집 컨트롤을 인쇄하고 있습니다. 먼저 내용을 풍부한 편집 컨트롤 (적어도 2.0은 리치 편집 3.0 일 수 있음)에 복사 한 다음 거기에서 인쇄합니다.인쇄 : 틀린 아래쪽 여백

나는 모두 작동하고 있지만 ... 여백은 엉뚱한/부정확합니다.

코드를 반복적으로 검토하고 디버거에서 번호를 확인했지만 여전히 인쇄 할 수있는 페이지의 여백이 잘못되었습니다.

이 코드는 더 또는 '그물 주위에 사용할 수있는 다양한 편집에서 인쇄의 다양한 예로부터 복사 작 - 등 올드 새로운 것, MSDN의 문서와 CodeProject의 등이

그것은 아래로 비등 (

// printer dot's per inch (pixels) 
const CSize dpi = { GetDeviceCaps(hdc, LOGPIXELSX), GetDeviceCaps(hdc, LOGPIXELSY) }; 

// paper size (in printer's dots ~ pixels) 
const CSize paper = { GetDeviceCaps(hdc, PHYSICALWIDTH), GetDeviceCaps(hdc, PHYSICALHEIGHT) }; 

// printable size (pixels) - this defines the largest possible usable rect for this printer 
const CRect rcPrintable(CPoint(GetDeviceCaps(hdc, PHYSICALOFFSETX), GetDeviceCaps(hdc, PHYSICALOFFSETY)), CSize(GetDeviceCaps(hdc, HORZRES), GetDeviceCaps(hdc, VERTRES))); 

// determine the paper extents using our desired margins without violating the device's minimum margins 
const CSize margin = { dpi.cx/4, dpi.cy/2 }; // 1/4" horizontal x 1/2" vertical margins 
const CRect rcPaper(__max(rcPrintable.left, margin.cx), __max(rcPrintable.top, margin.cy), __min(rcPrintable.right, paper.cx - margin.cx), __min(rcPrintable.bottom, paper.cy - margin.cy)); 

// convert paper size in printer dots (pixels) to paper size in TWIPS 
const CRect rcPage(MulDiv(rcPaper.left, 1440, dpi.cx), MulDiv(rcPaper.top, 1440, dpi.cy), MulDiv(rcPaper.right, 1440, dpi.cx), MulDiv(rcPaper.bottom, 1440, dpi.cy)); 

// build our format range data 
FORMATRANGE fr; 
Zero(fr); 
fr.hdc = hdc; 
fr.hdcTarget = hdc; 

// Set page rect to physical page size in TWIPS 
fr.rc = rcPage; 
fr.rcPage = rcPage; 

// set our target device to the printer 
m_RichEdit.SetTargetDevice(hdc, rcPage.Width()); 

m_RichEdit.SetSel(0, -1); // Select the entire contents. 
m_RichEdit.GetSel(fr.chrg); // Get the selection into a CHARRANGE 

// track the number of pages generated 
unsigned nPages = 0; 

// give this job a reasonable name 
CString strPrintJobName = GetPrintJobName(); 

// Use GDI to print successive pages 
DOCINFO di = { sizeof(di) }; 
di.lpszDocName = strPrintJobName; 
if (!StartDoc(hdc, &di)) 
    throw CLabeledException(_T("Unable to start the print job")); 

BOOL fSuccess = TRUE; 
while (fr.chrg.cpMin < fr.chrg.cpMax) 
{ 
    // start page 
    fSuccess = StartPage(hdc) > 0; 
    if (!fSuccess) 
     break; 

    // format page 
    int cpMin = m_RichEdit.FormatRange(&fr, TRUE); 

    // ensure we made forward progress (avoid infinite loop!) 
    fSuccess = cpMin > fr.chrg.cpMin; 
    if (!fSuccess) 
     break; 

    // render page 
    fSuccess = m_RichEdit.DisplayBand(const_cast<CRect&>(rcPage)); 
    if (!fSuccess) 
     break; 

    // end page 
    fSuccess = EndPage(hdc) > 0; 
    if (!fSuccess) 
     break; 

    // update no. pages printed 
    ++nPages; 

    // update our new position 
    fr.chrg.cpMin = cpMin; 
} 

// release internal cached data from rich edit control 
m_RichEdit.FormatRange(nullptr, FALSE); 

// complete or abort the print job 
if (fSuccess) 
{ 
    EndDoc(hdc); 
    MessageBox(FormatString(_T("Printed %u pages"), nPages)); 
} 
else 
{ 
    DWORD dwError = GetLastError(); 
    AbortDoc(hdc); 
    throw CContextException(FormatString(_T("Print failed on page %u"), nPages+1), dwError); 
} 

내 600dpi의 프린터의 rcPaper 인해 실제 최소로 치수 6600 수직 화소 이하 100dots 의해 가로 5100 픽셀 나온다 : HDC 사용자 선택된 용지 공급원을 사용하여 사용자가 선택한 프린터)입니다 오프셋/제한.

내 1/4 "x 1/2"여백은 항상 프린터 제한보다 크기 때문에 페이지 = {150, 300, 4950, 6300} (픽셀)로 끝납니다.

실제로 인쇄 될 때 나는 약 5/8 "의 상단 여백과 약 3/16"의 하단 여백과 약 3/8 "의 왼쪽 여백과 약 1/8"의 오른쪽 여백을 얻습니다. .

그래서 프린터 자체가 제한 값 (PHYSICALOFFSETXPHYSICALOFFSETY)을 값에 더하여 다시 추가하는 것과 비슷합니다 (또는 rich edit 컨트롤은 모든 값을 해당 값으로 상쇄합니다).

... 또는 다른 작업이 진행 중이고/또는 내가 오해 중입니다!

아이디어가 있으십니까?

+0

좋아 -은 "대답은"프린터가 0,0로'PHSYCIALOFFSETX/Y'를 간주하는 것 같다. 그래서, 올바른 장소에 물건이 나타나기 위해서는, 결과 값을'rcPaper'에서 빼야합니다 (필자의 경우). 그리고 나서 모든 것이 "완벽합니다"(이 프린터의 모든 경우 1/32 "이내) – Mordachai

답변

0

대답은 위의 수학이 원하는 마진 세트에 대한 프린터의 기능 및 제한 사항과 일치하는 "절대"rect를 찾는 것이 맞지만 출력 rect를 만들려면 실제 오프셋을 뺄 필요가 있다는 것 같습니다. 0,0에 대한 순서로 실제 물리적 페이지에 0,0 될 수 있습니다 :

// subtract out the physical offsets 
// note: I see no documentation that this is what must be done, yet, it must be done 
//  otherwise the entire page is off by this exact amount :(
rcPaper.left -= rcPrintable.left; 
rcPaper.right -= rcPrintable.left; 
rcPaper.top -= rcPrintable.top; 
rcPaper.bottom -= rcPrintable.top; 
관련 문제