LESSON 9 修改应用程序的外观工具栏状态栏编程.docx
- 文档编号:10856604
- 上传时间:2023-05-28
- 格式:DOCX
- 页数:21
- 大小:22.82KB
LESSON 9 修改应用程序的外观工具栏状态栏编程.docx
《LESSON 9 修改应用程序的外观工具栏状态栏编程.docx》由会员分享,可在线阅读,更多相关《LESSON 9 修改应用程序的外观工具栏状态栏编程.docx(21页珍藏版)》请在冰点文库上搜索。
LESSON9修改应用程序的外观工具栏状态栏编程
第一部分改变应用程序的外观
1>在窗口创建前修改窗口style.:
在CMainFrame:
:
PreCreateWindow()中直接修改cs.
2>创建后修改窗口style:
SetWindowLong。
3>在窗口创建前修改窗口窗口的图标、光标和背景:
一:
1)在PreCreateWindow()中编写一个窗口类并注册之。
2)view类的precreatewindow中,指定窗口类为刚才自己编写的这个窗口类。
或AfxRegisterWndClass()。
4>在窗口创建之后,还能不能修改它的图标、光标背景?
:
SetClassLong
一、 问题:
要修改一个应用程序的外观,应该在应用程序创建之前还是在创建之后修改呢?
修改一幢楼房应在建成之前,应在窗口创建之前修改。
要改变一个框架窗口的外观,应在CMainFrame:
:
PreCreateWindow()中去改变,CREATESTRUCTcs结构体的类型和个数与创建窗口的CreateWindowEx()的个数和类型是完全一致的。
只是顺序正好相反。
PreCreateWindow(cs)的参数cs被声明为一个引用类型,如果在子类中修改了cs的值,这种改变会反应到MFC的底层代码中。
1、创建前修改窗口的大小:
BOOLCMainFrame:
:
PreCreateWindow(CREATESTRUCT&cs)
{
if(!
CFrameWnd:
:
PreCreateWindow(cs))
returnFALSE;
//TODO:
ModifytheWindowclassorstylesherebymodifying
// theCREATESTRUCTcs
cs.cx=300;
cs.cy=200;
returnTRUE;
}
2、修改窗口的标题
BOOLCMainFrame:
:
PreCreateWindow(CREATESTRUCT&cs)
{
if(!
CFrameWnd:
:
PreCreateWindow(cs))
returnFALSE;
//TODO:
ModifytheWindowclassorstylesherebymodifying
// theCREATESTRUCTcs
cs.lpszName="http:
//www.sunxin.org";
returnTRUE;
}
标题并没有被改变。
分析:
程序是一个SDI应用程序,打开Word时,它的标题栏显示的一个“文档1”标题,
在MSDN中,WindowStyles
在一个SDI应用程序中,缺省的窗口类型是WS_OVERLAPPEDWINDOW和FWS_ADDTOTITLE的组合。
FWS_ADDTOTITLE用来增加文档的标题到窗口的标题
去掉FWS_ADDTOTITLE属性。
cs.style&=~FWS_ADDTOTITLE; //取反,并进行与操作。
cs.style=WS_OVERLAPPEDWINDOW;//直接赋值
二、 问题:
在窗口创建之后能不能修改外观和大小呢?
TheSetWindowLongfunctionchangesanattributeofthespecifiedwindow
LONGSetWindowLong(
HWNDhWnd,
intnIndex, GWL_STYLE
LONGdwNewLong
);
在OnCreate函数中去改变
在所有的窗口对象(C++对象)中都有一个公有的成员变量m_hWnd,保存了与对象相关的窗口的句柄。
SetWindowLong(m_hWnd,GWL_STYLE,WS_OVERLAPPEDWINDOW);
问题:
在使用SetWindowLong设置窗口类型里,想获得现有的窗口类型,怎么进行?
LONGGetWindowLong(
HWNDhWnd,//窗口句柄
intnIndex //常量,指定窗口的那种信息如:
GWL_STYLE
);
获取现有类型,去掉最大化按钮
SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_hWnd,GWL_STYLE)
&~WS_MAXIMIZEBOX);
三、 如果要修改窗口的图标、光标和背景,应该如何去修改?
图标、光标和背景是在设计窗口类时被指定的,窗口类的设计和注册是由MFC的底层代码自动实现的,不可能去修改MFC的底层代码,如何修改?
一、自己编写窗口类,并注册,让随后的窗口的创建按照我们设计好的窗口类去创建。
在PreCreateWindow()中编写一个窗口类并注册之。
WNDCLASSwndcls;
wndcls.cbClsExtra=0;
wndcls.cbWndExtra=0;
wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);//获取一个黑色的背景画刷
wndcls.hCursor=LoadCursor(NULL,IDC_HELP);
wndcls.hIcon=LoadIcon(NULL,IDI_ERROR);
wndcls.hInstance=AfxGetInstanceHandle();//注意用全局函数获取应用程序hInstance句柄
wndcls.lpfnWndProc=:
:
DefWindowProc;//必须指定为API函数,不同于CWnd中的DefWindowProc(参数个数不同)
wndcls.lpszClassName="sunxin.org";
wndcls.lpszMenuName=NULL;//菜单的创建并不是在设计窗口类时创建的,由MFC在构造pDocTemplate=newCSingleDocTemplate(IDR_MAINFRAME,…)被创建。
wndcls.style=CS_HREDRAW|CS_VREDRAW;
RegisterClass(&wndcls);
cs.lpszClass="sunxin.org";//precreatewindow()中判lpszClass是否为空,不为空说明已注册
编译并运行,发现只有图标被改变,背景、光标未改变,为什么?
答:
view始终履盖在frame窗口上,必须在view类的precreatewindow中,指定窗口类为刚才自己编写的这个窗口类。
BOOLCStyleView:
:
PreCreateWindow(CREATESTRUCT&cs)
{
cs.lpszClass="sunxin.org";//这个窗口类已经注册了,只要指定即可
returnCView:
:
PreCreateWindow(cs);
}
四、 在框架窗口中只能修改图标,为了修改图标需要重写窗口类,太麻烦,MFC中提供了一个全局函数,AfxRegisterWndClass()修改、设定一个窗口类的类型,光标、背景、图标。
返回一个注册成功的窗口类类名。
如果只修改类的类型(wndcls.style),只要第一个参数,其它取默认值。
LPCTSTRAFXAPIAfxRegisterWndClass(
UINTnClassStyle,
HCURSORhCursor=0,
HBRUSHhbrBackground=0,
HICONhIcon=0
);
1、 改变框架窗口的图标
BOOLCMainFrame:
:
PreCreateWindow(CREATESTRUCT&cs)
{
if(!
CFrameWnd:
:
PreCreateWindow(cs))
returnFALSE;
cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW
|CS_VREDRAW,0,0,LoadIcon(NULL,IDI_WARNING));//
returnTRUE;
}
2、改变光标和背景,在view中
BOOLCStyleView:
:
PreCreateWindow(CREATESTRUCT&cs)
{
cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW,
LoadCursor(NULL,IDC_CROSS),(HBRUSH)GetStockObject(BLACK_BRUSH),0);
returnCView:
:
PreCreateWindow(cs);
}
3、只给AfxRegisterWndClass()的第一个参数赋值,其余取缺省值,cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW);
发现:
图标变成wave-flag,光标是箭头形状,背景变成透明。
MSDN:
hCursor
Specifiesahandletothecursorresourcetobeinstalledineachwindowcreatedfromthewindowclass.Ifyouusethedefaultof0,youwillgetthestandardIDC_ARROWcursor.
hbrBackground
Specifiesahandletothebrushresourcetobeinstalledineachwindowcreatedfromthewindowclass.Ifyouusethedefaultof0,youwillhaveaNULLbackgroundbrush,andyourwindowwill,bydefault,noteraseitsbackgroundwhileprocessingWM_ERASEBKGND.
hIcon
Specifiesahandletotheiconresourcetobeinstalledineachwindowcreatedfromthewindowclass.Ifyouusethedefaultof0,youwillgetthestandard,waving-flagWindowslogoicon.
五、 以上都是在窗口创建之前,在窗口创建之后,还能不能修改它的图标、光标背景?
DWORDSetClassLong(
HWNDhWnd,
intnIndex,
LONGdwNewLong
);
TheSetClassLongfunctionreplacesthespecified32-bit(long)valueatthespecifiedoffsetintotheextraclassmemoryortheWNDCLASSEXstructurefortheclasstowhichthespecifiedwindowbelongs.
DWORDGetClassLong(
HWNDhWnd,
intnIndex
);
TheGetClassLongfunctionretrievesthespecified32-bit(long)valuefromtheWNDCLASSEXstructureassociatedwiththespecifiedwindow
1、 在框架窗口中修改图标,在CMainFrame:
:
OnCreate()函数中:
SetClassLong(m_hWnd,GCL_HICON,(LONG)LoadIcon(NULL,IDI_ERROR));
2、 在View中修改光标、背景,在CStyleView:
:
OnCreate()函数中
SetClassLong(m_hWnd,GCL_HBRBACKGROUND,(LONG)GetStockObject(BLACK_BRUSH));
SetClassLong(m_hWnd,GCL_HCURSOR,(LONG)LoadCursor(NULL,IDC_HELP));
3、 利用SetClassLong()实现不断变化的图标(图标的动画效果)
在CMainFrame:
:
OnCreate()安装一个定时器。
初始化一个存储图标的句柄的数组(在CMainFrame增加m_hIcons[3]成员变量),注意MAKEINTRESOURCE宏的使用,以及三种获当前实例句柄的方法。
m_hIcons[0]=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1));
m_hIcons[1]=LoadIcon(theApp.m_hInstance,MAKEINTRESOURCE(IDI_ICON2));
m_hIcons[2]=LoadIcon(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDI_ICON3));
在一个源文件中要用到另一个源文件的变量。
可以声明一个变量在外部定义的。
externCStyleApptheApp;
LoadIcon()的第二个参数要求一个字符指针,但我们只有图标的ID号,ID号转换为LPTSTR指针类型,MAKEINTRESOURCE()
LPTSTRMAKEINTRESOURCE(
WORDwInteger
);
TheMAKEINTRESOURCEmacroconvertsanintegervaluetoaresourcetypecompatiblewiththeresource-managementfunctions.Thismacroisusedinplaceofastringcontainingthenameoftheresource.
添架定时器的响应函数CMainFrame:
:
OnTimer(UINTnIDEvent)
voidCMainFrame:
:
OnTimer(UINTnIDEvent)
{
staticintindex=1;
SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hIcons[index]);
index=++index%3;
当Index为0时,模3,商为0,余数0-0=0,
当Index为1时,模3,商为0,余数1-0=1
当Index为2时,模3,商为0,余数2-0=2
当Index为3时,模3,商为1,余数3-3=0
CTimet=CTime:
:
GetCurrentTime();
CStringstr=t.Format("%H:
%M:
%S");
CClientDCdc(this);
CSizesz=dc.GetTextExtent(str);
m_wndStatusBar.SetPaneInfo(1,IDS_TIMER,SBPS_NORMAL,sz.cx);
m_wndStatusBar.SetPaneText(1,str);
m_progress.StepIt();
CFrameWnd:
:
OnTimer(nIDEvent);
}
第二部分
一、工具栏的编程:
在一些按钮与按钮之间有一些分隔符,如何产生这种分隔符,拖动一个按钮向右移动一段距离
如何删除一个按钮,把这个按钮拖出工具栏即可。
Del键是删除按钮上的图像。
创建工具栏的步骤:
(两种方法)
VisualC++providesyouwithtwomethodstocreateatoolbar.TocreateatoolbarresourceusingtheResourceEditor,followthesesteps:
1、Createatoolbarresource.
2、ConstructtheCToolBarobject.
3、CalltheCreate(orCreateEx)functiontocreatetheWindowstoolbarandattachittotheCToolBarobject.
4CallLoadToolBartoloadthetoolbarresource.
Otherwise,followthesesteps:
1、ConstructtheCToolBarobject.
2、CalltheCreate(orCreateEx)functiontocreatetheWindowstoolbarandattachittotheCToolBarobject.
3、CallLoadBitmaptoloadthebitmapthatcontainsthetoolbarbuttonimages.
4、CallSetButtonstosetthebuttonstyleandassociateeachbuttonwithanimageinthebitmap.
两个EnableDocking函数的比较:
CControlBar:
:
EnableDocking让工具栏可以停靠。
Callthisfunctiontoenableacontrolbartobedocked.
voidEnableDocking(
DWORDdwDockStyle
);
CFrameWnd:
:
EnableDocking让框架窗口可以被停靠。
CFrameWndOverview|ClassMembers|HierarchyChart|CControlBar:
:
EnableDocking|CFrameWnd:
:
DockControlBar|CFrameWnd:
:
FloatControlBar
Callthisfunctiontoenabledockablecontrolbarsinaframewindow.
voidEnableDocking(
DWORDdwDockStyle
);
创建工具栏:
1、 构造一个工具栏对象
protected:
CToolBar m_wndToolBar;
CToolBar m_newToolBar;
2、 创建工具栏对象,加载工具栏资源
if(!
m_newToolBar.CreateEx(this,TBSTYLE_FLAT,WS_CHILD|WS_VISIBLE|CBRS_TOP|CBRS_GRIPPER|CBRS_TOOLTIPS|CBRS_FLYBY|CBRS_SIZE_DYNAMIC)||
!
m_newToolBar.LoadToolBar(IDR_TOOLBAR1)
{
TRACE0("Failedtocreatetoolbar\n");
return-1; //failtocreate
}
m_newToolBar..EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_newToolBar);//停靠在创建时规定的默认位置
3、 创建一个菜单项,响应工具栏的显示和隐藏。
①第一种显示工具栏的方法:
菜单项的响应函数voidCMainFrame:
:
OnViewNewtool()
{
//TODO:
Addyourcommandhandlercodehere
/*if(m_newToolBar.IsWindowVisible())
{
m_newToolBar.ShowWindow(SW_HIDE);
}
else
{
m_newToolBar.ShowWindow(SW_SHOW);
}
RecalcLayout();
DockControlBar(&m_newToolBar);*/ShowControlBar(&m_newToolBar,!
m_newToolBar.IsWindowVisible(),FALSE);
}
分析:
RecalcLayout()不调用这个函数,只会隐藏工具栏上的按钮,而不会隐藏工具栏,当工具栏被显示或隐藏之后,其它的控制栏的位置可能会有所变动,需要调用一个函数RecalcLayout()重新调整它们的位置,
DockControlBar(&m_newToolBar)的调用分析:
如果把工具栏拖放使其处于浮动状态,隐藏,发现只会隐藏工具栏上的按钮,而不会隐藏工具栏,当工具栏显示或隐藏后,需要再次调用DockControlBar()。
但这样做,只会使工具栏停靠在top位置,而不会停靠在原来浮动的位置。
RecalcLayout()
Calledbytheframeworkwhenthestandardcontrolbarsaretoggledonorofforwhentheframewindowisresized.
virtualvoidRecalcLayout(
BOOLbNotify=TRUE
);
Parameters
bNotify
Determineswhethertheactivein-placeitemfortheframewindowreceivesnotificationofthelayoutchange.IfTRUE,theitemisnotified;otherwiseFALSE.
如果把工具栏拖放使其处于浮动状态,隐藏,再显示它,发现它不会在原来浮动的
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- LESSON 修改应用程序的外观工具栏状态栏编程 修改 应用程序 外观 工具栏 状态栏 编程