Newsgroup: it.comp.programmare.win32
Titolo: Visualizzare/stampare una bitmap

Salve a tutti,
ho la necessità di visualizzare e talvolta stampare una bitmap normalissima
(VC6.0+NT4). Ho trovato su codeguru due funzioni: una per caricare un file
bmp e una per visualizzarlo. Ora tutto funziona a dovere finchè faccio
un'anteprima di stampa a monitor, quando invece lancio la stampa vera e
propria, la funzione di output viene ignorata e non provoca niente, neanche
un'errore.
Ho provato anche con una bitmap creata con l'editor di risorse e il codice
di esempio che si trova sotto CDC::CreateCompatibleDC, ma ottengo
esattamente lo stesso risultato.
Evidentemente c'è qualcosa che mi sfugge nel passaggio da anteprima a
stampa; la stampante è grafica, ma credo che sia qualche problema del
puntatore CDC. Oppure la bitmap assume dimensioni o colori tali da essere
invisibile.
Qualcuno sa aiutarmi???
Grazie
Stefano

 un'errore.
Se hai il codice, perche` non fai il debug per vedere esattamente quale
API restituisce errore?
Forse usi StretchBlt() o un'altra funzione simile per disegnare il
bitmap sul DC, ridimensionandolo in modo che occupi tutto lo spazio
possibile? In quel caso puo` darsi che il bitmap diventi troppo grande
(una stampante ha una risoluzione molto maggiore di quella di un
monitor) e StretchBlt() o un'altrta funzione ritorni errore.
---
Bye! Lorenzo Lutti
http://antani.virtualave.net/

 monitor) e StretchBlt() o un'altrta funzione ritorni errore.
In realtà alla fine ho risolto il problema con una funzione diversa (sempre
derivata da codeguru):
BOOL Inserisci_BMP( LPCTSTR sBMPFile , CDC* pDC , int x , int y , int prc )
{
 CFile file;
 if( !file.Open( sBMPFile, CFile::modeRead) ) return FALSE;
  CPalette *pPal;
 BITMAPFILEHEADER bmfHeader;
  pPal = new CPalette;
 long nFileLen = file.GetLength();
 // Read file header
 if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
return FALSE;
 // File type should be 'BM'
 if (bmfHeader.bfType != ((WORD) ('M' << 8) | 'B')) return FALSE;
 HGLOBAL hDIB = ::GlobalAlloc(GMEM_FIXED, nFileLen);
 if (hDIB == 0) return FALSE;
 // Read the remainder of the bitmap file.
 if (file.ReadHuge((LPSTR)hDIB, nFileLen - sizeof(BITMAPFILEHEADER)) !=
nFileLen - sizeof(BITMAPFILEHEADER) )
 {
  ::GlobalFree(hDIB);
  return FALSE;
 }
 BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
 int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed : 1
<< bmInfo.bmiHeader.biBitCount;
 // Create the palette
 if( nColors <= 256 )
 {
  UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
  LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
  pLP->palVersion = 0x300;
  pLP->palNumEntries = nColors;
  for( int i=0; i < nColors; i++)
  {
   pLP->palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed;
   pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
   pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue;
   pLP->palPalEntry[i].peFlags = 0;
  }
  pPal->CreatePalette( pLP );
  delete[] pLP;
 }
 LPVOID lpDIBBits;  // Pointer to DIB bits
 BOOL bSuccess=FALSE;  // Success/fail flag
// BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
// nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed : 1 <<
bmInfo.bmiHeader.biBitCount;
 if( bmInfo.bmiHeader.biBitCount > 8 ) lpDIBBits =
(LPVOID)((LPDWORD)(bmInfo.bmiColors + bmInfo.bmiHeader.biClrUsed) +
((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
 else                                lpDIBBits = (LPVOID)(bmInfo.bmiColors +
nColors);
 if( pPal && (pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE) )
 {
  pDC->SelectPalette(pPal, FALSE);
  pDC->RealizePalette();
 }
  ::StretchDIBits(
  pDC->m_hDC,                   // handle to DC
  x,                            // x-coord of destination upper-left corner
  y,                            // y-coord of destination upper-left corner
  bmInfo.bmiHeader.biWidth  * prc / 100,    // width of destination
rectangle
  bmInfo.bmiHeader.biHeight * prc / 100,    // height of destination
rectangle
  0,                            // x-coord of source upper-left corner
  0,                            // y-coord of source upper-left corner
  bmInfo.bmiHeader.biWidth,     // width of source rectangle
  bmInfo.bmiHeader.biHeight,    // height of source rectangle
  lpDIBBits,                    // bitmap bits
  (LPBITMAPINFO)hDIB,           // bitmap data
  DIB_RGB_COLORS,               // usage options
  SRCCOPY  );
  ::GlobalFree(hDIB);
  return TRUE;
}
Fornendo a questa funzione nome del file BMP (pare funzionare a 8 e 24 bit
ma non rle), il puntatore al contesto grafico, le coordinate di
visualizzazione e una percentuale di scalatura tutto pare funzionare
correttamente, sia durante l'anteprima di stampa a monitor che durante la
stampa vera e propria.
Forse il trucco stava nel fatto che la prima versione utilizzava le bitmap
come DDB mentre questa utilizza le DIB e forse queste ultime sono necessarie
per la stampa fisica...
In ogni caso la situazione rimane piuttosto fumosa per me, quindi ogni
ulteriore informazione/delucidazione sarà estremamente gradita..
Saluti
Stefano