卫士的换肤对话框,真的蛮好看的。我非常想做一个。我是用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一定要设置控件高度,如果不设置,列表上的图片显示不出。