改变窗口属性

http://blog.csdn.net/strategycn/article/details/6428851

 

在窗口创建之前完成之前改变窗口属性

MFC中通过重写PreCreateWindow()  虚函数改变AppWizard生成的窗口的默认属性

①通过改变PreCreateWindow()函数的CREATSTRUCT来改变。

typedef     struct     tagCREATESTRUCT { 
   LPVOID    lpCreateParams;  
   HANDLE    hInstance;            //实例
   HMENU     hMenu;                //窗口菜单
   HWND      hwndParent;           //父窗口
   int       cy;                   //窗口宽度
   int       cx;                   //窗口高度
   int       y;                    //窗口左上角y坐标
   int       x;                    //窗口左上角x坐标
   LONG      style;                //窗口类型(初始最大/小化、 有无最大/小化按钮、边框、重叠窗口等等)
   LPCSTR    lpszName;             //窗口标题名(受style影响,如果style有FWS_ADDTOTITLE这一属性就不能自己设置)
   LPCSTR    lpszClass;            //窗口类 WNDCLASS ,可以通过自定义窗口类来改变窗口光标、图标、背景颜色,但是对于SDI单文档程序来说,Frame类上覆盖一个View类,因此在Frame类的PreCreateWindow()函数中改变了窗口类中改变了光标和背景以后,看起来只改变了图标而没有改变光标和背景颜色,这是因为:View类在前,显示的是View类的光标和背景,根据实际需要改变View类的光标和背景颜色即可,由于该窗口类已创建,在View类的PreCreateWindow()函数中给CREATESTRUCT结构体的lpszClass赋值为已注册的新建窗口类即可。     
   DWORD     dwExStyle;             //扩展窗口类型
} CREATESTRUCT; 
 

NOTE:通过改变CREATSTRUCT结构体中的 lpszName来改变窗口的标题,结果发现没有变,原因是缺省的窗口类型是WS_OVERLAPPEDWINDOW  FWS_ADDTOTITLE联合。 而FWS_ADDTOTITLE是用来通知框架用文档的标题当作窗口的标题,如果要修改窗口标题我们就要去掉这个属性。

so: 

cs.style = cs.style & ~FWS_ADDTOTITLE; 或者 

cs.style &= ~FWS_ADDTOTITLE;                也可以直接对style赋值:

cs.style = WS_OVERLAPPEDWINDOW;

更多欢笑更多惊喜更多style可用的值(Available  styles)见MSDN CWnd::PreCreateWindow

NOTE:窗口类只是窗口的一部分,完整的窗口修改就是修改CREATSTRUCT结构体,该结构体包括窗口对应的窗口类(通过指定类名来修改窗口对应的窗口类)。

②一个具体的例子(方法1:新建窗口类)

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    if( !CFrameWnd::PreCreateWindow(cs) )
        return FALSE;
    cs.cx = 800;  //宽度
     cs.cy = 600; //高度
     cs.style = cs.style & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX & ~FWS_ADDTOTITLE;
    cs.lpszName = "我的程序"; 

    // new WNDCLASS
    WNDCLASS wndcls;
    wndcls.cbClsExtra = 0;
    wndcls.cbWndExtra = 0;
    wndcls.hbrBackground = (HBRUSH) GetStockObject(LTGRAY_BRUSH);
    wndcls.hCursor = LoadCursor(NULL, IDC_CROSS);
    wndcls.hInstance = AfxGetInstanceHandle();   //取得当前应用 程序的句柄
     TRACE("Application instance handle1 is 0x%0X/n", AfxGetInstanceHandle());  //调试输出

     //wndcls.hInstance = (HINSTANCE) GetWindowLong(m_hWnd, GWL_HINSTANCE);//尝试这样得到应用程序句柄,结果发现虽然不报错,但是结合下面取得窗口过程出错我认为:此时窗口还没有创建完成,也就取不到该窗口对应的程序实例句柄。
     TRACE("Application instance handle2 is 0x%0X/n", GetWindowLong(m_hWnd, GWL_HINSTANCE)); //调试发现和上面取得的应用程序句柄不一样。

     //wndcls.lpfnWndProc = (WNDPROC)GetWindowLong(m_hWnd, GWL_WNDPROC); //尝试这样取得窗口过程,报错“空文档建立失败”, 所以认为:在PreCreateWindow()中窗口建成,所以只能用SetWindowLong()之类Set函数

    wndcls.lpfnWndProc = ::DefWindowProc; //缺省窗口过程(见:设计窗口类时设计窗口过程函数的完成代码)。
    wndcls.lpszClassName = "cuihaoWndClass";
    wndcls.lpszMenuName = MAKEINTRESOURCE(IDR_MAINFRAME);
    wndcls.style = CS_HREDRAW | CS_VREDRAW;
    wndcls.hIcon = LoadIcon(NULL, IDI_WARNING);
    RegisterClass(&wndcls);
    cs.lpszClass = "cuihaoWndClass"; 

    return TRUE;
}

BOOL CMy44View::PreCreateWindow(CREATESTRUCT& cs)
{
    cs.lpszClass = "cuihaoWndClass";  //这样即可,因为 cuihaoWndClass类已经注册 
    return CView::PreCreateWindow(cs);
}

③一个具体例子(方法2 :快速创建窗口类)

AfxRegisterWndClass   该函数快速注册一个窗口类,参数仅有:类样式,光标,背景色,图标。返回一个窗口类的类名

LPCTSTR   AFXAPI      AfxRegisterWndClass(
    UINT    nClassStyle,
    HCURSOR    hCursor=0,
    HBRUSHhbr   Background=0,
    HICON    hIcon=0
);

 


eg.

CString strClass = ""; //用来保存类名,全局变量,以便在View类中为CREATESTRUCT结构体制定

// lpszClass = strClass;
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    if( !CFrameWnd::PreCreateWindow(cs) )
        return FALSE;

    cs.cx = 800;
    cs.cy = 600; 
    cs.style = cs.style & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX & ~FWS_ADDTOTITLE;
    cs.lpszName = "我的程序";   
    strClass = cs.lpszClass = AfxRegisterWndClass(CS_VREDRAW | CS_HREDRAW, LoadCursor(NULL, IDC_CROSS),
 (HBRUSH)GetStockObject(BLACK_BRUSH), LoadIcon(NULL, IDI_WINLOGO)); 

    return TRUE;
}

BOOL CMy44View::PreCreateWindow(CREATESTRUCT& cs)
{
    extern CString strClass; //声明在其他源文件中定义的全局变量
     cs.lpszClass = strClass; //指定类名 OK
    return CView::PreCreateWindow(cs);
}

3 窗口生成以后再改变窗口属性

在窗口OnCreate()函数中coding

LONG SetWindowLong

LONG SetWindowLong(
    HWND    hWnd,      //窗口句柄,所有从CWnd类继承来的类都有一个m_hWnd成员变量标识 
    int     nIndex,     //要设置的值的基于0 的偏移量或者下列值
    LONG    dwNewLong   //根据nIndex的值而设定的新值 
);

nIndex:

   
GWL_EXSTYLE Sets a new extended window style. For more information, seeCreateWindowEx.
GWL_STYLE 窗口类型 见MSDN: window style.
GWL_WNDPROC 窗口过程函数
GWL_HINSTANCE 应用程序实例句柄  
GWL_ID Sets a new identifier of the window.
GWL_USERDATA Sets the user data associated with the window. This data is intended for use by the application that created the window. Its value is initially zero.

如果hWnd是一个对话框的时候用下面的值

   
DWL_DLGPROC Sets the new address of the dialog box procedure.
DWL_MSGRESULT Sets the return value of a message processed in the dialog box procedure.
DWL_USER Sets new extra information that is private to the application, such as handles or pointers.

获得窗口属性用函数

LONG GetWindowLong(
    HWND  hWnd,     // handle to window 
    int   nIndex    // offset of value to retrieve
);

NOTE:至少在窗口创建完成后才能调用这个函数

SetClassLong

DWORD SetClassLong(
    HWND     hWnd,      // handle to window
    int      nIndex,    // index of value to change
    LONG    dwNewLong   // new value 
);

GetClassLong

DWORD GetClassLong(
    HWND      hWnd,     // handle to window
    int       nIndex    // offset of value to retrieve
);

4  总结:

在窗口创建之前在PreCreateWindow()函数中用AfxRegisterWndClass创建窗口类

在窗口创建完后在OnCreat()函数中用 SetWindowLong()  SetClassLong()

SetWindowLong()设置窗口属性, SetClassLong()设置窗口类属性

GetWindowLong()取得窗口属性, GetClassLong()取得窗口类属性


 


 

你可能感兴趣的:(改变窗口属性)