使用.msstyles皮肤文件美化MFC程序

xtreme中有个使用.msstyles文件美化Dialog的例子, VistaTaskDialog

改变皮肤的代码非常的简洁

void CTaskPageSamples::OnBnClickedCheckSkinframework() { UpdateData(); #ifdef _XTP_INCLUDE_SKINFRAMEWORK if (m_bSkinFramework) { XTPSkinManager()->LoadSkin(_T("Styles//zune.msstyles")); } else { XTPSkinManager()->LoadSkin(0, 0); } #endif }

.msstyles 文件类型:Windows XP Style 扩展名为.msstyles的文件是一个系统文件。 文件说明: Theme file for Windows XP that contains colors and images used by windows, buttons, and other elements within the Windows GUI; two popular MSSTYLES from Microsoft include the Luna and Zune themes; the Royale theme is used by Windows XP Media Center Edition. MSSTYLES files must be digitally signed by Microsoft in order to work correctly with the Windows operating system; custom themes developed by users can be implemented using the StyleXP program..msstyles 打开.msstyles文件 Mac OS Parallels Desktop 5 for Mac with Windows installed   Windows Referenced by the Windows operating system TGT Soft StyleXP (for custom MSSTYLES) 

 

使用皮肤文件来美化Dialog, 这是最简单的方案了, 只要更换.msstyles就可以有不同的效果.

皮肤效果可以由美工来完成或从网上下载各种皮肤. 即使是一个Demo,穿个新马甲, 也没人会说这是个Demo.

都会认为是精心泡制的UI, 增强用户使用我们软件的体验是一个好的开始.

 

实验完成

// stdafx.h : include file for standard system include files, // or project specific include files that are used frequently, but // are changed infrequently // #if !defined(AFX_STDAFX_H__A5758EF5_3D0B_4763_80FD_5910155A1345__INCLUDED_) #define AFX_STDAFX_H__A5758EF5_3D0B_4763_80FD_5910155A1345__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers #include <afxwin.h> // MFC core and standard components #include <afxext.h> // MFC extensions #include <afxdisp.h> // MFC Automation classes #include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls #ifndef _AFX_NO_AFXCMN_SUPPORT #include <afxcmn.h> // MFC support for Windows Common Controls #endif // _AFX_NO_AFXCMN_SUPPORT #include <XTToolkitPro.h> // Xtreme Toolkit Pro components //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_STDAFX_H__A5758EF5_3D0B_4763_80FD_5910155A1345__INCLUDED_)

// XtremeSkinDialogDlg.cpp : implementation file // #include "stdafx.h" #include "XtremeSkinDialog.h" #include "XtremeSkinDialogDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CXtremeSkinDialogDlg dialog CXtremeSkinDialogDlg::CXtremeSkinDialogDlg(CWnd* pParent /*=NULL*/) : CDialog(CXtremeSkinDialogDlg::IDD, pParent) { //{{AFX_DATA_INIT(CXtremeSkinDialogDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); TCHAR szStylesPath[_MAX_PATH]; VERIFY(::GetModuleFileName( AfxGetApp()->m_hInstance, szStylesPath, _MAX_PATH)); m_strStylesPath = szStylesPath; int nIndex = m_strStylesPath.ReverseFind(_T('//')); if (nIndex > 0) { m_strStylesPath = m_strStylesPath.Left(nIndex); } else { m_strStylesPath.Empty(); } m_strStylesPath += _T("//Styles//"); XTPSkinManager()->SetApplyOptions( XTPSkinManager()->GetApplyOptions() | xtpSkinApplyMetrics | xtpSkinApplyFrame | xtpSkinApplyColors | xtpSkinApplyMenus); XTPSkinManager()->LoadSkin(0, 0); } void CXtremeSkinDialogDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CXtremeSkinDialogDlg) // NOTE: the ClassWizard will add DDX and DDV calls here DDX_Control(pDX, IDC_SLIDER_SAMPLE, m_wndSlider); DDX_Control(pDX, IDC_TAB_SAMPLE, m_wndTab); DDX_Control(pDX, IDC_PROGRESS_SAMPLE, m_wndProgress); DDX_Control(pDX, IDC_LISTCTRL_SAMPLE, m_wndListCtrl); DDX_Control(pDX, IDC_LIST_SAMPLE, m_wndListBox); DDX_Control(pDX, IDC_SCROLLBAR_HORZ_SAMPLE, m_wndScrollBar); DDX_Control(pDX, IDC_CHECK_SAMPLE, m_wndCheckBox); DDX_Control(pDX, IDC_RADIO_SAMPLE, m_wndRadio); DDX_Control(pDX, IDC_BUTTON_SAMPLE, m_wndButton); DDX_CBIndex(pDX, IDC_COMBO_HORIZONTAL, m_nHorizAlign); DDX_CBIndex(pDX, IDC_COMBO_VERTICAL, m_nVertAlign); DDX_Check(pDX, IDC_CHECK_ENABLED, m_bEnabled); DDX_Radio(pDX, IDC_RADIO_VISUALTHEME, m_nVisualTheme); DDX_Check(pDX, IDC_CHECK_RIGHTBUTTON, m_bRightButton); DDX_Text(pDX, IDC_EDIT_SCROLLPOS, m_nScrollPos); DDX_Check(pDX, IDC_CHECK_MULTILINE, m_bMultiLine); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CXtremeSkinDialogDlg, CDialog) //{{AFX_MSG_MAP(CXtremeSkinDialogDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_TIMER() ON_BN_CLICKED(IDC_BUTTON2, OnButton2) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CXtremeSkinDialogDlg message handlers PCHAR szSkinStyle[] = { "Addy Blue.msstyles", "Aero7.msstyles", "dzartRV.msstyles", "Lucid (no user pic).msstyles", "Lucid.msstyles", "luna.msstyles", "New Luna.msstyles", "Sakura.msstyles", "VistaVG.msstyles", "zune.msstyles", "Vista.cjstyles", "WinXP.Luna.cjstyles", "WinXP.Royale.cjstyles", "Codejock.cjstyles", "Office2007.cjstyles", }; BOOL CXtremeSkinDialogDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here InitControl(); //ChangeSkin(); return TRUE; // return TRUE unless you set the focus to a control } void CXtremeSkinDialogDlg::ChangeSkin() { /** * @note * 在定时器中换Skin不好使, 刷新不好 * 也许 XTPSkinManager()->LoadSkin 不能在线程中用 * 可以在线程中SendMessage来改变皮肤 */ static int nSkinStylePos = 0; /** 一共15中皮肤, 类型有 *.msstyles, *.cjstyles */ int nSkinNumbers = sizeof(szSkinStyle) / sizeof(PCHAR); if(nSkinStylePos >= nSkinNumbers) { nSkinStylePos = 0; } CString csSkinStyleName = szSkinStyle[nSkinStylePos++]; CString csSkinStylePathName = m_strStylesPath + csSkinStyleName; UpdateData();/** !!!换肤之前必须执行 */ XTPSkinManager()->LoadSkin((LPSTR)(LPCSTR)csSkinStylePathName); CString csTitle; csTitle.Format("%d : %s", nSkinStylePos, csSkinStyleName); SetWindowText((LPSTR)(LPCSTR)csTitle); } void CXtremeSkinDialogDlg::InitControl() { SCROLLINFO si; si.fMask = SIF_ALL; si.nPos = 50; //si.nPage = 20; //si.nMax = 100 + si.nPage - 1; si.nPage = 2; si.nMax = 90 + si.nPage - 1; si.nMin = 0; m_wndScrollBar.SetScrollInfo(&si); m_wndSlider.SetRange(0, 10); m_wndSlider.SetSelection(2, 5); int i; for (i = 0; i < 20; i++) { CString strItem; strItem.Format(_T("item %i"), i); m_wndListBox.AddString(strItem); } m_wndListCtrl.InsertColumn(0, _T("Items"), LVCFMT_LEFT, 100); for (i = 0; i < 20; i++) { CString strItem; strItem.Format(_T("Item %i"), i); m_wndListCtrl.InsertItem(i, strItem); } m_wndProgress.SetPos(50); m_wndTab.SetWindowPos(&CWnd::wndTop, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); TCITEM item; item.mask = TCIF_TEXT; item.pszText = _T("Item &1"); m_wndTab.InsertItem(0, &item); item.pszText = _T("Item &2"); m_wndTab.InsertItem(1, &item); } void CXtremeSkinDialogDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CXtremeSkinDialogDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CXtremeSkinDialogDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CXtremeSkinDialogDlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default CDialog::OnTimer(nIDEvent); } void CXtremeSkinDialogDlg::OnButton2() { // TODO: Add your control notification handler code here ChangeSkin(); }

工程中自带了15中皮肤, 显示效果如下:

使用.msstyles皮肤文件美化MFC程序_第1张图片

 

使用.msstyles皮肤文件美化MFC程序_第2张图片

使用.msstyles皮肤文件美化MFC程序_第3张图片

使用.msstyles皮肤文件美化MFC程序_第4张图片

使用.msstyles皮肤文件美化MFC程序_第5张图片

使用.msstyles皮肤文件美化MFC程序_第6张图片

使用.msstyles皮肤文件美化MFC程序_第7张图片

使用.msstyles皮肤文件美化MFC程序_第8张图片

使用.msstyles皮肤文件美化MFC程序_第9张图片

使用.msstyles皮肤文件美化MFC程序_第10张图片

使用.msstyles皮肤文件美化MFC程序_第11张图片

使用.msstyles皮肤文件美化MFC程序_第12张图片

使用.msstyles皮肤文件美化MFC程序_第13张图片  

使用.msstyles皮肤文件美化MFC程序_第14张图片

使用.msstyles皮肤文件美化MFC程序_第15张图片

使用.msstyles皮肤文件美化MFC程序_第16张图片

工程下载点:

使用.msstyles皮肤文件美化MFC程序_第17张图片

 

<2010_1217>

今天发现了一种用法, 可以使程序的全部外观都编程皮肤效果. 而不用设置Theme, 使程序的风格统一. 而且原始编码不变, 适用于已经写好的程序. sdi, mdi, dialog..., 因为这种用法是针对窗口句柄的.

// stdafx.h : include file for standard system include files, // or project specific include files that are used frequently, but // are changed infrequently // #if !defined(AFX_STDAFX_H__76D6930F_C91A_41A0_8B11_C8FB0AE1BE6A__INCLUDED_) #define AFX_STDAFX_H__76D6930F_C91A_41A0_8B11_C8FB0AE1BE6A__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers #include <afxwin.h> // MFC core and standard components #include <afxext.h> // MFC extensions #include <afxdisp.h> // MFC Automation classes #include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls #ifndef _AFX_NO_AFXCMN_SUPPORT #include <afxcmn.h> // MFC support for Windows Common Controls #endif // _AFX_NO_AFXCMN_SUPPORT #include <XTToolkitPro.h> #define MY_MAX_PATH (INT)4096 #define G_CS_SKIN_FILE_NAME "VistaVG.msstyles" //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_STDAFX_H__76D6930F_C91A_41A0_8B11_C8FB0AE1BE6A__INCLUDED_)

CString CMainApp::GetStyleFilePathName() { int nIndex = 0; TCHAR szStylesPath[MY_MAX_PATH]; if(m_strStylesPath.IsEmpty()) { ZeroMemory(szStylesPath, MY_MAX_PATH); ::GetModuleFileName(m_hInstance, szStylesPath, _MAX_PATH); m_strStylesPath = szStylesPath; nIndex = m_strStylesPath.ReverseFind(_T('//')); if(nIndex > 0) m_strStylesPath = m_strStylesPath.Left(nIndex); else m_strStylesPath.Empty(); m_strStylesPath += _T("//skin//"); } return m_strStylesPath + G_CS_SKIN_FILE_NAME; }

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { /** @note * 这个应用皮肤的例子是针对sdi的,也适用于其他类型程序, 因为是针对窗口句柄的用法 */ CMainApp * pApp = (CMainApp *)AfxGetApp(); if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) { TRACE0("Failed to create toolbar/n"); return -1; // fail to create } if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT))) { TRACE0("Failed to create status bar/n"); return -1; // fail to create } // TODO: Delete these three lines if you don't want the toolbar to // be dockable m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndToolBar); /** * 如果皮肤不能应用,考虑在此加入UpdateWindow 或 Update之类的刷新窗口的代码 * sdi 可以直接应用皮肤文件 */ XTPSkinManager()->SetApplyOptions( XTPSkinManager()->GetApplyOptions() | xtpSkinApplyMetrics | xtpSkinApplyFrame | xtpSkinApplyColors | xtpSkinApplyMenus); XTPSkinManager()->LoadSkin((LPSTR)(LPCSTR)pApp->GetStyleFilePathName()); //可以使程序的全部的外观编程皮肤效果 XTPSkinManager()->ApplyWindow(this->m_hWnd); return 0; }

实际运行效果:

使用.msstyles皮肤文件美化MFC程序_第18张图片

使用.msstyles皮肤文件美化MFC程序_第19张图片

使用.msstyles皮肤文件美化MFC程序_第20张图片

使用.msstyles皮肤文件美化MFC程序_第21张图片

这种解决程序整理显示效果的方法简单, 有效, 效果好.

 

<2010_1222>

找到一个皮肤文件下载站点 : http://www.xpzhuti.org/

 

你可能感兴趣的:(windows,Microsoft,mfc,dialog,include,initialization)