本文共 2099 字,大约阅读时间需要 6 分钟。
在wxWidgets开发中,窗口管理是核心的功能之一。所有的窗口都继承自wxTopLevelWindows,这一基类在Windows系统中负责管理所有顶层窗口。wxTopLevelWindows是一个全局变量,用于存储和管理所有顶层窗口的引用。
当我们需要创建一个Frame窗口时,通常会继承自wxFrame,并通过调用Create方法来实现。此方法的实现通常是通过调用wxTopLevelWindow::Create来完成窗口的创建。以下是wxFrame的继承关系:
wxFrame -> wxFrameBase -> wxTopLevelWindow -> wxTopLevelWindowMSW -> wxTopLevelWindowBase -> wxNonOwnedWindow -> wxWindow
需要注意的是,wxTopLevelWindowNative是一个宏定义,在include/wx/toplevel.h中定义:
#if defined(__WXMSW__) #include "wx/msw/toplevel.h" #define wxTopLevelWindowNative wxTopLevelWindowMSW#endif
在创建窗口时,wxFrame会调用wxTopLevelWindow::Create,具体实现如下:
bool wxFrame::Create(wxWindow *parent, wxWindowID id) { if (!wxTopLevelWindow::Create(parent, id, wxEmptyString, wxDefaultPosition, ...)) { return false; } // ... 其他初始化代码 ...} wxTopLevelWindow::Create方法主要负责将窗口添加到wxTopLevelWindows队列中,并初始化窗口的基础参数。接着,根据窗口类型调用CreateDialog或CreateFrame来完成具体窗口的创建。
CreateFrame方法的实现通常是通过调用wxTopLevelWindowMSW::CreateFrame来完成的,这个方法最终会调用MSWCreate来创建窗口。MSWCreate会根据窗口的类型和风格,调用Win32 API的CreateWindowEx函数来创建窗口,并返回窗口的HANDLE。
bool wxTopLevelWindowMSW::CreateFrame(const wxString &title, const wxPoint &pos, const wxSize &size) { // 获取窗口类名和其他参数 wxWindowCreationHook hook(this); m_hWnd = (WXHWND)CreateWindowEx(extendedStyle, className.t_str(), ...); SubclassWin(m_hWnd); return true;} 需要注意的是,在创建窗口之前,需要确保该窗口类已经注册。如果窗口类没有注册,会导致无法正常创建窗口。注册窗口类的过程通常是在应用启动时进行的。
wxWidgets通过全局的HashMap gs_windowHandles来管理窗口与HWND的关联。每当一个窗口被创建时,会调用SubclassWin方法,将 HWND 和 wxWindow 的指针进行关联。
void wxWindowMSW::SubclassWin(WXHWND hWnd) { wxAssociateWinWithHandle(hwnd, this); wxWindowCreateEvent event((wxWindow *)this); HandleWindowEvent(event);} 同时,在消息处理函数wxWndProc中,也会进行窗口与HWND的关联,以确保消息能够正确地发送到对应的wxWindow对象。
在Windows系统中,窗口创建后会立即收到消息,此时会调用wxWndProc来处理消息。为了确保窗口能够正确关联,SubclassWin方法会在窗口创建完成后进行关联。而在wxWndProc中,如果窗口尚未关联,则会通过全局变量gs_winBeingCreated进行关联。
这种双重关联机制确保了窗口在任何情况下都能正确地与其对应的HWND关联,从而保证消息的正确传递和处理。
wxWidgets通过其窗口管理机制,有效地将Windows系统的Win32API与用户代码隔离开来,提供了一套高级的GUI开发框架。这种机制不仅屏蔽了底层的API细节,还通过全局的窗口管理和消息处理机制,确保了窗口的生命周期管理和消息的正确传递。
转载地址:http://voyfz.baihongyu.com/