#include "stdafx.h" #include "CCompatibleDC.h" #ifndef MAX #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #endif #ifndef MIN #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #endif CCompatibleDC::CCompatibleDC() { } CCompatibleDC::~CCompatibleDC() { } BOOL DisplayBMP(CDC* pDC, int nX1, int nY1, int nXX, int nYY, CString strBMPFile, BOOL bStretch) { OFSTRUCT of; unsigned fh = OpenFile((char const*)strBMPFile, &of, OF_READ); if (fh == -1) return FALSE; DWORD size = (DWORD)(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); HANDLE hDIBInfo = GlobalAlloc(GMEM_MOVEABLE, size); BITMAPFILEHEADER bf; LPBITMAPINFOHEADER lpbi; lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIBInfo); _lread(fh, (LPSTR)&bf, sizeof(bf)); _lread(fh, (LPSTR)lpbi, sizeof(BITMAPINFOHEADER)); WORD nClrs = (WORD)lpbi->biClrUsed; size = ((((lpbi->biWidth*lpbi->biBitCount) + 31)&~31) >> 3)*lpbi->biHeight; if (nClrs == 0 && lpbi->biBitCount != 24) nClrs = 1 << lpbi->biBitCount; if (lpbi->biClrUsed == 0) lpbi->biClrUsed = (DWORD)nClrs; if (lpbi->biSizeImage == 0) lpbi->biSizeImage = size; WORD Size = (WORD)lpbi->biSize; WORD Width = (WORD)lpbi->biWidth; WORD Height = (WORD)lpbi->biHeight; WORD ClrUsed = (WORD)lpbi->biClrUsed; WORD BitCount = (WORD)lpbi->biBitCount; DWORD SizeImage = lpbi->biSizeImage; WORD SizeRGB = nClrs * sizeof(RGBQUAD); WORD SizeHeader = Size + SizeRGB; GlobalUnlock(hDIBInfo); hDIBInfo = GlobalReAlloc(hDIBInfo, SizeHeader + SizeImage, 0); lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIBInfo); _lread(fh, (LPSTR)(lpbi)+Size, SizeRGB); if (bf.bfOffBits != 0L) _llseek(fh, bf.bfOffBits, SEEK_SET); DWORD ul = SizeImage; BYTE *hp = (BYTE *)((LPSTR)lpbi + SizeHeader); while (ul > 30000L) { _lread(fh, (LPSTR)hp, 30000L); ul -= 30000L; hp += 30000L; } _lread(fh, (LPSTR)hp, (WORD)ul); _lclose(fh); HPALETTE hPalette = NULL, hOldPal = NULL; HANDLE hPalHeader = NULL; HDC hDC = pDC->m_hDC; LPBITMAPINFOHEADER lpHeader = lpbi; WORD wDIBUse = DIB_RGB_COLORS; if (ClrUsed) { WORD size = sizeof(LOGPALETTE) + ClrUsed * sizeof(PALETTEENTRY); NPLOGPALETTE npPal = (NPLOGPALETTE)LocalAlloc(LMEM_FIXED, size); npPal->palVersion = 0x300; npPal->palNumEntries = ClrUsed; RGBQUAD FAR *lpRGB = (RGBQUAD FAR *)((LPSTR)lpbi + Size); for (WORD i = 0; i < ClrUsed; i++, lpRGB++) { npPal->palPalEntry[i].peRed = lpRGB->rgbRed; npPal->palPalEntry[i].peGreen = lpRGB->rgbGreen; npPal->palPalEntry[i].peBlue = lpRGB->rgbBlue; npPal->palPalEntry[i].peFlags = 0; } hPalette = CreatePalette((LPLOGPALETTE)npPal); LocalFree((HANDLE)npPal); hOldPal = SelectPalette(hDC, hPalette, FALSE); RealizePalette(hDC); if (BitCount != 24) { size = Size + ClrUsed * sizeof(WORD); hPalHeader = GlobalAlloc(GMEM_MOVEABLE, size); LPBITMAPINFOHEADER lpPalInfo; lpPalInfo = (LPBITMAPINFOHEADER)GlobalLock(hPalHeader); *lpPalInfo = *lpbi; WORD FAR *lpTable = (WORD FAR *)((LPSTR)lpPalInfo + Size); for (WORD i = 0; i < ClrUsed; i++) *lpTable++ = i; GlobalUnlock(hPalHeader); lpHeader = (LPBITMAPINFOHEADER)GlobalLock(hPalHeader); wDIBUse = DIB_PAL_COLORS; } } HDC hMemDC = CreateCompatibleDC(hDC); HBITMAP hDDBitmap = CreateCompatibleBitmap(hDC, Width, Height); SetDIBits(hDC, hDDBitmap, 0, Height, (LPSTR)lpbi + SizeHeader, (LPBITMAPINFO)lpHeader, wDIBUse); HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDC, hDDBitmap); if (bStretch) { StretchBlt(hDC, nX1, nY1, nXX, nYY, hMemDC, 0, 0, Width, Height, SRCCOPY); } else { Width = MIN(Width, nXX); Height = MIN(Height, nYY); BitBlt(hDC, nX1, nY1, Width, Height, hMemDC, 0, 0, SRCCOPY); } SelectObject(hMemDC, hOldBitmap); DeleteDC(hMemDC); DeleteObject(hDDBitmap); if (ClrUsed) { SelectPalette(hDC, hOldPal, FALSE); DeleteObject(hPalette); if (BitCount != 24) { GlobalUnlock(hPalHeader); GlobalFree(hPalHeader); } } GlobalUnlock(hDIBInfo); GlobalFree(hDIBInfo); return TRUE; } void DrawColorButton(LPDRAWITEMSTRUCT lpDIS, COLORREF clrButton) { CDC* pDC = CDC::FromHandle(lpDIS->hDC); CRect rectButton = lpDIS->rcItem; UINT nStyle = DFCS_BUTTONPUSH; if (lpDIS->itemState & ODS_SELECTED) nStyle |= DFCS_PUSHED; if (lpDIS->itemState & ODS_DISABLED) nStyle |= DFCS_INACTIVE; pDC->DrawFrameControl(rectButton, DFC_BUTTON, nStyle); CRect rectColor = lpDIS->rcItem; rectColor.InflateRect(-1, -1, -1, -1); if (lpDIS->itemState & ODS_SELECTED) rectColor.InflateRect(-1, -1, 1, 1); if (lpDIS->itemState & ODS_DISABLED) { CPen pen(PS_SOLID, 1, RGB(128, 128, 128)); CPen* pOldPen = pDC->SelectObject(&pen); pDC->SetBkColor(RGB(192, 192, 192)); pDC->SetTextColor(clrButton); CBrush* pBrush = pDC->GetHalftoneBrush(); CBrush* pOldBrush = pDC->SelectObject(pBrush); pDC->Rectangle(rectColor); pDC->SelectObject(pOldBrush); pDC->SelectObject(pOldPen); } else { CBrush brush(clrButton); CBrush* pOldBrush = pDC->SelectObject(&brush); pDC->SelectStockObject(BLACK_PEN); pDC->Rectangle(rectColor); pDC->SelectObject(pOldBrush); } } void CCompatibleDC::Create(CDC* pDC) { m_pDrawDC = pDC; // 获取裁剪区域; m_pDrawDC->GetClipBox(m_rect); m_rect.right++; m_rect.bottom++; // 创建兼容DC; CreateCompatibleDC(m_pDrawDC); // 如果存在裁剪区域; //if (m_rect.Width() > 0) if(!m_rect.IsRectEmpty() && !m_rect.IsRectNull()) { // 创建兼容画布; m_bitmap.CreateCompatibleBitmap(m_pDrawDC, m_rect.Width(), m_rect.Height()); m_pOldBitmap = SelectObject(&m_bitmap); OffsetViewportOrg(-m_rect.left, -m_rect.top); IntersectClipRect(m_rect); CPoint point(0, 0); LPtoDP(&point); SetBrushOrg(point); //2011-11-01 add DeleteObject(m_bitmap); } //2011-11-02 add DeleteObject(m_pDrawDC); } void CCompatibleDC::Destroy(void) { SelectClipRgn(NULL); SetViewportOrg(0, 0); m_pDrawDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(), this, 0, 0, SRCCOPY); SelectObject(m_pOldBitmap); } void CCompatibleDC::Destroy(CRect rect) { SelectClipRgn(NULL); SetViewportOrg(0, 0); CRect rc1, rc2, rc3, rc4; ////////////////////////////////////// // 2 // // // // /////////////// // // 1 // // 3 // // // // // // ////////////// // // // // 4 // // // ////////////////////////////////////// rc1.left = m_rect.left; rc1.right = rect.left; rc1.top = m_rect.top; rc1.bottom = m_rect.bottom; rc2.left = m_rect.left; rc2.right = m_rect.right; rc2.top = m_rect.top; rc2.bottom = rect.top; rc3.left = rect.right; rc3.right = m_rect.right; rc3.top = m_rect.top; rc3.bottom = m_rect.bottom; rc4.left = m_rect.left; rc4.right = m_rect.right; rc4.top = rect.bottom; rc4.bottom = m_rect.bottom; m_pDrawDC->BitBlt(rc1.left, rc1.top, rc1.Width() / 1, rc1.Height(), this, 0, 0, SRCCOPY); m_pDrawDC->BitBlt(rc2.left, rc2.top, rc2.Width() / 1, rc2.Height(), this, 0, rc2.top, SRCCOPY); m_pDrawDC->BitBlt(rc3.left, rc3.top, rc3.Width() / 1, rc3.Height(), this, rc3.left, rc3.top, SRCCOPY); m_pDrawDC->BitBlt(rc4.left, rc4.top, rc4.Width() / 1, rc4.Height(), this, 0, rc4.top, SRCCOPY); SelectObject(m_pOldBitmap); //if( m_rect.leftBitBlt(rc1.left,rc1.top,rc1.Width()/1,rc1.Height(),this, 0,0, SRCCOPY); //m_pDrawDC->BitBlt(rc2.left,rc2.top,rc2.Width()/1,rc2.Height(),this, 0,rc2.top, SRCCOPY); //m_pDrawDC->BitBlt(rc3.left,rc3.top,rc3.Width()/1,rc3.Height(),this, rc3.left,rc3.top, SRCCOPY); //m_pDrawDC->BitBlt(rc4.left,rc4.top,rc4.Width()/1,rc4.Height(),this, 0,rc4.top, SRCCOPY); //SelectObject(m_pOldBitmap); }