正文

改变应用程序的外观2006-12-19 20:21:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/12567/21726.html

分享到:

第一部分 改变应用程序的外观
一、 问题:要修改一个应用程序的外观,应该在应用程序创建之前还是在创建之后修改呢?
修改一幢楼房应在建成之前,应在窗口创建之前修改。要改变一个框架窗口的外观,应在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,光标是箭头形状,背景变成透明。
 
 

阅读(3990) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册