原文转至:http://blog.csdn.net/zhangyang1990828/article/details/10489085 html
前些天用MFC开发一个桌面程序,实现功能后客户说界面太难看,本身仔细看看也着实难看,因此就仔细的研究了下MFC的美化方法,特此分享给你们。 less
★利用SkinMagic美化MFC的界面。 函数
SkinMagic是一个C++的皮肤库,使用它能够完美的实现给你的程序换肤。 oop
代码运行效果图以下: 学习
之前看到瑞星和金山词霸有换皮肤功能,非常羡慕,本身也想作个换皮肤的程序,但下手着实有些困难。我也试过像BCGCBar这样的大型软件,给个人感受是软件总是出问题,应用起来也很复杂。后来知道了SkinMagic软件包,但当时不知怎么用,发了贴子也没人回答。多是不多有人用的缘故吧,本站也未更新此软件包。偶然的一次机会,让我知道了怎样来用它, 字体
并且编译出来的软件体积很小,因此在这里向你们介绍一下,但愿对你们有些帮助。 动画
如何使用: 网站
① 新建工程后,将SkinMagic包中的SkinMagicLib.h、SkinMagicLib.lib、DETOURS.lib拷贝到所在文件夹下,点击Project->Add To Project->Files,包含到工程中。 ui
② 在Resource View中点击Import 菜单引入几个Skin二进制文件放在相同的“SKINMAGIC”文件夹下,分别给起一个名字(见源程序)。 this
③ 在stdafx.h中加入#include "SkinMagicLib.h"
④ 在此处添加以下内容
01.
if
(!ProcessShellCommand(cmdInfo))
02.
return
FALSE;
03.
/////////////////////////////////////////////////////////////
04.
VERIFY( 1 == InitSkinMagicLib( AfxGetInstanceHandle(),
"Demo"
,NULL,NULL ) );
//初始化类库
05.
VERIFY( 1 == LoadSkinFromResource( AfxGetInstanceHandle() ,
"KROMO"
,
"SKINMAGIC"
) );
//从资源中加载皮肤
06.
07.
VERIFY( 1 == SetWindowSkin( m_pMainWnd->m_hWnd ,
"MainFrame"
));
08.
VERIFY( 1 == SetDialogSkin(
"Dialog"
) );
09.
((CMainFrame*)m_pMainWnd)->m_bSkinned = TRUE;
10.
((CMainFrame*)m_pMainWnd)->m_nIndex = 0;
11.
////////////////////////////////////////////////////////
12.
m_pMainWnd->ShowWindow(SW_SHOW);
13.
m_pMainWnd->UpdateWindow();
⑤ 在MainFrame中加入换皮肤菜单,及相应的函数,在函数中加载皮肤。
1.
void
CMainFrame::OnDevior()
2.
{
3.
LoadSkinFromResource( AfxGetInstanceHandle() ,
"DEVIOR"
,
"SKINMAGIC"
) ;
4.
}
到此为止,完美的换皮肤程序就出来了。
若是想更换皮肤只须要更换LoadSkinFromResource的参数为当前目录下的皮肤文件就能够了。
我这里有完整的demo已经不少的皮肤文件,须要的能够点击这里下载。
★利用flash来美化MFC的界面:
效果图:
代码:
[cpp] view plaincopyprint?
BOOL CPlayFlashDlg::OnInitDialog() { CDialog::OnInitDialog(); ... // TODO: Add extra initialization here RECT rc; this->GetClientRect(&rc); m_FlashPlayer.MoveWindow( &rc, true ); TCHAR strCurDrt[500]; int nLen = ::GetCurrentDirectory(500,strCurDrt); if( strCurDrt[nLen]!='\\' ) { strCurDrt[nLen++] = '\\'; strCurDrt[nLen] = '\0'; } CString strFileName = strCurDrt; strFileName += "startup.swf"; m_FlashPlayer.LoadMovie(0, strFileName); m_FlashPlayer.Play(); return TRUE; // return TRUE unless you set the focus to a control }
[cpp] view plaincopyprint?
void CPlayFlashDlg::OnFSCommandShockwaveflash1(LPCTSTR command, LPCTSTR args) { // TODO: Add your control notification handler code here if( 0 == strcmp(command,"bt") ) { if( 0 == strcmp(args,"enter") ) { MessageBox("欢迎进入系统!"); } } else if( 0 == strcmp(command,"quit") ) { MessageBox("您选择了退出!"); CDialog::OnCancel(); } }
一下是一些详细的介绍:
1、准备工做
第一步:下载并安装Adobe Flash Player。
从官方网站(http://get.adobe.com/cn/flashplayer/)上下载最新的Flash Player(大约为2.66M),并安装。对于Windows 32位系统,其默认安装目录为:C:\WINDOWS\system32\Macromed\Flash\;对于64位系统,为:C:\Windows\SysWOW64\Macromed\Flash。
Flash控件的大版本号用数字表示,如9,10,11等,小版本号用小写字母表示,如a, b, c, d, e。如我安装的版本为:Flash10l.ocx。
第二步:经过regsvr32.exe注册flash控件 Flash10l.ocx。
从开始菜单中打开运行对话框,并输入:
regsvr32 C:\Windows\SysWOW64\Macromed\Flash\Flash10l.ocx 注册该控件(注册以后就能够在项目中进行控件添加了),若是注册成功,有以下提示:
注销控件的命令行为
regsvr32 /u C:\Windows\SysWOW64\Macromed\Flash\Flash10l.ocx。
2、新建MFC项目,添加Flash控件
第一步:创建基于对话框的MFC程序。
打开Visual Studio 2010,新建项目,选择“MFC应用程序”,并将其命名为MFCFlash。
在接下来的选型设置中,选择应用程序类型为“基于对话框”,其余可按默认设置。项目建成后,程序默认添加了MFCFlash和MFCFlashDlg的头文件和实现文件,截图以下:
第二步:添加Shockwave Flash Object类。
VC++ 6.0中,可使用ClassWizard添加ActiveX控件,而VS2005之后的版本没有。若是要添加ActiveX对应的类,能够先在解决方案管理器中选中项目后在菜单中点“项目”→“添加类”→“ActiveX控件中的MFC类”,打开“从ActiveX控件添加类向导”对话框。选择从“文件”添加类,找到Flash控件的安装位置,便可添加Shockwave Flash控件,接口选择“IShockwaveFlash”,以生成CShockwaveFlash类(类的名称能够修改)。插入后,VC会自动把这个类加入工程里面。
第三步:添加Shockwave Flash Object控件。
在资源视图里找到“Dialog”,并选择其中的IDD_MFCFLASH_DIALOG,在其上点右键,选择“插入ActiveX控件”,从弹出的列表中选择“Shockwave Flash Object”。
使用BUTTON、EDIT等其它Windows控件同样,咱们可使用这个类的成员函数来操纵这个对象,来进行Flash动画的控制以及和本身的程序进行交互等操做了。在Flash控件上点右键,而后选择“添加变量”,设定“变量名”为:m_FlashPlayer。可再次在Flash控件上点右键,而后选择“属性”,将其ID改成IDC_SHOCKWAVEFLASH。
第四步:使用成员函数LoadMovie和Play来导入并播放动画。
在MFCFlashDlg.cpp文件中,找到CMFCFlashDlg::OnInitDialog()函数,在“return TRUE”以前添加代码:
CString str = _T("E:\\VS\\Flash\\media\\test.swf");
m_FlashPlayer.LoadMovie (0, str);
m_FlashPlayer. Play ();
其中m_FlashPlayer.LoadMovie(0, str)用来将动画导入程序中,str为要播放的flash路径,要用绝对路径(注意路径用双斜杠“\\”隔开); m_FlashPlayer. Play ()开始播放动画。
相对路径转绝对路径:
wchar_t szPath[MAX_PATH];
memset(szPath, 0, sizeof(CHAR)*MAX_PATH);
GetCurrentDirectory(MAX_PATH, szPath);
StrCat(szPath, _T("\\风扇.swf"));
如今运行程序,就能够看到flash嵌入到程序里面了。还有几个经常使用的函数能够用来控制动画的播放,如GotoFrame(long FrameNum)能够转到FrameNum侦播放(侦数从0开始),StopPlay()能够中止播放。。。,还有不少,能够本身试试。下图是我作的一个飞行仪表,界面比较丑陋,凑合看吧^_^
3、实现MFC与Flash的通讯
一、Flash经过FSCommand消息调用MFC
第一步:添加消息处理函数。
在Flash控件上点右键,而后选择“添加事件处理程序”,在类列表选择“CMFCFlashDlg”,消息类型选择“FSCommand”,则函数处理程序名称自动为“FSCommandShockwaveflash”。它的形式大概是这样子的:
void CMFCFlashDlg::OnFSCommandShockwaveflash(LPCTSTR command, LPCTSTR args) ;函数有两个参数,就是flash的Action Script中FSCommand语句中的两个参数。其实并不必定两个参数都用到,flash脚本中能够就使用一个参数,这样这边的函数就只要对第一个参数进行处理就好了。
第二步:编写消息处理代码。
在刚添加的FSCommand消息处理函数中,对两个参数进行处理。其实就是作字符串比较的操做,根据是什么字符串来判断用户进行了什么操做。大概就是这样子的:
void CPlayFlashDlg::OnFSCommandShockwaveflash1(LPCTSTR command, LPCTSTR args)
{
// TODO: Add your control notification handler code here
if( 0 == strcmp(command,”bt”) )
{
if( 0 == strcmp(args,”enter”) )
{
MessageBox(“欢迎进入系统!”);
}
}
else if( 0 == strcmp(command,”quit”) )
{
MessageBox(“您选择了退出!”);
CDialog::OnCancel();
}
}
这只是最简单的处理形式,固然你能够在flash中发送复杂的字符串,在这边就要进行更多的处理了。
二、MFC经过CallFunction函数调用Flash
第一步:Flash中ExternalInterface.addCallback用处理。
在FLASH中,要用ExternalInterface.addCallback把能被外部调用的函数注册一下,例如: ExternalInterface.addCallback("setAlt", setAlt);
function setAlt (para:String = "3150")
{
alt.text = para; //alt为swf文件中的一个动态文本
}
第二步:MFC中使用CallFunction函数传入参数。
想让MFC主动往flash传内容而且让flash响应,用控件的CallFunction方法。在MFC中,调用CallFunction方法,传入一个比较复杂的字符串,描述了要调用的函数的名称、参数等等,以XML的形式呈现。详情参考FLASH帮助的“外部 API 的 XML 格式”一文。此处CallFunction传递的参数为XML格式,以下:
CString temp = _T("<invoke name=\"setAlt\" returntype=\"xml\">\
<arguments><string>3500FT</string></arguments>\
</invoke>");
m_FlashPlayer.CallFunction(temp);
注意,<arguments>必须是完整的一行,具体为何我也不太清楚。再次运行程序,能够发现ALT的值已经由3280FT变成了3500FT。
shockwave flash object控件的相应类是CShockwaveFlash类,该类的经常使用函数:
Play() 播放动画 StopPlay() 中止动画 IsPlaying():动画是否正在播放(true,false)
GotoFrame(frame_number)跳转到某帧(frame_number+1)
TotalFrames() 获取动画总帧数 CurrentFrame()回传当前动画所在帧数-1
Rewind() 使动画返回第一帧 SetZoomRect(left,top,right,buttom)放大指定区域
Zoom(percent) 改变更画大小 Pan(x_position,y_position,unit) 使动画在x,y方向上平移
PercentLoaded()返回动画被载入的百分比(0-100)
LoadMovie(level_number,path) 加载动画
TGotoFrame(movie_clip,frame_number) movie_clip跳转到指定帧数
TGotoLabel(muvie_clip,label_name) movie_clip跳转到指定标签
TCurrentFrame(movie_clip) 回传movie_clip当前帧-1
TCurrentLabel(movie_clip) 回传movie_clip当前标签
TPlay(movie_clip) 播放movie_clip TStopPlay(movie_clip) 中止movie_clip的播放
GetVariable(variable_name) 获取变量 SetVariable(variable_name,value) 变量赋值
TCallFrame(movie_clip,frame_number) call指定帧上的action
TCallLabel(movie_clip,label) call指定标签上的action
TGetProperty(movie_clip,property) 获取movie_clip的指定属性
TSetProperty(movie_clip,property,number) 设置movie_clip的指定属性
MFC中CShockwaveFlash控件相关说明
MFC中播放Flash使用的ActiceX控件Shockwave Flash Object,其对应的类为CShockwaveFlash。下面给出该控件的经常使用属性和方法说明:
==================================
FLASH播放器控件相关属性和方法说明.
==================================
++++++++++++++++++++++++
++++++++++属性++++++++++
++++++++++++++++++++++++
语法:AlignMode As Long
说明:对齐方式(与SAlign属性联动).当控件的长宽比例与影片不一致且WMode不为ExactFit时,影片在控件中显示的位置可用该属性调整.
属性值与相应的对齐方式:
1:左对齐
2:右对齐
4:顶对齐
8:底对齐
注意:也能够组合各类对齐方式,就是将这四个基本值组合相加.好比同时左对齐和顶对齐,属性值则设为5.
语法:BackgroundColor As Long
说明:影片的背景色.默认的影片背景色为-1.若是影片设置了底色或有图片看成背景,那么看不出来该属性值的改变会有什么影响 。
注意:颜色值使用RGB格式的颜色值
语法:Base As String
说明:指定用于解决影片中全部相对路径的声明的基地址.当影片与其须要的其余文件不在同一目录中的时候该属性特别有用.如不特别指定,Base的值默认为".",也就是当前影片所在的路径.
语法:BGColor As String
说明:影片的背景色.与BackgroundColor不一样的是,BGColor是一个六位的十六进制数,每两位分别表明红绿蓝颜色值.如:FFEEAA表示R值为FF,G值为EE,B值为AA.
语法:DeviceFont As Boolean
说明:决定是否使用影片内嵌的字体,默认值为False.将该属性值设为True则强制播放器不使用影片中内嵌的字体而使用本地系统字体.
语法:EmbedMovie As Boolean
说明:影片是否被存贮到控件所在的容器中.当你已载入一个影片后将该属性设为True,播放影片时就没必要再去读取SWF文件了.这样可使SWF文件镶进程序中,没必要再读取文件.但将该属性设为True后,控件的Movie属性就再也不接受新的值了.要想播放另外一个影片(给Movie属性赋新值),必须先将该属性(EmbedMovie)设为False.
语法:FrameNum As Long
说明:影片当前帧的编号(从0开始计数).设置该属性值将使影片停在由FrameNum指定的帧处.
注意:不只能够从中得到当前帧,还能够设置当前帧,即跳转到某帧
语法:Loop As Boolean
说明:控制影片是否循环播放.设为True就是循环播放,设为False则只播放一次.
语法:Menu As Boolean
说明:是否显示菜单.设为True显示全部菜单,设为False菜单被屏蔽,但仍有一项"About Macromedia Flash Player...",点击后会打开Macromedia的网站.若是你实在不喜欢这个菜单,应该在程序中经过拦截鼠标消息的方法来达到目的.
语法:Movie As String
说明:要播放的影片路径(URL).设置该属性为一个SWF文件的URL,当该属性被设置后,控件将自动载入文件并播放它.
语法:Playing As Boolean
说明:当前播放状态.若是影片正在播放,该属性值为True,不然为False.
语法:Quality As Long
说明:画面质量.
Quality的属性能够取:
0:至关于Quality2取"Low"
1:至关于Quality2取"High"
2:至关于Quality2取"AutoLow"
3:至关于Quality2取"AutoHigh"
语法:Quality2 As String
说明:画面质量
Quality的属性能够取:
Low:偏重于播放速度而无论显示效果,并且不启用消除锯齿功能.
High:偏重于画面而无论播放速度,而且老是启用消除锯齿功能.若是影片中不包含动画就平滑处理位图;若是有动画,那么位图就不被平滑处理.
AutoLow:先着重于播放速度,但只要有可能就改善显示效果.一开始播放时先禁用消除锯齿功能.若是播放器检测处处理器能承受得了,就启用消除锯齿功能.
AutoHigh:一开始是播放速度和显示效果并重,但若有必要就牺牲画质确保速度.开始播放时就启用消除锯齿功能.但若是实际的帧速率比设计时指定的速率慢了,就禁用消除锯齿功能来提升播放速度.
语法:ReadyState As Long
说明:影片的当前状态.
ReadyState的值有:
0:正在载入
1:未初始化
2:已载入
3:正在交互
4:完成例子
注意:可使用该属性来粗略的判断SWF文件的读取进度,但若是想获得更精确的判断,应该在在SWF文件中使用FScommand()来达到与VB的互动与联系,即传送资料给VB.
语法:SAlign As String
说明:对齐模式.与上文的AlignMode相同,但值的形式不一样罢了.
可取值:
L:即左对齐
T:即顶对齐
R:即右对齐
B:即底对齐
注意:当使用组合对齐方法是L,T,R,B的前后顺序不能变,如:左和底的对齐:SAlign="LB"
语法:Scale As String
说明:控制影片的缩放模式.
Scale的值能够取:
ShowAll:在控件内显示所有影片区域,保持影片长宽比例不变,影片的大小决定于控件长或宽中较小的一边.
NoBorder:在控件内显示部分影片区域,保持影片长宽比例不变,影片的大小决定于控件长或宽中较大的一边.
ExactFit:在控件内显示所有影片区域,不考虑影片的长宽比例,强制将影片的长宽等于控件的长宽.
语法:ScaleMode As Long
说明:缩放模式,与Scale相同,只不过属性值为数字而已.
ScaleMode能够取:
0:至关于Scale取"ShowAll"
1:至关于Scale取"NoBorder"
2:至关于Scale取"ExactFit"
语法:TotalFrames As Long
说明:返回影片中总帧数.该参数要到影片载入完成才有效,即ReadyState=4
语法:WMode As String
说明:控件的窗口模式(实现矢量图在VB界面显示的重要属性).
WMode能够取:
Window:WMode属性的默认值,按Flash播放器典型的方式工做,即在控件的矩形窗口中播放影片,这样通常都能提供最快的动画效果.
Opaque:使影片不透明.
Transparent:建立一个透明的影片,若是影片中有透明的片断时,就能够看到控件下面的背景.但使用此属性值,动画的播放速度可能会慢一些.
++++++++++++++++++++++++
++++++++++方法++++++++++
++++++++++++++++++++++++
Play() // 播放动画
StopPlay() // 中止动画
IsPlaying() // 动画是否正在播放(true,false)
GotoFrame(frame_number) // 跳转到某帧(frame_number+1)
CurrentFrame() // 回传当前动画所在帧数-1
Rewind() // 使动画返回第一帧
SetZoomRect(left,top,right,buttom) // 放大指定区域
Zoom(percent) // 改变更画大小
Pan(x_position,y_position,unit) // 使动画在x,y方向上平移
PercentLoaded() //返回动画被载入的百分比(0-100)
LoadMovie(level_number,path) // 加载动画
GetVariable(variable_name) // 获取变量
SetVariable(variable_name,value) //变量赋值
TotalFrames() // 获取动画总帧数
TPlay(movie_clip) // 播放movie_clip
TStopPlay(movie_clip) //中止movie_clip的播放
TGotoFrame(movie_clip,frame_number) // movie_clip跳转到指定帧数
TGotoLabel(muvie_clip,label_name) // movie_clip跳转到指定标签
TCurrentFrame(movie_clip) // 回传movie_clip当前帧-1
TCurrentLabel(movie_clip) // 回传movie_clip当前标签
TCallFrame(movie_clip,frame_number) // call指定帧上的action
TCallLabel(movie_clip,label) // call指定标签上的action
TGetProperty(movie_clip,property) // 获取movie_clip的指定属性
TSetProperty(movie_clip,property,number)// 设置movie_clip的指定属性
★用Html来美化咱们的MFC
效果图:
代码:
[cpp] view plaincopyprint?
CWebBrowser2 m_wndWeb; CWebBrowser2 m_wndWeb2; CHAR szPath[MAX_PATH]; memset(szPath, 0, sizeof(CHAR)*MAX_PATH); GetCurrentDirectory(MAX_PATH, szPath); StrCat(szPath, _T("\\Custom.html")); m_wndWeb.Navigate(szPath, NULL, NULL, NULL, NULL); CHAR szPath2[MAX_PATH]; memset(szPath2, 0, sizeof(CHAR)*MAX_PATH); GetCurrentDirectory(MAX_PATH, szPath2); StrCat(szPath2, _T("\\Custom1.html")); m_wndWeb2.Navigate(szPath2, NULL, NULL, NULL, NULL);具体的互操做的问题能够参考下例子,这里只介绍美化的工做。demo能够在 这里下载 。
★利用其它前辈封装好的类进行美化。
点击这里进行下载
★利用WPF进行美化,这个我没有用过,可是听说美化效果很好,之后学习会补充进来的~~
这么多种方法总有一种适合你,帮你打造你想要的MFC界面。