📄 backlistbox.cpp
字号:
//////////////////////////////////////////////////////////////////////
// FileFury
// Copyright (c) 2000 Tenebril Incorporated
// All rights reserved.
//
// This source code is governed by the Tenebril open source
// license (http://www.tenebril.com/developers/opensource/license.html)
//
// For more information on this and other open source applications,
// visit the Tenebril OpenSource page:
// http://www.tenebril.com/developers/opensource
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "BackListBox.h"
#include "Defines.h"
CBackListBox::CBackListBox()
: CListCtrl()
{
TextColor = RGB(0, 0, 0);
BackColor = RGB(255, 255, 255);
PaintingBackground = false;
InitBackDC = false;
m_bShouldRedraw = TRUE;
m_bHasBuiltCache = FALSE;
m_pOldCacheBmp = NULL;
m_pCacheBmp = NULL;
}
CBackListBox::~CBackListBox()
{
if(m_pOldCacheBmp) // Take the cache bitmap out of the DC.
m_CacheDC.SelectObject(m_pOldCacheBmp);
if(m_pCacheBmp) // Delete the cache bitmap.
delete m_pCacheBmp;
}
BEGIN_MESSAGE_MAP(CBackListBox, CListCtrl)
ON_WM_PAINT()
ON_WM_ERASEBKGND()
// Overrides just for painting:
ON_WM_LBUTTONDOWN()
ON_WM_RBUTTONDOWN()
END_MESSAGE_MAP()
BOOL CBackListBox::Create(DWORD dwStyle, const RECT &rect,
CWnd* ParentWnd, UINT ID,
UINT BackBmp, CSize bmpsize)
{
BackBitmap.LoadBitmap(BackBmp);
ParentWindow = ParentWnd;
m_cBmpSize = bmpsize;
return CListCtrl::Create(dwStyle, rect, ParentWnd, ID);
}
afx_msg BOOL CBackListBox::OnEraseBkgnd(CDC* pDC)
{
// if(!PaintingBackground)
// PaintBackground(pDC);
return TRUE;
}
afx_msg void CBackListBox::OnPaint()
{
CRect PaintRect;
// GetClientRect(&PaintRect);
// InvalidateRect(PaintRect, FALSE);
CPaintDC dc(this);
PaintBackground(&dc);
return;
}
void CBackListBox::PaintBackground(CDC *DC, bool JustBackground)
{
if(PaintingBackground)
return;
if(!InitBackDC)
{
InitBackDC = true;
BackDC.CreateCompatibleDC(DC);
BackDC.SelectObject(&BackBitmap);
BackColor = BackDC.GetPixel(0, 0);
}
PaintingBackground = true;
CRect PaintRect;
GetClientRect(&PaintRect);
if(PaintRect.Width() != m_cOldSize.cx ||
PaintRect.Height() != m_cOldSize.cy ||
m_bShouldRedraw)
{
CBrush BackBrush(BackColor);
CBrush WhiteBrush(::GetSysColor(COLOR_WINDOW));
CDC imageDC, memDC, maskDC;
CBitmap *pImageBack, *pMemBack, *pMaskBack;
CBitmap bmpImage, bitmap, maskBitmap;
CPoint StartPoint;
StartPoint.x = (int)((PaintRect.Width() - m_cBmpSize.cx) / 2);
StartPoint.y = (int)((PaintRect.Height() - m_cBmpSize.cy) / 2);
memDC.CreateCompatibleDC(DC);
bitmap.CreateCompatibleBitmap(DC, PaintRect.Width(),
PaintRect.Height());
// Draw the control
pMemBack = memDC.SelectObject(&bitmap);
memDC.FillRect(PaintRect, &WhiteBrush);
CWnd::DefWindowProc(WM_PAINT, (WPARAM)memDC.m_hDC, 0);
maskDC.CreateCompatibleDC(DC);
// Create monochrome bitmap for the mask
maskBitmap.CreateBitmap(PaintRect.Width(), PaintRect.Height(),
1, 1, NULL);
pMaskBack = maskDC.SelectObject(&maskBitmap);
memDC.SetBkColor(::GetSysColor(COLOR_WINDOW));
// Create the mask from the memory DC
maskDC.BitBlt(0, 0, PaintRect.Width(), PaintRect.Height(), &memDC,
PaintRect.left, PaintRect.top, SRCCOPY);
imageDC.CreateCompatibleDC(DC);
bmpImage.CreateCompatibleBitmap(DC, PaintRect.Width(),
PaintRect.Height());
pImageBack = imageDC.SelectObject(&bmpImage);
imageDC.FillRect(PaintRect, &BackBrush);
imageDC.BitBlt(StartPoint.x, StartPoint.y, m_cBmpSize.cx,
m_cBmpSize.cy, &BackDC,
0, 0, SRCCOPY);
// Set the background in memDC to black. Using SRCPAINT with black and
// any other color results in the other color, thus making black the
// transparent color
memDC.SetBkColor(RGB(0,0,0));
memDC.SetTextColor(RGB(255,255,255));
memDC.BitBlt(PaintRect.left, PaintRect.top,
PaintRect.Width(), PaintRect.Height(), &maskDC,
PaintRect.left, PaintRect.top, SRCAND);
// Set the foreground to black.
imageDC.SetBkColor(RGB(255,255,255));
imageDC.SetTextColor(RGB(0,0,0));
imageDC.BitBlt(PaintRect.left, PaintRect.top,
PaintRect.Width(), PaintRect.Height(), &maskDC,
PaintRect.left, PaintRect.top, SRCAND);
// Combine the foreground with the background
imageDC.BitBlt(PaintRect.left, PaintRect.top,
PaintRect.Width(), PaintRect.Height(),
&memDC, PaintRect.left, PaintRect.top, SRCPAINT);
// Setup the bitmap cache: clean out old stuff.
if(m_pOldCacheBmp)
{
CBitmap *pBmp = m_CacheDC.SelectObject(m_pOldCacheBmp);
// MAJOR BUG: Cannot delete pBmp; does not equal m_pCacheBmp! (VC6 bug?)
if(m_pCacheBmp) // Clean out the old bitmap.
delete m_pCacheBmp;
}
else
m_CacheDC.CreateCompatibleDC(DC); // Do this only once.
// Setup the bitmap cache: push in a new bitmap.
m_pCacheBmp = new CBitmap;
VERIFY(m_pCacheBmp->CreateCompatibleBitmap(DC, PaintRect.Width(),
PaintRect.Height()));
m_pOldCacheBmp = m_CacheDC.SelectObject(m_pCacheBmp);
ASSERT(m_pOldCacheBmp);
// Now draw into the bitmap cache.
m_CacheDC.BitBlt(0, 0, PaintRect.Width(), PaintRect.Height(),
&imageDC, PaintRect.left, PaintRect.top, SRCCOPY);
// Store the size information.
m_cOldSize.cx = PaintRect.Width();
m_cOldSize.cy = PaintRect.Height();
// Don't redraw now.
m_bShouldRedraw = FALSE;
BackColor = BackDC.GetPixel(0, 0);
// Clean out the local DC's.
// If we don't do this, there's a (big) memory leak (MFC bug?).
imageDC.SelectObject(pImageBack);
memDC.SelectObject(pMemBack);
maskDC.SelectObject(pMaskBack);
}
// Make sure we don't draw over a report header.
CHeaderCtrl *pCtrl = GetHeaderCtrl();
if(pCtrl)
{
CRect HeaderRect;
pCtrl->GetWindowRect(&HeaderRect);
PaintRect.top += HeaderRect.Height();
}
DC->BitBlt(PaintRect.left, PaintRect.top, m_cOldSize.cx, m_cOldSize.cy,
&m_CacheDC, 0, 0, SRCCOPY);
PaintingBackground = false;
return;
}
void CBackListBox::SetRedraw()
{
m_bShouldRedraw = TRUE;
InvalidateRect(NULL);
}
// The following functions must be overridden so we can redraw appropriately.
void CBackListBox::OnLButtonDown(UINT nFlags, CPoint point)
{
SetRedraw();
CListCtrl::OnLButtonDown(nFlags, point);
}
void CBackListBox::OnRButtonDown(UINT nFlags, CPoint point)
{
SetRedraw();
CListCtrl::OnRButtonDown(nFlags, point);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -