C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
!!Помогите кто нибудь найти ошибку в коде!!
FANTOM181
Отправлено: 02.04.2005, 15:35


Ученик-кочегар

Группа: Участник
Сообщений: 20



Скачал недавно с сайта codenet.ru пример кода, с помощью корого можно осуществлять печать из Image. Но там такая куча ошибок, что я сам не разберусь. А осуществить печать мне очень нужно. Помогите пожалуйста.

/*-----------------------------------------------------------------------
Эта функция является обработчиком события OnClick для TButton, которая
находится на TForm. На TForm также присутствует TImage с именем image.
------------------------------------------------------------------------*/
void __fastcall Tmain_form::print_image_btnClick(TObject *Sender)
{
TPrinter *p = Printer();

// создаём в памяти dc для картинки
HDC h_dc = image->Picture->Bitmap->Canvas->Handle;
int bmp_w = image->Picture->Bitmap->Width,
bmp_h = image->Picture->Bitmap->Height;
HDC h_mem_dc = ::CreateCompatibleDC (h_dc);
HBITMAP h_mem_bmp = ::CreateCompatibleBitmap (h_dc, bmp_w, bmp_h);
HBITMAP h_old_bmp = ::SelectObject (h_mem_dc, h_mem_bmp);

// фиксируем ошибки видео драйверов
bool is_pal_dev = false;
LOGPALETTE *pal;
HPALETTE h_pal, h_old_pal;

if (::GetDeviceCaps (image->Canvas->Handle, RASTERCAPS) & RC_PALETTE)
{
pal = static_cast(malloc (sizeof (LOGPALETTE) +
(sizeof (PALETTEENTRY) * 256)));
memset (pal, 0, sizeof (LOGPALETTE) + (sizeof (PALETTEENTRY) * 256));
pal->palVersion = 0x300;
pal->palNumEntries = ::GetSystemPaletteEntries(image->Canvas->Handle, 0,
256, pal->palPalEntry);
if (pal->palNumEntries != 0)
{
h_pal = ::CreatePalette (pal);
h_old_pal = ::SelectPalette (h_mem_dc, h_pal, false);
is_pal_dev = true;
}
else
{
free (pal);
}
}

// копируем картинку на dc в памяти
::BitBlt (h_mem_dc, 0, 0, bmp_w, bmp_h, h_dc, 0, 0, SRCCOPY);

if (is_pal_dev)
{
::SelectPalette (h_mem_dc, h_old_pal, false);
::DeleteObject (h_pal);
}

// удаляем dc в памяти
::SelectObject (h_mem_dc, h_old_bmp);
::DeleteDC (h_mem_dc);

// выделяем память для структуры BITMAPIFO
HANDLE h_bmp_info = ::GlobalAlloc (GHND,
sizeof (BITMAPINFO) + (sizeof (RGBQUAD) * 256));
BITMAPINFO* bmp_info = static_cast(::GlobalLock (h_bmp_info));
//Заполняем структуру
memset (bmp_info, NULL, sizeof (BITMAPINFO) + (sizeof (RGBQUAD) * 255));
bmp_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmp_info->bmiHeader.biPlanes = 1;
bmp_info->bmiHeader.biBitCount = 8;
bmp_info->bmiHeader.biWidth = bmp_w;
bmp_info->bmiHeader.biHeight = bmp_h;
bmp_info->bmiHeader.biCompression = BI_RGB;

// определяем размер памяти для битов
::GetDIBits (h_dc, h_mem_bmp, 0, bmp_h, NULL, bmp_info, DIB_RGB_COLORS);

// Выделяем память для битов
HANDLE h_bits = GlobalAlloc (GHND, bmp_info->bmiHeader.biSizeImage);
void *bits = ::GlobalLock (h_bits);

// получаем биты
::GetDIBits (h_dc, h_mem_bmp, 0, bmp_h, bits, bmp_info, DIB_RGB_COLORS);

// фиксируем ошибки видео драйверов
if (is_pal_dev)
{
for (int i = 0; i palNumEntries; i++)
{
bmp_info->bmiColors[i].rgbRed = pal->palPalEntry[i].peRed;
bmp_info->bmiColors[i].rgbGreen = pal->palPalEntry[i].peGreen;
bmp_info->bmiColors[i].rgbBlue = pal->palPalEntry[i].peBlue;
}
free (pal);
}

// начинаем печать
p->BeginDoc ();

// масштабируем размер печати
int scale_x, scale_y;
if (p->PageWidth PageHeight)
{
scale_x = p->PageWidth;
scale_y = image->Picture->Height * (p->PageWidth / bmp_w);
}
else
{
scale_x = image->Picture->Width * (p->PageHeight / bmp_h);
scale_y = p->PageHeight;
}

// устанавливаем палитру печати
is_pal_dev = false;
if (::GetDeviceCaps (h_dc, RASTERCAPS) & RC_PALETTE)
{
pal = static_cast(malloc (sizeof (LOGPALETTE) +
(sizeof (PALETTEENTRY) * 256)));
memset (pal, 0, sizeof (LOGPALETTE) + (sizeof (PALETTEENTRY) * 256));
pal->palVersion = 0x300;
pal->palNumEntries = 256;
for (int i = 0; pal->palNumEntries; i++)
{
pal->palPalEntry[i].peRed = bmp_info->bmiColors[i].rgbRed;
pal->palPalEntry[i].peGreen = bmp_info->bmiColors[i].rgbGreen;
pal->palPalEntry[i].peBlue = bmp_info->bmiColors[i].rgbBlue;
}
h_pal = CreatePalette(pal);
free (pal);
h_old_pal = SelectPalette(p->Canvas->Handle, h_pal, false);
is_pal_dev = true;
}

// посылаем биты на принтер
StretchDIBits(p->Canvas->Handle, 0, 0, scale_x, scale_y,
0, 0, bmp_w, bmp_h, bits,bmp_info, DIB_RGB_COLORS, SRCCOPY);

// конец печати
p->EndDoc ();

// освобождаем ресурсы
::DeleteObject (h_mem_bmp);
if (is_pal_dev)
{
::SelectObject (p->Canvas->Handle, h_old_pal);
::DeleteObject (h_pal);
}
::GlobalUnlock (bits);
::GlobalFree (h_bits);
::GlobalUnlock (bmp_info);
::GlobalFree (h_bmp_info);
}

62316e
  Отправлено: 02.04.2005, 16:25


Дежурный стрелочник

Группа: Участник
Сообщений: 38



1) Не надо тянуть з codenet.ru (codenet.ru подло з ошыбками стянуло з Борланда (без обид)), а если уже приспичило то четай от начяла до конца а не тани первый попавшыйся кусок!
CODE
void __fastcall TForm1::print_image_btnClick(TObject *Sender)
{    TPrinter *p = Printer();

   // create a memory dc for the image
   HDC h_dc = image->Picture->Bitmap->Canvas->Handle;
   int bmp_w = image->Picture->Bitmap->Width,
   bmp_h = image->Picture->Bitmap->Height;
   HDC h_mem_dc = ::CreateCompatibleDC (h_dc);
   HBITMAP h_mem_bmp = ::CreateCompatibleBitmap (h_dc, bmp_w, bmp_h);
   HBITMAP h_old_bmp = ::SelectObject (h_mem_dc, h_mem_bmp);

   // fix up bad video drivers
   bool is_pal_dev = false;
   LOGPALETTE *pal;
   HPALETTE h_pal, h_old_pal;

   if (::GetDeviceCaps (image->Canvas->Handle, RASTERCAPS) & RC_PALETTE)
   {
       pal = static_cast<LOGPALETTE *>(malloc (sizeof (LOGPALETTE) + (sizeof (PALETTEENTRY) * 256)));
       memset (pal, 0, sizeof (LOGPALETTE) + (sizeof (PALETTEENTRY) * 256));
       pal->palVersion = 0x300;
       pal->palNumEntries = ::GetSystemPaletteEntries(image->Canvas->Handle, 0, 256, pal->palPalEntry);
       if (pal->palNumEntries != 0)
       {
           h_pal = ::CreatePalette (pal);
           h_old_pal = ::SelectPalette (h_mem_dc, h_pal, false);
           is_pal_dev = true;
       }
       else
       {
           free (pal);
       }
   }

   // copy the image on to the memory dc
   ::BitBlt (h_mem_dc, 0, 0, bmp_w, bmp_h, h_dc, 0, 0, SRCCOPY);

   if (is_pal_dev)
   {
       ::SelectPalette (h_mem_dc, h_old_pal, false);
       ::DeleteObject (h_pal);
   }

   // delete the mem dc
   ::SelectObject (h_mem_dc, h_old_bmp);
   ::DeleteDC (h_mem_dc);

   // get memory for a BITMAPIFO Structure
   HANDLE h_bmp_info = ::GlobalAlloc (GHND, sizeof (BITMAPINFO) + (sizeof (RGBQUAD) * 256));
   BITMAPINFO* bmp_info = static_cast<tagBITMAPINFO*>(::GlobalLock (h_bmp_info));
   //Set up the structure
   memset (bmp_info, NULL, sizeof (BITMAPINFO) + (sizeof (RGBQUAD) * 255));
   bmp_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
   bmp_info->bmiHeader.biPlanes = 1;
   bmp_info->bmiHeader.biBitCount = 8;
   bmp_info->bmiHeader.biWidth = bmp_w;
   bmp_info->bmiHeader.biHeight = bmp_h;
   bmp_info->bmiHeader.biCompression = BI_RGB;

   // find out how much memory for the bits
   ::GetDIBits (h_dc, h_mem_bmp, 0, bmp_h, NULL, bmp_info, DIB_RGB_COLORS);

   // Allocate memory for the bits
   HANDLE h_bits = GlobalAlloc (GHND, bmp_info->bmiHeader.biSizeImage);
   void *bits = ::GlobalLock (h_bits);

   // this time get the bits
   ::GetDIBits (h_dc, h_mem_bmp, 0, bmp_h, bits, bmp_info, DIB_RGB_COLORS);

   // fix up for bad video driver
   if (is_pal_dev)
   {
       for (int i = 0; i < pal->palNumEntries; i++)
       {
           bmp_info->bmiColors[i].rgbRed = pal->palPalEntry[i].peRed;
           bmp_info->bmiColors[i].rgbGreen = pal->palPalEntry[i].peGreen;
           bmp_info->bmiColors[i].rgbBlue = pal->palPalEntry[i].peBlue;
       }
       free (pal);
   }

   // begin the printing
   p->BeginDoc ();

   // scale print size
   int scale_x, scale_y;
   if (p->PageWidth < p->PageHeight)
   {
       scale_x = p->PageWidth;
       scale_y = image->Picture->Height * (p->PageWidth / bmp_w);
   }
   else
   {
       scale_x = image->Picture->Width * (p->PageHeight / bmp_h);
       scale_y = p->PageHeight;
   }

   // fix up for print with palette
   is_pal_dev = false;
   if (::GetDeviceCaps (h_dc, RASTERCAPS) & RC_PALETTE)
   {
       pal = static_cast<LOGPALETTE*>(malloc (sizeof (LOGPALETTE) + (sizeof (PALETTEENTRY) * 256)));
       memset (pal, 0, sizeof (LOGPALETTE) + (sizeof (PALETTEENTRY) * 256));
       pal->palVersion = 0x300;
       pal->palNumEntries = 256;
       for (int i = 0; pal->palNumEntries; i++)
       {
           pal->palPalEntry[i].peRed = bmp_info->bmiColors[i].rgbRed;
           pal->palPalEntry[i].peGreen = bmp_info->bmiColors[i].rgbGreen;
           pal->palPalEntry[i].peBlue = bmp_info->bmiColors[i].rgbBlue;
       }
       h_pal = CreatePalette(pal);
       free (pal);
       h_old_pal = SelectPalette(p->Canvas->Handle, h_pal, false);
       is_pal_dev = true;
   }

   // send the bits to the printer
   StretchDIBits(p->Canvas->Handle, 0, 0, scale_x, scale_y,
 0, 0, bmp_w, bmp_h, bits,bmp_info, DIB_RGB_COLORS, SRCCOPY);

   // end the print
   p->EndDoc ();

   // clean up
   ::DeleteObject (h_mem_bmp);
   if (is_pal_dev)
   {
       ::SelectObject (p->Canvas->Handle, h_old_pal);
       ::DeleteObject (h_pal);
   }
   ::GlobalUnlock (bits);
   ::GlobalFree (h_bits);
   ::GlobalUnlock (bmp_info);
   ::GlobalFree (h_bmp_info);
}
По сути компилитса (даже линцерица) Не думаю что роботает! wink.gif (не переверял — сам)
vitavita
Отправлено: 02.04.2005, 18:44


Дежурный стрелочник

Группа: Участник
Сообщений: 59



А не проще ли печатать с помощью QReport ?
FANTOM181
Отправлено: 03.04.2005, 15:59


Ученик-кочегар

Группа: Участник
Сообщений: 20



Спасибки огромное. Тоько еще один вопрос. Если изображение такое большое что не умещается на один лист, оно должно разбиваться на несколько. А у меня он просто печатает одну страницу, и рисунок получается неполным(обрезаннным). Как это исправить?
62316e
Отправлено: 05.04.2005, 17:33


Дежурный стрелочник

Группа: Участник
Сообщений: 38



QUOTE
Если изображение такое большое что не умещается на один лист, оно должно разбиваться на несколько.
Что-тоя не могу понять как оно должно "разбиваться на несколько"? Может всьо таки эго нужно уменшыть?

Вернуться в Вопросы программирования в C++Builder