• 用DSkinLite实现QQ界面


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

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

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

    (1)    头文件路径

    …\FileCutterTool\include,其中包含DskinDef.hDSkinDLL.h两个文件

    (2)    库文件路径

    …\FileCutterTool\lib,其中dskinlite.lib为多字节编码,dskinliteu.libUnicode编码

    (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时,只是对窗口框架进行换肤,而其中的控件则不做修改,需要自己逐个换肤,详细代码可以参照上面代码。

  • 相关阅读:
    剑指offer2:替换空格
    题目:求第五个人的年龄
    编写一个函数,输入n为偶数时,调用函数求1/2+1/4+…+1/n,当输入n为奇数时,调用函数1/1+1/3+…+1/n(利用指针函数)
    原创| 输入数组,最大的与第一个元素交换,最小的与最后一个元素交换,输出数组。
    编程题30 题目:将一个数组逆序输出。
    编程题32 题目:取一个整数a从右端开始的4~7位。
    编程题31 题目:将一个数组逆序输出。
    daisy的词源
    2018年学习日志
    11
  • 原文地址:https://www.cnblogs.com/buffer/p/1408379.html
Copyright © 2020-2023  润新知