如何打印 Rich Edit 控件的内容

本节包含如何打印 Rich Edit 控件内容的相关信息。

需要了解的事项

技术

先决条件

  • C/C++
  • Windows 用户界面编程

说明

使用打印预览

要在 Rich Edit 控件中格式化文本,以便使其在目标设备(通常是打印页面)上显示,请发送 EM_SETTARGETDEVICE 消息,并传递目标设备的设备上下文 (HDC) 句柄和所需的行宽。 通常,可以通过调用目标 HDC 的 GetDeviceCaps 来获取线宽。

设置特定设备的打印格式

要为特定设备格式化 Rich Edit 控件的部分内容,请发送 EM_FORMATRANGE 消息。 与此消息一起使用的 FORMATRANGE 结构指定了要格式化的文本范围以及目标设备的 HDC。 (可选)此消息也可以将文本发送到打印机。

使用条带

条带是指使用一个或多个独立的矩形或区段来生成单个页面输出的过程。 当所有区段都位于页面上时,就会形成一幅完整图像。 光栅打印机通常使用这种方法,因为它们没有足够的内存或能力一次对整个页面进行成像。

要实现条带,请使用 EM_DISPLAYBAND 消息将 Rich Edit 控件内容的连续部分发送到设备。 此消息将打印到之前调用 EM_FORMATRANGE 时指定的设备上。 当然,EM_FORMATRANGE 消息的 wParam 参数应为 0,这样该消息就不会启动打印。

PrintRTF 代码示例

以下示例代码可将 Rich Edit 控件的内容打印到指定的打印机上。

// hwnd is the HWND of the rich edit control.
// hdc is the HDC of the printer. This value can be obtained for the 
// default printer as follows:
//
//     PRINTDLG pd = { sizeof(pd) };
//     pd.Flags = PD_RETURNDC | PD_RETURNDEFAULT;
//
//     if (PrintDlg(&pd))
//     {
//        HDC hdc = pd.hDC;
//        ...
//     }

BOOL PrintRTF(HWND hwnd, HDC hdc)
{
    DOCINFO di = { sizeof(di) };
    
    if (!StartDoc(hdc, &di))
    {
        return FALSE;
    }

    int cxPhysOffset = GetDeviceCaps(hdc, PHYSICALOFFSETX);
    int cyPhysOffset = GetDeviceCaps(hdc, PHYSICALOFFSETY);
    
    int cxPhys = GetDeviceCaps(hdc, PHYSICALWIDTH);
    int cyPhys = GetDeviceCaps(hdc, PHYSICALHEIGHT);

    // Create "print preview". 
    SendMessage(hwnd, EM_SETTARGETDEVICE, (WPARAM)hdc, cxPhys/2);

    FORMATRANGE fr;

    fr.hdc       = hdc;
    fr.hdcTarget = hdc;

    // Set page rect to physical page size in twips.
    fr.rcPage.top    = 0;  
    fr.rcPage.left   = 0;  
    fr.rcPage.right  = MulDiv(cxPhys, 1440, GetDeviceCaps(hDC, LOGPIXELSX));  
    fr.rcPage.bottom = MulDiv(cyPhys, 1440, GetDeviceCaps(hDC, LOGPIXELSY)); 

    // Set the rendering rectangle to the pintable area of the page.
    fr.rc.left   = cxPhysOffset;
    fr.rc.right  = cxPhysOffset + cxPhys;
    fr.rc.top    = cyPhysOffset;
    fr.rc.bottom = cyPhysOffset + cyPhys;

    SendMessage(hwnd, EM_SETSEL, 0, (LPARAM)-1);          // Select the entire contents.
    SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&fr.chrg);  // Get the selection into a CHARRANGE.

    BOOL fSuccess = TRUE;

    // Use GDI to print successive pages.
    while (fr.chrg.cpMin < fr.chrg.cpMax && fSuccess) 
    {
        fSuccess = StartPage(hdc) > 0;
        
        if (!fSuccess) break;
        
        int cpMin = SendMessage(hwnd, EM_FORMATRANGE, TRUE, (LPARAM)&fr);
        
        if (cpMin <= fr.chrg.cpMin) 
        {
            fSuccess = FALSE;
            break;
        }
        
        fr.chrg.cpMin = cpMin;
        fSuccess = EndPage(hdc) > 0;
    }
    
    SendMessage(hwnd, EM_FORMATRANGE, FALSE, 0);
    
    if (fSuccess)
    {
        EndDoc(hdc);
    } 
    
    else 
    
    {
        AbortDoc(hdc);
    }
    
    return fSuccess;
    
}

使用 Rich Edit 控件

Windows 通用控件演示 (CppWindowsCommonControls)