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]; };
然后是类的实现

#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); }