修改应用程序窗口的外观
第一:在窗口创建之前设置
在MainFrame类的PreCreateWindow成员函数中进行.即对函数的形参cs进行设置.
注:cs是CREATETRUCT结构.
CREATESTRUCT
typedef struct tag CREATESTRUCT
{
LPVOID lpCreateParams;
HANDLE hInstance;
HMENU hMenu;
HWND hwndParent;
int cy;
int cx;
int y;
int x;
LONG style;
LPCSTR lpszName;
LPCSTR lpszClass;
DWORD dwExStyle;
}
CREATESTRUCT;CREATESTRUCT结构定义了传递给应用程序的窗口过程的初始化参数。
成员:
lpCreateParams 指向将被用于创建窗口的数据的指针。
hInstance 标识了拥有新窗口的模块的模块实例的句柄。
hMenu 标识了要被用于新窗口的菜单。如果是子窗口,则包含整数ID。
hwndParent 标识了拥有新窗口的窗口。如果新窗口是一个顶层窗口,这个参数可以为NULL。
cy 指定了新窗口的高。
cx 指定了新窗口的宽。
y 指定了新窗口的左上角的y轴坐标。如果新窗口是一个子窗口,则坐标是相对于父窗口的;否则坐标是相对于屏幕原点的。
x 指定了新窗口的左上角的x轴坐标。如果新窗口是一个子窗口,则坐标是相对于父窗口的;否则坐标是相对于屏幕原点的。
style 指定了新窗口的风格。
lpszName 指向以结束符('\0')表示结尾的字符串,该字符串指定了新窗口的名字。(如果指向空字符串,也就是只包含一个结束符,就相当于传递参数NULL,下同)
lpszClass 指向以结束符('\0')表示结尾的字符串,该字符串指定了新窗口的Windows类名(一个WNDCLASS结构;更多的信息参见Win32 SDK文档)
dwExStyle 指定了新窗口的扩展风格。
创建的Style应用程序是一个单文档界面(SDI)应用程序,框架的默认窗口样式是WS_OVERLAPPEDWINDOW和FWS_ADDTOTITLE样式的组合.因此,如果想让窗口显示自己设置的标题,只需要将窗口的FWS_ADDTOTITLE样式去掉.或者也可以将style设置为WS_OVERLAPPENDWINDOW.
第二:在窗口创建之后修改
想要在窗口创建之后修改窗口,可以在框架类(CMainFrame)的OnCreate函数中添加具体的实现代码.它是先调用基类的OnCreate函数,来创建窗口.即我们可以在函数回之前添加我们自己的代码.其中SetWindowLong函数可以实现这个功能.
注:SetWindowLong是一个Windows API函数。该函数用来改变指定窗口的属性.函数也将指定的一个32位值设置在窗口的额外存储空间的指定偏移位置。
函数原型:
值
|
意义
|
---|---|
GWL_EXSTYLE
|
设定一个新的扩展
风格。
|
GWL_HINSTANCE
|
设置一个新的
应用程序实例句柄。
|
GWL_ID
| |
GWL_STYLE
|
设定一个新的窗口风格。
|
GWL_USERDATA
|
设置与窗口有关的32位值。每个窗口均有一个由创建该窗口的应用程序使用的32位值。
|
GWL_WNDPROC
|
为窗口过程设定一个新的地址。
|
值
|
意义
|
---|---|
DWL_DLGPROC
|
设置对话框过程的新
地址。
|
DWL_MSGRESULT
|
设置在对话框过程中处理的消息的返回值。
|
DWL_USER
|
设置的应用程序私有的新的额外信息,例如一个句柄或
指针。
|
譬如,SetWindowLong(m_hWnd,GWL_STYLE,WS_OVERLAPPEDWINDOW) ,语句的功能是去掉文档的标题.
与之对应的函数是GetWindowLong.它的原型是LONG GetWindowLong(HWND hWnd, int nIndex); 注释:GWL就是GetWindowLong三个单词首字母的缩写.
它的功能是获得窗口的现有类型.
譬如,SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_hWnd,GWL_STYLE) & ~WS_MAXIMIZEBOX),使得窗口右上角的最大化框变灰及失效.
修改窗口的光标,图标和背景
第一:在窗口创建之前修改
因为图标,光标和背景是在设计窗口类的时候指定的,窗口类的设计和注册是MFC底层代码自动帮助我们完成的,因此我们不可能通过修改MFC底层代码来修改光标,图标和背景。但是,我们可以编写自己的窗口类并注册。
我们可以在PreCreateWindow函数中编写一个自己的窗口类并注册。
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;
//cs.style&=~FWS_ADDTOTITLE;
cs.style=WS_OVERLAPPEDWINDOW;
cs.lpszName="http://www.sunxin.org";
return TRUE;
*/
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";
return TRUE;
}
AfxGetInstanceHandle函数是获取当前应用程序的句柄。(注释:Afx开始的函数都是应用程序框架类函数,也就是全局函数,在程序的所有类中都可以直接调用)。
lpszMenuName(菜单的名称)。设置成NULL。因为窗口的菜单不
但是仅仅这样并不能修改光标和背景。因为应用程序包含两个窗口:应用程序框架类窗口和视类窗口。后者覆盖在前者的上面。因此我们还需要在CStyleView类的PreCreateWindow函数中调用AfxRegisterWndClass函数。
BOOL CStyleView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
// cs.lpszClass="sunxin.org";
cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW,LoadCursor(NULL,IDC_CROSS),(HBRUSH)GetStockObject(BLACK_BRUSH),0);
return CView::PreCreateWindow(cs);
}
第二:在窗口创建之后修改
我们可以利用全局API函数:SetClasLong 来实现。该函数用来重置指定窗口所属窗口类的WNDCLASSEX结构体(是WNDCLASS结构的扩展)中指定数据成员的属性,该函数的原型声明为:
DWORD SetClassLong( HWND hWnd,int nIndex,Long dwNewLong);
SetClassLong(m_hWnd,GCL_HCURSOR,(LONG)LoadCursor(NULL,IDC_HELP));