00001 //------------------------------------------------------------------------------ 00002 // DIBAPI.CPP -- 00003 // 00004 // Original code from MicroSoft MSDN sample 00005 // 00006 // 00007 //------------------------------------------------------------------------------ 00008 #define STRICT 00009 #include <windows.h> 00010 #pragma hdrstop 00011 00012 #include "dibapi.h" 00013 00014 WORD DIBNumColors (LPSTR lpbi) 00015 { 00016 WORD wBitCount; 00017 00018 00019 // If this is a Windows style DIB, the number of colors in the 00020 // color table can be less than the number of bits per pixel 00021 // allows for (i.e. lpbi->biClrUsed can be set to some value). 00022 // If this is the case, return the appropriate value. 00023 00024 if (IS_WIN3x_DIB (lpbi)) 00025 { 00026 DWORD dwClrUsed; 00027 00028 dwClrUsed = ((LPBITMAPINFOHEADER) lpbi)->biClrUsed; 00029 00030 if (dwClrUsed) 00031 return (WORD) dwClrUsed; 00032 } 00033 00034 00035 // Calculate the number of colors in the color table based on 00036 // the number of bits per pixel for the DIB. 00037 00038 if (IS_WIN3x_DIB (lpbi)) 00039 wBitCount = ((LPBITMAPINFOHEADER) lpbi)->biBitCount; 00040 else 00041 wBitCount = ((LPBITMAPCOREHEADER) lpbi)->bcBitCount; 00042 00043 switch (wBitCount) 00044 { 00045 case 1: 00046 return 2; 00047 00048 case 4: 00049 return 16; 00050 00051 case 8: 00052 return 256; 00053 00054 default: 00055 return 0; 00056 } 00057 } 00058 00059 00060 LPSTR FindDIBBits (LPSTR lpbi) 00061 { 00062 return (lpbi + *(LPDWORD)lpbi + PaletteSize (lpbi)); 00063 } 00064 00065 00066 00067 WORD PaletteSize (LPSTR lpbi) 00068 { 00069 if (IS_WIN3x_DIB (lpbi)) 00070 return (DIBNumColors (lpbi) * sizeof (RGBQUAD)); 00071 else 00072 return (DIBNumColors (lpbi) * sizeof (RGBTRIPLE)); 00073 } 00074 00075 00076 // 00077 // CreateDIBPalette 00078 // 00079 // Creates a palette from a DIB. Parameter passed in is the 00080 // handle to global memory containing the DIB. 00081 // 00082 00083 HPALETTE CreateDIBPalette (HANDLE hDIB) 00084 { 00085 LPLOGPALETTE lpPal; 00086 HANDLE hLogPal; 00087 HPALETTE hPal = NULL; 00088 int i, wNumColors; 00089 LPSTR lpbi; 00090 LPBITMAPINFO lpbmi; 00091 LPBITMAPCOREINFO lpbmc; 00092 BOOL bWinStyleDIB; 00093 00094 if(!hDIB) 00095 return NULL; 00096 00097 lpbi = (char *)GlobalLock (hDIB); 00098 lpbmi = (LPBITMAPINFO) lpbi; 00099 lpbmc = (LPBITMAPCOREINFO) lpbi; 00100 wNumColors = DIBNumColors (lpbi); 00101 bWinStyleDIB = IS_WIN3x_DIB (lpbi); 00102 00103 if (wNumColors) 00104 { 00105 hLogPal = GlobalAlloc (GHND, sizeof (LOGPALETTE) + 00106 sizeof (PALETTEENTRY) * wNumColors); 00107 00108 if (!hLogPal) 00109 { 00110 MessageBox (NULL, "Couldn't allocate memory for LOGPALETTE!", NULL, MB_OK); 00111 GlobalUnlock (hDIB); 00112 return NULL; 00113 } 00114 00115 lpPal = (LPLOGPALETTE) GlobalLock (hLogPal); 00116 00117 lpPal->palVersion = PALVERSION; 00118 lpPal->palNumEntries = wNumColors; 00119 00120 for (i = 0; i < wNumColors; i++) 00121 { 00122 if (bWinStyleDIB) 00123 { 00124 lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed; 00125 lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen; 00126 lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue; 00127 lpPal->palPalEntry[i].peFlags = 0; 00128 } 00129 else 00130 { 00131 lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed; 00132 lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen; 00133 lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue; 00134 lpPal->palPalEntry[i].peFlags = 0; 00135 } 00136 } 00137 00138 hPal = CreatePalette (lpPal); 00139 00140 if (!hPal) 00141 MessageBox (NULL, "CreatePalette() failed!", NULL, MB_OK); 00142 00143 GlobalUnlock (hLogPal); 00144 GlobalFree (hLogPal); 00145 } 00146 00147 GlobalUnlock (hDIB); 00148 00149 return hPal; 00150 } 00151 00152 00153 00154 00155 DWORD DIBHeight (LPSTR lpDIB) 00156 { 00157 LPBITMAPINFOHEADER lpbmi; 00158 LPBITMAPCOREHEADER lpbmc; 00159 00160 lpbmi = (LPBITMAPINFOHEADER) lpDIB; 00161 lpbmc = (LPBITMAPCOREHEADER) lpDIB; 00162 00163 if(lpbmi->biSize == sizeof (BITMAPINFOHEADER)) 00164 return lpbmi->biHeight; 00165 else 00166 return (DWORD)lpbmc->bcHeight; 00167 } 00168 00169 00170 00171 DWORD DIBWidth (LPSTR lpDIB) 00172 { 00173 LPBITMAPINFOHEADER lpbmi; 00174 LPBITMAPCOREHEADER lpbmc; 00175 00176 lpbmi = (LPBITMAPINFOHEADER) lpDIB; 00177 lpbmc = (LPBITMAPCOREHEADER) lpDIB; 00178 00179 if (lpbmi->biSize == sizeof (BITMAPINFOHEADER)) 00180 return lpbmi->biWidth; 00181 else 00182 return (DWORD) lpbmc->bcWidth; 00183 } 00184 00185 00186 00187 00188 // Given a handle to memory with a DIB, create/realize a palette into 00189 // the given DC. Returns old palette in the DC (or NULL on error). 00190 00191 HPALETTE RealizeDIBPalette(HDC hDC, HANDLE hDIB) 00192 { 00193 HPALETTE hPal, hOldPal = NULL; 00194 00195 if(hDIB && hDC) 00196 { 00197 if(hPal = CreateDIBPalette(hDIB)) 00198 { 00199 hOldPal = SelectPalette(hDC, hPal, FALSE); 00200 if(hOldPal) 00201 RealizePalette(hDC); 00202 else 00203 DeleteObject(hPal); 00204 } 00205 } 00206 return hOldPal; 00207 } 00208 00209 void PaintDIBInBands(HDC hDC, 00210 HANDLE hDIB, 00211 int nDIBWidth, 00212 int nDIBHeight, 00213 int nBandHeight) 00214 { 00215 int y; 00216 00217 for (y = 0; y < nDIBHeight; y += nBandHeight) 00218 // if (gnZoomFactor == 1) 00219 DIBBlt (hDC, 00220 0, y, 00221 nDIBWidth, nBandHeight, 00222 hDIB, 00223 0, y, 00224 SRCCOPY); 00225 /* 00226 else 00227 StretchDIBBlt(hDC, 00228 0, y * gnZoomFactor, 00229 nDIBWidth * gnZoomFactor, nBandHeight * gnZoomFactor, 00230 hDIB, 00231 0, y, 00232 nDIBWidth, nBandHeight, 00233 SRCCOPY); 00234 */ 00235 } 00236 00240 #pragma argsused 00241 BOOL DIBBlt(HDC hDC, 00242 int xDst, 00243 int yDst, 00244 int nWidth, 00245 int nHeight, 00246 HANDLE hDIB, 00247 int xSrc, 00248 int ySrc, 00249 DWORD dwROP) 00250 { 00251 LPSTR lpDIBHdr, lpDIBBits; 00252 BOOL bSuccess = TRUE; 00253 int nDIBWidth, nDIBHeight; 00254 00255 00256 // Make sure we've got proper handles. 00257 if (!hDIB || !hDC) 00258 return FALSE; 00259 00260 // Lock down the DIB, and get a pointer to the beginning of the bit 00261 // buffer. Then get the DIB's height/width. Translate 00262 // the passed in y coordinate into the DIB coord system. 00263 lpDIBHdr = (char *)GlobalLock(hDIB); 00264 lpDIBBits = FindDIBBits (lpDIBHdr); 00265 nDIBWidth = (int) DIBWidth (lpDIBHdr); 00266 nDIBHeight = (int) DIBHeight (lpDIBHdr); 00267 ySrc = (int) nDIBHeight - ySrc - nHeight; 00268 00269 00270 // Insure the x/y/widht/height are valid. Adjust if not, or abort 00271 // if no painting necessary. 00272 00273 if (xSrc > nDIBWidth) 00274 bSuccess = FALSE; 00275 else if (xSrc < 0) 00276 { 00277 nWidth += xSrc; 00278 xSrc = 0; 00279 } 00280 00281 if (ySrc > nDIBHeight) 00282 bSuccess = FALSE; 00283 else if (ySrc < 0) 00284 { 00285 nHeight -= ySrc; 00286 ySrc = 0; 00287 } 00288 00289 00290 // Do the SetDIBitsToDevice(). 00291 00292 if (bSuccess) 00293 bSuccess = SetDIBitsToDevice (hDC, // hDC 00294 xDst, // DestX 00295 yDst, // DestY 00296 nWidth, // nDestWidth 00297 nHeight, // nDestHeight 00298 xSrc, // SrcX 00299 ySrc, // SrcY 00300 0, // nStartScan 00301 nDIBHeight, // nNumScans 00302 lpDIBBits, // lpBits 00303 (LPBITMAPINFO) lpDIBHdr, // lpBitsInfo 00304 DIB_RGB_COLORS) != 0; // wUsage 00305 00306 00307 // Clean up and get outta here. 00308 GlobalUnlock (hDIB); 00309 00310 return bSuccess; 00311 } 00312 00313 HBITMAP DIBToDDB (HANDLE hDIB, HPALETTE hPal) 00314 { 00315 LPSTR lpDIBHdr, lpDIBBits; 00316 HBITMAP hBitmap; 00317 HDC hDC; 00318 HPALETTE hOldPal = NULL; 00319 00320 if (!hDIB) 00321 return NULL; 00322 00323 lpDIBHdr = (char *)GlobalLock (hDIB); 00324 lpDIBBits = FindDIBBits (lpDIBHdr); 00325 hDC = GetDC (NULL); 00326 00327 if (!hDC) 00328 { 00329 GlobalUnlock (hDIB); 00330 return NULL; 00331 } 00332 00333 if (hPal) 00334 hOldPal = SelectPalette (hDC, hPal, FALSE); 00335 00336 RealizePalette (hDC); 00337 00338 hBitmap = CreateDIBitmap (hDC, 00339 (LPBITMAPINFOHEADER) lpDIBHdr, 00340 CBM_INIT, 00341 lpDIBBits, 00342 (LPBITMAPINFO) lpDIBHdr, 00343 DIB_RGB_COLORS); 00344 00345 if (!hBitmap) 00346 MessageBox (NULL, "CreateDIBitmap() failed!", NULL, MB_OK); 00347 00348 if (hOldPal) 00349 SelectPalette (hDC, hOldPal, FALSE); 00350 00351 ReleaseDC (NULL, hDC); 00352 GlobalUnlock (hDIB); 00353 00354 return hBitmap; 00355 } 00356 00357 BOOL AddDIBToListBox(HWND hList, LPSTR myStr, DIB * pBmp) 00358 { 00359 LRESULT dwIndex; 00360 00361 if(pBmp) 00362 { 00363 dwIndex = SendMessage(hList, LB_ADDSTRING, 0, (LONG)myStr); 00364 if((dwIndex != LB_ERR) && (dwIndex != LB_ERRSPACE)) 00365 if(SendMessage(hList, LB_SETITEMDATA, (WPARAM)dwIndex, (LONG)pBmp) != LB_ERR) 00366 return TRUE; 00367 } 00368 return FALSE; 00369 } 00370 00371 void RemoveListBoxDIBs(HWND hList) 00372 { 00373 DIB * pBmp; 00374 DWORD cnt = (DWORD)SendMessage(hList, LB_GETCOUNT, 0, 0); 00375 00376 for(int i = 0; i < cnt; i++) 00377 { 00378 pBmp = (DIB *)SendMessage(hList, LB_GETITEMDATA, i, 0L); 00379 if(pBmp) 00380 delete pBmp; 00381 } 00382 } 00383 00384