zoukankan      html  css  js  c++  java
  • 窗口类

    前幾天逛msdn,看了一下關於window class的介紹,發現有些東西沒有注意到的,特此翻譯

     

    窗口類的類別:有三種——systemClasses、Application Global Classes、Application Local Classes

    這三種的不同在于作用域以及何時、如何注冊和銷毀方面。

    SysTemClasses

    所謂的SystemClasses,是指那些已經由windows預先注冊的類——windows標準控件的窗口類就是他們。由于是系統注冊了這些類,因此用戶無法銷毀他們。

    當一個進程的線程第一次開始呼叫GDI函數時,系統就會為這個進程注冊這些systemClasses。

    每個應用程序接收屬于自己的那份systemClasses拷貝,所有的16位應用程序在同一個VDM(Virtual Dos machine)是共享systemClasses的。

    systemClasses定義內容如下,這部分是可以被用戶直接獲得使用的:

    Class

    Description

    Button

    The class for a button.

    ComboBox

    The class for a combo box.

    Edit

    The class for an edit control.

    ListBox

    The class for a list box.

    MDIClient

    The class for an MDI client window.

    ScrollBar

    The class for a scroll bar.

    Static

    The class for a static control.

    這部分是給系統用的

    Class

    Description

    ComboLBox

    The class for the list box contained in a combo box.

    DDEMLEvent

    The class for Dynamic Data Exchange Management Library (DDEML) events.

    Message

    The class for a message-only window.

    #32768

    The class for a menu.

    #32769

    The class for the desktop window.

    #32770

    The class for a dialog box.

    #32771

    The class for the task switch window.

    #32772

    The class for icon titles.

    Application Global Classes

    由Exe或者Dll注冊,可以被其他進程模塊訪問到。比如,其他進程一旦加載了這個dll(注冊了這個窗口類),那么該進程就可以創建這個窗口類的實例了。

        要創建可以被每個進程使用的窗口類,就需要把它放在Dll中,并使得可自動加載在每個進程中——可以把Dll的文件名放到注冊表HKEY_LOCAL_MACHINE/Software/Microsoft/Windows NT/CurrentVersion/Windows

    此路徑下的AppInit_DLLs  鍵值 。

         這樣,在進程啟動時,進入入口函數以前,系統就會為進程加載指定的dll。所以在dll中,窗口類的注冊必須在初始化dll過程時進行,而且必須指定CS_GLOBALCLASS風格。

    Application Local Classes

    與Global Classes相反,他只適合在本進程里面使用。其他進程無法獲得該窗口類的任何信息,當然也找不到它。

    一個窗口類只會注冊一次,即使你調用了很多次RegisterClass。當注冊該窗口類的模塊終止了,系統會銷毀這個Local Class

     

    系統是如何定位一個窗口類呢?

        系統會為每種類型的窗口類(即以上說明的三種窗口類)分別維護一個結構列表。當應用程序調用CreateWindow或CreateWindowEx來創建一個窗口時,系統會根據指定的窗口類,按照以下過程來定位這個類:

    1、根據指定的窗口類名和進程(或模塊)的實例句柄(因為其他模塊,也會以相同的窗口類名注冊,所以會以模塊的實例句柄作區分),查找Application Local Classes;

    2、若沒有在1步驟中找到,則查找Application Global Classes;

    3、若沒有在2步驟中找到,則查找System Classes;

    所有由應用程序創建的窗口,包括因應用程序的行為使系統創建的窗口,都是采用這個過程定位的。

     

    注冊窗口類

        窗口類定義了窗口的特性,比如style、Icon、Cursor、Menu和window procedure。注冊窗口類,首先要做的是填充WNDCLASSEX 結構,然后把這個結構傳給RegisterClassEx函數。

        若要把窗口類注冊為全局的(application Global Classes),則需要設定CS_GLOBALCLASS。

        RegisterClassEx也區分是否為Unicode版本的函數。如RegisterClassExA,表示支持單字節字符集的Ansi版本 ,應用程序就要求系統傳遞消息(messages)的文本參數,要使用ANSI字符集;若是RegisterClassExW,則系統會被要求以unicode字符集傳遞。

        可以用IsUnicodeWindow判斷一個窗口所要求采用的字符集。

        那些注冊窗口類的Exe或Dll,本身為這些窗口類的擁有者(Owner of the class)。系統依據WNDCLASSEX結構的成員hInstance,判斷此窗口類的擁有關系。如,對DLL來說,hInstance為DLL的handle。

        擁有窗口類的(Owner of the class)DLL若被卸載了,但窗口類本身并不會被銷毀。因此,如果system調用了此窗口類的窗口過程,則會出現地址錯誤,因為dll中的那個窗口過程已經不在內存中了。所以DLL注冊的窗口類,必須在進程銷毀前,銷毀掉(unregisterCLass)窗口類。

     

    窗口類的成員

    typedef struct {
      UINT      cbSize;
      UINT      style;
      WNDPROC   lpfnWndProc;
      int       cbClsExtra;
      int       cbWndExtra;
      HINSTANCE hInstance;
      HICON     hIcon;
      HCURSOR   hCursor;
      HBRUSH    hbrBackground;
      LPCTSTR   lpszMenuName;
      LPCTSTR   lpszClassName;
      HICON     hIconSm;
    } WNDCLASSEX, *PWNDCLASSEX;

     

        這些成員定義了窗口的默認行為。應用程序注冊一個類,先通過對WNDCLASSEX結構賦值,然后傳給CreateWindowEx。GetClassInfoEx和GetClassInfo可以根據給定的窗口類,取得相關信息。SetClassLong可以改變局部窗口類(Application Local Class)或全局窗口類(Application Global Class)的成員內容。

        雖然一個完整的窗口類由很多成員組成,但是系統僅要求應用程序提供class Name、window-procedure-address、instance handle。但是必須要初始化WNDCLASSEx結構其他未使用的成員為0或NULL。

        以下是窗口類的成員說明

    Element

    Purpose

    Class Name

    Distinguishes the class from other registered classes.

    Window Procedure Address

    Pointer to the function that processes all messages sent to windows in the class and defines the behavior of the window.

    Instance Handle

    Identifies the application or .dll that registered the class.

    Class Cursor

    Defines the mouse cursor that the system displays for a window of the class.

    Class Icons

    Defines the large icon and the small icon.

    Class Background Brush

    Defines the color and pattern that fill the client area when the window is opened or painted.

    Class Menu

    Specifies the default menu for windows that do not explicitly define a menu.

    Class Styles

    Defines how to update the window after moving or resizing it, how to process double-clicks of the mouse, how to allocate space for the device context, and other aspects of the window.

    Extra Class Memory

    Specifies the amount of extra memory, in bytes, that the system should reserve for the class. All windows in the class share the extra memory and can use it for any application-defined purpose. The system initializes this memory to zero.

    Extra Window Memory

    Specifies the amount of extra memory, in bytes, that the system should reserve for each window belonging to the class. The extra memory can be used for any application-defined purpose. The system initializes this memory to zero.

    下面挑出一些需要特別說明的東西:

    Class Name

       如一個唯一的ID,標識自己。可以通過設置WNDCLASSEX結構成員lpszCLASSNAME——指向存放0結尾字串的地址,來設置CLASSNAME。由于窗口類是進程指定的,所以在同一個進程內,窗口類必須是唯一的。同時,由于CLASSName占用的是系統原子表(system’s ATOM TABLE)空間,所以盡可能要短。

       GetClassName可以獲取指定的窗口的窗口類名。

    Class Cursor

        用于定義光標在窗口的客戶區域(Client area)的形狀。當光標進入客戶區域時,系統會自動將光標改為class Cursor所指定的。我們可以通過LoadCursor加載系統預定義的光標,再將返回的句柄賦給hCursor。

        也可以從應用程序的資源文件里,用LoadCursor加載自定義的光標。

         系統不要求一定要給這個成員賦值。當應用程序把這個成員值設為null時,那么系統會認為:應用程序自己會在每次光標移動時自己設置光標的形狀。

    我們也可以通過SetCursor設定一個窗口的光標形狀。

    Class ICON

        用于設定應用程序的圖標。應用程序有兩種圖標:一個大的和一個小的。當我們使用ALT+TAB時,會出現任務切換窗口(TASK-Switch WINDOW),上面顯示的是應用程序的大圖標,也出現在Explorer和開始菜單中以大圖標視圖查看。小圖標,如出現在標題欄或explorer和開始菜單的小圖標視圖查看時。

        要設置大圖標,則給hIcon;小圖標,則是hIconSM。圖標的維度大小,要遵循系統約定。可以通過GetSystemMetrics取得維度大小。對于大圖標,傳SM_CXICON和SM_CYICON兩個參數;對于小圖標,傳SM_CXSMIcon和SM_CYSMIcon。

        若這兩個成員都沒有設定,那么系統會采用默認的應用程序圖標作為大、小圖標。若只給了大圖標,系統會依據大圖標,再創建一個小圖標;若只給了小圖標,系統會采用默認的程序圖標作為大圖標。

        相關的操作消息: WM_SetIcon、WM_GetIcon

    Class Background Brush

       背景刷子(brush),用於後續窗口的繪畫。系統會用這裡指定的刷子,在窗口的客戶區域(Client Area),以指定的純色(solid color)或圖案繪畫。因此,系統會清除之前屬於這個窗口區域的所有圖像。系統會通過發送消息WM_ERASEBKGND通知窗口,以告知窗口的背景是否需要重畫。

       我們可以創建一個新的刷子,並把返回的句柄賦給它,也可以直接給它賦 系統標準的顏色值(參考GetSysColorBrushSetSysColors)。

      

    Class Styles

     

    Style

    Action

    CS_BYTEALIGNCLIENT

    Aligns the window's client area on a byte boundary (in the x direction). This style affects the width of the window and its horizontal placement on the display.

    CS_BYTEALIGNWINDOW

    Aligns the window on a byte boundary (in the x direction). This style affects the width of the window and its horizontal placement on the display.

    CS_CLASSDC

    Allocates one device context to be shared by all windows in the class. Because window classes are process specific, it is possible for multiple threads of an application to create a window of the same class. It is also possible for the threads to attempt to use the device context simultaneously. When this happens, the system allows only one thread to successfully finish its drawing operation.

    CS_DBLCLKS

    Sends a double-click message to the window procedure when the user double-clicks the mouse while the cursor is within a window belonging to the class.

    CS_DROPSHADOW

    Windows XP: Enables the drop shadow effect on a window. The effect is turned on and off through SPI_SETDROPSHADOW. Typically, this is enabled for small, short-lived windows such as menus to emphasize their Z order relationship to other windows.

    CS_GLOBALCLASS

    Specifies that the window class is an application global class. For more information, see Application Global Classes.

    CS_HREDRAW

    Redraws the entire window if a movement or size adjustment changes the width of the client area.

    CS_NOCLOSE

    Disables Close on the window menu.

    CS_OWNDC

    Allocates a unique device context for each window in the class.

    CS_PARENTDC

    Sets the clipping rectangle of the child window to that of the parent window so that the child can draw on the parent. A window with the CS_PARENTDC style bit receives a regular device context from the system's cache of device contexts. It does not give the child the parent's device context or device context settings. Specifying CS_PARENTDC enhances an application's performance.

    CS_SAVEBITS

    Saves, as a bitmap, the portion of the screen image obscured by a window of this class. When the window is removed, the system uses the saved bitmap to restore the screen image, including other windows that were obscured. Therefore, the system does not send WM_PAINT messages to windows that were obscured if the memory used by the bitmap has not been discarded and if other screen actions have not invalidated the stored image.

    This style is useful for small windows (for example, menus or dialog boxes) that are displayed briefly and then removed before other screen activity takes place. This style increases the time required to display the window, because the system must first allocate memory to store the bitmap.

    CS_VREDRAW

    Redraws the entire window if a movement or size adjustment changes the height of the client area.

  • 相关阅读:
    中国大学排名爬虫
    基于bs4库的HTML内容查找方法和HTML格式化和编码
    自动化提取51啦数据的信息
    简单目录扫描工具
    一个简单音乐播放器
    【原创】C++中对象的序列化
    [android]android开发中的运行错误之:adb.exe
    [转载]十大编程算法助程序员走上高手之路
    [原创]二叉树相关笔试题代码
    [原创]VS2010中创建动态链接库及其调用
  • 原文地址:https://www.cnblogs.com/sideny/p/3281476.html
Copyright © 2011-2022 走看看