孙鑫VC++第9章定制应用程序外观

 

                             九、定制应用程序外观

 

1.      如果希望在应用程序窗口创建之前修改它的外观和大小,就应该在CMainFrame类的PreCreateWindow成员函数中进行;(只需要修改CREATETRUCT结构体中的相关成员变量就行)

//修改窗口大小

Cs.cx = 300;

Cs.cx =200;

//修改程序窗口风格

//如果想让窗口显示自己的标题,只需要将窗口的FWS_ADDTOTITLE样式去掉;

Cs.lpszName = http://www.sunxin.org;

Cs.style &=~FWS_ADDTOTITLE;

 

2.      在窗口创建之后修改

 

在窗口创建之后修改其外观,可以在框架类的OnCreate函数中添加具体的实现代码;

利用SetWindowLong,和GetWindowLong;

 

SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_hWnd,

        GWL_STYLE) &~WS_MAXIMIZEBOX);

 

3.      修改窗口的光标、图标和背景:在窗口创建前修改

 

在框架类的PreCreateWindow函数中编写一个自己的窗口类并注册;

 

WNDCLASS wndcls;

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;

wndcls.lpszClassName = "sunxin.org";

wndcls.lpszMenuName = NULL;

wndcls.style = CS_HREDRAW | CS_VREDRAW;

 

RegisterClass(&wndcls);

cs.lpszClass = "sunxin.org";//指定类名,得跟注册的名字一样

 

但凡以AFX开始的函数都是应用程序框架类函数,也是全局函数,在程序的所有类中都可以直接调用;

 

注意:在MFC程序中,如果想要修改应用程序窗口的图标,则应在框架类中进行,因为在框架窗口中才有标题栏,所以才能修改位于该标题栏上的图标;如果想要修改程序窗口的背景和光标,就应该在视类中进行;

 

 

所以得在视类的PreCreateWindow函数中添加

Cs.lpszClas = “sunxin.org”;

 

 

第二种方法:不需要重写整个窗口类,比较简单

 

//不需要重写整个框架类

cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW |CS_VREDRAW,0,0,//光标和背景都为0

LoadIcon(NULL,IDI_WARNING));

 

 

4.      修改窗口的光标、图标、和背景:在窗口创建之后修改:OnCreate函数中

 

SetClassLong(m_hWnd,GCL_HICON,(LONG)LoadIcon(NULL,IDI_ERROR));

 

5,模拟动画图标:利用定时器和SetClassLong函数就可以完成这个功能;

 

6,加载图标资源

 

             

       externCStyleApp theApp;

       //LoadIcon函数的第一个参数为NULL,加载的是系统图标

       //使用自定义图标,第一个参数应为应用程序的当前实例句柄

 

       //MAKEINTERSOURCE宏将资源ID号转换为资源标识符字符串

 

 

       m_hIcons[0]= LoadIcon(AfxGetInstanceHandle(),MAKEINTERSOURCE(IDI_ICON1));

       //利用全部变量theapp,需要添加声明 extern C**App theApp;

       m_hIcons[1]= LoadIcon(theApp.m_hInstance,MAKEINTERSOURCE(IDI_ICON2));

m_hIcons[2]=LoadIcon(AfxGetApp()->m_hinstance,MAKEINTERSOURCE(IDI_ICON3));

 

 

然后设置定时器:SetTimer(1,1000,NULL);

然后再为类添加定时器消息WM_TIMER的响应函数,并调用SetClassLong函数改变应用程序窗口的图标;

 

 

作为静态的局部变量,它将存放在程序的数据区中,而不是在栈中分配空间的;static

 

1.      工具栏编程

 

在工具栏中删除按钮:不要用delete,而是在按钮上按下鼠标左键,然后拖出工具栏就可以了;

 

2.      创建工具栏的方法有两种:

 

(一)  第一种方法:

1.      创建工具栏资源;

2.      构造CToolBar对象

3.      调用Create或者CreateEx函数创建windows工具栏,并把它与已创建的CToolBar对象关联起来;

4.      调用LoadToolBar函数加载工具栏资源;

 

(二)  第二种方法:

1.      构造CToolBar对象;

2.      调用Create或者CreateEx函数创建windows工具栏,并把它与已创建的CToolBar对象关联起来;

3.      调用LoadBitmap函数加载包含工具栏按钮的图像的位图;(该位图为Toolbar.bmp,里面有许多小图像,对应按钮)

4.      调用SetButtons函数设置样式,并把工具栏上的一个按钮与位图中的一个图像相关联;

 

 

3.      MFC创建工具栏的过程

 

在框架类的OnCreate函数中;

 

MFC为我们自动创建的工具栏和主菜单的资源ID是一样的,也就是说,在MFC编程中,一个ID可以表示多种资源;

 

4.      创建自定义的工具栏

 

调用工具栏对象的EnableDockng函数允许工具栏停靠于客户区的任意位置;

框架类的EnableDocking函数,让主框架窗口可以被停靠;

最后调用的DockControlBar函数,可以让这个新工具栏停靠在主框架窗口上;

 

 

   如何让工具栏显示和隐藏:

 

              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);

 

 

 

       设置菜单复选标志:

       为这个菜单添加一个UPDATE_COMMAND_UT消息响应函数

 

       pCmdUI->SetCheck(m_newToolBar.IsWindowVisible());

 

 

5.      状态栏编程:在框架类中的OnCreate函数中;用CStatusBar类定义了一个m_wndStatusBar变量;

 

 

6.      状态栏的右下角称为状态指示器;

 

状态栏对象也是在框架类中定义的;

在调用状态栏对象Create函数创建状态栏后,接着调用SetIndicators函数设置状态栏指示器,其中用到一个数组参数:indicators;,这个数组在框架类的源文件定义的,

数组的元素其实就是ID(状态栏指示器),后面三个ID其实就是MFC预先为我们定义好的字符串资源ID;

 

//获取时间

CTime t = CTime::GetCurrentTime();

CString str = t.Format("%H:%M:%S");

//将它显示在状态栏上

m_wndStatusBar.SetPaneText(1,str);//1是索引

 

 

 

 

 

       //不知道索引的情况下,可通过ID来得到相应的索引  

       CTimet = CTime::GetCurrentTime();

       CStringstr = t.Format("%H:%M:%S");

      

       intindex =0;

       index= m_wndStatusBar.CommandToIndex(IDS_TIMER);

 

       m_wndStatusBar.SetPaneText(index,str);

      

 

 

/*

       //获取足够的宽度来显示时间

       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_NOBORDERS,sz.cx);

       m_wndStatusBar.SetPaneText(index,str);

       */

 

7.      进度栏编程

 

在窗口中创建进度栏

先定义一个CProgressCtrl类型的成员变量:m_progress,然后在OnCreate函数中创建;

 

m_progress.Create(WS_CHILD | WS_VISIBLE,CRect(100,100,120,120),this,123);

//显示当前进度

m_progress.SetPos(50);

 

 

8.      在状态栏的窗格中创建进度栏

 

首先要获得该窗格的区域,然后将这个区域的大小作为进度栏的大小;GetItemRect函数

 

 

框架类的OnCreate函数是在响应框架窗口的WM_CREATE消息时候调用的;

 

 

为了避免我们自定义的这条消息与其他已有消息发生冲突,应用利用windows提供的一个常量:WM_USER,我们只需要加1就可以用了;(我们自定义的消息最好用UM_为前缀)

 

 

 

命令消息是用ON_COMMAND宏将消息与消息响应函数关联起来,而对于自定义的消息来说,是使用ON_MESSAGE宏来实现这一功能的;

 

 

 

编写状态栏最好在响应WM_PAINT的消息函数中:

 

 

CRect rect;

m_wndStatusBar.GetItemRect(2,&rect);

//判断是否已经创建进度栏

if (!m_progress.m_hWnd)

{

        m_progress.Create(WS_CHILD | WS_VISIBLE|PBS_SMOOTH,rect,&m_wndStatusBar,123);

}

else

{

        //把进度栏移动到目标矩形区域中

        m_progress.MoveWindow(rect);

}

m_progress.SetPos(50);

 

 

自动增加步长,可在响应定时器消息中:

 

m_progress.StepIt();

 

 

 

14,在状态栏中显示鼠标当前位置(视类中实现)

 

       视类没有包含框架类中的头文件,要引用框架类中定义的东西,必须得在视类中包含进来;

 

响应鼠标移动的消息

 

       CStringstr;

       str.Format("x=%d,y=%d",point.x,point.y);

       //第一种要改m_wndStatusBar的权限

       ((CMainFrame*)GetParent())->m_wndStatusBar.SetWindowText(str);

       //或者用另外一个函数

       //((CMainFrame*)GetParent())->SetMessageText(str);

       //第三种方法,用GetMessageBar()返回状态栏对象的指针,从而不用改权限

       //((CMainFrame*)GetParent())->GetMessageBar()->SetWindowText(str);

 

      

       状态栏不属于视类窗口,它属于框架类窗口;

      

       CMainFrame类派生于CFrameWnd类;

 

 

15,启动画面(利用组件Splash screen)

 

       在CSplashWnd类的OnCreate函数中,可以看到它设置了一个定时器;

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值