669 lines
17 KiB
C
669 lines
17 KiB
C
/*
|
|
- B I T M A P . C
|
|
-
|
|
* Purpose:
|
|
* Bitmap and Listbox support functions for InBox in sample mail client.
|
|
*
|
|
* Copyright 1993-1995 Microsoft Corporation. All Rights Reserved.
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <windows.h>
|
|
#include <windowsx.h>
|
|
#ifdef _WIN32
|
|
#include <objerror.h>
|
|
#include <objbase.h>
|
|
#endif
|
|
#ifdef WIN16
|
|
#include <compobj.h>
|
|
#endif
|
|
#include <mapiwin.h>
|
|
#include <mapidbg.h>
|
|
#include <mapi.h>
|
|
#include <mapix.h>
|
|
#include "bitmap.h"
|
|
#include "client.h"
|
|
|
|
// Fonts to use in dialogs
|
|
|
|
#ifdef _WIN32
|
|
#define SHELL_FONT "MS Shell Dlg"
|
|
#define SHELL_FONT_SIZE 8
|
|
#else
|
|
#define SHELL_FONT "MS Sans Serif"
|
|
#define SHELL_FONT_SIZE 8
|
|
#endif
|
|
|
|
/*
|
|
* globals
|
|
*/
|
|
|
|
DWORD rgbWindowColor = 0xFF000000; // variables for the current
|
|
DWORD rgbHiliteColor = 0xFF000000; // system color settings.
|
|
DWORD rgbWindowText = 0xFF000000; // on a WM_SYSCOLORCHANGE
|
|
DWORD rgbHiliteText = 0xFF000000; // we check to see if we need
|
|
DWORD rgbGrayText = 0xFF000000; // to reload our bitmap.
|
|
DWORD rgbDDWindow = 0xFF000000; //
|
|
DWORD rgbDDHilite = 0xFF000000; // 0xFF000000 is an invalid RGB
|
|
|
|
// an array of integers containing the tab stops, in pixels. The tab
|
|
// stops must be sorted in ascending order; back tabs are not allowed.
|
|
|
|
int rgTabs[] = { 2, 28, 135, 292 };
|
|
int dxbmpLB, dybmpLB; // dx and dy of listbox bmps
|
|
|
|
HDC hdcMemory = 0; // hdc to hold listbox bitmaps (for speed)
|
|
HBITMAP hbmpOrigMemBmp = 0; // original null bitmap in hdcMemory
|
|
HBITMAP hbmpLB = 0; // cached listbox bitmaps
|
|
HFONT hfontLB = 0; // hfont of LB
|
|
HWND hwndLB = 0; // hwnd of LB
|
|
|
|
FONTSTYLE fontStyle = { SHELL_FONT_SIZE, FW_NORMAL, 0, TEXT(SHELL_FONT) };
|
|
|
|
extern HANDLE hInst;
|
|
|
|
|
|
/*
|
|
- DeInitBmps
|
|
-
|
|
* Purpose:
|
|
* cleans up LB hfonts, hdc, and hbmps
|
|
*/
|
|
|
|
VOID DeInitBmps(VOID)
|
|
{
|
|
DeleteBitmapLB();
|
|
if(hdcMemory)
|
|
{
|
|
DeleteDC(hdcMemory);
|
|
hdcMemory = 0;
|
|
}
|
|
|
|
if(hfontLB)
|
|
{
|
|
SetWindowFont(hwndLB, GetStockObject(SYSTEM_FONT), FALSE);
|
|
DeleteObject(hfontLB);
|
|
hfontLB = 0;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
- SetLBFont
|
|
-
|
|
* Purpose:
|
|
* creates a font from the global fontStyle
|
|
* sets global hfontLB to new font and WM_SETFONTs
|
|
* the hwndLB to the new font
|
|
*/
|
|
|
|
VOID SetLBFont(VOID)
|
|
{
|
|
LOGFONT lf;
|
|
|
|
lf.lfHeight = fontStyle.lfHeight;
|
|
lf.lfWidth = 0;
|
|
lf.lfEscapement = 0;
|
|
lf.lfOrientation = 0;
|
|
lf.lfWeight = fontStyle.lfWeight;
|
|
lf.lfItalic = fontStyle.lfItalic;
|
|
lf.lfUnderline = 0;
|
|
lf.lfStrikeOut = 0;
|
|
lf.lfCharSet = ANSI_CHARSET;
|
|
lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
|
|
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
|
|
lf.lfQuality = DEFAULT_QUALITY;
|
|
lf.lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS;
|
|
lstrcpy(lf.lfFaceName, fontStyle.lfFaceName);
|
|
|
|
hfontLB = CreateFontIndirect(&lf);
|
|
if(hfontLB)
|
|
SetWindowFont(hwndLB, hfontLB, FALSE);
|
|
}
|
|
|
|
|
|
/*
|
|
- InitBmps
|
|
-
|
|
* Purpose:
|
|
* inits listbox globals, creates listbox
|
|
*
|
|
* Arguments:
|
|
* HWND main hwnd of app (parent of LB)
|
|
*
|
|
* Returns:
|
|
* TRUE - success; FALSE - failed
|
|
*/
|
|
|
|
BOOL InitBmps(HWND hwnd, int idLB)
|
|
{
|
|
HDC hdcScreen;
|
|
HBITMAP hbmpTemp;
|
|
|
|
hdcScreen = GetDC(0);
|
|
if(!hdcScreen)
|
|
goto CantInit;
|
|
hdcMemory = CreateCompatibleDC(hdcScreen);
|
|
if(!hdcMemory)
|
|
goto ReleaseScreenDC;
|
|
|
|
hbmpTemp = CreateCompatibleBitmap(hdcMemory, 1, 1);
|
|
if(!hbmpTemp)
|
|
goto ReleaseMemDC;
|
|
hbmpOrigMemBmp = SelectObject(hdcMemory, hbmpTemp); // get hbmp of NULL
|
|
if(!hbmpOrigMemBmp) // bmp for hdcMemory
|
|
goto ReleaseMemDC; // for when we delete
|
|
SelectObject(hdcMemory, hbmpOrigMemBmp); // it later in life
|
|
DeleteObject(hbmpTemp);
|
|
ReleaseDC(0, hdcScreen);
|
|
|
|
SetRGBValues(); // set the global RGB values
|
|
LoadBitmapLB(); // load the bmps into hdcMemory
|
|
|
|
hwndLB = GetDlgItem(hwnd, idLB);
|
|
|
|
SetLBFont(); // set the font of our listbox
|
|
return TRUE;
|
|
|
|
/* Error recovery exits */
|
|
ReleaseMemDC:
|
|
DeleteDC(hdcMemory);
|
|
hdcMemory = 0;
|
|
|
|
ReleaseScreenDC:
|
|
ReleaseDC(0, hdcScreen);
|
|
|
|
CantInit:
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
- SetRGBValues
|
|
-
|
|
* Purpose:
|
|
* To set various system colors in static variables. Called at
|
|
* init time and when system colors change.
|
|
*/
|
|
|
|
VOID SetRGBValues(VOID)
|
|
{
|
|
rgbWindowColor = GetSysColor(COLOR_WINDOW);
|
|
rgbHiliteColor = GetSysColor(COLOR_HIGHLIGHT);
|
|
rgbWindowText = GetSysColor(COLOR_WINDOWTEXT);
|
|
rgbHiliteText = GetSysColor(COLOR_HIGHLIGHTTEXT);
|
|
rgbGrayText = GetSysColor(COLOR_GRAYTEXT);
|
|
}
|
|
|
|
|
|
/*
|
|
- MeasureItem
|
|
-
|
|
* Purpose:
|
|
* called from msg WM_MEASUREITEM: returns max dy of listbox items
|
|
*
|
|
* Arguments:
|
|
* HWND hwnd of main window
|
|
* pmis measureitemstruct from WM_MEASUREITEM call
|
|
*/
|
|
|
|
VOID MeasureItem(HANDLE hwnd, LPMEASUREITEMSTRUCT pmis)
|
|
{
|
|
HDC hDC = GetDC(hwnd);
|
|
HANDLE hFont = hfontLB;
|
|
TEXTMETRIC TM;
|
|
|
|
if(!hFont)
|
|
hFont = GetStockObject(SYSTEM_FONT);
|
|
hFont = SelectObject(hDC, hFont);
|
|
GetTextMetrics(hDC, &TM);
|
|
SelectObject(hDC, hFont);
|
|
ReleaseDC(hwnd, hDC);
|
|
|
|
// set the height to be max of (dyfont or dybitmap)
|
|
pmis->itemHeight = max(dybmpLB, TM.tmHeight);
|
|
}
|
|
|
|
|
|
/*
|
|
- OutTextFormat
|
|
-
|
|
* Purpose:
|
|
* to parse the string in the listbox and draw it accordingly:
|
|
* first char == chBOLD: line is bold
|
|
* first char == chUNDERLINE: line is underlined (can follow chBOLD)
|
|
* char == chTAB: go to next column in rgTabs
|
|
* '/001#': bitblt that numbered bitmap.
|
|
* otherwise, outtext the line
|
|
*
|
|
* Arguments:
|
|
* pDI from DrawItem from WM_DRAWITEM msg
|
|
*/
|
|
|
|
VOID OutTextFormat(LPDRAWITEMSTRUCT pDI)
|
|
{
|
|
TCHAR szDateRec[32];
|
|
TCHAR szItem[256];
|
|
TCHAR szTemp[4];
|
|
TCHAR szDots[4] = {"..."};
|
|
TCHAR *pch;
|
|
INT nT;
|
|
INT nTab = 0; // current tab we is on
|
|
INT nBmp; // index of envelope bitmap
|
|
HFONT hfDef = 0;
|
|
HFONT hfOld = 0; // bold or underlined font
|
|
TCHAR *pchBuff = NULL;
|
|
LPMSGID lpMsgId = (LPMSGID)pDI->itemData;
|
|
|
|
pch = szItem;
|
|
|
|
// Format a string from the info in lpMsgNode
|
|
// First, calculate the index to the desired bitmap
|
|
|
|
nBmp = ((!lpMsgId->fUnRead) * 2) + ((!!lpMsgId->fHasAttach) * 1 );
|
|
|
|
// Convert our received date and build string
|
|
|
|
ConvertDateRec (lpMsgId->lpszDateRec, szDateRec);
|
|
|
|
// Limit our subject size
|
|
|
|
szTemp[0] = '\0';
|
|
|
|
if(lpMsgId->lpszSubject && (lstrlen(lpMsgId->lpszSubject) > 32))
|
|
{
|
|
memcpy(szTemp, &lpMsgId->lpszSubject[28], 4);
|
|
memcpy(&lpMsgId->lpszSubject[28], szDots, 4);
|
|
}
|
|
|
|
wsprintf(szItem, "\001%d\t%s\t%s\t%s", nBmp,
|
|
(lpMsgId->lpszFrom ? lpMsgId->lpszFrom : ""),
|
|
(lpMsgId->lpszSubject ? lpMsgId->lpszSubject : ""),
|
|
szDateRec);
|
|
|
|
// erase background
|
|
ExtTextOut(pDI->hDC, 0, 0, ETO_OPAQUE, &pDI->rcItem, NULL, 0, NULL);
|
|
|
|
// underline or bold this line? Only check first & second char
|
|
if(*pch == chBOLD || *pch == chUNDERLINE)
|
|
{
|
|
LOGFONT lf;
|
|
|
|
hfOld = GetWindowFont(pDI->hwndItem);
|
|
if(!hfOld)
|
|
hfOld = GetStockObject(SYSTEM_FONT);
|
|
GetObject(hfOld, sizeof(lf), &lf);
|
|
|
|
if(*pch == chBOLD)
|
|
{
|
|
lf.lfWeight = FW_BOLD;
|
|
pch++;
|
|
}
|
|
if(*pch == chUNDERLINE)
|
|
{
|
|
lf.lfUnderline = TRUE;
|
|
pch++;
|
|
}
|
|
|
|
hfDef = CreateFontIndirect(&lf);
|
|
if(hfDef)
|
|
SelectObject(pDI->hDC, hfDef);
|
|
}
|
|
|
|
// selected or nonselected bmps?
|
|
nT = (ODS_SELECTED & pDI->itemState) ? (BMWIDTH * NUMBMPS) : 0;
|
|
|
|
// parse the string
|
|
for(; *pch; pch++)
|
|
{
|
|
TCHAR *pchT;
|
|
RECT rc;
|
|
|
|
if(*pch == chBITMAP) // do we have a bitmap?
|
|
{
|
|
++pch;
|
|
// draw the bitmap
|
|
BitBlt(pDI->hDC, pDI->rcItem.left + rgTabs[nTab],
|
|
pDI->rcItem.top, BMWIDTH, BMHEIGHT, hdcMemory,
|
|
nT + (int)(*pch - TEXT('0')) * BMWIDTH, 0, SRCCOPY);
|
|
continue;
|
|
}
|
|
|
|
if(*pch == chTAB) // move to next tabstop?
|
|
{
|
|
nTab++;
|
|
continue;
|
|
}
|
|
|
|
pchT = pch; // find end of the column of text
|
|
while(*pchT && (*pchT != chTAB))
|
|
pchT++;
|
|
|
|
// set rect to drawtext in
|
|
SetRect(&rc, pDI->rcItem.left + rgTabs[nTab], pDI->rcItem.top,
|
|
pDI->rcItem.right, pDI->rcItem.bottom);
|
|
|
|
// draw the text
|
|
ExtTextOut(pDI->hDC, rc.left, rc.top + 1, ETO_OPAQUE | ETO_CLIPPED,
|
|
&rc, pch, pchT - pch, NULL);
|
|
pch = pchT - 1; // move to end of this column
|
|
}
|
|
|
|
if(hfDef) // delete underline or bold font if we created it
|
|
{
|
|
SelectObject(pDI->hDC, hfOld);
|
|
DeleteObject(hfDef);
|
|
}
|
|
|
|
if(szTemp[0] != '\0')
|
|
{
|
|
memcpy(&lpMsgId->lpszSubject[28], szTemp, 4);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
- DrawItem
|
|
-
|
|
* Purpose:
|
|
* Handles WM_DRAWITEM for both drive and directory listboxes.
|
|
*
|
|
* Parameters:
|
|
* pDI LPDRAWITEMSTRUCT passed from the WM_DRAWITEM message.
|
|
*/
|
|
|
|
VOID DrawItem(LPDRAWITEMSTRUCT pDI)
|
|
{
|
|
COLORREF crText, crBack;
|
|
|
|
if((int)pDI->itemID < 0)
|
|
return;
|
|
|
|
if((ODA_DRAWENTIRE | ODA_SELECT) & pDI->itemAction)
|
|
{
|
|
if(pDI->itemState & ODS_SELECTED)
|
|
{
|
|
// Select the appropriate text colors
|
|
crText = SetTextColor(pDI->hDC, rgbHiliteText);
|
|
crBack = SetBkColor(pDI->hDC, rgbHiliteColor);
|
|
}
|
|
|
|
// parse and spit out bmps and text
|
|
OutTextFormat(pDI);
|
|
|
|
// Restore original colors if we changed them above.
|
|
if(pDI->itemState & ODS_SELECTED)
|
|
{
|
|
SetTextColor(pDI->hDC, crText);
|
|
SetBkColor(pDI->hDC, crBack);
|
|
}
|
|
}
|
|
|
|
if((ODA_FOCUS & pDI->itemAction) || (ODS_FOCUS & pDI->itemState))
|
|
DrawFocusRect(pDI->hDC, &pDI->rcItem);
|
|
}
|
|
|
|
|
|
/*
|
|
- ConvertDateRec
|
|
-
|
|
* Purpose:
|
|
* To convert the lpszDateReceived field of a message to a
|
|
* more paletable display format; namely: mm/dd/yy hh:mmAM.
|
|
*
|
|
* Parameters:
|
|
* lpszDateRec - Original format
|
|
* lpszDateDisplay - Display format
|
|
*/
|
|
|
|
VOID ConvertDateRec (LPSTR lpszDateRec, LPSTR lpszDateDisplay)
|
|
{
|
|
char szDateTmp[32];
|
|
LPSTR lpszYear;
|
|
LPSTR lpszMonth;
|
|
LPSTR lpszDay;
|
|
LPSTR lpszHour;
|
|
LPSTR lpszMinute;
|
|
int nHour;
|
|
static char szFoo[2][3] =
|
|
{"AM", "PM"};
|
|
|
|
*lpszDateDisplay = 0;
|
|
if (!lpszDateRec || !*lpszDateRec)
|
|
return;
|
|
|
|
lstrcpy(szDateTmp, lpszDateRec);
|
|
|
|
lpszYear = strtok (szDateTmp, "/ :");
|
|
lpszMonth = strtok (NULL, "/ :");
|
|
lpszDay = strtok (NULL, "/ :");
|
|
lpszHour = strtok (NULL, "/ :");
|
|
lpszMinute = strtok (NULL, "/ :");
|
|
|
|
if(lpszHour)
|
|
nHour = atoi (lpszHour);
|
|
else
|
|
nHour = 0;
|
|
|
|
if (nHour > 12)
|
|
wsprintf (lpszHour, "%d", nHour - 12);
|
|
|
|
wsprintf (lpszDateDisplay, "%s/%s/%s %s:%s%s", lpszMonth,
|
|
(lpszDay ? lpszDay : ""),
|
|
(lpszYear ? lpszYear : ""),
|
|
(lpszHour ? lpszHour : ""),
|
|
(lpszMinute ? lpszMinute : ""),
|
|
szFoo[(nHour > 11 ? 1 : 0)]);
|
|
}
|
|
|
|
|
|
/*
|
|
* RgbInvertRgb
|
|
*
|
|
* Purpose:
|
|
* To reverse the byte order of the RGB value (for file format
|
|
*
|
|
* Arguments:
|
|
*
|
|
* Returns:
|
|
* New color value (RGB to BGR)
|
|
*/
|
|
|
|
#define RgbInvertRgb(_rgbOld) \
|
|
(DWORD)RGB(GetBValue(_rgbOld), GetGValue(_rgbOld), GetRValue(_rgbOld))
|
|
|
|
|
|
/*
|
|
* LoadAlterBitmap (mostly stolen from commdlg)
|
|
*
|
|
* Purpose:
|
|
* Loads the IDB_ENVELOPE bitmap and gives all the pixels that are
|
|
* RGBREPLACE a new color.
|
|
*
|
|
* Assumption:
|
|
* This function will work on one bitmap during it's lifetime.
|
|
* (Due to the fact that it finds RGBREPLACE once and then
|
|
* operates on that offset whenever called again because under NT,
|
|
* it appears that the bitmap is cached, so the second time you go
|
|
* looking for RGBREPLACE, it won't be found.) You could load the
|
|
* resource, copy it, then modify the copy as a workaround. But I
|
|
* chose the cheap way out as I will only ever modify one bmp.
|
|
*
|
|
* Arguments:
|
|
* rgbInstead rgb value to replace defined RGBREPLACE with
|
|
*
|
|
* Returns:
|
|
* NULL - failed or hbmp of new modified bitmap
|
|
*/
|
|
|
|
HBITMAP LoadAlterBitmap(DWORD rgbInstead)
|
|
{
|
|
HANDLE hbmp = 0;
|
|
LPBITMAPINFOHEADER qbihInfo;
|
|
HDC hdcScreen;
|
|
HRSRC hresLoad;
|
|
HGLOBAL hres;
|
|
LPBYTE qbBits;
|
|
DWORD rgbReplace = 0;
|
|
DWORD *rgdw = NULL;
|
|
DWORD *lpdw = NULL;
|
|
ULONG cb = 0;
|
|
|
|
if (rgbInstead)
|
|
rgbReplace = RGBREPLACE;
|
|
|
|
// load our listbox bmps resource
|
|
hresLoad = FindResource(hInst, MAKEINTRESOURCE(IDB_ENVELOPE), RT_BITMAP);
|
|
if(hresLoad == 0)
|
|
return 0;
|
|
hres = LoadResource(hInst, hresLoad);
|
|
if(hres == 0)
|
|
return 0;
|
|
|
|
rgbReplace = RgbInvertRgb(rgbReplace);
|
|
rgbInstead = RgbInvertRgb(rgbInstead);
|
|
qbihInfo = (LPBITMAPINFOHEADER)LockResource(hres);
|
|
|
|
// Skip over the header structure
|
|
qbBits = (LPBYTE)(qbihInfo + 1);
|
|
|
|
// Skip the color table entries, if any
|
|
qbBits += (1 << (qbihInfo->biBitCount)) * sizeof(RGBQUAD);
|
|
|
|
// Copy the resource into writable memory so we can
|
|
// munge the color table to set our background color
|
|
cb = (ULONG)(qbBits - (LPBYTE)qbihInfo) + qbihInfo->biSizeImage;
|
|
rgdw = (DWORD *)GlobalAllocPtr(GMEM_MOVEABLE, cb);
|
|
|
|
CopyMemory((LPVOID)rgdw, (LPVOID)qbihInfo, cb);
|
|
|
|
// find the color to replace in the color table
|
|
for(lpdw = (DWORD *)((LPBYTE)rgdw + qbihInfo->biSize); ; lpdw++)
|
|
{
|
|
if(*lpdw == rgbReplace)
|
|
break;
|
|
}
|
|
|
|
// replace that color value with our new one
|
|
*lpdw = (DWORD)rgbInstead;
|
|
|
|
// Create a color bitmap compatible with the display device
|
|
hdcScreen = GetDC(0);
|
|
if(hdcScreen != 0)
|
|
{
|
|
hbmp = CreateDIBitmap(hdcScreen, (LPBITMAPINFOHEADER)rgdw,
|
|
(LONG)CBM_INIT, qbBits, (LPBITMAPINFO) rgdw, DIB_RGB_COLORS);
|
|
ReleaseDC(0, hdcScreen);
|
|
}
|
|
|
|
UnlockResource(hres);
|
|
FreeResource(hres);
|
|
|
|
GlobalFreePtr(rgdw);
|
|
|
|
return hbmp;
|
|
}
|
|
|
|
|
|
/*
|
|
* DeleteBitmapLB
|
|
*
|
|
* Purpose:
|
|
* Get rid of hbmpLB, if it exists
|
|
*/
|
|
|
|
VOID DeleteBitmapLB(VOID)
|
|
{
|
|
if(hbmpOrigMemBmp)
|
|
{
|
|
SelectObject(hdcMemory, hbmpOrigMemBmp);
|
|
if(hbmpLB != 0)
|
|
{
|
|
DeleteObject(hbmpLB);
|
|
hbmpLB = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* LoadBitmapLB (mostly stolen from commdlg)
|
|
*
|
|
* Purpose:
|
|
* Creates the listbox bitmap. If an appropriate bitmap
|
|
* already exists, it just returns immediately. Otherwise, it
|
|
* loads the bitmap and creates a larger bitmap with both regular
|
|
* and highlight colors.
|
|
*
|
|
* Returns:
|
|
* TRUE - success; FALSE - failure
|
|
*/
|
|
|
|
BOOL LoadBitmapLB(VOID)
|
|
{
|
|
BITMAP bmp;
|
|
HANDLE hbmp, hbmpOrig;
|
|
HDC hdcTemp;
|
|
BOOL bWorked = FALSE;
|
|
|
|
// check for existing bitmap and validity
|
|
if( (hbmpLB != 0) &&
|
|
(rgbWindowColor == rgbDDWindow) &&
|
|
(rgbHiliteColor == rgbDDHilite))
|
|
{
|
|
if(SelectObject(hdcMemory, hbmpLB))
|
|
return TRUE;
|
|
}
|
|
|
|
DeleteBitmapLB();
|
|
|
|
rgbDDWindow = rgbWindowColor;
|
|
rgbDDHilite = rgbHiliteColor;
|
|
|
|
if(!(hdcTemp = CreateCompatibleDC(hdcMemory)))
|
|
goto LoadExit;
|
|
|
|
if(!(hbmp = LoadAlterBitmap(rgbWindowColor)))
|
|
goto DeleteTempDC;
|
|
|
|
GetObject(hbmp, sizeof(BITMAP), (LPBYTE) &bmp);
|
|
dybmpLB = bmp.bmHeight;
|
|
dxbmpLB = bmp.bmWidth;
|
|
|
|
hbmpOrig = SelectObject(hdcTemp, hbmp);
|
|
|
|
hbmpLB = CreateDiscardableBitmap(hdcTemp, dxbmpLB*2, dybmpLB);
|
|
if(!hbmpLB)
|
|
goto DeleteTempBmp;
|
|
|
|
if(!SelectObject(hdcMemory, hbmpLB))
|
|
{
|
|
DeleteBitmapLB();
|
|
goto DeleteTempBmp;
|
|
}
|
|
|
|
BitBlt(hdcMemory, 0, 0, dxbmpLB, dybmpLB, // copy unhighlited bmps
|
|
hdcTemp, 0, 0, SRCCOPY); // into hdcMemory
|
|
SelectObject(hdcTemp, hbmpOrig);
|
|
|
|
DeleteObject(hbmp);
|
|
|
|
if(!(hbmp = LoadAlterBitmap(rgbHiliteColor)))
|
|
goto DeleteTempDC;
|
|
|
|
hbmpOrig = SelectObject(hdcTemp, hbmp);
|
|
BitBlt(hdcMemory, dxbmpLB, 0, dxbmpLB, dybmpLB, // copy highlited bmps
|
|
hdcTemp, 0, 0, SRCCOPY); // into hdcMemory
|
|
SelectObject(hdcTemp, hbmpOrig);
|
|
|
|
bWorked = TRUE;
|
|
|
|
DeleteTempBmp:
|
|
DeleteObject(hbmp);
|
|
DeleteTempDC:
|
|
DeleteDC(hdcTemp);
|
|
LoadExit:
|
|
return bWorked;
|
|
}
|