zoukankan      html  css  js  c++  java
  • win32编程day03 学习笔记

    一 窗口注册和创建

      1 Win32窗口程序创建步骤
     
        1.1 WinMain入口函数的定义
        1.2 WindowProc函数的定义
        1.3 注册窗口类
          RegisterClass/RegisterClassEx
        1.4 创建窗口
          CreateWindow/CreateWindowEx
        1.5 窗口的显示和刷新
          ShowWindow/UpdateWindow
        1.6 消息处理
          GetMessage/DispatchMessage
        1.7 窗口退出
          WM_DESTROY/PostQuitMessage

      2 窗口的注册
       
       2.1 窗口类的分类
         2.1.1 系统全局的窗口类.比如按钮("BUTTON")、文本编辑框("EDIT")等。
         2.1.2 应用程序的全局窗口类。可以在一个应用程序中EXE、DLL等所有模块中使用的窗口类。
         2.1.3 局部窗口类。只能在本模块中使用的窗口类。

      2.2 实现窗口类的注册
         2.2.1 系统全局的窗口类,无需注册直接使用。使用CreateWindow函数,在CLASSNAME中指定系统已经定义好的窗口类型名称即可。

    View Code
    #include <windows.h>
    #include "stdio.h"
    
    HINSTANCE g_hInst = NULL;
    LRESULT CALLBACK WndProc(HWND hWnd, UINT nMsg, 
                             WPARAM wParam, LPARAM lParam)
    {
        switch(nMsg) {
        case WM_DESTROY: PostQuitMessage(0);
            return 0;
        }
        return DefWindowProc(hWnd, nMsg, wParam, lParam);
    }
    
    HWND CreateButton()
    {
        HWND hWnd = CreateWindow("BUTTON", "Button", WS_OVERLAPPEDWINDOW, 
            0, 0, 500, 600, NULL, NULL, g_hInst, NULL);
        return hWnd;
    }
    
    void DisplayWnd(HWND hWnd)
    {
        ShowWindow(hWnd, SW_SHOW);
        UpdateWindow(hWnd);
    }
    
    void Message()
    {
        MSG msg = {0};
        while(GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    
    int WINAPI WinMain(HINSTANCE hInst,
                       HINSTANCE hPrevInt,
                       LPSTR lpCmdLine,
                       int nShowCmd)
    {
        g_hInst = hInst;
        HWND hWndBtn = CreateButton();
        DisplayWnd(hWndBtn);
        Message();
        return 0;
    }

         2.2.2 应用程序的全局窗口类,需要用代码实现注册,在注册时需要增加CS_GLOBALCLASS定义。
           实现方式:

                 WNDCLASS wc = {0};
                 wc.style = CS_GLOBALCLASS|CS_HREDRAW..;
                 ....
                 RegisterClass( &wc );

         2.2.3 局部窗口类,不是增加CS_GLOBALCLASS定义。使用RegisterClass和RegisterClassEx注册

                    typedef struct _WNDCLASSEX { 
                        UINT    cbSize; //结构体的大小
                          UINT    style; 
                          WNDPROC lpfnWndProc; 
                          int     cbClsExtra; 
                          int     cbWndExtra; 
                          HANDLE  hInstance; 
                          HICON   hIcon; 
                          HCURSOR hCursor; 
                          HBRUSH  hbrBackground; 
                          LPCTSTR lpszMenuName; 
                          LPCTSTR lpszClassName; 
                          HICON   hIconSm; //小图标
                        } WNDCLASSEX; 

        2.2.4 窗口类风格

                    CS_HREDRAW 窗口水平变化,重新绘制窗口。
                       CS_VREDRAW 窗口垂直变化,重新绘制窗口。
                       CS_DBCLICK 窗口可以接收鼠标双击消息
                       CS_GLOBALCLASS 创建应用程序全局窗口类。
                       CS_BYTEALIGNWINDOW 窗口对齐方式,以8的倍数对齐
                       CS_BYTEALIGNCLIENT 窗口客户区对齐方式,以8的倍数对齐
                       CS_CLASSDC 所有这种类型的窗口使用同一个DC(设备描述表,绘图使用)
                    CS_OWNDC 每个窗口拥有自己的DC
                    CS_PARENTDC 使用父窗口的DC
                    CS_SAVEBITS 是用位图保存窗口界面,可以提高窗口界面的刷新性能
                       CS_NOCLOSE 禁止关闭命令.
    View Code
    #include <windows.h>
    #include "stdio.h"
    
    HINSTANCE g_hInst = NULL;
    LRESULT CALLBACK WndProc(HWND hWnd, UINT nMsg, 
                             WPARAM wParam, LPARAM lParam)
    {
        switch(nMsg) {
        case WM_DESTROY: PostQuitMessage(0);
            return 0;
        }
        return DefWindowProc(hWnd, nMsg, wParam, lParam);
    }
    
    BOOL RegisterWnd(LPSTR pszClassName)
    {
        WNDCLASSEX wce = {0};
        wce.cbSize = sizeof(wce);
        wce.style = CS_VREDRAW|CS_HREDRAW;
        wce.lpfnWndProc = WndProc;
        wce.cbClsExtra = 0;
        wce.cbWndExtra = 0;
        wce.hCursor = NULL;
        wce.hIcon = NULL;
        wce.hbrBackground = HBRUSH(COLOR_BTNFACE+1);
        wce.lpszClassName = pszClassName;
        wce.lpszMenuName = NULL;
        wce.hInstance = g_hInst;
        ATOM nAtom = RegisterClassEx(&wce);
        if(0 == nAtom)
        {
            MessageBox(NULL, "registerError", "Error", MB_OK);
            return FALSE;
        }
        return TRUE;
    }
    
    HWND CreateWnd(LPSTR pszClassName)
    {
        HWND hWnd = CreateWindow(pszClassName,
            "MyWnd", WS_OVERLAPPEDWINDOW, 0, 0, 400, 500,
            NULL, NULL, g_hInst, NULL);
        return hWnd;
    }
    
    void DisplayWnd(HWND hWnd)
    {
        ShowWindow(hWnd, SW_SHOW);
        UpdateWindow(hWnd);
    }
    
    void Message()
    {
        MSG msg = {0};
        while(GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    
    int WINAPI WinMain(HINSTANCE hInst,
                       HINSTANCE hPrevInt,
                       LPSTR lpCmdLine,
                       int nShowCmd)
    {
        g_hInst = hInst;
        RegisterWnd("MyWnd1");
        HWND hMyWnd = CreateWnd("MyWnd1");
    
        DisplayWnd(hMyWnd);
        Message();
        return 0;
    }

        2.2.5 窗口类的附加数据 cbClsExtra
          在窗口类的数据信息中添加自己信息.
           cbClsExtra 用于添加信息的内存的大小
           SetClassLong 将信息保存到内存中
           GetClassLong 将信息从内存中取出

                         DWORD SetClassLong(
                                  HWND hWnd,//窗口的句柄
                                  int nIndex, //值的索引号
                                  LONG dwNewLong   //
                                );
                          DWORD GetClassLong(
                                  HWND hWnd,//窗口的句柄
                                  int nIndex, //值的索引号
                                );

         cbClsExtra的长度一般是4字节的倍数
        2.2.6 窗口附加数据 cbWndExtra
           在窗口的数据信息中添加自己信息.
             cbWndExtra 用于添加信息的内存的大小
             SetWindowLong 将信息保存到内存中
             GetWindowLong 将信息从内存中取出

    View Code
    #include <windows.h>
    #include "stdio.h"
    
    HINSTANCE g_hInst = NULL;
    LRESULT CALLBACK WndProc(HWND hWnd, UINT nMsg, 
                             WPARAM wParam, LPARAM lParam)
    {
        switch(nMsg) {
        case WM_DESTROY: PostQuitMessage(0);
            return 0;
        }
        return DefWindowProc(hWnd, nMsg, wParam, lParam);
    }
    
    BOOL RegisterWnd(LPSTR pszClassName)
    {
        WNDCLASSEX wce = {0};
        wce.cbSize = sizeof(wce);
        wce.style = CS_VREDRAW|CS_HREDRAW;
        wce.lpfnWndProc = WndProc;
        wce.cbClsExtra = 100;
        wce.cbWndExtra = 100;
        wce.hCursor = NULL;
        wce.hIcon = NULL;
        wce.hbrBackground = HBRUSH(COLOR_BTNFACE+1);
        wce.lpszClassName = pszClassName;
        wce.lpszMenuName = NULL;
        wce.hInstance = g_hInst;
        ATOM nAtom = RegisterClassEx(&wce);
        if(0 == nAtom)
        {
            MessageBox(NULL, "registerError", "Error", MB_OK);
            return FALSE;
        }
        return TRUE;
    }
    
    HWND CreateWnd(LPSTR pszClassName)
    {
        HWND hWnd = CreateWindow(pszClassName,
            "MyWnd", WS_OVERLAPPEDWINDOW, 0, 0, 400, 500,
            NULL, NULL, g_hInst, NULL);
        return hWnd;
    }
    
    void SetExtra(HWND hWnd)
    {
        SetClassLong(hWnd, 1, 100);
        SetWindowLong(hWnd, 1, 200);
    }
    
    void GetExtra(HWND hWnd)
    {
        DWORD nClass = GetClassLong(hWnd, 1);
        DWORD nWnd = GetWindowLong(hWnd, 1);
    
        CHAR szText[256] = {0};
        sprintf(szText, "CLS:%d WND:%d", nClass, nWnd);
        MessageBox(NULL, szText, "Extra", MB_OK);
    }
    
    void DisplayWnd(HWND hWnd)
    {
        ShowWindow(hWnd, SW_SHOW);
        UpdateWindow(hWnd);
    }
    
    void Message()
    {
        MSG msg = {0};
        while(GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    
    int WINAPI WinMain(HINSTANCE hInst,
                       HINSTANCE hPrevInt,
                       LPSTR lpCmdLine,
                       int nShowCmd)
    {
        g_hInst = hInst;
        RegisterWnd("MyWnd1");
        HWND hMyWnd1 = CreateWnd("MyWnd1");
        HWND hMyWnd2 = CreateWnd("MyWnd1");
    
        SetExtra(hMyWnd1);
        GetExtra(hMyWnd1);
        GetExtra(hMyWnd2);
    
        DisplayWnd(hMyWnd1);
        Message();
        return 0;
    }

       2.3 窗口类的相关函数
        RegisterClass/RegisterClassEx 注册
         UnregisterClass 注销
         GetClassInfo/GetClassInfoEx 获取信息
         GetClassName 获取窗口的窗口类名称
         GetClassLong/SetClassLong 窗口类附加数据的设置和获取
         GetWindowLong/SetWindowLong 窗口的附加数据的设置和获取
       
        2.4 创建窗口时如何定位窗口类
       
          2.4.1 查找应用程序局部的窗口类。如果找到,执行2.4.2,否则执行2.4.3
          2.4.2 如果找到名称一致的窗口类,会比较HISNTANCE句柄。如果相等,就使用找到的窗口类信息创建窗口,如果不同,继续查找,执行2.4.3。
          2.4.3 如果未找到名称一致的窗口类,会继续在应用程序全局窗口类中查找。如果找到,执行2.4.4,否则执行2.4.5
          2.4.4 全局窗口类找到一致的,使用找到的窗口类信息创建窗口。
          2.4.5 系统全局窗口类中查找。如果找到,创建窗口,否则返回失败。

      3 窗口创建
      
        3.1 窗口创建函数

          CreateWindow/CreateWindowEx
          HWND CreateWindowEx(
                      DWORD dwExStyle,//窗口的扩展样式
                      LPCTSTR lpClassName,  // pointer to registered class name
                      LPCTSTR lpWindowName, // pointer to window name
                      DWORD dwStyle,        // window style
                      int x,                // horizontal position of window
                      int y,                // vertical position of window
                      int nWidth,           // window width
                      int nHeight,          // window height
                      HWND hWndParent,      // handle to parent or owner window
                      HMENU hMenu,          // handle to menu, or child-window identifier
                      HINSTANCE hInstance,  // handle to application instance
                      LPVOID lpParam );     // pointer to window-creation data

       3.2 窗口风格和扩展风格
      
          窗口风格: WS_XXXX定义的风格,是窗口的基本风格.
          扩展风格: WS_EX_XXXXX 定义的风格,是窗口的扩展风格.比如: ToolWindow窗口等等.
          在CreateWindow可以使用基本窗口风格,扩展的窗口风格,需要使用CreateWindowEx设置.
         
          WS_OVERLAPPED窗口,层叠式窗口
          WS_POPUP窗口,弹出式窗口
          WS_CHILD窗口,子窗口
         
         3.3 父窗口和子窗口
            3.3.1 CreateWindow时,指定父窗口
            3.3.2 将窗口的风格增加WS_CHILD
            3.3.3 可以使用SetParent和GetParent函数设置和获取指定窗口的父窗口.
              
            其他: MoveWindow 移动窗口.

         3.4 MDI窗口的创建
            3.4.1 创建主窗口
               注册主窗口类型,创建主窗口.

                            HWND hWnd = CreateWindowEx( 0,
                                pszClassName, "MainWnd", 
                                WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
                                CW_USEDEFAULT, CW_USEDEFAULT,
                                CW_USEDEFAULT, NULL, NULL, g_hInst,
                                NULL );

            3.4.2 MDICLIENT窗口
              1 添加CLIENTCREATESTRUCT结构,作为附加数据
          CLIENTCREATESTRUCT cs = { 0 };
          cs.idFirstChild = 1000;//MDI第一个子窗口的ID
          2 创建时,使用"MDICLIENT"窗口类型.
          3 它的父窗口是主窗口

                            HWND hWnd = CreateWindowEx( 0,
                                "MDICLIENT", "MainWnd", 
                                WS_CHILD|WS_VISIBLE, CW_USEDEFAULT,
                                CW_USEDEFAULT, CW_USEDEFAULT,
                                CW_USEDEFAULT, hParent, NULL, g_hInst,
                                &cs );

            3.4.3 创建一个MDI子窗口
                1 注册主窗口类型,创建子窗口
                2 它的父窗口为MDICLIENT窗口
                3 增加WS_EX_MDICHILD的风格

                          HWND hWnd = 
                          CreateWindowEx( WS_EX_MDICHILD,
                            pszClassName, "ChildWnd", 
                            WS_CHILD|WS_VISIBLE, CW_USEDEFAULT,
                            CW_USEDEFAULT, CW_USEDEFAULT,
                            CW_USEDEFAULT, hParent, NULL, 
                            g_hInst, NULL );
    View Code
    // WinMDI.cpp : Defines the entry point for the application.
    //
    
    #include "stdafx.h"
    
    HINSTANCE g_hInst = NULL;
    HWND g_hMDIClient = NULL;
    
    //主窗口的窗口处理函数
    LRESULT CALLBACK MainProc( HWND hWnd,
                               UINT nMsg,
                               WPARAM wParam,
                               LPARAM lParam )
    {
        switch( nMsg )
        {
        case WM_DESTROY:
            PostQuitMessage( 0 );
            return 0;
        }
        return DefFrameProc( hWnd, g_hMDIClient,
            nMsg, wParam, lParam );
    }
    //子窗口的窗口处理函数
    LRESULT CALLBACK ChildProc( HWND hWnd,
                                UINT nMsg,
                                WPARAM wParam,
                                LPARAM lParam )
    {
        return DefMDIChildProc( hWnd, nMsg,
            wParam, lParam );
    }
    //窗口注册函数
    BOOL RegisterWnd( LPSTR   pszClassName,
                      WNDPROC Proc,
                      int     nBrush )
    {
        WNDCLASSEX wce = { 0 };
        wce.cbSize     = sizeof( wce );
        wce.style      = CS_HREDRAW|CS_VREDRAW;
        wce.cbClsExtra = 0;
        wce.cbWndExtra = 0;
        wce.lpfnWndProc= Proc;
        wce.hInstance  = g_hInst;
        wce.hCursor    = NULL;
        wce.hIcon      = NULL;
        wce.hbrBackground = HBRUSH(nBrush);
        wce.lpszClassName = pszClassName;
        wce.lpszMenuName  = NULL;
        wce.hIconSm       = NULL;
    
        ATOM nAtom = RegisterClassEx( &wce );
        if( nAtom == 0 )
        {
            return FALSE;
        }
        return TRUE;
    }
    //显示窗口
    void DisplayWnd( HWND hWnd )
    {
        ShowWindow( hWnd, SW_SHOW );
        UpdateWindow( hWnd );
    }
    //消息循环
    void Message( )
    {
        MSG msg = { 0 };
        while( GetMessage( &msg, NULL, 0, 0 ) )
        {
            DispatchMessage( &msg );
        }
    }
    //创建主窗口
    HWND CreateMainWnd( LPSTR pszClassName )
    {
        HWND hWnd = CreateWindowEx( 0,
            pszClassName, "MainWnd", 
            WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
            CW_USEDEFAULT, CW_USEDEFAULT,
            CW_USEDEFAULT, NULL, NULL, g_hInst,
            NULL );
        return hWnd;
    }
    //创建MDICLIENT窗口
    HWND CreateMDIClient( HWND hParent )
    {
        CLIENTCREATESTRUCT cs = { 0 };
        cs.idFirstChild = 1000;
        HWND hWnd = CreateWindowEx( 0,
            "MDICLIENT", "MainWnd", 
            WS_CHILD|WS_VISIBLE, CW_USEDEFAULT,
            CW_USEDEFAULT, CW_USEDEFAULT,
            CW_USEDEFAULT, hParent, NULL, g_hInst,
            &cs );
        return hWnd;
    }
    //创建MDI子窗口
    HWND CreateChildWnd( LPSTR pszClassName, 
                         HWND hParent )
    {
        HWND hWnd = CreateWindowEx( WS_EX_MDICHILD,
            pszClassName, "ChildWnd", 
            WS_CHILD|WS_VISIBLE, CW_USEDEFAULT,
            CW_USEDEFAULT, CW_USEDEFAULT,
            CW_USEDEFAULT, hParent, NULL, g_hInst,
            NULL );
        return hWnd;
    }
    
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {    //注册主窗口
        RegisterWnd( "MainWnd", MainProc, 
            COLOR_BTNFACE+1 );
        //注册子窗口
        RegisterWnd( "ChildWnd", ChildProc,
            COLOR_WINDOW );
        //创建MDI主窗口
        HWND hMain = CreateMainWnd( "MainWnd" );
        //创建MDICLIENT窗口
        g_hMDIClient = CreateMDIClient( hMain );
        MoveWindow( g_hMDIClient, 0, 0, 500, 
            500, TRUE );
        //创建MDI子窗口
        CreateChildWnd( "ChildWnd", 
            g_hMDIClient );
        CreateChildWnd( "ChildWnd", 
            g_hMDIClient );
        CreateChildWnd( "ChildWnd", 
            g_hMDIClient );
    
        //显示和消息处理
        DisplayWnd( hMain );
        Message( );
        return 0;
    }
    View Code
    // WinCreate.cpp : Defines the entry point for the application.
    //
    
    #include "stdafx.h"
    
    HINSTANCE g_hInst = NULL;
    // 父窗口的处理函数
    LRESULT CALLBACK WndProc( HWND hWnd,
                              UINT nMsg,
                              WPARAM wParam,
                              LPARAM lParam )
    {
        switch( nMsg )
        {
        case WM_DESTROY:
            PostQuitMessage( 0 );
            return 0;
        }
        return DefWindowProc( hWnd, nMsg, 
            wParam, lParam );
    }
    //子窗口的处理函数
    LRESULT CALLBACK ChildProc( HWND hWnd,
                                UINT nMsg,
                                WPARAM wParam,
                                LPARAM lParam )
    {
        return DefWindowProc( hWnd, nMsg, 
            wParam, lParam );
    }
    //消息处理函数
    void Message( )
    {
        MSG msg = { 0 };
        while( GetMessage( &msg, NULL, 0, 0 ) )
        {
            DispatchMessage( &msg );
        }
    }
    //显示窗口
    void DisplayWnd( HWND hWnd )
    {
        ShowWindow( hWnd, SW_SHOW );
        UpdateWindow( hWnd );
    }
    //创建窗口
    HWND CreateWnd( LPSTR pszClassName, 
                    DWORD nStyle,
                    HWND  hParent )
    {
        HWND hWnd = CreateWindowEx( 
            0,
            pszClassName, 
            "MyWnd", 
            nStyle,
            CW_USEDEFAULT, 
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            hParent,NULL,g_hInst,NULL );
        return hWnd;
    }
    //注册窗口
    BOOL RegisterWnd( LPSTR      pszClassName, 
                      WNDPROC proc,
                      int     nBrush )
    {
        WNDCLASSEX wce = { 0 };
        wce.cbSize      = sizeof( wce );
        wce.style       = CS_HREDRAW|CS_VREDRAW;
        wce.cbClsExtra  = 0;
        wce.cbWndExtra  = 0;
        wce.lpfnWndProc = proc;
        wce.hIcon        = NULL;
        wce.hCursor     = NULL;
        wce.hbrBackground = HBRUSH( nBrush );
        wce.hInstance     = g_hInst;
        wce.lpszClassName = pszClassName;
        wce.lpszMenuName  = NULL;
        wce.hIconSm       = NULL;
        ATOM nAtom = RegisterClassEx( &wce );
        if( 0 == nAtom )
        {
            return FALSE;
        }
        return TRUE;
    }
    
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
        g_hInst = hInstance;
        //注册父窗口类
        RegisterWnd( "MyWnd", WndProc, 
            COLOR_BTNFACE+1 );
        //注册子窗口类
        RegisterWnd( "Child", ChildProc,
            COLOR_WINDOW );
        //创建父窗口
        HWND hWnd = CreateWnd( "MyWnd", 
            WS_OVERLAPPEDWINDOW, NULL );
        //创建子窗口
        HWND hChild1 = CreateWnd( "Child", 
            WS_CHILD|WS_VISIBLE|WS_BORDER|
            WS_THICKFRAME|WS_CAPTION|WS_SYSMENU|
            WS_MINIMIZEBOX|WS_MAXIMIZEBOX, 
            hWnd );
        HWND hChild2 = CreateWnd( "Child", 
            WS_POPUP|WS_VISIBLE|
            WS_THICKFRAME|WS_CAPTION|WS_SYSMENU, 
            hWnd );
        HWND hChild3 = CreateWnd( "Child", 
            WS_CHILD|WS_VISIBLE|WS_BORDER, 
            hWnd );
        //移动窗口位置
        MoveWindow( hChild1, 100, 100, 
            200, 200, TRUE );
        MoveWindow( hChild2, 100, 200, 
            200, 200, TRUE );
        MoveWindow( hChild3, 100, 300, 
            200, 200, TRUE );
        //显示父窗口
        DisplayWnd( hWnd );
        Message( );
        return 0;
    }
  • 相关阅读:
    BestCoder17 1001.Chessboard(hdu 5100) 解题报告
    codeforces 485A.Factory 解题报告
    codeforces 485B Valuable Resources 解题报告
    BestCoder16 1002.Revenge of LIS II(hdu 5087) 解题报告
    codeforces 374A Inna and Pink Pony 解题报告
    codeforces 483B Friends and Presents 解题报告
    BestCoder15 1002.Instruction(hdu 5083) 解题报告
    codeforces 483C.Diverse Permutation 解题报告
    codeforces 483A. Counterexample 解题报告
    NSArray中地内存管理 理解
  • 原文地址:https://www.cnblogs.com/tangzhengyue/p/2633933.html
Copyright © 2011-2022 走看看