Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Подробное описание способа печати содержимого формы 
:(
    Опции темы
Poseidon
Дата 20.6.2005, 01:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 53
Всего: 133



Данный документ содержит подробное описание способа печати содержимого формы: получение отдельных битов устройства при 256-цветной форме, и использования полученных битов для печати формы на принтере. 

Кроме того, в данном коде осуществляется проверка палитры устройства (экран или принтер), и включается обработка палитры соответствующего устройства. Если устройством палитры является устройство экрана, принимаются дополнительные меры по заполнению палитры растрового изображения из системной палитры, избавляющие от некорректного заполнения палитры некоторыми видеодрайверами. 

Примечание: Поскольку данный код делает снимок формы, форма должна располагаться на самом верху, поверх остальных форм, быть полность на экране, и быть видимой на момент ее "съемки". 

Код

unit Prntit; 

interface 

uses 
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, 
  Controls, Forms, Dialogs, StdCtrls, ExtCtrls; 

type 
  TForm1 = class(TForm) 
    Button1: TButton; 
    Image1: TImage; 
    procedure Button1Click(Sender: TObject); 
  private 
    { Private declarations } 
  public 
    { Public declarations } 
  end; 

var 
  Form1: TForm1; 

implementation 

{$R *.DFM} 

uses Printers; 

procedure TForm1.Button1Click(Sender: TObject); 
var 

  dc: HDC; 
  isDcPalDevice: BOOL; 
  MemDc: hdc; 
  MemBitmap: hBitmap; 
  OldMemBitmap: hBitmap; 
  hDibHeader: Thandle; 
  pDibHeader: pointer; 
  hBits: Thandle; 
  pBits: pointer; 
  ScaleX: Double; 
  ScaleY: Double; 
  ppal: PLOGPALETTE; 
  pal: hPalette; 
  Oldpal: hPalette; 
  i: integer; 
begin 

  {Получаем dc экрана} 
  dc := GetDc(0); 
  {Создаем совместимый dc} 
  MemDc := CreateCompatibleDc(dc); 
  {создаем изображение} 
  MemBitmap := CreateCompatibleBitmap(Dc, 
    form1.width, 
    form1.height); 
  {выбираем изображение в dc} 
  OldMemBitmap := SelectObject(MemDc, MemBitmap); 

  {Производим действия, устраняющие ошибки при работе с некоторыми типами видеодрайверов} 
  isDcPalDevice := false; 
  if GetDeviceCaps(dc, RASTERCAPS) and 
    RC_PALETTE = RC_PALETTE then 
  begin 
    GetMem(pPal, sizeof(TLOGPALETTE) + 
      (255 * sizeof(TPALETTEENTRY))); 
    FillChar(pPal^, sizeof(TLOGPALETTE) + 
      (255 * sizeof(TPALETTEENTRY)), #0); 
    pPal^.palVersion := $300; 
    pPal^.palNumEntries := 
      GetSystemPaletteEntries(dc, 
      0, 
      256, 
      pPal^.palPalEntry); 
    if pPal^.PalNumEntries <> 0 then 
    begin 
      pal := CreatePalette(pPal^); 
      oldPal := SelectPalette(MemDc, Pal, false); 
      isDcPalDevice := true 
    end 
    else 
      FreeMem(pPal, sizeof(TLOGPALETTE) + 
        (255 * sizeof(TPALETTEENTRY))); 
  end; 

  {копируем экран в memdc/bitmap} 
  BitBlt(MemDc, 
    0, 0, 
    form1.width, form1.height, 
    Dc, 
    form1.left, form1.top, 
    SrcCopy); 

  if isDcPalDevice = true then 
  begin 
    SelectPalette(MemDc, OldPal, false); 
    DeleteObject(Pal); 
  end; 

  {удаляем выбор изображения} 
  SelectObject(MemDc, OldMemBitmap); 
  {удаляем dc памяти} 
  DeleteDc(MemDc); 
  {Распределяем память для структуры DIB} 
  hDibHeader := GlobalAlloc(GHND, 
    sizeof(TBITMAPINFO) + 
    (sizeof(TRGBQUAD) * 256)); 
  {получаем указатель на распределенную память} 
  pDibHeader := GlobalLock(hDibHeader); 

  {заполняем dib-структуру информацией, которая нам необходима в DIB} 
  FillChar(pDibHeader^, 
    sizeof(TBITMAPINFO) + (sizeof(TRGBQUAD) * 256), 
    #0); 
  PBITMAPINFOHEADER(pDibHeader)^.biSize := 
    sizeof(TBITMAPINFOHEADER); 
  PBITMAPINFOHEADER(pDibHeader)^.biPlanes := 1; 
  PBITMAPINFOHEADER(pDibHeader)^.biBitCount := 8; 
  PBITMAPINFOHEADER(pDibHeader)^.biWidth := form1.width; 
  PBITMAPINFOHEADER(pDibHeader)^.biHeight := form1.height; 
  PBITMAPINFOHEADER(pDibHeader)^.biCompression := BI_RGB; 

  {узнаем сколько памяти необходимо для битов} 
  GetDIBits(dc, 
    MemBitmap, 
    0, 
    form1.height, 
    nil, 
    TBitmapInfo(pDibHeader^), 
    DIB_RGB_COLORS); 

  {Распределяем память для битов} 
  hBits := GlobalAlloc(GHND, 
    PBitmapInfoHeader(pDibHeader)^.BiSizeImage); 
  {Получаем указатель на биты} 
  pBits := GlobalLock(hBits); 

  {Вызываем функцию снова, но на этот раз нам передают биты!} 
  GetDIBits(dc, 
    MemBitmap, 
    0, 
    form1.height, 
    pBits, 
    PBitmapInfo(pDibHeader)^, 
    DIB_RGB_COLORS); 

  {Пробуем исправить ошибки некоторых видеодрайверов} 
  if isDcPalDevice = true then 
  begin 
    for i := 0 to (pPal^.PalNumEntries - 1) do 
    begin 
      PBitmapInfo(pDibHeader)^.bmiColors[i].rgbRed := 
        pPal^.palPalEntry[i].peRed; 
      PBitmapInfo(pDibHeader)^.bmiColors[i].rgbGreen := 
        pPal^.palPalEntry[i].peGreen; 
      PBitmapInfo(pDibHeader)^.bmiColors[i].rgbBlue := 
        pPal^.palPalEntry[i].peBlue; 
    end; 
    FreeMem(pPal, sizeof(TLOGPALETTE) + 
      (255 * sizeof(TPALETTEENTRY))); 
  end; 

  {Освобождаем dc экрана} 
  ReleaseDc(0, dc); 
  {Удаляем изображение} 
  DeleteObject(MemBitmap); 

  {Запускаем работу печати} 
  Printer.BeginDoc; 

  {Масштабируем размер печати} 
  if Printer.PageWidth < Printer.PageHeight then 
  begin 
    ScaleX := Printer.PageWidth; 
    ScaleY := Form1.Height * (Printer.PageWidth / Form1.Width); 
  end 
  else 
  begin 
    ScaleX := Form1.Width * (Printer.PageHeight / Form1.Height); 
    ScaleY := Printer.PageHeight; 
  end; 

  {Просто используем драйвер принтера для устройства палитры} 
  isDcPalDevice := false; 
  if GetDeviceCaps(Printer.Canvas.Handle, RASTERCAPS) and 
    RC_PALETTE = RC_PALETTE then 
  begin 
    {Создаем палитру для dib} 
    GetMem(pPal, sizeof(TLOGPALETTE) + 
      (255 * sizeof(TPALETTEENTRY))); 
    FillChar(pPal^, sizeof(TLOGPALETTE) + 
      (255 * sizeof(TPALETTEENTRY)), #0); 
    pPal^.palVersion := $300; 
    pPal^.palNumEntries := 256; 
    for i := 0 to (pPal^.PalNumEntries - 1) do 
    begin 
      pPal^.palPalEntry[i].peRed := 
        PBitmapInfo(pDibHeader)^.bmiColors[i].rgbRed; 
      pPal^.palPalEntry[i].peGreen := 
        PBitmapInfo(pDibHeader)^.bmiColors[i].rgbGreen; 
      pPal^.palPalEntry[i].peBlue := 
        PBitmapInfo(pDibHeader)^.bmiColors[i].rgbBlue; 
    end; 
    pal := CreatePalette(pPal^); 
    FreeMem(pPal, sizeof(TLOGPALETTE) + 
      (255 * sizeof(TPALETTEENTRY))); 
    oldPal := SelectPalette(Printer.Canvas.Handle, Pal, false); 
    isDcPalDevice := true 
  end; 

  {посылаем биты на принтер} 
  StretchDiBits(Printer.Canvas.Handle, 
    0, 0, 
    Round(scaleX), Round(scaleY), 
    0, 0, 
    Form1.Width, Form1.Height, 
    pBits, 
    PBitmapInfo(pDibHeader)^, 
    DIB_RGB_COLORS, 
    SRCCOPY); 

  {Просто используем драйвер принтера для устройства палитры} 
  if isDcPalDevice = true then 
  begin 
    SelectPalette(Printer.Canvas.Handle, oldPal, false); 
    DeleteObject(Pal); 
  end; 

  {Очищаем распределенную память} GlobalUnlock(hBits); 
  GlobalFree(hBits); 
  GlobalUnlock(hDibHeader); 
  GlobalFree(hDibHeader); 

  {Заканчиваем работу печати} 
  Printer.EndDoc; 

end;
 



--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0828 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.