卫士的换肤对话框,真的蛮好看的。我非常想做一个。我是用CBkListBox的,主要是考虑以后要翻页。
1.做好xml配置
list_template_chang_skin.xml
View Code
1 <listitem height="68">
2 <dlg pos="0,0,-0,-0" crbg="FFFFFF">
3 <memimage id="6401" pos="2,2,62,66" ></memimage>
4 <memimage id="6402" pos="63,2,123,66" ></memimage>
5 <memimage id="6403" pos="125,2,184,66" ></memimage>
6 </dlg>
7 </listitem>
dlg_skin_set.xml
View Code
1 <layer width="188" height="83" appwin="0" resize="0">
2 <body width="full" height="full">
3 <img pos="0,0" skin="skinsetbg"/>
4 <realwnd pos="2,2,-2,-0" id="6400" ctrlid="6400" />
5 </body>
6 <rgn>
7 <area CreateMode="5">
8 <point pointx="1" pointy="1"/>
9 <point pointx="1" pointy="2"/>
10 <point pointx="2" pointy="1"/>
11
12 <point pointx="-1" pointy="1"/>
13 <point pointx="-1" pointy="2"/>
14 <point pointx="-2" pointy="1"/>
15
16 <point pointx="1" pointy="-1"/>
17 <point pointx="1" pointy="-2"/>
18 <point pointx="2" pointy="-1"/>
19
20 <point pointx="-1" pointy="-1"/>
21 <point pointx="-1" pointy="-2"/>
22 <point pointx="-2" pointy="-1"/>
23 </area>
24
25 </rgn>
26 </layer>
2.在bkwinres.rc2定义两个xml文件对应的宏。
DEFINE_XML(IDR_BK_CHANGE_SKIN, 531, "res\\dlg_skin_set.xml")
DEFINE_XML(IDR_BK_LISTSKINSET, 111, "res\\list_template_chang_skin.xml")
3.定义和实现
ChangeSkinDlg.h
#ifndef CChangeSkinDlg_H
#define CChangeSkinDlg_H
#include <bkres/bkres.h>
#include "bkwin/bklistbox.h"
#include "SmartPtr.h"
using namespace Loki;
class CFinancialHallDlg;
class CChangeSkinDlg
: public CBkDialogImpl<CChangeSkinDlg>
{
public:
CChangeSkinDlg(CFinancialHallDlg *pParent);
~CChangeSkinDlg();
public:
//初始化
void RefreshAll();
protected:
void InitCtrl();
BOOL OnInitDialog(CWindow /*wndFocus*/, LPARAM /*lInitParam*/);
protected:
LRESULT OnListBoxGetDispInfo(LPNMHDR pnmh);
LRESULT OnListBoxGetmaxHeight(LPNMHDR pnmh);
LRESULT OnListBoxGetItemHeight(LPNMHDR pnmh);
LRESULT OnBkListBoxClickCtrl(LPNMHDR pnmh);
public:
BK_NOTIFY_MAP(IDC_RICHVIEW_WIN)
BK_NOTIFY_MAP_END()
BEGIN_MSG_MAP_EX(CChangeSkinDlg)
MSG_BK_NOTIFY(IDC_RICHVIEW_WIN)
CHAIN_MSG_MAP(CBkDialogImpl<CChangeSkinDlg>)
MSG_WM_INITDIALOG(OnInitDialog)
NOTIFY_HANDLER_EX(IDC_SKIN_LIST, BKLBM_GET_DISPINFO, OnListBoxGetDispInfo)
NOTIFY_HANDLER_EX(IDC_SKIN_LIST, BKLBM_CALC_MAX_HEIGHT, OnListBoxGetmaxHeight)
NOTIFY_HANDLER_EX(IDC_SKIN_LIST, BKLBM_CALC_ITEM_HEIGHT, OnListBoxGetItemHeight)
NOTIFY_HANDLER_EX(IDC_SKIN_LIST, BKLBM_ITEMCLICK, OnBkListBoxClickCtrl)
REFLECT_NOTIFICATIONS_EX()
END_MSG_MAP()
protected:
CFinancialHallDlg *m_pParent;
SmartPtr<CBkListBox> m_List;
int m_nRowCount;
};
#endif /*CChangeSkinDlg_H */
ChangeSkinDlg.cpp
#include "stdafx.h"
#include "ChangeSkinDlg.h"
#include "SoftProduct/SoftProductStore.h"
#include "GlobalFun/GlobalFun.h"
#include "ConfigInfo/ConfigInfo.h"
#include "FinancialHallDlg.h"
#include "UserStatus/UserStatus.h"
#define CON_LIST_COLUMN_COUNT 3
#define CMDSET_LIST_ITEM_HEIGHT 37
using namespace std;
CChangeSkinDlg::CChangeSkinDlg(CFinancialHallDlg *pParent)
: CBkDialogImpl<CChangeSkinDlg>(IDR_BK_CHANGE_SKIN)
,m_pParent(pParent)
{
}
CChangeSkinDlg::~CChangeSkinDlg()
{
}
void CChangeSkinDlg::InitCtrl()
{
TYPEMAPSKINDEFINE::iterator pos;
for (pos = BkResManager::GetSkinMap().begin();pos != BkResManager::GetSkinMap().end();++pos)
{
CSkinDefine *pSkinDefine = pos->second;
pSkinDefine->Set_Image(Gdiplus::Image::FromFile(BkResManager::GetResourcePath()+pSkinDefine->strThumbPic));
}
m_List = new CBkListBox;
m_List->Create( GetViewHWND(), IDC_SKIN_LIST);
m_List->Load(IDR_BK_LISTSKINSET);
m_List->SetCanGetFocus(FALSE);
int num = BkResManager::GetSkinCount();
m_nRowCount = (BkResManager::GetSkinCount() % CON_LIST_COLUMN_COUNT == 0)? BkResManager::GetSkinCount() / CON_LIST_COLUMN_COUNT:BkResManager::GetSkinCount() / CON_LIST_COLUMN_COUNT + 1;
m_List->SetItemCount(m_nRowCount);
}
LRESULT CChangeSkinDlg::OnListBoxGetDispInfo( LPNMHDR pnmh )
{
BKLBMGETDISPINFO* pdi = (BKLBMGETDISPINFO*)pnmh;
if (pdi->nListItemID >= m_nRowCount)
return 0;
pdi->nHeight = CMDSET_LIST_ITEM_HEIGHT;
int nLowIndex = pdi->nListItemID * CON_LIST_COLUMN_COUNT;
int nHighIndex = (pdi->nListItemID + 1) * CON_LIST_COLUMN_COUNT;
int iCount = 0;
int nShow = 0;
TYPEMAPSKINDEFINE::iterator pos;
for (pos = BkResManager::GetSkinMap().begin();pos != BkResManager::GetSkinMap().end();++pos)
{
CSkinDefine *pSkinDefine = pos->second;
if ( iCount >= nLowIndex && iCount < nHighIndex)
{
nShow = iCount - nLowIndex;
CStringA strMem;
strMem.Format("%d",pSkinDefine->Get_Image());
m_List->SetItemAttribute(IDC_SKIN_CMD1+ nShow, "mempointer",strMem );
m_List->SetItemAttribute(IDC_SKIN_CMD1 + nShow,"tip",CT2A(pSkinDefine->strSkinDesc, CP_UTF8));
m_List->SetItemVisible(IDC_SKIN_CMD1 + nShow,TRUE);
}
++iCount;
}
for (int i= nShow + 1;i<CON_LIST_COLUMN_COUNT;++i)
{
m_List->SetItemVisible(IDC_SKIN_CMD1 + i,FALSE);
}
return 0;
}
LRESULT CChangeSkinDlg::OnListBoxGetmaxHeight( LPNMHDR pnmh )
{
BKLBITEMCALCMAXITEM *pdi = (BKLBITEMCALCMAXITEM*)pnmh;
pdi->nMaxHeight = CMDSET_LIST_ITEM_HEIGHT;
return 0;
}
LRESULT CChangeSkinDlg::OnListBoxGetItemHeight( LPNMHDR pnmh )
{
BKLBITEMCACLHEIGHT *pdi = (BKLBITEMCACLHEIGHT*)pnmh;
if (pdi->nListItemId >= m_nRowCount)
return 0;
pdi->nHeight = CMDSET_LIST_ITEM_HEIGHT;
return 0;
}
LRESULT CChangeSkinDlg::OnBkListBoxClickCtrl( LPNMHDR pnmh )
{
LPBKLBMITEMCLICK pnms = (LPBKLBMITEMCLICK)pnmh;
if (pnms->nListItemID >= m_nRowCount)
return 0;
UINT nSkinID = CON_LIST_COLUMN_COUNT * (pnms->nListItemID)+(pnms->uCmdID-IDC_SKIN_CMD1);
TYPEMAPSKINDEFINE::iterator pos;
int i=0;
for (pos = BkResManager::GetSkinMap().begin();pos != BkResManager::GetSkinMap().end();++pos,++i)
{
if (nSkinID==i)
{
UINT nID = pos->first;
if (!BkResManager::SetSkin(nID))
{
MessageBox(_T("此皮肤已损坏"));
}
else
{
TheConfigInfo::Instance().Set_SkinID(nSkinID);
}
}
}
BkPngPool::Clear();
BkBmpPool::Clear();
BkSkin::ReloadResource();
BkStyle::LoadStyles(IDR_BK_STYLE_DEF);
m_pParent->ReloadStyle();
m_pParent->Redraw();
return 0;
}
BOOL CChangeSkinDlg::OnInitDialog(CWindow /*wndFocus*/, LPARAM /*lInitParam*/)
{
InitCtrl();
SetDisplayRgn();
return TRUE;
}
void CChangeSkinDlg::RefreshAll()
{
for ( int i=0; i < m_nRowCount; ++i)
{
m_List->RedrawItem(i);
}
}
4.点击按钮,弹出换肤对话框.
void CFinancialHallDlg::OnBkBtnChangeSkin()
{
if (m_changeSkinDlg.IsWindowVisible())
{
m_changeSkinDlg.ShowWindow(SW_HIDE);
}
else
{
SetSkinWindow();
m_changeSkinDlg.ShowWindow(SW_SHOW);
}
}
5.确定按钮位置的函数。在OnSize、OnMove都调用此函数。
void CFinancialHallDlg::SetSkinWindow()
{
if (m_changeSkinDlg.IsWindow())
{
const int n_Dlg_Width = 187;
const int n_Dlg_Height = 82;
CRect rc,rc1;
GetWindowRect(&rc);
GetItemRect(IDC_CTL_IE_DLG,rc1);
m_changeSkinDlg.MoveWindow(
rc.left + rc1.right - n_Dlg_Width -107,
rc.top + 23,
n_Dlg_Width,
n_Dlg_Height);
}
}
7.OnListBoxGetItemHeight一定要设置控件高度,如果不设置,列表上的图片显示不出。