第九章 定制应用程序外观
9.1 修改应用程序窗口的外观
9.1.1 在窗口创建之前修改
1.应该在CMainFrame类的PreCreateWindow成员函数中进行。
2.修改应用程序窗口的 大小 和 标题 ,都是通过CREATETRUCT结构体“cs”来实现。
9.1.2 在窗口创建之后修改
1.通过SetWindowLong(设置窗口外观)和GetWindowLong(获得窗口外观)来实现。
2.例如,将窗口的最大化窗口去掉的话,可以这样做:
SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_hWnd,GWL_STYLE) & ~WS_MAXIMIZEBOX);
其中,先用GetWindowLong(m_hWnd,GWL_STYLE)获得窗口的GWL_STYLE值,再将它与
WS_MAXIMIZEBOX进行与操作,去掉最大化按钮。
9.2 修改窗口的光标、图标和背景
9.2.1 在窗口创建之前修改
1.图标,光标和背景是在设计窗口类时指定的,有MFC底层代码自动完成。我们不能修改底层代码,
但可以编写自己的窗口类,并注册,然后让随后的窗口按照我们编写的窗口去创建。
2.修改图标方法:
(1)首先定义一个WONDCLASS类型的变量wndcls
WNDCLASS wndcls;
(2)然后设置各个成员
比如:wndcls.hIcon = LoadIcon(NULL,IDI_RROR);
wndcls.lpszClassName = "MyWindowsClass";
(3)注册wndcls
RegisterClass(&wndcls);
(4)将CREATETRUCT结构体“cs”的类型修改为与wndcls一样
cs.lpszClassName = "MyWindowsClass";
3.图标在框架类上,要在框架类上修改;而背景和光标在视图类上,要在视图类上修改,否则无
效。
4.在视图类上修改背景和光标时,可以用全局注册函数AfxRegisterWndClass实现。它返回一个类
名,正好可以赋给cs.lpszClassName,完成修改。
9.2.2 在窗口创建之后修改
通过SetWindowLong(设置窗口外观)和GetWindowLong(获得窗口外观)来实现。
9.3 模拟动画图标
9.3.1 加载图标资源
可以使用LoadIcon()函数实现加载图标资源。
该函数需要两个参数,第一个参数是应用程序的句柄;第二个是图标对应的资源标识字符串。
1.有三种方法可以获得应用程序的句柄:
(1)AfxGetInstanceHandle() 直接获得句柄的万能方法
(2)theApp.m_hInstance 对象“theApp”代表应用程序
(3)AfxGetApp()->m_hInstance AfxGetApp可以获得theApp
2.要使theApp可以在其他类中自由使用,可以将它声明为外部定义:
extern CStyleApp theApp;
9.3.2 定时器的处理
1.开始初用SetTimer()设置时钟,多长时间调用一次OnTimer()。
2.在OnTimer()中实现程序处理。
9.4 工具栏编程
9.4.1 在工具栏上添加和删除按钮
9.4.2 创建工具栏
#工具栏的显示和隐藏
1.原始方法:
(1)m_newToolBar.ShowWindow(SW_HIDE) 或者SW_SHOW
(2)RecalcLayout() 重新调整控制条上对象的位置
(3)DockControlBar(&m_newSToolBar) 重新让工具栏停靠在主框架窗口上
2.方便方法:
ShowCantrolBar(&m_newToolBar,!m_newToolBar.IsWindowVisible(),FALSE);
9.5 状态栏编程
1.状态栏上的各项目是在框架类的源文件开头定义的。分别有:
ID_SEPARATOR 提示行
ID_INDICATOR_CAPS Caps Lock
ID_INDICATOR_NUM Num Lock
ID_INDICATOR_SCRL Scroll Lock
IDS_TIMER 时钟
IDS_PROGRESS 进度条
2.设置时钟
CTime t=CTime::GetCurrentTime(); 获得当前时间
CString str=t.Format("%H:%M:%S"); 以时间格式写入字符串上
CClientDC dc(this);
CSize sz=dc.GetTextExtent(str); 获得当前程序窗口的字体尺寸
m_wndStatusBar.SetPaneInfo(1,IDS_TIMER,SBPS_NORMAL,sz.cx);
将状态栏时间部分的尺寸设置为和上面一样
m_wndStatusBar.SetPaneText(1,str); 字符串写入状态栏
9.6 进度栏编程
9.6.1 在窗口中创建进度栏
1.m_progress.Create(WS_CHILD|WS_VISIBLE,CRect(100,100,200,120),this,123);
2.m_progress.SetPos(0);
9.6.2 在状态栏的窗格中创建进度栏
1.在状态栏中常见进度条,需要先用 GetItemRect() 获得进度条所在的位置;而获得位置前,又
要先完成应用程序窗口的创建。
一般选择在OnPaint函数中创建进度条。代码如下:
CRect rect;
m_wndStatusBar.GetItemRect(2,&rect); (1)获得进度条所在的位置
if(!m_progress.m_hWnd) (2)判断进度条是否已经创建
m_progress.Create(WS_CHILD | WS_VISIBLE ,//| PBS_SMOOTH,rect,&m_wndStatusBar,123);
else
m_progress.MoveWindow(rect); (3)窗口变化时可以移动到正确的位置
m_progress.SetPos(50);
2.CProgressCtrtl类有两个成员函数:
(1)StepIt(): 进度条按步长自动增长。
(2)SetStep():设置进度条步长。
3.SendMessage和PostMessage机制差异:
SendMessage:把消息发送给消息响应函数,响应函数处理完后,SendMessage才返回。
PostMessage:把消息放到消息队列中,然后立即返回。
9.7 在状态栏上显示鼠标当前位置
1.框架类是视图类的父类。可以用 ((CMainFrame*)GetParent()) 获得框架类指针。
但也可以用((CMainFrame*)AfxGetMainWnd())获得框架类指针。
2.状态栏的第一栏上显示字体,可以直接用m_wndStatusBar.SetWindowText(str).
3.代码如下:
CString str;
str.Format("x=%d,y=%d",point.x,point.y);
((CMainFrame*)AfxGetMainWnd())->m_wndStatusBar.SetWindowText(str);
9.8 启动画面
只需三个步骤就可以显示:
1.添加Splash screen组件。
2.修改IDB_SPLASH位图资源。
3.在CSplashWnd::OnCreate()中用SetTimer()设置画面持续时间。
程序是通过在CMainFrame里的OnCreate()函数中插入 ShowSplash()函数来启动画面的。它是一个静
态函数。