关于MFC美化界面的一个实现

 熟悉VC/MFC编写界面的朋友经常会遇到这样的问题:自己编写的小软件功能已经完全实现,但是界面极其难看,因为使用的都是Windows默认的菜单,对话框,状态栏等元素。
因此,软件后期的美化界面是一项比较重要的工作,上网搜了一下,总结如下:
一般美化界面有很多方案:


A、使用皮肤,网上有很多现成的皮肤加载方案
B、给予对话框的使用CDialogSk和CButtonST简单美化(即贴图)
C、使用Flash 作界面
D、使用网页做界面
E、使用WPF
      第一种方案是最傻瓜的,也是使用比较多的.只要软件功能实现了,加入几行简单的代码就可以实现美化。

       第一种方案,经常用到的实现途径是使用SkinMagic换肤,SkinMagic网上有很多破解版本,而且网友也提供了很多漂亮的皮肤,只需要在程序中间加入几行初始化的代码即可使得程序瞬间变得很漂亮,一般使用方法如下:
(1)将SkinMagicTrial.lib、SkinMagicTrial.dll和SkinMagicLib.h拷贝到项目根目录下,并在工程中添加;
(2)把Skins文件夹放在项目根目录下;
(3)将 #include "SkinMagicLib.h" 拷贝到 StdAfx.h文件中;
(4)在C**App类中打开InitInstance()函数,在函数其开始部分增加
       VERIFY( 1 == InitSkinMagicLib( AfxGetInstanceHandle(), _T("ReadUI") ,NULL,NULL ) );
       VERIFY( 1 == LoadSkinFile("Skins\\corona.smf")); 
       VERIFY( 1 == SetDialogSkin( _T("Dialog") ) );
(5)在InitInstance()函数最后,但在以下代码之前,
       m_pMainWnd->ShowWindow(SW_SHOW);
       m_pMainWnd->UpdateWindow();
 加入如下代码
        VERIFY( 1 == SetWindowSkin(m_pMainWnd->m_hWnd ,  _T("MainFrame") ) );
(6)通过类向导给C**App增加ExitInstance() 函数,内容如下
        ExitSkinMagicLib();
        return CWinApp::ExitInstance();
这样就很轻松实现美化界面的目标。
  

       但是经我本人实践,使用这个方法会出现一个问题:换肤后导致主菜单项不能像以前那样操作;比如以前我想操作第一个子菜单,就可以使用CMenu *pMenu=GetMenu()->GetSubMenu(0)获取控制, 但是使用了SkinMagic之后编译依然正常,但运行时却出错!!!


      究其原因:产生该Bug的原因是SkinMagic在换肤时将窗体上面的默认菜单栏给去掉了,就是使用了SetMenu(NULL)方法。目的是为了用户在操作时不再有默认的菜单栏在原位置出现。用户所看到的菜单栏其实是SkinMagic通过内部保存的HMenu来绘制的。所以用户在GetMenu()时返回的值为NULL,CMenu *pMenu=GetMenu()->GetSubMenu(2) 这段话自然就会出错。


         多次察看SkinMagicLib.h文件,终于找到解决办法如下:
      SkinMagic的动态库中都会提供了一个这样的函数HMENU __stdcall GetSkinMenu( HWND hWnd ),看到他就知道什么意思了吧?当时是可以得到菜单的句柄,这样的话就可以联合API函数HMENU GetSubMenu(  HMENU hMenu,   int nPos)得到子菜单的句柄,进而进行一些操作:
比如此时我要禁止第一个子菜单的第一个菜单项,就可以使用如下语句
EnableMenuItem(GetSubMenu(GetSkinMenu(*AfxGetApp()->m_pMainWnd), 0), 0, MF_BYPOSITION  | MF_GRAYED | MF_DISABLED);

           一起去充分享受界面随意改变的乐趣吧。。。。。

你可能感兴趣的:(windows,Flash,null,mfc,dialog,WPF)