09定制应用程序外观Word文档下载推荐.docx
《09定制应用程序外观Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《09定制应用程序外观Word文档下载推荐.docx(15页珍藏版)》请在冰豆网上搜索。
![09定制应用程序外观Word文档下载推荐.docx](https://file1.bdocx.com/fileroot1/2023-2/2/91291eea-c078-451a-b43f-b19084064c38/91291eea-c078-451a-b43f-b19084064c381.gif)
//哪个窗口,什么类型
//SetWindowLong(m_hWnd,GWL_STYLE,WS_OVERLAPPEDWINDOW);
SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_hWnd,GWL_STYLE)&
~WS_MAXIMIZEBOX);
3、改变图标,光标,背景,应该在PreCreateWindow()中编写
获取当前应用程序的句柄
HINSTANCEAfxGetInstanceHandle();
通过重写窗口类,达到修改程序外观的目的
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();
wndcls.lpfnWndProc=:
DefWindowProc;
//cwnd类中有一个同名的函数,所以要用:
区分
wndcls.lpszClassName="
sunxin.org"
//窗口类名
wndcls.lpszMenuName=NULL;
wndcls.style=CS_HREDRAW|CS_VREDRAW;
RegisterClass(&
wndcls);
//注册窗口类
cs.lpszClass="
//把新的窗口类送给PreCreateWindow()中传入的参数cs
修改窗口图标,应该在MainFrame类中修改,因为图标是属于框架类的
修改光标,背景应该在View类中修改,因为那是view类窗口上的,把最后一句移到view同函数中即可
4、上面的方法太麻烦了,用另一个函数,
LPCTSTRAFXAPIAfxRegisterWndClass(UINTnClassStyle,HCURSORhCursor=0,HBRUSHhbrBackground=0,HICONhIcon=0);
//窗口类型,光标,画刷,图标,返回新类的类名
缺省参数,箭头光标,空画刷,windows标志图标
可以这样写,达到上面一样的目的
cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW,0,0,LoadIcon(NULL,IDI_WARNING));
5、窗口建立后改变外观
DWORDSetClassLong(HWNDhWnd,intnIndex,LONGdwNewLong);
//改变WNDCLASSEX结构体的内容
哪个窗口改变类型新类型
改变图标,可以用GCL_HICON,改变背景可以用GCL_HBRBACKCROUND
SetClassLong(m_hWnd,GCL_HICON,(LONG)LoadIcon(NULL,IDI_ERROR));
把资源id号改变为LPCTSTR的一个宏
LPCTSTRMAKEINTRESOURCE(WORDwInteger);
m_hIcons[0]=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1));
CTestApp的父类CWinApp有一个数据成员m_hInstance表示的当前的程序实例
m_hIcons[1]=LoadIcon(theApp.m_hInstance,MAKEINTRESOURCE(IDI_ICON2));
一个类内需要调用另一个类的成员对象,需要用extern声明
externCStyleApptheApp;
//声明在外部源文件当中定义的
则,theApp.m_hInstance和AfxGetInstanceHandle()的效果是一样的
CWinApp*AfxGetApp();
//返回一个CWinApp的指针
m_hIcons[2]=LoadIcon(AfxGetApp()->
m_hInstance,MAKEINTRESOURCE(IDI_ICON3));
让一个值在某一个范围内变化,可以用取模的方法
index=++intdex%3
6、工具栏
工具图标的id设成和某菜单项的一样,然后对菜单项命令消息编程就行了
把工具栏图标往右拖动一点距离,就能产生分隔符了
删除工具栏按钮,拖出工具栏就行了,用del键只能删除其上图象
7、创建工具栏
CToolBar:
CControlBar:
CWnd:
CCmdTarget:
CObject
第一种方法:
1建立工具栏资源
2创建CToolBar对象
3用Create()或者CreateEx()建立一个工具栏并与工具栏对象相关联
4用LoadToolBAr()载入工具栏
CToolBar:
Create
BOOLCreate(CWnd*pParentWnd,DWORDdwStyle=WS_CHILD|WS_VISIBLE|CBRS_TOP,UINTnID=AFX_IDW_TOOLBAR);
//父窗口指针,工具栏样式,工具栏id
CreateEx
BOOLCreateEx(CWnd*pParentWnd,DWORDdwCtrlStyle=TBSTYLE_FLAT,DWORDdwStyle=WS_CHILD|WS_VISIBLE|CBRS_ALIGH_TOP,CRectrcBorders+CRect(0,0,0,0),UINTnID=AFX_IDW_TOOLBAR);
//父窗口指针,扩展风格,工具栏样式,工具栏宽度,工具栏id
第二种方法:
1创建一个CToolBar对象
2调用Create()或者CreateEx()建立一个工具栏并与工具栏对象相关联
3调用LoadBitmap()载入工具栏图象
4调用SetButtons()设置工具栏样式并与图标关联
让工具栏可以停靠
CControlBar:
EnableDocking
voidEnableDocking(DWORDdwStyle);
CBRS_ALIGN_TOP顶部
CBRS_ALIGN_BOTTON底部
让框架窗口可以被停靠
CFrameWnd:
voidEnableDocking(DWORDdwDockStyle);
//MainFrame从CFrameWnd继承,所以此函数可以被直接调用
让工具栏停靠在主窗口下
DockControlBar(CToolBar*hhh);
if(!
m_wndStatusBar.Create(this)||
!
m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("
Failedtocreatestatusbar\n"
);
return-1;
//failtocreate
}
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&
m_wndToolBar);
8、判断一个窗口是否是可视的
判断工具栏是否可视:
m_newToolBar.IsWindowVisible();
//可视返回真,否则返回假
如果工具栏处在停靠状态,调用IsWindowVisible()只会让工具栏上的按钮消失,工具栏还在
调用下面的函数可以解决该问题
RecalcLayout
virtualvoidRecalcLayout(BOOLbNotify=TRUE);
//重新调整工具栏位置
当工具栏处于浮动状态,调用以上2个函数后,只是按钮消失了,工具栏还在
要解决该问题,还必须调用DockControlBar(&
这时,工具栏隐藏没问题,但恢复时会使工具栏出现在顶端,而不是在原来的位置浮动显示
第一种显示方法示例
voidCMainFrame:
OnViewNewtool()
if(m_newToolBar.IsWindowVisible())
m_newToolBar.ShowWindow(SW_HIDE);
else
m_newToolBar.ShowWindow(SW_SHOW);
RecalcLayout();
m_newToolBar);
9、第二种显示方法
ShowControlBar
voidShowControlBar(CControlBar*pBar,BOOLbShow,BoolbDelay);
工具栏指针真显假隐显示延时否,真延时,假立即显示
一个函数完成以上功能
ShowControlBar(&
m_newToolBar,!
m_newToolBar.IsWindowVisible(),FALSE);
10、为菜单项加上复选标记
添加菜单项UPDATE_COMMAND_UI响应消息及函数
OnUpdateViewNewtool(CCmdUI*pCmdUI)
pCmdUI->
SetCheck(m_newToolBar.IsWindowvisible());
//用SetCheck()设置
11、状态栏
CMainFrame.h中
CStatusBarm_wndStatusBar;
CMainFrame.cpp中
staticUINTindicators[]=//内容的个数就是状态栏里的项目数
ID_SEPARATOR,//statuslineindicator
ID_INDICATOR_CAPS,//在资源里的stringtool定义
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
m_wndStatusBar.SetIndicators(indicators,//这个就是上面定义的全局静态数组
如果想要在状态栏中添加自己的项目,资源里的stringtable定义自己的常量
12、在状态栏中添加时钟
获取当前时间
CTime:
GetCurrentTime
staticCTimePASCALGetCurrentTime();
//返回一个CTime对象,他表示了当前的时间
格式化时间对象
Format
CStringFormat(LPCTSTRpFormat)const;
//格式化一个时间对象,返回为指定格式的字符串
CStringFormat(UINTnFormatID)const;
%D天,%H小时,%M分钟,%S秒,%%
把信息输出到状态栏
CStatusBar:
SetPaneText
BOOLSetPaneText(intnIndex,LPCTSTRlpszNewText,BOOLbUpdate=TRUE);
状态栏哪个格的索引要输出的内容wm_paint时重绘
如果不知道你要输出的小格的索引,可以用下面的函数
CommandToIndex
intCommandToIndex(UINTnIDFind)const;
//通过资源字符串(就是那个静态数组)的id获取其索引
改变小格的大小,以适应输出的内容,默认小格是很小的
SetPaneInfo
voidSetPaneInfo(intnIndex,UINTnID,UINTnStyle,intcxWidth);
小格索引重新分配新的id类型小格宽度
如何获取我们要显示的内容的宽度以赋值给cxWidth呢,用GetTextExtent();
啊,前面说过了
SetTimer(1,1000,NULL);
CTimet=CTime:
GetCurrentTime();
CStringstr=t.Format("
%H:
%M:
%S"
CClientDCdc(this);
CSizesz=dc.GetTextExtent(str);
intindex=0;
index=m_wndStatusBar.CommandToIndex(IDS_TIMER);
m_wndStatusBar.SetPaneInfo(index,IDS_TIMER,SBPS_NORMAL,sz.cx);
m_wndStatusBar.SetPaneText(index,str);
13、进度栏
CProgressCtrl:
CProgressCtrl
CProgressCtrl();
//构造对象后用create()创建
BOOLCreate(DWORDdwStyle,constRECT&
rect,CWnd*pParentWnd,UINTnID);
类型大小父窗口进度栏id号
类型有:
PBS_VERTICAL垂直(默认是水平的)PBS_SMOOTH平滑
设置进度栏进到哪个位置
SetPos
SetPos(这个参数填个整数,50代表50%,也就是一半,当百分比用了)
如何把进度条放到状态栏的小格当中呢
首先要获得小格的矩形区域
GetItemRect
voidGetItemRect(intnIndex,LPRECTlpRect)const;
//小格索引,用来接收矩形区域坐标的参数
1CProgressCtrlm_progress;
2
/*CRectrect;
m_wndStatusBar.GetItemRect(2,&
rect);
//m_progress.Create(WS_CHILD|WS_VISIBLE|PBS_VERTICAL,
//CRect(100,100,120,200),this,123);
m_progress.Create(WS_CHILD|WS_VISIBLE,//|PBS_VERTICAL,
rect,&
m_wndStatusBar,123);
m_progress.SetPos(50);
*/
//SendMessage(UM_PROGRESS);
//PostMessage(UM_PROGRESS);
//CG:
ThefollowinglinewasaddedbytheSplashScreencomponent.
CSplashWnd:
ShowSplashScreen(this);
14、自定义消息
1在头文件中#defineUM_PROGRESSWM_USER+1
消息都是一个整数值表示的
2写上消息宏afx_msgvoidOnProgress();
3消息映射ON_MESSAGE(UM_PROGESS,OnProgress)
4写响应函数
OnProgress()
CRectrect;
m_progress.Create(WS_CHILD|WS_VISIBLE|PBS_SMOOTH,
5在使用的地方发送消息SendMessage(UM_PROGRESS);
或者PostMessage(UM_PROGRESS);
两者是有差别的,
SendMessage(UM_PROGRESS);
//发送消息后直接到消息响应函数运行,结束后回到原函数直接运行
PostMessage(UM_PROGRESS);
//将消息添加到消息对列当中后立即回到调用函数,系统GetMessage()到该消息后才执行消息响应函数,这样就能够让原函数执行完毕后再操作
在实例中,必须要让oncreate()执行完成,将窗口建立完毕后才能获取状态栏信息,所以用SendMessage(UM_PROGRESS);
不合适,应该用PostMessage(UM_PROGRESS);
OnPaint()
CPaintDCdc(this);
//devicecontextforpainting
//TODO:
Addyourmessagehandlercodehere
if(!
m_progress.m_hWnd)
m_progress.Create(WS_CHILD|WS_VISIBLE,//|PBS_SMOOTH,
m_progress.MoveWindow(rect);
//移动窗口,避免窗口尺寸变化的时候进度条移动
//DonotcallCFrameWnd:
OnPaint()forpaintingmessages
15、让进度栏前进
设置进度栏前进步长
SetStep
intSetStep(intnStep);
进度栏前进
StepIt();
设置进度栏前进范围
SetRange
voidSetRange(shortnLower,shortnUpper);
voidSetRange32(intnLower,intnUpper);
//默认0,100
m_progress.StepIt();
16、状态栏左条显示文本
直接用框架类的成员变量,但要把成员变量改成共有的,同时包含CMainFrame头文件
((CMainFrame*)GetParent())->
m_wndStatusBar.SetWindowText(str);
用框架类的成员函数
SetMessageText
voidSetMessageText(LPCTSTRlpszText);
//直接在状态栏放置文本,不需要框架类对象了
SetMessageText(str);
用GetMessageBar()
GetMessageBar
virtualCWnd*GetMessageBar();
//返回一个指向状态栏的指针
GetMessageBar()->
SetWindowText(str);
用GetDescendantWindow()
CWnd:
GetDescendantWindow
CWnd*GetDescendantWindow(intnID,BOOLbOnlyPerm=FALSE)const;
//搜索所有子窗口直到找到给定id的窗口,并返回该窗口的指针窗口id,是否返回临时窗口,true返回持久窗口,false可以返回临时窗口
状态栏的id是多少呢?
BOOLCreate(CWnd*pParentWnd,DWORDdwStyle=WS_CHILD|WS_VISIBLE|CBRS_BOTTOM,UINTnID=AFX_IDW_STATUS_BAR);
//-------->
最后这个就是系统给定的状态栏的id号
系统为每个常用的工具窗口都预设了一个id号,可以通过一个已知的id用查找定义的方法找到定义的地方,或到mfc\include\找到定义文件
GetParent()->
GetDescendantWindow(AFX_IDW_STATUS_BAR)->
//这里不用(CMainFrame*)强制转换窗口类型,要不要转换,要看你后面所用的函数是属于哪个类的,属于CMainFrame,就转换为CMainFrame,属于CWnd就转换