• hge source explor 0x2 windows module


    Windows窗口

      hge的window窗口的具体建立是在System_Initiate函数中,现在将hge中关于Windows窗口相关的代码拿出来。

      Windows相关参数

    windows attribute
    hge_impl.h
        HINSTANCE           hInstance;
        HWND                hwnd;
        HWND                hwndParent;
        bool                bActive; 
        const char*         szIcon;
        char                szWinTitle[256];
        int                 nScreenWidth;
        int                 nScreenHeight; 
        bool                bWindowed;
        bool                bHideMouse;
        RECT                rectW;
        LONG                styleW;
        RECT                rectFS;
        LONG                styleFS;
    system.cpp
        const char      *WINDOW_CLASS_NAME = "HGE__WNDCLASS";
        WNDCLASS       winclass;
        int                width, height;    

      在有了上面的参数之后,就开始创建一个窗口,详细看system.cpp文件中的System_Initiate函数中的部分。具体实现为:

    创建过程
    填写WNDCLASS wndclass
        winclass.style            = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
        winclass.lpfnWndProc      = WindowProc;
        winclass.cbClsExtra       = 0;
        winclass.cbWndExtra       = 0;
        winclass.hInstance        = hInstance;
        winclass.hCursor          = LoadCursor(NULL, IDC_ARROW);
        winclass.hbrBackground    = (HBRUSH)GetStockObject(BLACK_BRUSH);
        winclass.lpszMenuName     = NULL; 
        winclass.lpszClassName    = WINDOW_CLASS_NAME;
        if(szIcon) winclass.hIcon = LoadIcon(hInstance, szIcon);
        else winclass.hIcon       = LoadIcon(NULL, IDI_APPLICATION);    
    注册 wndclass
        if (!RegisterClass(&winclass)) {
            _PostError("Can't register window class");
            return false;
        }
    设置窗口大小和窗口格式
        width=nScreenWidth + GetSystemMetrics(SM_CXFIXEDFRAME)*2;
        height=nScreenHeight + GetSystemMetrics(SM_CYFIXEDFRAME)*2 + GetSystemMetrics(SM_CYCAPTION);
    
        rectW.left=(GetSystemMetrics(SM_CXSCREEN)-width)/2;
        rectW.top=(GetSystemMetrics(SM_CYSCREEN)-height)/2;
        rectW.right=rectW.left+width;
        rectW.bottom=rectW.top+height;
        styleW=WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_VISIBLE; //WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX;
    
        rectFS.left=0;
        rectFS.top=0;
        rectFS.right=nScreenWidth;
        rectFS.bottom=nScreenHeight;
        styleFS=WS_POPUP|WS_VISIBLE; //WS_POPUP
    
        if(hwndParent)
        {
            rectW.left=0;
            rectW.top=0;
            rectW.right=nScreenWidth;
            rectW.bottom=nScreenHeight;
            styleW=WS_CHILD|WS_VISIBLE; 
            bWindowed=true;
        }
    创建窗口,考虑是否为窗口模式
        if(bWindowed)
            hwnd = CreateWindowEx(0, WINDOW_CLASS_NAME, szWinTitle, styleW,
                    rectW.left, rectW.top, rectW.right-rectW.left, rectW.bottom-rectW.top,
                    hwndParent, NULL, hInstance, NULL);
        else
            hwnd = CreateWindowEx(WS_EX_TOPMOST, WINDOW_CLASS_NAME, szWinTitle, styleFS,
                    0, 0, 0, 0,
                    NULL, NULL, hInstance, NULL);
    显示窗口
        ShowWindow(hwnd, SW_SHOW);

     


      上面的步骤完成的情况下,关于Windows的创建就完成了,然后只要完成消息处理函数。这样一个窗口就完成了。那么我现在想运行起来的话,至少需要的函数有:

    hge.h  
    virtual bool            System_Init() = 0;
    virtual bool            System_Start() = 0;
    
    extern "C" { EXPORT GE* GECreate(int ver); }
    hge_impl.h  
        virtual bool            System_Init();
        virtual bool            System_Start();
        
        hge_Impl(); 

      现在我要把这部分拿出来,写成一个类,然后将所有的关于窗口的操作都通过这个类来实现。已经完成的工程,具体的实现的效果为:

      

      那么我的类为

    class Win
    {
    public:
        Win();
        ~Win();
        
        bool        Init();
        void        Shutdown();
    
    
    public:
        HINSTANCE     hInstance;
        HWND          hwndParent;
        HWND          hwnd;
    
        WNDCLASSEX     wnd;
    
        RECT        rWin;
        RECT        rFS;
        LONG        styleWin;
        LONG        styleFS;
    
        bool          bWindowed;
        int            nScreenWidth;
        int            nScreenHeight;
        const char*    szIcon;
        const char*   szIconSm;
        char          szWinTitle[256];
        bool          bHideMouse;
        bool          bActive;
        
        char          WINDOW_CLASS_NAME[256];
    };
    win.h

      然后是类的实现

    #include "win.h"
    #include "ge_impl.h"
    
    // 消息处理函数
    LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
    
    Win::Win()
    {
        hwnd = 0;
        hwndParent = 0;
        bActive = false;
    
        wnd.cbSize = 0;
        szIcon = 0;
        szIconSm = 0;
        strcpy(szWinTitle, TEXT("GameEngine Window Module _es"));
        strcpy(WINDOW_CLASS_NAME, TEXT("window_class"));
        nScreenHeight = 600;
        nScreenWidth = 800;
        bWindowed = true;
        bHideMouse = false;
    }
    
    bool Win::Init()
    {
        // 注册窗口类
        wnd.cbSize = sizeof(WNDCLASSEX);
        wnd.cbClsExtra = 0;
        wnd.cbWndExtra = 0;
        wnd.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
        wnd.hInstance = hInstance;
        wnd.lpszMenuName = 0;
        wnd.hCursor = LoadCursor(NULL, IDC_ARROW);
        wnd.lpszClassName = WINDOW_CLASS_NAME;
        wnd.lpfnWndProc = WinProc;
        wnd.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
    
        if (szIcon){
            wnd.hIcon=LoadIcon(hInstance, szIcon);
        }
        else{
            wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        }
    
        if (szIconSm){
            wnd.hIconSm = LoadIcon(hInstance, szIconSm);
        }
        else{
            wnd.hIconSm = 0;
        }
    
        if (!RegisterClassEx(&wnd)){    // 注册窗口失败
            
            return false;
        }
    
    
        // 这是要创建的窗口的属性
        int width = nScreenWidth + GetSystemMetrics(SM_CXFIXEDFRAME) * 2;
        int height = nScreenHeight + GetSystemMetrics(SM_CYFIXEDFRAME) * 2 + GetSystemMetrics(SM_CYCAPTION);
    
        // 窗口化 ,是的窗口在屏幕正中间
        rWin.left = (GetSystemMetrics(SM_CXSCREEN) - width) / 2;
        rWin.top = (GetSystemMetrics(SM_CYSCREEN) - height) / 2;
        rWin.right = rWin.left + width;
        rWin.bottom = rWin.top + height;
        styleWin = WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE;
    
        // 全屏时
        rFS.left = 0;
        rFS.top = 0;
        rFS.right = GetSystemMetrics(SM_CXSCREEN); //GetSystemMetrics(SM_CXSCREEN);
        rFS.bottom = GetSystemMetrics(SM_CYSCREEN); //GetSystemMetrics(SM_CYSCREEN);
        styleFS = WS_POPUP | WS_VISIBLE;
    
        // 如果为子窗口,定不是全屏
        if (hwndParent)
        {
            rWin.left = 0;
            rWin.top = 0;
            rWin.right = nScreenWidth;
            rWin.right = nScreenHeight;
            styleWin = WS_CHILD | WS_VISIBLE;
            bWindowed = true;
        }
    
        if (bWindowed){
            hwnd = CreateWindowEx(0, WINDOW_CLASS_NAME, szWinTitle, styleWin, rWin.left, rWin.top, rWin.right - rWin.left, rWin.bottom - rWin.top, hwndParent, NULL, hInstance, NULL);
        }
        else{
            // 全屏模式下就不要考虑 hwndparent
            hwnd = CreateWindowEx(WS_EX_TOPMOST, WINDOW_CLASS_NAME, szWinTitle, styleFS, rFS.left, rFS.top, rFS.right-rFS.left, rFS.bottom-rFS.top, NULL, NULL, hInstance, NULL);
        }
    
        if (!hwnd){            // 创建窗口失败
            return false;
        }
    
        // 展示窗口
        ShowWindow(hwnd, SW_SHOW);
    
        return true;
    }
    
    Win::~Win()
    {
        //
    }
    
    void Win::Shutdown()
    {
        if (hwnd){
            DestroyWindow(hwnd);
            hwnd = 0;
        }
    
        if (!wnd.cbSize){
            UnregisterClass(WINDOW_CLASS_NAME, hInstance);
        }
    }
    
    LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
    {
        //bool bActivating;
    
        switch (msg)  
        {
        case WM_CREATE:
            HDC hdc;
            PAINTSTRUCT ps;
            hdc = BeginPaint(hwnd, &ps);
            EndPaint(hwnd, &ps);
            return FALSE;
    
        case WM_PAINT:
            break;
    
        case WM_KEYDOWN:
            if (wparam == VK_ESCAPE){
                if (pge->win){
                    MessageBox(hwnd, "Get the escape", "Get Message", MB_OK);
                    PostQuitMessage(0);
                    break;
                }
            }
            break;
    
        case WM_DESTROY:
            PostQuitMessage(0);
            return FALSE;
        }
    
        return DefWindowProc(hwnd, msg, wparam, lparam);
    }
    win.cpp
  • 相关阅读:
    OpenCV (十二)阈值操作
    OpenCV (十一)图像金字塔
    OpenCV (十)提取水平线与垂直线
    OpenCV (九)形态学操作:开操作,闭操作,形态学梯度,顶帽,黑帽
    电商平台资料学习
    四、eslint配置rules
    三、export和export default区别
    二、安装国际化
    一、vue安装
    vue执行命令时提示错误——vue : 无法加载文件 C:UsersAdministratorAppDataRoaming pmvue.ps1,因为在此系统上禁止运行脚本
  • 原文地址:https://www.cnblogs.com/yoru/p/5501948.html
Copyright © 2020-2023  润新知