使用DSkinLite美化界面


相信已经有很多人用过QQ2009了,自然也对其中的UI设计很感兴趣,觉得设计很是完美。但是这是怎么设计的呢?下面我介绍一个用来实现这种效果的设计库--DSkinLite(源于CodeProject)。下面通过一个演示程序来介绍使用过程:

程序中,我主要对主窗口和两个通用对话框(打开对话框和浏览对话框)进行了换肤,这里我所有的窗口都使用了同一个皮肤(定义在XML文件中),通常应该为每个对话框都定义自己的皮肤。下面我简要描述一下使用过程:

1、 将头文件和库文件放在你的工程目录下:

(1) 头文件路径

…/FileCutterTool/include,其中包含DskinDef.h和DSkinDLL.h两个文件

(2) 库文件路径

…/FileCutterTool/lib,其中dskinlite.lib为多字节编码,dskinliteu.lib为Unicode编码

(3) 在工程的属性中添加附加依赖项路径,保证.lib库导入到工程中。

2、 在stdafx.h中导入库文件:


#ifdef DSKINDLL_EXPORTS

#define DSKINDLL_API extern "C" __declspec(dllexport)

#else

#define DSKINDLL_API extern "C" __declspec(dllimport)

#endif

#include "../include/dskindll.h"

#include "../include/dskindef.h"

#include <afxdlgs.h>


3、 在FileCutterTool.cpp文件中添加初始化库和结束库的代码:

(1) 在InitInstance()中添加初始化库代码


//Load the skin theme

dsLoadSkin( _T("SkinQQ"));


(2) 在Existance()中添加结束库的代码(也可放在InitInstance()的最后)

dsExitSkin();

4、 在XML文件中定义皮肤(略)

5、 在对话框的OnInitDialog()中添加换肤的代码


dsSkinWindow( GetSafeHwnd(), SKIN_TYPE_DIALOG, _T("mfctestdialog"), FALSE);

dsSkinWindow( GetDlgItem( IDC_SOURCEBROWSER)->GetSafeHwnd(), SKIN_TYPE_BUTTON, _T("button"), FALSE);

dsSkinWindow( GetDlgItem( IDC_DESTBROWSER)->GetSafeHwnd(), SKIN_TYPE_BUTTON, _T("button"), FALSE);

dsSkinWindow( GetDlgItem( IDC_START)->GetSafeHwnd(), SKIN_TYPE_BUTTON, _T("button"), FALSE);

dsSkinWindow( GetDlgItem( IDC_STOP)->GetSafeHwnd(), SKIN_TYPE_BUTTON, _T("button"), FALSE);

dsSkinWindow( GetDlgItem( IDCANCEL)->GetSafeHwnd(), SKIN_TYPE_BUTTON, _T("button"), FALSE);

dsSkinWindow( GetDlgItem( IDC_STATIC_1)->GetSafeHwnd(), SKIN_TYPE_STATIC, NULL, FALSE);

dsSkinWindow( GetDlgItem( IDC_STATIC_2)->GetSafeHwnd(), SKIN_TYPE_STATIC, NULL, FALSE);

dsSkinWindow( GetDlgItem( IDC_EDITSOURCE)->GetSafeHwnd(), SKIN_TYPE_EDIT, _T("edit"), FALSE);

dsSkinWindow( GetDlgItem( IDC_EDITDEST)->GetSafeHwnd(), SKIN_TYPE_EDIT, _T("edit"), FALSE);

dsSkinWindow( GetDlgItem( IDC_STATUSTEXT)->GetSafeHwnd(), SKIN_TYPE_EDIT, _T("edit"), FALSE);

dsSkinWindow( GetDlgItem( IDC_SELECTSPLIT)->GetSafeHwnd(), SKIN_TYPE_RADIOBUTTON, _T("radiobutton"), FALSE);

dsSkinWindow( GetDlgItem( IDC_SELECTMERGE)->GetSafeHwnd(), SKIN_TYPE_RADIOBUTTON, _T("radiobutton"), FALSE);

dsSkinWindow( GetDlgItem( IDC_COMBO1)->GetSafeHwnd(), SKIN_TYPE_COMBOBOX, _T("combobox"), FALSE);

dsSkinWindow( GetDlgItem( IDC_STATIC)->GetSafeHwnd(), SKIN_TYPE_GROUPBOX, _T("groupbox"), FALSE);

dsSkinWindow( GetDlgItem( IDC_PROGRESS1)->GetSafeHwnd(), SKIN_TYPE_PROGRESS, _T("progress"), FALSE);

dsSkinWindow( GetDlgItem( IDC_BUTTON1)->GetSafeHwnd(), SKIN_TYPE_BUTTON, _T("mainmenubutton"), FALSE);

dsSkinWindow( GetDlgItem( IDC_BUTTON2)->GetSafeHwnd(), SKIN_TYPE_BUTTON, _T("messagebutton"), FALSE);

dsSkinWindow( GetDlgItem( IDC_BUTTON3)->GetSafeHwnd(), SKIN_TYPE_BUTTON, _T("smsbutton"), FALSE);

dsSkinWindow( GetDlgItem( IDC_BUTTON4)->GetSafeHwnd(), SKIN_TYPE_BUTTON, _T("appcenterbutton"), FALSE);

dsSkinWindow( GetDlgItem( IDC_BUTTON5)->GetSafeHwnd(), SKIN_TYPE_BUTTON, _T("petbutton"), FALSE);

dsSkinWindow( GetDlgItem( IDC_BUTTON6)->GetSafeHwnd(), SKIN_TYPE_BUTTON, _T("gamebutton"), FALSE);

dsSkinWindow( GetDlgItem( IDC_BUTTON7)->GetSafeHwnd(), SKIN_TYPE_BUTTON, _T("chatbutton"), FALSE);


6、 为打开对话框添加换肤代码

要为打开对话框添加换肤代码,首先要自定义一个类,在类中实现,详细代码如下:

头文件:


#pragma once

// CMyFileDialog

class CMyFileDialog

{

// 接口

public:

// 构造函数

CMyFileDialog(void);

// 获取文件全名(含路径)

LPCTSTR GetFile() { return m_szFile; }

// 显示打开对话框

BOOL OpenFileDialog(HWND hWndParent);

// 内部实现

protected:

// 文件名

WCHAR m_szFile[MAX_PATH];

OPENFILENAME m_openFile;

// CALLBACK function

static UINT_PTR CALLBACK OFNHookProc(HWND hdlg,UINT uiMsg,WPARAM wParam,LPARAM lParam);

};


实现文件:


// MyFileDialog.cpp : 实现文件

//

#include "stdafx.h"

#include "FileCutterTool.h"

#include "MyFileDialog.h"

#include "windows.h"

// CMyFileDialog

CMyFileDialog::CMyFileDialog()

{

memset(m_szFile,0,MAX_PATH);

::ZeroMemory(&m_openFile,sizeof(OPENFILENAME));

m_openFile.lStructSize = sizeof(OPENFILENAME);

m_openFile.hwndOwner = NULL;

m_openFile.lpstrFile = m_szFile;

m_openFile.nMaxFile = MAX_PATH;

m_openFile.lpstrFilter = _T("All Files(*.*)/0*.*/0/0");

// m_openFile.Flags = OFN_ENABLEHOOK | OFN_EXPLORER;

m_openFile.Flags = OFN_ENABLEHOOK;

m_openFile.lpfnHook = OFNHookProc;

}

BOOL CMyFileDialog::OpenFileDialog(HWND hWndParent)

{

m_openFile.hwndOwner = hWndParent;

if(GetOpenFileName(&m_openFile))

{

return TRUE;

}

return FALSE;

}

UINT_PTR CALLBACK CMyFileDialog::OFNHookProc(HWND hdlg,UINT uiMsg,WPARAM wParam,LPARAM lParam)

{

if (uiMsg==WM_INITDIALOG)

{

dsSkinWindow( hdlg, SKIN_TYPE_DIALOG, _T("mfctestdialog"), TRUE);

}

return 0;


}

调用代码:


// 打开文件对话框

CMyFileDialog sourceDlg;

if (sourceDlg.OpenFileDialog(m_hWnd))

{

// 获取源文件名

strSourceText = sourceDlg.GetFile();


}

7、 为浏览对话框添加换肤代码

要实现为浏览对话框换肤,也需要自定义一个类,详细实现代码如下:

头文件:


#ifndef _DIRDIALOG_H_

#define _DIRDIALOG_H_

#include <shlobj.h>

class CDirDialog

{

// 接口

public:

CDirDialog(void);

// 显示浏览对话框

BOOL DoBrowser(HWND hWndParent,LPCTSTR pszTitle = NULL);

// 取得用户选择的目录名称

LPCTSTR GetPath() { return m_szPath; }

protected:

// 浏览对话框所需的结构体,详见MSDN

BROWSEINFO m_info;

// 用来接受用户选择目录的缓冲区

WCHAR m_szDisplay[MAX_PATH];

WCHAR m_szPath[MAX_PATH];

// CALLBACK function

static int CALLBACK BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam,LPARAM lpData);

};


#endif // _DIRDIALOG_H_

实现文件:


#include "stdafx.h"

#include "windows.h"

#include "DirDialog.h"

CDirDialog::CDirDialog()

{

memset(&m_info,0,sizeof(m_info));

m_info.hwndOwner = NULL;

m_info.pidlRoot = NULL;

m_info.pszDisplayName = m_szDisplay;

m_info.lpszTitle = NULL;

m_info.ulFlags = BIF_RETURNONLYFSDIRS;

m_info.lpfn = BrowseCallbackProc;

m_szPath[0] = '/0';

}

BOOL CDirDialog::DoBrowser(HWND hWndParent, LPCTSTR pszTitle)

{

if (pszTitle == NULL)

{

m_info.lpszTitle = _T("选择目标文件夹");

}

else

{

m_info.lpszTitle = pszTitle;

}

m_info.hwndOwner = hWndParent;

LPITEMIDLIST pItem = ::SHBrowseForFolder(&m_info);

if (pItem != 0)

{

::SHGetPathFromIDList(pItem,m_szPath);

return TRUE;

}

return FALSE;

}

int CALLBACK CDirDialog::BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam,LPARAM lpData)

{

if (uMsg==BFFM_INITIALIZED)

{

dsSkinWindow( hwnd, SKIN_TYPE_DIALOG, _T("mfctestdialog"), TRUE);

}

return 0;


}

调用代码:


// 浏览目录对话框

CDirDialog sourceDlg;

if (sourceDlg.DoBrowser(m_hWnd))

{

// 获取源文件目录

strSourceText = sourceDlg.GetPath();


}

上面的代码即可实现换肤,在这里我要强调一个函数dsSkinWindow(),当最后一个参数为TRUE时,则整个窗口可实现全部换肤;当为FALSE时,只是对窗口框架进行换肤,而其中的控件则不做修改,需要自己逐个换肤,详细代码可以参照上面代码。


你可能感兴趣的:(使用DSkinLite美化界面)