본문으로 바로가기

투명리스트 컨트롤 구현(TransListBox)

category 개발언어/c++ 2016. 7. 16. 19:49

 

HEAD

#if !defined(AFX_LSTRANSLISTBOX_H__1DE15F21_6DE3_11D4_8CDF_0008C73F82B8__INCLUDED_)

#define AFX_LSTRANSLISTBOX_H__1DE15F21_6DE3_11D4_8CDF_0008C73F82B8__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

// CTransparentListBox.h : header file

//

 

//#include "LSRgnBmpScrollButton.h"

#include <afxtempl.h>

 

/////////////////////////////////////////////////////////////////////////////

// CTransparentListBox window

typedef CMap<long,long,long,long> CMapWordToWord;

 

class CTransparentListBox : public CListBox

{

// Construction

public:

    CTransparentListBox();

 

// Attributes

public:

 

// Operations

public:

void SetFont(int nPointSize, CString FaceName,COLORREF Color,COLORREF SelColor,BOOL Shadow=TRUE,int SOffset = 2,COLORREF ShadowColor = RGB(0,0,0));

void SetColor(COLORREF Color,COLORREF SelColor,COLORREF ShadowColor = RGB(0,0,0));

 

BOOL SetTopIndex(int Index);

int ScrollUp(int Lines=1);

int ScrollDown(int Lines=1);

int AddString(CString Text,DWORD ItemData = 0,BOOL Enabled = TRUE);

int InsertString(int Index,CString Text, DWORD ItemData = 0,BOOL Enabled = TRUE);

virtual void ResetContent(BOOL bInvalidate = TRUE);

 

// Overrides

    // ClassWizard generated virtual function overrides

    //{{AFX_VIRTUAL(CTransparentListBox)

    protected:

    virtual void PreSubclassWindow();

    //}}AFX_VIRTUAL

 

// Implementation

public:

    virtual ~CTransparentListBox();

 

    // Generated message map functions

protected:

int m_ItemHeight;

COLORREF m_Color;

COLORREF m_SelColor;

COLORREF m_ShadowColor;

CFont m_Font;

CBitmap m_Bmp;

BOOL m_HasBackGround;

int m_ShadowOffset;

BOOL m_Shadow;

long m_PointSize;

 

 

virtual CFont *GetFont();

virtual void MeasureItem(LPMEASUREITEMSTRUCT /*lpMeasureItemStruct*/);

virtual void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );

virtual void DrawItem(CDC &Dc,int Index,CRect &Rect,BOOL Selected);

 

 

    //{{AFX_MSG(CTransparentListBox)

    afx_msg BOOL OnEraseBkgnd(CDC* pDC);

    afx_msg void OnPaint();

    afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);

afx_msg BOOL OnLbnSelchange();

afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);

afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);

    //}}AFX_MSG

    DECLARE_MESSAGE_MAP()

public:

afx_msg void OnMove(int x, int y);

afx_msg void OnSize(UINT nType, int cx, int cy);

};

 

/////////////////////////////////////////////////////////////////////////////

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_LSTRANSLISTBOX_H__1DE15F21_6DE3_11D4_8CDF_0008C73F82B8__INCLUDED_)

 

 

CPP

// CTransparentListBox.cpp : implementation file

//

 

#include "stdafx.h"

#include "TransparentListBox.h"

#include ".\transparentlistbox.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

/////////////////////////////////////////////////////////////////////////////

// CTransparentListBox

 

CTransparentListBox::CTransparentListBox()

: m_ItemHeight(20),

m_HasBackGround(FALSE),

m_Color(RGB(0,0,0)),

m_SelColor(RGB(255,0,0)),

m_ShadowColor(RGB(0,0,0)),

m_Shadow(FALSE),

m_ShadowOffset(3)

{

m_SelColor = GetSysColor(COLOR_HIGHLIGHTTEXT);

m_Color = GetSysColor(COLOR_WINDOWTEXT);

}

 

CTransparentListBox::~CTransparentListBox()

{

}

 

 

BEGIN_MESSAGE_MAP(CTransparentListBox, CListBox)

    //{{AFX_MSG_MAP(CTransparentListBox)

    ON_WM_ERASEBKGND()

    ON_WM_PAINT()

    ON_WM_VSCROLL()

ON_CONTROL_REFLECT_EX(LBN_SELCHANGE, OnLbnSelchange)

ON_WM_KEYDOWN()

ON_WM_CHAR()

    //}}AFX_MSG_MAP

ON_WM_MOVE()

ON_WM_SIZE()

END_MESSAGE_MAP()

 

 

/////////////////////////////////////////////////////////////////////////////

// CTransparentListBox message handlers

 

void CTransparentListBox::PreSubclassWindow()

{

    CListBox::PreSubclassWindow();

 

ModifyStyle(0,SS_NOTIFY|LBS_NOSEL);

 

CWnd *pParent = GetParent();

if (pParent)

{

CRect Rect;

GetClientRect(&Rect);

ClientToScreen(&Rect);

pParent->ScreenToClient(&Rect);

CDC *pDC = pParent->GetDC();

m_Bmp.CreateCompatibleBitmap(pDC,Rect.Width(),Rect.Height());

}

}

 

 

void CTransparentListBox::SetFont(int nPointSize, CString FaceName,COLORREF Color,COLORREF SelColor,BOOL Shadow,int SOffset,COLORREF ShadowColor)

{

m_Shadow = Shadow;

m_ShadowColor = ShadowColor;

m_ShadowOffset = SOffset;

m_Color = Color;

m_SelColor = SelColor;

m_PointSize = nPointSize;

CDC *DC = GetDC();

m_Font.DeleteObject();

m_Font.CreateFont(nPointSize,0,0,0,FW_BOLD,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_CHARACTER_PRECIS,CLIP_CHARACTER_PRECIS,PROOF_QUALITY,DEFAULT_PITCH,FaceName);

if (GetCount())

{

CRect Rect;

Rect.SetRectEmpty();

 

CFont *oldFont = DC->SelectObject(&m_Font);

CString Text;

GetText(0,Text);

DC->DrawText(Text,&Rect,DT_CALCRECT|DT_EXPANDTABS|DT_NOPREFIX);

m_ItemHeight = static_cast<long>(Rect.Height());

DC->SelectObject(oldFont);

}

ReleaseDC(DC);

 

}

 

void CTransparentListBox::SetColor(COLORREF Color,COLORREF SelColor,COLORREF ShadowColor)

{

m_ShadowColor = ShadowColor;

m_Color = Color;

m_SelColor = SelColor;

}

 

void CTransparentListBox::ResetContent(BOOL bInvalidate)

{

Default();

    if ( bInvalidate )

    {

        Invalidate();

        UpdateWindow();

    }

}

 

 

int CTransparentListBox::AddString(CString Text,DWORD ItemData,BOOL Enabled)

{

if (!GetCount())

{

CDC *DC = GetDC();

CRect Rect;

Rect.SetRectEmpty();

 

CFont *oldFont = DC->SelectObject(GetFont());

DC->DrawText(Text,&Rect,DT_CALCRECT|DT_EXPANDTABS|DT_NOPREFIX);

m_ItemHeight = static_cast<long>(Rect.Height());

DC->SelectObject(oldFont);

ReleaseDC(DC);

}

 

int Index = CListBox::AddString(Text);

CListBox::SetItemData(Index,ItemData);

return Index;

}

 

int CTransparentListBox::InsertString(int Index,CString Text, DWORD ItemData,BOOL Enabled)

{

if (!GetCount())

{

CDC *DC = GetDC();

CRect Rect;

Rect.SetRectEmpty();

 

CFont *oldFont = DC->SelectObject(GetFont());

DC->DrawText(Text,&Rect,DT_CALCRECT|DT_EXPANDTABS|DT_NOPREFIX);

m_ItemHeight = static_cast<long>(Rect.Height());

DC->SelectObject(oldFont);

ReleaseDC(DC);

}

 

Index = CListBox::InsertString(Index,Text);

CListBox::SetItemData(Index,ItemData);

return Index;

}

 

 

 

BOOL CTransparentListBox::OnEraseBkgnd(CDC* pDC)

{

if (!m_HasBackGround)

{

CWnd *pParent = GetParent();

if (pParent)

{

CRect Rect;

GetClientRect(&Rect);

ClientToScreen(&Rect);

pParent->ScreenToClient(&Rect);

CDC *pDC = pParent->GetDC();

CDC memdc;

memdc.CreateCompatibleDC(pDC);

CBitmap *oldbmp = memdc.SelectObject(&m_Bmp);

memdc.BitBlt(0,0,Rect.Width(),Rect.Height(),pDC,Rect.left,Rect.top,SRCCOPY);

memdc.SelectObject(oldbmp);

m_HasBackGround = TRUE;

pParent->ReleaseDC(pDC);

}

}

 

return TRUE;

 

}

 

CFont *CTransparentListBox::GetFont()

{

if (m_Font.m_hObject == NULL)

{

return CListBox::GetFont();

}

 

return &m_Font;

}

 

void CTransparentListBox::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )

{

}

 

 

void CTransparentListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)

{

CDC *DC = GetDC();

CRect Rect;

Rect.SetRectEmpty();

 

CFont *oldFont = DC->SelectObject(GetFont());

DC->DrawText("XYZ",&Rect,DT_CALCRECT|DT_EXPANDTABS|DT_NOPREFIX);

m_ItemHeight = lpMeasureItemStruct->itemHeight = static_cast<long>(Rect.Height());

DC->SelectObject(oldFont);

ReleaseDC(DC);

}

 

 

void CTransparentListBox::DrawItem(CDC &Dc,int Index,CRect &Rect,BOOL Selected)

{

if (Index == LB_ERR || Index >= GetCount())

return;

 

CRect TheRect = Rect;

Dc.SetBkMode(TRANSPARENT);

 

CDC memdc;

memdc.CreateCompatibleDC(&Dc);

 

CFont *pFont = GetFont();

CFont *oldFont = Dc.SelectObject(pFont);

CBitmap *oldbmp = memdc.SelectObject(&m_Bmp);

Dc.BitBlt(TheRect.left,TheRect.top,TheRect.Width(),TheRect.Height(),&memdc,TheRect.left,TheRect.top,SRCCOPY);

CString Text;

GetText(Index,Text);

if (m_Shadow)

{

if (IsWindowEnabled())

{

Dc.SetTextColor(m_ShadowColor);

}

else

{

Dc.SetTextColor(RGB(255,255,255));

}

TheRect.OffsetRect(m_ShadowOffset,m_ShadowOffset);

Dc.DrawText(Text,TheRect,DT_LEFT|DT_EXPANDTABS|DT_NOPREFIX);

TheRect.OffsetRect(-m_ShadowOffset,-m_ShadowOffset);

}

 

if (IsWindowEnabled())

{

if (Selected)

{

Dc.SetTextColor(m_SelColor);

}

else

{

Dc.SetTextColor(m_Color);

}

}

else

{

Dc.SetTextColor(RGB(140,140,140));

}

Dc.DrawText(Text,TheRect,DT_LEFT|DT_EXPANDTABS|DT_NOPREFIX);

Dc.SelectObject(oldFont);

memdc.SelectObject(oldbmp);

}

 

void CTransparentListBox::OnPaint()

{

CPaintDC dc(this); // device context for painting

 

CRect Rect;

GetClientRect(&Rect);

 

int Width = Rect.Width();

int Height = Rect.Height();

 

CDC MemDC;

MemDC.CreateCompatibleDC(&dc);

CBitmap MemBmp;

MemBmp.CreateCompatibleBitmap(&dc,Width,Height);

 

CBitmap *pOldMemBmp = MemDC.SelectObject(&MemBmp);

 

CDC MemDC2;

MemDC2.CreateCompatibleDC(&dc);

CBitmap *pOldbmp = MemDC2.SelectObject(&m_Bmp);

MemDC.BitBlt(0,0,Width,Height,&MemDC2,0,0,SRCCOPY);

MemDC2.SelectObject(pOldbmp);

 

 

Rect.top = 0;

Rect.left = 0;

Rect.bottom = Rect.top + GetItemHeight(0);

Rect.right = Width;

 

int size = GetCount();

for (int i = GetTopIndex(); i < size && Rect.top <= Height;++i)

{

DrawItem(MemDC,i,Rect,GetSel(i));

Rect.OffsetRect(0,GetItemHeight(i));

}

 

dc.BitBlt(0,0,Width,Height,&MemDC,0,0,SRCCOPY);

 

MemDC.SelectObject(pOldMemBmp);

}

 

void CTransparentListBox::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)

{

SetRedraw(FALSE);

CListBox::OnVScroll(nSBCode,nPos,pScrollBar);

SetRedraw(TRUE);

 

RedrawWindow(0,0,RDW_FRAME|RDW_INVALIDATE|RDW_UPDATENOW);

}

 

BOOL CTransparentListBox::OnLbnSelchange()

{

RedrawWindow(0,0,RDW_FRAME|RDW_INVALIDATE|RDW_UPDATENOW);

return FALSE;

}

 

int CTransparentListBox::SetTopIndex(int Index)

{

SetRedraw(FALSE);

int Ret = CListBox::SetTopIndex(Index);

SetRedraw(TRUE);

RedrawWindow(0,0,RDW_FRAME|RDW_INVALIDATE|RDW_UPDATENOW);

return Ret;

}

 

int CTransparentListBox::ScrollUp(int Lines)

{

int Index = GetTopIndex();

if (Index-Lines < 0)

{

Index = Lines;

}

return SetTopIndex(Index-Lines);

}

 

int CTransparentListBox::ScrollDown(int Lines)

{

int Index = GetTopIndex();

if (Index+Lines > GetCount()-1)

{

Index = GetCount()-Lines;

}

return SetTopIndex(Index+Lines);

}

 

void CTransparentListBox::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)

{

SetRedraw(FALSE);

CListBox::OnKeyDown(nChar, nRepCnt, nFlags);

SetRedraw(TRUE);

}

 

void CTransparentListBox::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)

{

SetRedraw(FALSE);

CListBox::OnChar(nChar, nRepCnt, nFlags);

SetRedraw(TRUE);

}

 

void CTransparentListBox::OnMove(int x, int y)

{

CListBox::OnMove(x, y);

 

ShowWindow(SW_HIDE);

m_HasBackGround = FALSE;

Invalidate();

UpdateWindow();

ShowWindow(SW_SHOW);

 

}

 

void CTransparentListBox::OnSize(UINT nType, int cx, int cy)

{

CListBox::OnSize(nType, cx, cy);

 

CWnd *pParent = GetParent();

if (pParent)

{

m_Bmp.DeleteObject();

CRect Rect;

GetClientRect(&Rect);

ClientToScreen(&Rect);

pParent->ScreenToClient(&Rect);

CDC *pDC = pParent->GetDC();

m_Bmp.CreateCompatibleBitmap(pDC,Rect.Width(),Rect.Height());

}

ShowWindow(SW_HIDE);

m_HasBackGround = FALSE;

Invalidate();

UpdateWindow();

ShowWindow(SW_SHOW);

}