修改应用程序的外观,工具栏、状态栏

 
第一部分 改变应用程序的外观
一、 问题:要修改一个应用程序的外观,应该在应用程序创建之前还是在创建之后修改呢?
修改一幢楼房应在建成之前,应在窗口创建之前修改。要改变一个框架窗口的外观,应在CMainFrame::PreCreateWindow()中去改变,
CREATESTRUCT cs结构体的类型和个数与创建窗口的CreateWindowEx()的个数和类型是完全一致的。只是顺序正好相反。
PreCreateWindow(cs)的参数cs被声明为一个引用类型,如果在子类中修改了cs的值,这种改变会反应到MFC的底层代码中。
1、修改窗口的大小:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
       if( !CFrameWnd::PreCreateWindow(cs) )
              return FALSE;
       // TODO: Modify the Window class or styles here by modifying
       // the CREATESTRUCT cs
       cs.cx=300;
       cs.cy=200;
       return TRUE;
}
2、修改窗口的标题
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
       if( !CFrameWnd::PreCreateWindow(cs) )
              return FALSE;
       // TODO: Modify the Window class or styles here by modifying
       // the CREATESTRUCT cs
       cs.lpszName="http://www.sunxin.org";
       return TRUE;
}
标题并没有被改变。
分析:程序是一个SDI应用程序,打开Word时,它的标题栏显示的一个“文档1”标题,
在MSDN中,Window Styles
在一个SDI应用程序中,缺省的窗口类型是WS_OVERLAPPEDWINDOW 和FWS_ADDTOTITLE的组合。
FWS_ADDTOTITLE 用来增加文档的标题到窗口的标题
去掉FWS_ADDTOTITLE属性。
cs.style&=~FWS_ADDTOTITLE;   //取反,并进行与操作。
cs.style=WS_OVERLAPPEDWINDOW; //直接赋值
二、 问题:在窗口创建之后能不能修改外观和大小呢?
The SetWindowLong function changes an attribute of the specified window
LONG SetWindowLong(         
HWND hWnd,
    int nIndex,     GWL_STYLE
    LONG dwNewLong
);
在OnCreate函数中去改变
在所有的窗口对象(C++对象)中都有一个公有的成员变量m_hWnd,保存了与对象相关的窗口的句柄。
SetWindowLong(m_hWnd,GWL_STYLE,WS_OVERLAPPEDWINDOW);
问题:在使用SetWindowLong设置窗口类型里,想获得现有的窗口类型,怎么进行?
LONG GetWindowLong(         
HWND hWnd, //窗口句柄
    int nIndex       //常量,指定窗口的那种信息 如:GWL_STYLE
);
获取现有类型,去掉最大化按钮
SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_hWnd,GWL_STYLE)
& ~WS_MAXIMIZEBOX);
三、              如果要修改窗口的图标、光标和背景,应该如何去修改?
图标、光标和背景是在设计窗口类时被指定的,窗口类的设计和注册是由MFC的底层代码自动实现的,不可能去修改MFC的底层代码,如何修改?
一、自己编写窗口类,并注册,让随后的窗口的创建按照我们设计好的窗口类去创建。
在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();//注意用全局函数获取应用程序hInstance句柄
       wndcls.lpfnWndProc=::DefWindowProc;//必须指定为API函数,不同于CWnd中的DefWindowProc(参数个数不同)
       wndcls.lpszClassName="sunxin.org";
       wndcls.lpszMenuName=NULL;//菜单的创建并不是在设计窗口类时创建的,由MFC在构造pDocTemplate = new CSingleDocTemplate(IDR_MAINFRAME,…) 被创建。
       wndcls.style=CS_HREDRAW | CS_VREDRAW;
       RegisterClass(&wndcls);
       cs.lpszClass="sunxin.org";//precreatewindow()中判lpszClass是否为空,不为空说明已注册
编译并运行,发现只有图标被改变,背景、光标未改变,为什么?
答:view始终履盖在frame窗口上,必须在view类的precreatewindow中,指定窗口类为刚才自己编写的这个窗口类。
BOOL CStyleView::PreCreateWindow(CREATESTRUCT& cs)
{
      
       cs.lpszClass="sunxin.org"; //这个窗口类已经注册了,只要指定即可
      
       return CView::PreCreateWindow(cs);
}
四、              在框架窗口中只能修改图标,为了修改图标需要重写窗口类,太麻烦,MFC中提供了一个全局函数,AfxRegisterWndClass()修改、设定一个窗口类的类型,光标、背景、图标。返回一个注册成功的窗口类类名。如果只修改类的类型(wndcls.style),只要第一个参数,其它取默认值。
LPCTSTR AFXAPI AfxRegisterWndClass(
   UINT nClassStyle,
   HCURSOR hCursor = 0,
   HBRUSH hbrBackground = 0,
   HICON hIcon = 0
);
1、 改变框架窗口的图标
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
       if( !CFrameWnd::PreCreateWindow(cs) )
              return FALSE;
cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW
| CS_VREDRAW,0,0,LoadIcon(NULL,IDI_WARNING));//
       return TRUE;
}
2、改变光标和背景,在view中
BOOL CStyleView::PreCreateWindow(CREATESTRUCT& cs)
{
       cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,
       LoadCursor(NULL,IDC_CROSS),(HBRUSH)GetStockObject(BLACK_BRUSH),0);
              return CView::PreCreateWindow(cs);
}
3、只给AfxRegisterWndClass()的第一个参数赋值,其余取缺省值,cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW);
发现:图标变成wave-flag,光标是箭头形状,背景变成透明。
MSDN:
hCursor
Specifies a handle to the cursor resource to be installed in each window created from the window class. If you use the default of 0, you will get the standard IDC_ARROW cursor.
hbrBackground
Specifies a handle to the brush resource to be installed in each window created from the window class. If you use the default of 0, you will have a NULL background brush, and your window will, by default, not erase its background while processing WM_ERASEBKGND.
hIcon
Specifies a handle to the icon resource to be installed in each window created from the window class. If you use the default of 0, you will get the standard, waving-flag Windows logo icon.
五、              以上都是在窗口创建之前,在窗口创建之后,还能不能修改它的图标、光标背景?
DWORD SetClassLong(         
HWND hWnd,
    int nIndex,
    LONG dwNewLong
);
The SetClassLong function replaces the specified 32-bit (long) value at the specified offset into the extra class memory or the WNDCLASSEX structure for the class to which the specified window belongs.
DWORD GetClassLong(         
HWND hWnd,
    int nIndex
);
The GetClassLong function retrieves the specified 32-bit (long) value from the WNDCLASSEX structure associated with the specified window
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));
LoadIcon()的第二个参数要求一个字符指针,但我们只有图标的ID号,ID号转换为LPTSTR指针类型,MAKEINTRESOURCE()
LPTSTR MAKEINTRESOURCE(
    WORD wInteger
);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值