9.3模拟动画图标

利用定时器和SetWindowLong函数就可以实现该功能。

9.3.1加载图标资源

首先将三个图标资源放到res目录下。接着Insert\Resource->Import->找到res目录,选中上述三个图标资源导入。
这样资源视图Icon中就有了三幅新图标:IDI_ICON1,IDI_ICON2,IDI_ICON3。如图。
在这里插入图片描述
然后,在框架类中,定义一个图标句柄数组的成员变量,框架类上鼠标右键进行添加。如图。
在这里插入图片描述
接下来就在框架类的OnCreate函数中利用LoadIcon函数来加载这三个图标,同时初始化图标句柄数组。

extern CStyleApp theApp;
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
 ……
 // TODO: Delete these three lines if you don't want the toolbar to
 //  be dockable
 m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
 EnableDocking(CBRS_ALIGN_ANY);
 DockControlBar(&m_wndToolBar);
 SetClassLong(m_hWnd,GCL_HICON,(LONG)LoadIcon(NULL,IDI_ERROR));
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));
 return 0;
}

LoadIcon函数如果使用系统图标,第一个参数就为NULL;否则设置为应用程序的当前实例句柄。获取应用程序的当前实例句柄有三种方式:
1、通过调用AfxGetInstanceHandle()函数获取当前实例句柄。
2、CStyleApp类有一个数据成员:m_hIstance,标识了当前应用程序的实例。
theApp是CStyleApp类型的全局对象。但是在一个源文件中调用另一个源文件的全局变量,先要在框架类OnCreate函数之前进行声名:
extern CStyleApp theApp;
3、MFC提供了一个全局函数:AfxGetApp(),可以获得当前应用程序对象的指针,利用AfxGetApp()函数的返回值来访问应用程序的m_hIstance数据成员。
第二个参数需要的是图标的名称或者图标资源标识字符串,而我们只有图标资源的ID,通过MAKEINTRESOURCE将资源ID转换成资源标识字符串。

9.3.2定时器的处理

本例设置时间间隔为1000ms触发一次定时器消息。
在OnCreate函数最后加上:SetTimer(1,1000,NULL);

然后为框架类添加WM_TIMER消息的响应函数,并在该响应函数中调用SetClassLong函数改变应用程序窗口的图标。

void CMainFrame::OnTimer(UINT nIDEvent) 
{
 // TODO: Add your message handler code here and/or call default
 static int index=0;
 SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hIcons[index]);
 index=++index%3;
 CFrameWnd::OnTimer(nIDEvent);
}

作为静态的局部变量,它将存放在程序的数据区中,而不是在栈中分配。
因为第三个参数需要LONG类型,而m_hIcons类型是HICON。因此需要强制类型转换。

如果希望应用程序启动后不再显示原来的图标,而是直接显示自定义的图标。
需要在SetTimer(1,1000,NULL);之前添加:
SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hIcons[0]);

9.4工具栏编程

在ResourceView->Toolbar->IDR_MIANFRAME。
双击这个资源ID,就可以打开工具栏资源,这是一些带有位图图标的按钮,通过这些位图就大概知道每个按钮的功能。
双击这些位图,就可以查看工具栏上某个按钮的属性。如图。
可以发现子菜单文件下新建菜单项的ID与工具栏上面的按钮ID相同,通过使用工具栏上面的按钮将会更加便捷。
在这里插入图片描述

9.4.1在工具栏上面添加和删除按钮

添加的方法:
首先单击工具栏上面组后一个空白按钮,并设置外观,如图。将其ID设置为IDM_TEST。
在这里插入图片描述
然后再在帮助的子菜单下添加一个菜单项,ID设置为IDM_TEST,Caption设置为Test,添加命令消息响应函数OnTest。

void CMainFrame::OnTest() 
{
 // TODO: Add your command handler code here
 MessageBox("Test");
}

可以单击菜单项,也可以单击工具栏按钮进行运行。如图。
工具栏有一条竖线,称为分隔符,在工具栏资源视图中,将T按钮向旁边移动一点,就会在中间出现分隔符,进行区分。

删除工具栏上面按钮:在资源编辑窗口,在此按钮中按下鼠标左键,将其拖出工具栏,松开鼠标左键就将该按钮从工具栏上面删除了。

9.4.2创建工具栏

框架类中定义了一个CToolBar类型的成员变量:m_wndToolBar,CToolBar就是一个工具栏类,派生于CControlBar类,后者派生于CWnd类,因此工具栏也是一个窗口。

创建工具栏的方法1:
创建工具栏资源;
构造CToolBar对象;
调用Create或CreateEx函数创建Windows工具栏,并把已创建的CToolBar对象关联起来。
调用LoadToolBar函数加载工具栏资源。

BOOL Create( CWnd* pParentWnd, DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_TOP, UINT nID = AFX_IDW_TOOLBAR );
第一个参数是父窗口指针;第二个参数指定工具栏样式:子窗口(WS_CHILD),可视(WS_VISIBLE),停靠在窗口顶部(CBRS_TOP)
第三个参数指定工具栏子窗口的ID。

BOOL CreateEx(CWnd* pParentWnd, DWORD dwCtrlStyle = TBSTYLE_FLAT, DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP, CRect rcBorders = CRect(0, 0, 0, 0), UINT nID = AFX_IDW_TOOLBAR);
该函数第一个、第三个与第五个参数与上述函数参数相同。
第二个参数工具栏上控件创建时的扩展风格,默认为TBSTYLE_FLAT。
第四个参数指工具栏窗口边框的宽度。

创建工具栏的方法2:
构造CToolBar对象
调用Create或CreateEx函数创建Windows工具栏,并把已创建的CToolBar对象关联起来。
调用LoadBitmap函数加载包含工具栏按钮图像的位图。
调用SetButtons函数设置按钮的样式,并把工具栏上的一个按钮与位图中的一个图像相关联。

MFC创建工具栏的过程:
MFC自动创建的工具栏的代码存在于框架类的OnCreate函数中

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
 ……
 if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
  | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
  !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
 {
  TRACE0("Failed to create toolbar\n");
  return -1;      // fail to create
 }
 ……
 // TODO: Delete these three lines if you don't want the toolbar to
 //  be dockable
 m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
 EnableDocking(CBRS_ALIGN_ANY);
 DockControlBar(&m_wndToolBar);
 ……
}

先是调用CreateEx函数创建程序的工具栏对象,然后调用LoadToolBar函数加载工具栏资源:IDR_MAINFRAME
然后调用工具栏对象的EnableDocking成员函数设置工具栏停靠的位置,这里设置为允许停靠在客户区的任意一边。
后者是框架类对象调用EnableDocking成员函数,目的是让主框架窗口可以停靠。
最后调用DockControlBar函数,让工具栏停靠在主框架窗口上。

创建自定义的工具栏:
首先得插入一个新的工具栏资源:第一种方法Insert\Resource->选中ToolBar->单击New;第二种方法资源视图下->鼠标右键单击ToolBar->Insert ToolBar。
然后该程序中就插入了一个名为IDR_TOOLBAR1的工具栏资源,添加三个按钮。如图。
在这里插入图片描述
接下来就是要构造一个CToolBar对象,右键单击框架类,添加一个CToolBar类型的成员变量。名称为m_newToolBar,如图。
在这里插入图片描述
然后利用Create或CreateEx函数创建工具栏,并于CToolBar对象相关联。这里可以复制框架类OnCreate函数中前面的代码。但是对象名改为m_newToolBar,资源ID为IDR_TOOLBAR1。然后停靠位置设为CBRS_RIGHT。
然后调用函数允许新工具栏任意停靠到客户区,由于主框架窗口在前面已经停靠,可以不写,最后调用DockControlBar将新工具栏停靠到主框架窗口上。

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
 ……
 SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hIcons[0]);
 SetTimer(1,1000,NULL);
 if (!m_newToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_RIGHT
  | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
  !m_newToolBar.LoadToolBar(IDR_TOOLBAR1))
 {
  TRACE0("Failed to create toolbar\n");
  return -1;      // fail to create
 }
 m_newToolBar.EnableDocking(CBRS_ALIGN_ANY);
 DockControlBar(&m_newToolBar);
 return 0;
}

在这里插入图片描述
现在在查看子菜单下添加一个菜单项,ID为IDM_VIEW_NEWTOOLBAR,Caption为新的工具栏。该菜单项主要用来显示和隐藏新建的工具栏。
接着为框架类添加该菜单项的命令消息响应函数,因为工具栏本身也是窗口,可以调用CWnd类ShowWindow函数让其显示和隐藏。

void CMainFrame::OnViewNewtoolbar() 
{
 // TODO: Add your command handler code here
 if(m_newToolBar.IsWindowVisible())
 {
  m_newToolBar.ShowWindow(SW_HIDE);
 }
 else
 {
  m_newToolBar.ShowWindow(SW_SHOW);
 }
 RecalcLayout();
 DockControlBar(&m_newToolBar);
}

单击菜单项,发现工具栏没有消息,只是上面的按钮消失了。如图。
在这里插入图片描述
这是因为窗口上的工具栏被隐藏后,停靠在窗口上的其他控制条对象位置有可能变动,这时需要在最后调用框架类的RecalcLayout成员函数来重新调整它们的位置:RecalcLayout();
将工具栏拖到窗口中间的某个位置,让它处于浮动状态,单击查看下的菜单项,会发现工具栏上面的按钮消失了,但是工具栏仍然存在。原因就是工具栏再次显示和隐藏后,需要再次调用框架类DockControlBar函数,让工具栏停靠在主框架窗口上。

单击菜单项,确实可以隐藏,但是再次单击发现工具栏停靠在客户区顶部了。如图。
在这里插入图片描述
那么如何将新建的工具栏从原处显示出来呢?这就需要用到CMainFrame类ShowControlBar函数。
void ShowControlBar( CControlBar* pBar, BOOL bShow, BOOL bDelay );
第一个参数指向将要显示或隐藏的控制条;第二个参数若为TRUE就显示指定的控制条,FALSE就指隐藏指定的控制条;第三个参数TRUE表示延迟显示控制条,FALSE表示立即显示控制条。

void CMainFrame::OnViewNewtoolbar() 
{
 // TODO: Add your command handler code here
ShowControlBar(&m_newToolBar,!m_newToolBar.IsWindowVisible(),FALSE);
}

利用该函数将比较简洁地实现相关功能。

下面为新的工具栏的菜单项设置复选标记,因此需要为这个菜单项添加UPDATE_COMMAND_UI消息响应函数。右键单击该菜单项,选择ClassWizard。
然后在该消息响应函数内部添加:

void CMainFrame::OnUpdateViewNewtoolbar(CCmdUI* pCmdUI) 
{
 // TODO: Add your command update UI handler code here
 pCmdUI->SetCheck(m_newToolBar.IsWindowVisible());
}

选中,就显示工具栏;未选中,就隐藏工具栏。如图。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

身影王座

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值