///////////////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 1998 Active Voice Corporation. All Rights Reserved. // // Active Agent(r) and Unified Communications(tm) are trademarks of Active Voice Corporation. // // Other brand and product names used herein are trademarks of their respective owners. // // The entire program and user interface including the structure, sequence, selection, // and arrangement of the dialog, the exclusively "yes" and "no" choices represented // by "1" and "2," and each dialog message are protected by copyrights registered in // the United States and by international treaties. // // Protected by one or more of the following United States patents: 5,070,526, 5,488,650, // 5,434,906, 5,581,604, 5,533,102, 5,568,540, 5,625,676, 5,651,054. // // Active Voice Corporation // Seattle, Washington // USA // ///////////////////////////////////////////////////////////////////////////////////////// //// // gfx.c - Windows graphics functions //// #include "winlocal.h" #include #include "gfx.h" #include "mem.h" #include "str.h" #include "trace.h" //// // public functions //// //// // bitmap routines //// // GfxBitmapBackfill - replace bitmap's white backg with curr backg color // (i/o) bitmap handle // (i) current background color // (i) option flags // 0 use default method // BF_EXTFLOODFILL use ExtFloodFill function // BF_GETSETPIXEL use GetPixel/SetPixel functions // NOTE: rarely, ExtFloodFill will GP the display device driver // return 0 if success // int DLLEXPORT WINAPI GfxBitmapBackfill(HBITMAP hBitmap, COLORREF crBkColor, WORD wFlags) { BOOL fSuccess = TRUE; BOOL fExtFloodFill = (BOOL) !(wFlags & BF_GETSETPIXEL); BITMAP Bitmap; HDC hdc = NULL; HDC hdcMem = NULL; HBITMAP hBitmapOld = NULL; HBRUSH hbr = NULL; HBRUSH hbrOld = NULL; COLORREF crMaskColor = RGB(255, 255, 255); // RGB_WHITE // need not continue if COLOR_WINDOW is white // if (crMaskColor == crBkColor) return 0; if (hBitmap == NULL) fSuccess = TraceFALSE(NULL); // get width and height of bitmap // else if (GetObject((HGDIOBJ) hBitmap, sizeof(BITMAP), &Bitmap) == 0) fSuccess = TraceFALSE(NULL); // get device context for screen // else if ((hdc = GetDC(NULL)) == NULL) fSuccess = TraceFALSE(NULL); // create a memory device context // else if ((hdcMem = CreateCompatibleDC(hdc)) == NULL) fSuccess = TraceFALSE(NULL); // select the bitmap into the memory device context // else if ((hBitmapOld = SelectObject(hdcMem, hBitmap)) == NULL) fSuccess = TraceFALSE(NULL); // create a brush with specified background color // else if ((hbr = CreateSolidBrush(crBkColor)) == NULL) fSuccess = TraceFALSE(NULL); // select the brush into the memory device context // else if ((hbrOld = SelectObject(hdcMem, hbr)) == NULL) fSuccess = TraceFALSE(NULL); else { int cx = Bitmap.bmWidth; int cy = Bitmap.bmHeight; if (fExtFloodFill) { ExtFloodFill(hdcMem, 0, 0, crMaskColor, FLOODFILLSURFACE); ExtFloodFill(hdcMem, cx - 1, 0, crMaskColor, FLOODFILLSURFACE); ExtFloodFill(hdcMem, 0, cy - 1, crMaskColor, FLOODFILLSURFACE); ExtFloodFill(hdcMem, cx - 1, cy - 1, crMaskColor, FLOODFILLSURFACE); } else { int x; int y; for (x = 0; x < cx; ++x) for (y = 0; y < cy; ++y) if (GetPixel(hdcMem, x, y) == crMaskColor) SetPixel(hdcMem, x, y, crBkColor); } } // restore old brush, if any // if (hbrOld != NULL) SelectObject(hdcMem, hbrOld); // delete new brush // if (hbr != NULL && !DeleteObject(hbr)) fSuccess = TraceFALSE(NULL); // restore old bitmap, if any // if (hBitmapOld != NULL) SelectObject(hdcMem, hBitmapOld); // free the memory device context // if (hdcMem != NULL && !DeleteDC(hdcMem)) fSuccess = TraceFALSE(NULL); // release the common device context // if (hdc != NULL && !ReleaseDC(NULL, hdc)) fSuccess = TraceFALSE(NULL); return fSuccess ? 0 : -1; } // GfxBitmapDisplay - display specified bitmap // (i) device context for destination window // (i) bitmap handle for source bitmap // (i) x coordinate for destination window // (i) y coordinate for destination window // (i) display bitmap inverted // return 0 if success // int DLLEXPORT WINAPI GfxBitmapDisplay(HDC hdc, HBITMAP hBitmap, int x, int y, BOOL fInvert) { BOOL fSuccess = TRUE; HDC hdcMem = NULL; HBITMAP hBitmapOld = NULL; BITMAP Bitmap; if (hdc == NULL) fSuccess = TraceFALSE(NULL); else if (hBitmap == NULL) fSuccess = TraceFALSE(NULL); // get width and height of bitmap // else if (GetObject((HGDIOBJ) hBitmap, sizeof(BITMAP), &Bitmap) == 0) fSuccess = TraceFALSE(NULL); // create a memory device context // else if ((hdcMem = CreateCompatibleDC(hdc)) == NULL) fSuccess = TraceFALSE(NULL); // select the bitmap into the memory device context // else if ((hBitmapOld = SelectObject(hdcMem, hBitmap)) == NULL) fSuccess = TraceFALSE(NULL); // copy the bitmap from hdcMem to hdc, inverted if necessary // else if (!BitBlt(hdc, x, y, Bitmap.bmWidth, Bitmap.bmHeight, hdcMem, 0, 0, fInvert ? NOTSRCCOPY : SRCCOPY)) fSuccess = TraceFALSE(NULL); // restore old bitmap, if any // if (hBitmapOld != NULL) SelectObject(hdcMem, hBitmapOld); // free the memory device context // if (hdcMem != NULL) DeleteDC(hdcMem); return fSuccess ? 0 : -1; } // GfxBitmapDrawTransparent - draw specified bitmap // (i) device context for destination window // (i) bitmap handle for source bitmap // (i) x coordinate for destination window // (i) y coordinate for destination window // (i) transparent color // (i) control flags // 0 reserved; must be zero // return 0 if success // #if 1 int DLLEXPORT WINAPI GfxBitmapDrawTransparent(HDC hdc, HBITMAP hBitmap, int x, int y, COLORREF crTransparent, DWORD dwFlags) { BOOL fSuccess = TRUE; BITMAP bmp; int cx; int cy; HBITMAP hbmpMask = NULL; HDC hdcMem = NULL; HDC hdcMem2 = NULL; HBITMAP hbmpOld; HBITMAP hbmpOld2; COLORREF crBkOld; COLORREF crTextOld; if (GetObject(hBitmap, sizeof(BITMAP), (LPVOID) &bmp) == 0) fSuccess = TraceFALSE(NULL); else if (cx = bmp.bmWidth, cy = bmp.bmHeight, FALSE) ; else if ((hbmpMask = CreateBitmap(cx, cy, 1, 1, NULL)) == NULL) fSuccess = TraceFALSE(NULL); else if ((hdcMem = CreateCompatibleDC(hdc)) == NULL) fSuccess = TraceFALSE(NULL); else if ((hdcMem2 = CreateCompatibleDC(hdc)) == NULL) fSuccess = TraceFALSE(NULL); else if ((hbmpOld = SelectObject(hdcMem, hBitmap)), FALSE) ; else if ((hbmpOld2 = SelectObject(hdcMem2, hbmpMask)), FALSE) ; else if (SetBkColor(hdcMem, crTransparent), FALSE) ; else if (!BitBlt(hdcMem2, 0, 0, cx, cy, hdcMem, 0, 0, SRCCOPY)) fSuccess = TraceFALSE(NULL); else if ((crBkOld = SetBkColor(hdc, RGB(255, 255, 255))) == CLR_INVALID) fSuccess = TraceFALSE(NULL); else if ((crTextOld = SetTextColor(hdc, RGB(0, 0, 0))) == CLR_INVALID) fSuccess = TraceFALSE(NULL); else if (!BitBlt(hdc, x, y, cx, cy, hdcMem, 0, 0, SRCINVERT)) fSuccess = TraceFALSE(NULL); else if (!BitBlt(hdc, x, y, cx, cy, hdcMem2, 0, 0, SRCAND)) fSuccess = TraceFALSE(NULL); else if (!BitBlt(hdc, x, y, cx, cy, hdcMem, 0, 0, SRCINVERT)) fSuccess = TraceFALSE(NULL); else if (SetBkColor(hdc, crBkOld) == CLR_INVALID) fSuccess = TraceFALSE(NULL); else if (SetTextColor(hdc, crTextOld) == CLR_INVALID) fSuccess = TraceFALSE(NULL); else if (SelectObject(hdcMem, hbmpOld), FALSE) ; else if (SelectObject(hdcMem2, hbmpOld2), FALSE) ; if (hbmpMask != NULL && !DeleteObject(hbmpMask)) fSuccess = TraceFALSE(NULL); else hbmpMask = NULL; if (hdcMem != NULL && !DeleteDC(hdcMem)) fSuccess = TraceFALSE(NULL); else hdcMem = NULL; if (hdcMem2 != NULL && !DeleteDC(hdcMem2)) fSuccess = TraceFALSE(NULL); else hdcMem2 = NULL; return 0; } #else int DLLEXPORT WINAPI GfxBitmapDrawTransparent(HDC hdc, HBITMAP hBitmap, int x, int y, COLORREF crTransparent, DWORD dwFlags) { BOOL fSuccess = TRUE; BITMAP bmp; POINT ptSize; COLORREF cr; HBITMAP hbmpAndBack = NULL; HBITMAP hbmpAndObject = NULL; HBITMAP hbmpAndMem = NULL; HBITMAP hbmpSave = NULL; HBITMAP hbmpBackOld = NULL; HBITMAP hbmpObjectOld = NULL; HBITMAP hbmpMemOld = NULL; HBITMAP hbmpSaveOld = NULL; HDC hdcTemp = NULL; HDC hdcBack = NULL; HDC hdcObject = NULL; HDC hdcMem = NULL; HDC hdcSave = NULL; // Select the bitmap // if ((hdcTemp = CreateCompatibleDC(hdc)) == NULL) fSuccess = TraceFALSE(NULL); else if (SelectObject(hdcTemp, hBitmap), FALSE) ; // Get dimensions of bitmap // else if (GetObject(hBitmap, sizeof(BITMAP), (LPVOID) &bmp) == 0) fSuccess = TraceFALSE(NULL); else if (ptSize.x = bmp.bmWidth, ptSize.y = bmp.bmHeight, FALSE) ; // Convert from device to logical points // else if (!DPtoLP(hdcTemp, &ptSize, 1)) fSuccess = TraceFALSE(NULL); // Create some DCs to hold temporary data. // else if ((hdcBack = CreateCompatibleDC(hdc)) == NULL) fSuccess = TraceFALSE(NULL); else if ((hdcObject = CreateCompatibleDC(hdc)) == NULL) fSuccess = TraceFALSE(NULL); else if ((hdcMem = CreateCompatibleDC(hdc)) == NULL) fSuccess = TraceFALSE(NULL); else if ((hdcSave = CreateCompatibleDC(hdc)) == NULL) fSuccess = TraceFALSE(NULL); // Create a bitmap for each DC. DCs are required for a number of GDI functions. // else if ((hbmpAndBack = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL)) == NULL) fSuccess = TraceFALSE(NULL); else if ((hbmpAndObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL)) == NULL) fSuccess = TraceFALSE(NULL); else if ((hbmpAndMem = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y)) == NULL) fSuccess = TraceFALSE(NULL); else if ((hbmpSave = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y)) == NULL) fSuccess = TraceFALSE(NULL); // Each DC must select a bitmap object to store pixel data. // else if ((hbmpBackOld = SelectObject(hdcBack, hbmpAndBack)) == NULL) fSuccess = TraceFALSE(NULL); else if ((hbmpObjectOld = SelectObject(hdcObject, hbmpAndObject)) == NULL) fSuccess = TraceFALSE(NULL); else if ((hbmpMemOld = SelectObject(hdcMem, hbmpAndMem)) == NULL) fSuccess = TraceFALSE(NULL); else if ((hbmpSaveOld = SelectObject(hdcSave, hbmpSave)) == NULL) fSuccess = TraceFALSE(NULL); // Set proper mapping mode. // else if (SetMapMode(hdcTemp, GetMapMode(hdc)) == 0) fSuccess = TraceFALSE(NULL); // Save the bitmap sent here, because it will be overwritten. // else if (!BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY)) fSuccess = TraceFALSE(NULL); // Set the background color of the source DC to the color. // contained in the parts of the bitmap that should be transparent // else if ((cr = SetBkColor(hdcTemp, crTransparent)) == CLR_INVALID) fSuccess = TraceFALSE(NULL); // Create the object mask for the bitmap by performing a BitBlt // from the source bitmap to a monochrome bitmap. // else if (!BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY)) fSuccess = TraceFALSE(NULL); // Set the background color of the source DC back to original color. // else if (SetBkColor(hdcTemp, cr) == CLR_INVALID) fSuccess = TraceFALSE(NULL); // Create the inverse of the object mask. // else if (!BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, NOTSRCCOPY)) fSuccess = TraceFALSE(NULL); // Copy the background of the main DC to the destination. // else if (!BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdc, x, y, SRCCOPY)) fSuccess = TraceFALSE(NULL); // Mask out the places where the bitmap will be placed. // else if (!BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND)) fSuccess = TraceFALSE(NULL); // Mask out the transparent colored pixels on the bitmap. // else if (!BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND)) fSuccess = TraceFALSE(NULL); // XOR the bitmap with the background on the destination DC. // else if (!BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT)) fSuccess = TraceFALSE(NULL); // Copy the destination to the screen. // else if (!BitBlt(hdc, x, y, ptSize.x, ptSize.y, hdcMem, 0, 0, SRCCOPY)) fSuccess = TraceFALSE(NULL); // Place the original bitmap back into the bitmap sent here. // else if (!BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY)) fSuccess = TraceFALSE(NULL); // restore old bitmaps // if (hdcBack != NULL && hbmpBackOld != NULL && SelectObject(hdcBack, hbmpBackOld) == NULL) fSuccess = TraceFALSE(NULL); if (hdcObject != NULL && hbmpObjectOld != NULL && SelectObject(hdcObject, hbmpObjectOld) == NULL) fSuccess = TraceFALSE(NULL); if (hdcMem != NULL && hbmpMemOld != NULL && SelectObject(hdcMem, hbmpMemOld) == NULL) fSuccess = TraceFALSE(NULL); if (hdcSave != NULL && hbmpSaveOld != NULL && SelectObject(hdcSave, hbmpSaveOld) == NULL) fSuccess = TraceFALSE(NULL); // Delete the memory bitmaps. // if (hbmpAndBack != NULL && !DeleteObject(hbmpAndBack)) fSuccess = TraceFALSE(NULL); if (hbmpAndObject != NULL && !DeleteObject(hbmpAndObject)) fSuccess = TraceFALSE(NULL); if (hbmpAndMem != NULL && !DeleteObject(hbmpAndMem)) fSuccess = TraceFALSE(NULL); if (hbmpSave != NULL && !DeleteObject(hbmpSave)) fSuccess = TraceFALSE(NULL); // Delete the memory DCs. // if (hdcBack != NULL && !DeleteDC(hdcBack)) fSuccess = TraceFALSE(NULL); if (hdcObject != NULL && !DeleteDC(hdcObject)) fSuccess = TraceFALSE(NULL); if (hdcMem != NULL && !DeleteDC(hdcMem)) fSuccess = TraceFALSE(NULL); if (hdcSave != NULL && !DeleteDC(hdcSave)) fSuccess = TraceFALSE(NULL); if (hdcTemp != NULL && !DeleteDC(hdcTemp)) fSuccess = TraceFALSE(NULL); return fSuccess ? 0 : -1; } #endif // GfxBitmapScroll - scroll specified bitmap // (i) device context for destination window // (i) bitmap handle for source bitmap // (i) amt of horizontal scroll (cx < 0 scrolls left) // (i) amt of vertical scroll (cx < 0 scrolls up) // (i) control flags // BS_ROTATE rotate bitmap // return 0 if success // int DLLEXPORT WINAPI GfxBitmapScroll(HDC hdc, HBITMAP hBitmap, int dx, int dy, DWORD dwFlags) { BOOL fSuccess = TRUE; BITMAP bmp; POINT ptSize; HDC hdcMem = NULL; HDC hdcTemp = NULL; HBITMAP hbmpTemp = NULL; HBITMAP hbmpSave = NULL; int dxAbs; int dyAbs; // Get dimensions of bitmap // if (GetObject(hBitmap, sizeof(BITMAP), (LPVOID) &bmp) == 0) fSuccess = TraceFALSE(NULL); else if (ptSize.x = bmp.bmWidth, ptSize.y = bmp.bmHeight, FALSE) ; else if (dx = dx % ptSize.x, dy = dy % ptSize.y, FALSE) ; else if (dxAbs = abs(dx), dyAbs = abs(dy), FALSE) ; // prepare mem dc // else if ((hdcMem = CreateCompatibleDC(hdc)) == NULL) fSuccess = TraceFALSE(NULL); else if (!DPtoLP(hdcMem, &ptSize, 1)) fSuccess = TraceFALSE(NULL); else if (SelectObject(hdcMem, hBitmap), FALSE) ; // Set proper mapping mode. // else if (SetMapMode(hdcMem, GetMapMode(hdc)) == 0) fSuccess = TraceFALSE(NULL); // prepare temp copy // else if (dwFlags & BS_ROTATE) { if ((hdcTemp = CreateCompatibleDC(hdc)) == NULL) fSuccess = TraceFALSE(NULL); else if ((hbmpTemp = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y)) == NULL) fSuccess = TraceFALSE(NULL); else if ((hbmpSave = SelectObject(hdcTemp, hbmpTemp)), FALSE) ; else if (!BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcMem, 0, 0, SRCCOPY)) fSuccess = TraceFALSE(NULL); } // scroll (rotate if specified) // if (fSuccess && dx < 0) { if (!BitBlt(hdcMem, 0, 0, ptSize.x - dxAbs, ptSize.y, hdcMem, dxAbs, 0, SRCCOPY)) fSuccess = TraceFALSE(NULL); else if ((dwFlags & BS_ROTATE) && !BitBlt(hdcMem, ptSize.x - dxAbs, 0, dxAbs, ptSize.y, hdcTemp, 0, 0, SRCCOPY)) fSuccess = TraceFALSE(NULL); } if (fSuccess && dx > 0) { if (!BitBlt(hdcMem, dxAbs, 0, ptSize.x - dxAbs, ptSize.y, hdcMem, 0, 0, SRCCOPY)) fSuccess = TraceFALSE(NULL); else if ((dwFlags & BS_ROTATE) && !BitBlt(hdcMem, 0, 0, dxAbs, ptSize.y, hdcTemp, ptSize.x - dxAbs, 0, SRCCOPY)) fSuccess = TraceFALSE(NULL); } if (fSuccess && dy < 0) { if ((dwFlags & BS_ROTATE) && dx != 0 && !BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcMem, 0, 0, SRCCOPY)) fSuccess = TraceFALSE(NULL); else if (!BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y - dyAbs, hdcMem, 0, dyAbs, SRCCOPY)) fSuccess = TraceFALSE(NULL); else if ((dwFlags & BS_ROTATE) && !BitBlt(hdcMem, 0, ptSize.y - dyAbs, ptSize.x, dyAbs, hdcTemp, 0, 0, SRCCOPY)) fSuccess = TraceFALSE(NULL); } if (fSuccess && dy > 0) { if ((dwFlags & BS_ROTATE) && dx != 0 && !BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcMem, 0, 0, SRCCOPY)) fSuccess = TraceFALSE(NULL); else if (!BitBlt(hdcMem, 0, dyAbs, ptSize.x, ptSize.y - dyAbs, hdcMem, 0, 0, SRCCOPY)) fSuccess = TraceFALSE(NULL); else if ((dwFlags & BS_ROTATE) && !BitBlt(hdcMem, 0, 0, ptSize.x, dyAbs, hdcTemp, 0, ptSize.y - dyAbs, SRCCOPY)) fSuccess = TraceFALSE(NULL); } if (!fSuccess) ; // copy back to original bitmap // else if (!BitBlt(hdc, 0, 0, ptSize.x, ptSize.y, hdcMem, 0, 0, SRCCOPY)) fSuccess = TraceFALSE(NULL); // clean up // if (hdcTemp != NULL) SelectObject(hdcTemp, hbmpSave); if (hdcMem != NULL && !DeleteDC(hdcMem)) fSuccess = TraceFALSE(NULL); if (hbmpTemp != NULL && !DeleteObject(hbmpTemp)) fSuccess = TraceFALSE(NULL); if (hdcTemp != NULL && !DeleteDC(hdcTemp)) fSuccess = TraceFALSE(NULL); return fSuccess ? 0 : -1; } // GfxLoadBitmapEx - load specified bitmap resource, get palette // (i) handle of module to load resource from // NULL load pre-defined Windows bitmap // (i) name of bitmap resource // or MAKEINTRESOURCE(idBitmap) // or if hInstance is NULL // (o) palette is returned here // NULL do not return palette // return bitmap handle if success, otherwise NULL // NOTE: see documentation for LoadBitmap function // NOTE: call DeleteObject() to free returned bitmap and palette handles // HBITMAP DLLEXPORT WINAPI GfxLoadBitmapEx(HINSTANCE hInstance, LPCTSTR lpszBitmap, HPALETTE FAR *lphPalette) { BOOL fSuccess = TRUE; HRSRC hRsrc = NULL; HGLOBAL hGlobal = NULL; LPBITMAPINFOHEADER lpbi = NULL; HDC hdc = NULL; HPALETTE hPalette = NULL; HBITMAP hBitmap = NULL; int nColors; if ((hRsrc = FindResource(hInstance, lpszBitmap, RT_BITMAP)) == NULL) fSuccess = TraceFALSE(NULL); else if ((hGlobal = LoadResource(hInstance, hRsrc)) == NULL) fSuccess = TraceFALSE(NULL); else if ((lpbi = (LPBITMAPINFOHEADER) LockResource(hGlobal)) == NULL) fSuccess = TraceFALSE(NULL); else if ((hdc = GetDC(NULL)) == NULL) fSuccess = TraceFALSE(NULL); else if ((hPalette = CreateDIBPalette((LPBITMAPINFO)lpbi, &nColors)) == NULL) fSuccess = TraceFALSE(NULL); else if (SelectPalette(hdc, hPalette, FALSE), FALSE) ; else if (RealizePalette(hdc) == GDI_ERROR) fSuccess = TraceFALSE(NULL); else if ((hBitmap = CreateDIBitmap(hdc, (LPBITMAPINFOHEADER) lpbi, (LONG) CBM_INIT, (LPSTR)lpbi + lpbi->biSize + nColors * sizeof(RGBQUAD), (LPBITMAPINFO) lpbi, DIB_RGB_COLORS)) == NULL) { fSuccess = TraceFALSE(NULL); } // clean up // #ifndef _WIN32 if (hGlobal != NULL) { UnlockResource(hGlobal); FreeResource(hGlobal); } #endif if (hdc != NULL) ReleaseDC(NULL, hdc); if (!fSuccess || lphPalette == NULL) { if (hPalette != NULL && !DeleteObject(hPalette)) fSuccess = TraceFALSE(NULL); } // return palette handle here // if (fSuccess && lphPalette != NULL) *lphPalette = hPalette; // return bitmap handle here // return fSuccess ? hBitmap : NULL; } // GfxCreateDIBPalette - create palette // (i) ptr to BITMAPINFO struct, describes DIB // (o) number of colors is returned here // return new palette handle if success, otherwise NULL // HPALETTE DLLEXPORT WINAPI CreateDIBPalette (LPBITMAPINFO lpbmi, LPINT lpnColors) { BOOL fSuccess = TRUE; LPBITMAPINFOHEADER lpbi; LPLOGPALETTE lpPal = NULL; HPALETTE hPal = NULL; int nColors; if ((lpbi = (LPBITMAPINFOHEADER) lpbmi) == NULL) fSuccess = TraceFALSE(NULL); else { // calculate color table size // if (lpbi->biBitCount <= 8) nColors = (1 << lpbi->biBitCount); else nColors = 0; // No palette needed for 24 BPP DIB if (lpbi->biClrUsed > 0) nColors = lpbi->biClrUsed; // Use biClrUsed if (nColors <= 0) fSuccess = TraceFALSE(NULL); } if (fSuccess) { if ((lpPal = (LPLOGPALETTE) MemAlloc(NULL, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * nColors, 0)) == NULL) fSuccess = TraceFALSE(NULL); else { int i; // // We have to initalize the memory allocated with MemAlloc // memset( lpPal, 0, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * nColors); lpPal->palVersion = 0x300; lpPal->palNumEntries = (unsigned short) nColors; for (i = 0; i < nColors; i++) { lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed; lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen; lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue; lpPal->palPalEntry[i].peFlags = 0; } if ((hPal = CreatePalette(lpPal)) == NULL) fSuccess = TraceFALSE(NULL); if ((lpPal = MemFree(NULL, lpPal)) != NULL) { // // We should delete hPal resource // DeleteObject( hPal ); hPal = NULL; fSuccess = TraceFALSE(NULL); } } } // return number of colors here // if (fSuccess && lpnColors != NULL) *lpnColors = nColors; // return new palette here // return fSuccess ? hPal : NULL; } //// // text routines //// // GfxTextExtentTruncate - truncate string if too long // (i/o) string to truncate // (i) current device context // (i) maximum string width in logical units // return new length of string (0 if error) // int DLLEXPORT WINAPI GfxTextExtentTruncate(LPTSTR lpsz, HDC hdc, int cxMax) { BOOL fSuccess = TRUE; int cbString; if (hdc == NULL) fSuccess = TraceFALSE(NULL); else if (lpsz == NULL) fSuccess = TraceFALSE(NULL); else { // calculate how many chars in string will fit within cxMax // cbString = StrLen(lpsz); while (fSuccess && cbString > 0) { SIZE size; if (!GetTextExtentPoint(hdc, lpsz, cbString, &size)) fSuccess = TraceFALSE(NULL); else if (size.cx <= cxMax) break; else --cbString; } // truncate string so it fits // *(lpsz + cbString) = '\0'; } return fSuccess ? cbString : 0; } //// // cursor routines //// // GfxShowHourglass - show the hourglass cursor // (i) window to capture mouse input during hourglass // return old cursor (NULL if error or none) // HCURSOR DLLEXPORT WINAPI GfxShowHourglass(HWND hwnd) { BOOL fSuccess = TRUE; HCURSOR hCursorSave; HCURSOR hCursorHourglass; // get predefined hourglass cursor handle // if ((hCursorHourglass = LoadCursor(NULL, IDC_WAIT)) == NULL) fSuccess = TraceFALSE(NULL); else { // capture all mouse input to specified window // SetCapture(hwnd); // replace previous cursor with hourglass // hCursorSave = SetCursor(hCursorHourglass); } return fSuccess ? hCursorSave : NULL; } // GfxHideHourglass - hide the hourglass cursor // (i) cursor handle returned from GfxShowHourglass // NULL replace cursor with IDC_ARROW // return 0 if success // int DLLEXPORT WINAPI GfxHideHourglass(HCURSOR hCursorRestore) { BOOL fSuccess = TRUE; // get predefined arrow cursor handle if necessary // if (hCursorRestore == NULL) hCursorRestore = LoadCursor(NULL, IDC_ARROW); // replace hourglass with previous cursor // if (SetCursor(hCursorRestore) == NULL) fSuccess = TraceFALSE(NULL); // restore normal mouse input processing // ReleaseCapture(); return fSuccess ? 0 : -1; } // GfxDeviceIsMono - determine if device context is monochrome // (i) device context // NULL use screen device context // return TRUE if monochrome, FALSE if color // BOOL DLLEXPORT WINAPI GfxDeviceIsMono(HDC hdc) { BOOL fSuccess = TRUE; BOOL fMono; HDC hdcScreen = NULL; // get screen device context if none specified // if (hdc == NULL && (hdc = hdcScreen = GetDC(NULL)) == NULL) fSuccess = TraceFALSE(NULL); else { int nColors = GetDeviceCaps(hdc, NUMCOLORS); fMono = (BOOL) (nColors >= 0 && nColors <= 2); // release screen device context if necessary // if (hdcScreen != NULL && !ReleaseDC(NULL, hdcScreen)) fSuccess = TraceFALSE(NULL); } return fSuccess ? fMono : TRUE; }