|
|
//-----------------------------------------------------------------------------
// File: Cbitmap.cpp
//
// Desc: CBitmap class is an object that wraps around a Windows bitmap.
//
// Copyright (C) 1999-2000 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
#include "id3dsurf.h"
//@@BEGIN_MSINTERNAL
#ifdef DDKBUILD
//HMODULE g_MSImg32 = NULL;
//ALPHABLEND g_AlphaBlend = NULL;
#endif
//@@END_MSINTERNAL
BOOL DI_AlphaBlend( HDC hdcDest, // handle to destination DC
int nXOriginDest, // x-coord of upper-left corner
int nYOriginDest, // y-coord of upper-left corner
int nWidthDest, // destination width
int nHeightDest, // destination height
HDC hdcSrc, // handle to source DC
int nXOriginSrc, // x-coord of upper-left corner
int nYOriginSrc, // y-coord of upper-left corner
int nWidthSrc, // source width
int nHeightSrc // source height
) { LPBYTE pbDestBits = NULL; HBITMAP hTempDestDib = NULL; int nXOriginDestLogical = nXOriginDest, nYOriginDestLogical = nYOriginDest;
// Convert nXOriginDest and nYOriginDest from logical coord to device coord
POINT pt = {nXOriginDest, nYOriginDest}; LPtoDP(hdcDest, &pt, 1); nXOriginDest = pt.x; nYOriginDest = pt.y; // Convert nXOriginSrc and nYOriginSrc from logical coord to device coord
pt.x = nXOriginSrc; pt.y = nYOriginSrc; LPtoDP(hdcSrc, &pt, 1); nXOriginSrc = pt.x; nYOriginSrc = pt.y;
// Get the bits for both source and destination first
// Every BITMAP used in the UI is created with CreateDIBSection, so we know we can get the bits.
HBITMAP hSrcBmp, hDestBmp; DIBSECTION SrcDibSec, DestDibSec; hSrcBmp = (HBITMAP)GetCurrentObject(hdcSrc, OBJ_BITMAP); GetObject(hSrcBmp, sizeof(DIBSECTION), &SrcDibSec); hDestBmp = (HBITMAP)GetCurrentObject(hdcDest, OBJ_BITMAP); GetObject(hDestBmp, sizeof(DIBSECTION), &DestDibSec); if (!SrcDibSec.dsBm.bmBits) return FALSE; // Not necessary, but to be absolutely safe.
// Calculate the rectangle to perform the operation.
if (nXOriginSrc + nWidthSrc > SrcDibSec.dsBm.bmWidth) nWidthSrc = SrcDibSec.dsBm.bmWidth - nXOriginSrc; if (nYOriginSrc + nHeightSrc > SrcDibSec.dsBm.bmHeight) nHeightSrc = SrcDibSec.dsBm.bmHeight - nYOriginSrc; if (nXOriginDest + nWidthDest > DestDibSec.dsBm.bmWidth) nWidthDest = DestDibSec.dsBm.bmWidth - nXOriginDest; if (nYOriginDest + nHeightDest > DestDibSec.dsBm.bmHeight) nHeightDest = DestDibSec.dsBm.bmHeight - nYOriginDest;
if (nWidthDest > nWidthSrc) nWidthDest = nWidthSrc; if (nHeightDest > nHeightSrc) nHeightDest = nHeightSrc; if (nWidthSrc > nWidthDest) nWidthSrc = nWidthDest; if (nHeightSrc > nHeightDest) nHeightSrc = nHeightDest;
BITMAPINFO bmi; ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = nWidthDest; bmi.bmiHeader.biHeight = nHeightDest; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biCompression = BI_RGB;
// Bitmap will have the same width as the dest, but only lines covered in the subrect.
hTempDestDib = CreateDIBSection(hdcDest, &bmi, DIB_RGB_COLORS, (LPVOID*)&pbDestBits, NULL, NULL); if (!hTempDestDib) return FALSE;
HDC hTempDC = CreateCompatibleDC(hdcDest); if (!hTempDC) { DeleteObject(hTempDestDib); return FALSE; } HBITMAP hOldTempBmp = (HBITMAP)SelectObject(hTempDC, hTempDestDib); BOOL res = BitBlt(hTempDC, 0, 0, nWidthDest, nHeightDest, hdcDest, nXOriginDestLogical, nYOriginDestLogical, SRCCOPY); SelectObject(hTempDC, hOldTempBmp); DeleteDC(hTempDC); if (!res) { DeleteObject(hTempDestDib); return FALSE; }
// We have the bits. Now do the blend.
for (int j = 0; j < nHeightSrc; ++j) { assert(j >= 0 && j < nHeightDest); LPBYTE pbDestRGB = (LPBYTE)&((DWORD*)pbDestBits)[j * nWidthDest];
assert(nYOriginSrc+SrcDibSec.dsBm.bmHeight-nHeightSrc >= 0 && nYOriginSrc+SrcDibSec.dsBm.bmHeight-nHeightSrc < SrcDibSec.dsBm.bmHeight); LPBYTE pbSrcRGBA = (LPBYTE)&((DWORD*)SrcDibSec.dsBm.bmBits)[(j+nYOriginSrc+SrcDibSec.dsBm.bmHeight-nHeightSrc) * SrcDibSec.dsBm.bmWidth + nXOriginSrc];
for (int i = 0; i < nWidthSrc; ++i) { // Blend
if (pbSrcRGBA[3] == 255) { // Alpha is 255. straight copy.
*(LPDWORD)pbDestRGB = *(LPDWORD)pbSrcRGBA; } else if (pbSrcRGBA[3]) { // Alpha is non-zero
pbDestRGB[0] = pbSrcRGBA[0] + (((255-pbSrcRGBA[3]) * pbDestRGB[0]) >> 8); pbDestRGB[1] = pbSrcRGBA[1] + (((255-pbSrcRGBA[3]) * pbDestRGB[1]) >> 8); pbDestRGB[2] = pbSrcRGBA[2] + (((255-pbSrcRGBA[3]) * pbDestRGB[2]) >> 8); } pbDestRGB += sizeof(DWORD); pbSrcRGBA += sizeof(DWORD); } // for
} // for
HDC hdcTempDest = CreateCompatibleDC(hdcDest); if (hdcTempDest) { HBITMAP hOldTempBmp = (HBITMAP)SelectObject(hdcTempDest, hTempDestDib); // Select the temp dib for blitting
// Get logical coord for device coord of dest origin
POINT pt = {nXOriginDest, nYOriginDest}; DPtoLP(hdcDest, &pt, 1); BitBlt(hdcDest, pt.x, pt.y, nWidthDest, nHeightDest, hdcTempDest, 0, 0, SRCCOPY); SelectObject(hdcTempDest, hOldTempBmp); DeleteDC(hdcTempDest); }
DeleteObject(hTempDestDib); return TRUE; }
CBitmap::~CBitmap() { if (m_hbm != NULL) DeleteObject(m_hbm); m_hbm = NULL; m_bSizeKnown = FALSE; }
HDC CreateAppropDC(HDC hDC) { return CreateCompatibleDC(hDC); }
HBITMAP CreateAppropBitmap(HDC hDC, int cx, int cy) { if (hDC != NULL) return CreateCompatibleBitmap(hDC, cx, cy); HWND hWnd = GetDesktopWindow(); HDC hWDC = GetWindowDC(hWnd); HBITMAP hbm = NULL; if (hWDC != NULL) { hbm = CreateCompatibleBitmap(hWDC, cx, cy); ReleaseDC(hWnd, hWDC); }
return hbm; }
CBitmap *CBitmap::CreateFromResource(HINSTANCE hInst, LPCTSTR tszName) { return CreateViaLoadImage(hInst, tszName, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE); }
CBitmap *CBitmap::CreateFromFile(LPCTSTR tszFileName) { return CreateViaD3DX(tszFileName); }
// Use D3DX API to load our surface with image content.
CBitmap *CBitmap::CreateViaD3DX(LPCTSTR tszFileName, LPDIRECT3DSURFACE8 pUISurf) { HRESULT hr; LPDIRECT3D8 pD3D = NULL; LPDIRECT3DDEVICE8 pD3DDev = NULL; LPDIRECT3DTEXTURE8 pTex = NULL; LPDIRECT3DSURFACE8 pSurf = NULL; HBITMAP hDIB = NULL;
__try { //@@BEGIN_MSINTERNAL
pSurf = GetCloneSurface(512, 512); /*
//@@END_MSINTERNAL
// If the UI surface is NULL, create a new device. Otherwise, use existing device.
if (!pUISurf) { pD3D = Direct3DCreate8(D3D_SDK_VERSION); if (!pD3D) return NULL; OutputDebugString(_T("D3D created\n")); D3DDISPLAYMODE Mode; pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &Mode); D3DPRESENT_PARAMETERS d3dpp; d3dpp.BackBufferWidth = 1; d3dpp.BackBufferHeight = 1; d3dpp.BackBufferFormat = Mode.Format; d3dpp.BackBufferCount = 1; d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; d3dpp.SwapEffect = D3DSWAPEFFECT_COPY; d3dpp.hDeviceWindow = NULL; d3dpp.Windowed = TRUE; d3dpp.EnableAutoDepthStencil = FALSE; d3dpp.FullScreen_RefreshRateInHz = 0; d3dpp.FullScreen_PresentationInterval = 0; d3dpp.Flags = 0; hr = pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, GetActiveWindow(), D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pD3DDev); if (FAILED(hr)) { TCHAR tszMsg[MAX_PATH];
_stprintf(tszMsg, _T("CreateDevice returned 0x%X\n"), hr); OutputDebugString(tszMsg); return NULL; } } else { hr = pUISurf->GetDevice(&pD3DDev); if (FAILED(hr)) return NULL; }
OutputDebugString(_T("D3D device createed\n")); hr = pD3DDev->CreateTexture(512, 512, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pTex); if (FAILED(hr)) return NULL; OutputDebugString(_T("D3D texture createed\n")); hr = pTex->GetSurfaceLevel(0, &pSurf); if (FAILED(hr)) return NULL; OutputDebugString(_T("Surface interface obtained\n"));
//@@BEGIN_MSINTERNAL
*/ //@@END_MSINTERNAL
D3DXIMAGE_INFO d3dii; if (FAILED(D3DXLoadSurfaceFromFile(pSurf, NULL, NULL, tszFileName, NULL, D3DX_FILTER_NONE, 0, &d3dii))) return NULL;
// Create a bitmap and copy the texture content onto it.
int iDibWidth = d3dii.Width, iDibHeight = d3dii.Height; if (iDibWidth > 430) iDibWidth = 430; if (iDibHeight > 310) iDibHeight = 310; LPBYTE pDIBBits; BITMAPINFO bmi; bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); bmi.bmiHeader.biWidth = iDibWidth; bmi.bmiHeader.biHeight = iDibHeight; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biSizeImage = 0; bmi.bmiHeader.biXPelsPerMeter = 0; bmi.bmiHeader.biYPelsPerMeter = 0; bmi.bmiHeader.biClrUsed = 0; bmi.bmiHeader.biClrImportant = 0; hDIB = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (LPVOID*)&pDIBBits, NULL, 0); if (!hDIB) return NULL;
// Pre-process the pixel data based on alpha for AlphaBlend()
D3DLOCKED_RECT lrc; pSurf->LockRect(&lrc, NULL, NULL); BYTE *pbData = (LPBYTE)lrc.pBits; { for (DWORD i = 0; i < 512 * 512; ++i) { BYTE bAlpha = pbData[i * 4 + 3]; pbData[i * 4] = pbData[i * 4] * bAlpha / 255; pbData[i * 4 + 1] = pbData[i * 4 + 1] * bAlpha / 255; pbData[i * 4 + 2] = pbData[i * 4 + 2] * bAlpha / 255; } } pSurf->UnlockRect();
// Lock the surface
D3DLOCKED_RECT D3DRect; hr = pSurf->LockRect(&D3DRect, NULL, 0); if (FAILED(hr)) return NULL;
// Copy the bits
// Note that the image is reversed in Y direction, so we need to re-reverse it.
for (int y = 0; y < iDibHeight; ++y) CopyMemory(pDIBBits + ((iDibHeight-1-y) * iDibWidth * 4), (LPBYTE)D3DRect.pBits + (y * D3DRect.Pitch), iDibWidth * 4);
// Unlock
pSurf->UnlockRect();
CBitmap *pbm = new CBitmap; if (!pbm) return NULL; pbm->m_hbm = hDIB; hDIB = NULL; pbm->FigureSize();
return pbm; } __finally { if (hDIB) DeleteObject(hDIB); if (pSurf) pSurf->Release(); if (pTex) pTex->Release(); if (pD3DDev) pD3DDev->Release(); if (pD3D) pD3D->Release(); } //@@BEGIN_MSINTERNAL
/*
//@@END_MSINTERNAL
return NULL; //@@BEGIN_MSINTERNAL
*/ //@@END_MSINTERNAL
}
CBitmap *CBitmap::CreateViaLoadImage(HINSTANCE hInst, LPCTSTR tszName, UINT uType, int cx, int cy, UINT fuLoad) { if (fuLoad & LR_SHARED) { assert(0); return NULL; }
CBitmap *pbm = new CBitmap; if (pbm == NULL) return NULL; HANDLE handle = ::LoadImage(hInst, tszName, uType, cx, cy, fuLoad); if (handle == NULL) { delete pbm; return NULL; }
pbm->m_hbm = (HBITMAP)handle;
pbm->FigureSize();
return pbm; }
BOOL CBitmap::FigureSize() { BITMAP bm;
if (0 == GetObject((HGDIOBJ)m_hbm, sizeof(BITMAP), (LPVOID)&bm)) return FALSE;
m_size.cx = abs(bm.bmWidth); m_size.cy = abs(bm.bmHeight);
return m_bSizeKnown = TRUE; }
CBitmap *CBitmap::StealToCreate(HBITMAP &refbm) { if (refbm == NULL) return NULL;
CBitmap *pbm = new CBitmap; if (pbm == NULL) return NULL; pbm->m_hbm = refbm; refbm = NULL;
pbm->FigureSize();
return pbm; }
BOOL CBitmap::GetSize(SIZE *psize) { if (m_hbm == NULL || !m_bSizeKnown || psize == NULL) return FALSE;
*psize = m_size; return TRUE; }
void CBitmap::AssumeSize(SIZE size) { m_size = size; m_bSizeKnown = TRUE; //m_hbm != NULL;
}
CBitmap *CBitmap::CreateResizedTo(SIZE size, HDC hDC, int iStretchMode, BOOL bStretch) { CBitmap *pbm = new CBitmap; HDC hSrcDC = NULL; HDC hDestDC = NULL; HBITMAP hBitmap = NULL; HGDIOBJ hOldSrcBitmap = NULL, hOldDestBitmap = NULL; BOOL bRet = FALSE; int oldsm = 0; POINT brushorg;
if (pbm == NULL || size.cx < 1 || size.cy < 1 || m_hbm == NULL || !m_bSizeKnown) goto error;
hSrcDC = CreateAppropDC(hDC); hDestDC = CreateAppropDC(hDC); if (hSrcDC == NULL || hDestDC == NULL) goto error;
hBitmap = CreateAppropBitmap(hDC, size.cx, size.cy); if (hBitmap == NULL) goto error;
if (bStretch) { if (GetStretchBltMode(hDestDC) != iStretchMode) { if (iStretchMode == HALFTONE) GetBrushOrgEx(hDestDC, &brushorg); oldsm = SetStretchBltMode(hDestDC, iStretchMode); if (iStretchMode == HALFTONE) SetBrushOrgEx(hDestDC, brushorg.x, brushorg.y, NULL); } }
hOldSrcBitmap = SelectObject(hSrcDC, m_hbm); hOldDestBitmap = SelectObject(hDestDC, hBitmap); if (bStretch) bRet = StretchBlt(hDestDC, 0, 0, size.cx, size.cy, hSrcDC, 0, 0, m_size.cx, m_size.cy, SRCCOPY); else bRet = BitBlt(hDestDC, 0, 0, size.cx, size.cy, hSrcDC, 0, 0, SRCCOPY); SelectObject(hDestDC, hOldDestBitmap); SelectObject(hSrcDC, hOldSrcBitmap);
if (bStretch) { if (oldsm != 0) { if (oldsm == HALFTONE) GetBrushOrgEx(hDestDC, &brushorg); SetStretchBltMode(hDestDC, oldsm); if (oldsm == HALFTONE) SetBrushOrgEx(hDestDC, brushorg.x, brushorg.y, NULL); } }
if (!bRet) goto error;
pbm->m_hbm = hBitmap; hBitmap = NULL; pbm->AssumeSize(size);
goto cleanup; error: if (pbm != NULL) delete pbm; pbm = NULL; cleanup: if (hBitmap != NULL) DeleteObject(hBitmap); if (hSrcDC != NULL) DeleteDC(hSrcDC); if (hDestDC != NULL) DeleteDC(hDestDC);
return pbm; }
HDC CBitmap::BeginPaintInto(HDC hCDC) { if (m_hDCInto != NULL) { assert(0); return NULL; }
m_hDCInto = CreateAppropDC(hCDC); if (m_hDCInto == NULL) return NULL;
m_hOldBitmap = SelectObject(m_hDCInto, m_hbm);
return m_hDCInto; }
void CBitmap::EndPaintInto(HDC &hDC) { if (hDC == NULL || hDC != m_hDCInto) { assert(0); return; }
SelectObject(m_hDCInto, m_hOldBitmap); DeleteDC(m_hDCInto); m_hDCInto = NULL; hDC = NULL; }
void CBitmap::PopOut() { if (m_hDCInto == NULL) { assert(0); return; }
SelectObject(m_hDCInto, m_hOldBitmap); }
void CBitmap::PopIn() { if (m_hDCInto == NULL) { assert(0); return; }
m_hOldBitmap = SelectObject(m_hDCInto, m_hbm); }
BOOL CBitmap::Draw(HDC hDC, POINT origin, SIZE crop, BOOL bAll) { if (hDC == NULL || m_hbm == NULL) return FALSE;
if (bAll && !m_bSizeKnown) return FALSE;
if (bAll) crop = m_size;
HDC hDCbm = CreateAppropDC(hDC); if (hDCbm == NULL) return FALSE;
BOOL bPop = m_hDCInto != NULL;
if (bPop) PopOut();
HGDIOBJ hOldBitmap = SelectObject(hDCbm, m_hbm); BOOL bRet = BitBlt(hDC, origin.x, origin.y, crop.cx, crop.cy, hDCbm, 0, 0, SRCCOPY); SelectObject(hDCbm, hOldBitmap); DeleteDC(hDCbm);
if (bPop) PopIn();
return bRet; }
BOOL CBitmap::Blend(HDC hDC, POINT origin, SIZE crop, BOOL bAll) { if (hDC == NULL || m_hbm == NULL) return FALSE;
if (bAll && !m_bSizeKnown) return FALSE;
if (bAll) crop = m_size;
HDC hDCbm = CreateAppropDC(hDC); if (hDCbm == NULL) return FALSE;
BOOL bPop = m_hDCInto != NULL;
if (bPop) PopOut();
#ifndef AC_SRC_ALPHA
#define AC_SRC_ALPHA AC_SRC_NO_PREMULT_ALPHA
#endif
HGDIOBJ hOldBitmap = SelectObject(hDCbm, m_hbm); BOOL bRet;
//@@BEGIN_MSINTERNAL
/* if (!g_AlphaBlend) // If AlphaBlend is not available, use BitBlt instead.
{ bRet = BitBlt(hDC, origin.x, origin.y, crop.cx, crop.cy, hDCbm, 0, 0, SRCPAINT); } else { BLENDFUNCTION blendfn = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA}; bRet = g_AlphaBlend(hDC, origin.x, origin.y, crop.cx, crop.cy, hDCbm, 0, 0, m_size.cx, m_size.cy, blendfn); }*/ //@@END_MSINTERNAL
bRet = DI_AlphaBlend(hDC, origin.x, origin.y, crop.cx, crop.cy, hDCbm, 0, 0, m_size.cx, m_size.cy); SelectObject(hDCbm, hOldBitmap); DeleteDC(hDCbm);
if (bPop) PopIn();
return bRet; }
CBitmap *CBitmap::Dup() { SIZE t; if (!GetSize(&t)) return NULL; return CreateResizedTo(t, NULL, COLORONCOLOR, FALSE); }
CBitmap *CBitmap::Create(SIZE size, HDC hCDC) { CBitmap *pbm = new CBitmap; if (pbm == NULL) return NULL;
pbm->m_hbm = CreateAppropBitmap(hCDC, size.cx, size.cy); if (pbm->m_hbm == NULL) { delete pbm; return NULL; }
pbm->AssumeSize(size);
return pbm; }
CBitmap *CBitmap::Create(SIZE size, COLORREF color, HDC hCDC) { CBitmap *pbm = Create(size, hCDC); if (pbm == NULL) return NULL;
HDC hDC = pbm->BeginPaintInto(); if (hDC == NULL) { delete pbm; return NULL; } HGDIOBJ hBrush = (HGDIOBJ)CreateSolidBrush(color), hOldBrush;
if (hBrush) { hOldBrush = SelectObject(hDC, hBrush); Rectangle(hDC, -1, -1, size.cx + 1, size.cy + 1); SelectObject(hDC, hOldBrush); DeleteObject(hBrush); }
pbm->EndPaintInto(hDC);
return pbm; }
BOOL CBitmap::Get(HDC hDC, POINT point) { if (!m_bSizeKnown) return FALSE; return Get(hDC, point, m_size); }
BOOL CBitmap::Get(HDC hDC, POINT point, SIZE size) { if (m_hDCInto != NULL || hDC == NULL) return FALSE;
HDC hDCInto = BeginPaintInto(hDC); if (hDCInto == NULL) return FALSE;
BOOL bRet = BitBlt(hDCInto, 0, 0, size.cx, size.cy, hDC, point.x, point.y, SRCCOPY); EndPaintInto(hDCInto);
return bRet; }
CBitmap *CBitmap::CreateHorzGradient(const RECT &rect, COLORREF rgbLeft, COLORREF rgbRight) { SIZE size = GetRectSize(rect); COLORREF rgbMid = RGB( (int(GetRValue(rgbLeft)) + int(GetRValue(rgbRight))) / 2, (int(GetGValue(rgbLeft)) + int(GetGValue(rgbRight))) / 2, (int(GetBValue(rgbLeft)) + int(GetBValue(rgbRight))) / 2); return Create(size, rgbMid); }
BOOL CBitmap::MapToDC(HDC hDCTo, HDC hDCMapFrom) { if (hDCTo == NULL || !m_bSizeKnown || m_hDCInto != NULL) return FALSE;
HBITMAP hbm = CreateAppropBitmap(hDCTo, m_size.cx, m_size.cy); if (hbm == NULL) return FALSE;
HDC hDCFrom = NULL; HDC hDCInto = NULL; HGDIOBJ hOld = NULL; BOOL bRet = FALSE;
hDCFrom = BeginPaintInto(hDCMapFrom); if (!hDCFrom) goto cleanup;
hDCInto = CreateCompatibleDC(hDCTo); if (!hDCInto) goto cleanup;
hOld = SelectObject(hDCInto, (HGDIOBJ)hbm); bRet = BitBlt(hDCInto, 0, 0, m_size.cx, m_size.cy, hDCFrom, 0, 0, SRCCOPY); SelectObject(hDCInto, hOld);
cleanup: if (hDCFrom) EndPaintInto(hDCFrom); if (hDCInto) DeleteDC(hDCInto); if (bRet) { if (m_hbm) DeleteObject((HGDIOBJ)m_hbm); m_hbm = hbm; hbm = NULL; } if (hbm) DeleteObject((HGDIOBJ)hbm);
return bRet; }
|