zoukankan      html  css  js  c++  java
  • 详解CREATESTRUCT结构体

    CREATESTRUCT结构定义了传递给应用程序的窗口过程的初始化参数,它定义了窗口外观相关特性,CREATESTRUCT结构具有如下形式:

    typedef struct tagCREATESTRUCT
    {
      LPVOID  lpCreateParams;  //指向将被用于创建窗口的数据的指针。  
      HANDLE  hInstance;       //标识了拥有新窗口的模块的模块实例的句柄。  
      HMENU   hMenu;           //标识了要被用于新窗口的菜单。如果是子窗口,则包含整数ID。  
      HWND    hwndParent;      //标识了拥有新窗口的窗口。如果新窗口是一个顶层窗口,这个参数可以为NULL。  
      int     cy;              //指定了新窗口的高。  
      int     cx;              //指定了新窗口的宽。  
      int     y;               //指定了新窗口的左上角的y轴坐标。  
      int     x;               //指定了新窗口的左上角的x轴坐标。 
      LONG    style;           //指定了新窗口的风格。  
      LPCSTR  lpszName;        //指向一个以null结尾的字符串,指定了新窗口的名字。  
      LPCSTR  lpszClass;       //指向一个以null结尾的字符串,指定了新窗口的Windows类名
      DWORD   dwExStyle;       //指定了新窗口的扩展风格。  
    } CREATESTRUCT;


    在MFC中我们利用MFC向导就可以创建一个单文档和多文档APP,这里主要用单文档应用程序举例。MFC封装了Win32 API使得我们窗口的创建更加简单,利用APP Wizard可以生成具有默认属性的窗口程序。如果我们需要修改应用程序的默认属性,可以调用PreCreateWindow函数和SetWindowLong函数就行自定义,下面分别介绍之。


    PreCreateWindow函数


    PreCreateWindow函数从字面上看,就知道它是创建窗口有关系,它是在窗口创建之前进行外观修改,通过重载该函数,可以修改CREATESTRUCT结构,从而加入用户自定义的属性,其函数声明如下:

    virtual BOOL PreCreateWindow( CREATESTRUCT& cs );
    
    在SDI程序CMainFrame类中,一般都会自带该函数的实现,代码如下:
    BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
    {
    	if( !CFrameWnd::PreCreateWindow(cs) )
    		return FALSE;
    	// TODO: 在此处通过修改
    	//  CREATESTRUCT cs 来修改窗口类或样式
    
    	return TRUE;
    }

    由于该函数是虚函数,因此MFC底层代码创创建窗口之前,先会调用该函数,从而实现默认属性修改,这里我们修改宽度和高度,增加水平和垂直的滚动条,以及删除可调边框属性。

    例子1 修改外观

    BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
    {
        if( !CFrameWnd::PreCreateWindow(cs) )
            return FALSE;
        // TODO: 在此处通过修改
        //  CREATESTRUCT cs 来修改窗口类或样式
        //改变大小
        cs.cx = 500; 
        cs.cy = 400;
        //增加水平和垂直滚动条
        cs.style |= WS_HSCROLL | WS_VSCROLL;
        //去除可调边框属性
        cs.style &= ~WS_THICKFRAME ;
    
        return TRUE;
    }
    运行效果对比:


    例子2:修改窗口标题

         在默认的单文档和多文档应用程序中,框架窗口stytle风格都包含有FWS_ADDTOTITLE这个属性,其含义是将文档的标题做为窗口的标题,如果需要自定义窗口标题,需要将这个属性删除,具体代码如下:

    BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
    {
        if( !CFrameWnd::PreCreateWindow(cs) )
            return FALSE;
        //  CREATESTRUCT cs 来修改窗口类或样式
        //改变大小
        cs.cx = 400; 
        cs.cy = 300;
        //增加水平和垂直滚动条
        cs.style |= WS_HSCROLL | WS_VSCROLL;
        //去除FWS_ADDTOTITLE属性
        cs.style &= ~FWS_ADDTOTITLE ;
        //自定义标题
        cs.lpszName = "HelloWorld";
    
        return TRUE;
    }
    运行效果:




    SetWindowLong函数



    上面介绍的PreCreateWindow函数是在创建之前进行修改的,而SetWinowLong函数是在窗口创建之后进行修改的。

    我们在发现框架类(CMainFrame)中有个OnCreate函数,该函数的功能是完成窗口的创建,其部分代码如下:

    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
        if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
        ...
    
        // TODO: 如果不需要可停靠工具栏,则删除这三行
        m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
        EnableDocking(CBRS_ALIGN_ANY);
        DockControlBar(&m_wndToolBar);
    
        return 0;
    }


    我们发现该函数调用了基类的OnCreate()函数,就是这个函数完成了窗口的创建,我们可以在该函数返回前调用SetWindowLong完成指定窗口的属性修改,该函数声明如下:

    LONG SetWindowLong(HWND hWnd,int nlndex,LONG dwNewLong)
    hWnd:窗口句柄及间接给出的窗口所属的类。
    nlndex:指定将设定的大于等于0的偏移值。要设置其他任何值,可以指定下面值之一:

        GWL_EXISTYLE:设定一个新的扩展风格。
        GWL_STYLE:设定一个新的窗口风格。
        GWL_WNDPROC:为窗口过程设定一个新的地址。GWL_ID:设置一个新的窗口标识符。
         ....
    dwNewLong:指定的替换值。

    对应的,MFC提供了GetWindowLong函数来获取指定窗口的信息,其函数声明如下:

    LONG GetWindowLong(HWND hWnd,int nlndex)
    该函数的返回值就是窗口的信息,nIndex指定了要获取的内容,这个为GWL_STYLE,意为获得窗口风格,修改风格的具体代码如下:

    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
        if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
        ...
    
        // TODO: 如果不需要可停靠工具栏,则删除这三行
        m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
        EnableDocking(CBRS_ALIGN_ANY);
        DockControlBar(&m_wndToolBar);
        SetWindowLong(m_hWnd, 
                      GWL_STYLE, //获取风格
                      GetWindowLong(m_hWnd, GWL_STYLE) & ~WS_MAXIMIZEBOX);//修改风格 去除最大化属性。
        return 0;
    }
    运行效果对比:



  • 相关阅读:
    STL::next_permutation();
    P2626 斐波那契数列(升级版)
    P1029 最大公约数和最小公倍数问题
    P1075 质因数分解
    4.7生日当天测
    cin,scanf,gets,getline,cin.getline对于字符串的输入
    两个互质的数不能凑出来的数证明
    简单的全排列问题(给初学者)
    紫书 例题 10-22 UVa 1640(数位统计)
    紫书 例题 10-21 UVa 11971(连续概率)
  • 原文地址:https://www.cnblogs.com/jinxiang1224/p/8468361.html
Copyright © 2011-2022 走看看