Пытаясь найти подходящее решение для обработки оконных сообщений, я столкнулся с этим вопросом здесь, в StackOverflow:
Объектно-ориентированный c ++ win32?
Ответы предлагали отличные решения, и мой личный фаворит — это принятый ответ с использованием std :: map.
Однако всякий раз, когда я использую std :: map в моем коде, это выглядит так:
#include <cstdio>
#include <map>
#include <windows.h>
#include <helixirrwidgets/Window.hpp>
using namespace HelixirrWidgets;
/// ----------------------------
/// @class Window
/// @brief Represents a window.
/// ----------------------------
/// Inner classes:
class Window::Helper{
public:
/// Constructors & destructors:
Helper(void) : active(false), created_window(false), handle_instance(GetModuleHandle(NULL)), handle_window(nullptr), message({0}){
_ms_mopopHelpers.insert({handle_window, this});
}
Helper(Helper const& helper_) : active(false), created_window(false), handle_instance(helper_.handle_instance), handle_window(helper_.handle_window), message(helper_.message){
_ms_mopopHelpers.insert({handle_window, this});
}
Helper(Helper&& helper_) : active(false), created_window(false), handle_instance(std::move(helper_.handle_instance)), handle_window(std::move(helper_.handle_window)), message(std::move(helper_.message)){
helper_.handle_instance = nullptr;
helper_.handle_window = nullptr;
_ms_mopopHelpers.insert({handle_window, this});
}
~Helper(void){
handle_instance = nullptr;
handle_window = nullptr;
_ms_mopopHelpers.erase(handle_window);
}
/// Member data:
bool mutable active, created_window;
HINSTANCE mutable handle_instance;
HWND mutable handle_window;
MSG message;
/// Member functions (overloaded operators, assignment):
Helper& operator=(Helper const& helper_) = default;
Helper& operator=(Helper&& helper_) = default;
/// Static member functions:
static LRESULT CALLBACK handle_callback(HWND handle_window_, UINT message_, WPARAM wparam_, LPARAM lparam_){
if(_ms_mopopHelpers.size() != 0){
// Delegate message handling:
return _ms_mopopHelpers[handle_window_]->_handle_callback(message_, wparam_, lparam_);
}
return 0;
}
private:
/// Member functions:
LRESULT _handle_callback(UINT message_, WPARAM wparam_, LPARAM lparam_){
switch(message_){
case WM_DESTROY:
active = false;
DestroyWindow(handle_window);
return 0;
default:
return DefWindowProc(handle_window, message_, wparam_, lparam_);
}
}
/// Static member data:
static std::map<HWND, Window::Helper*> _ms_mopopHelpers;
};
/// Static member data:
std::map<HWND, Window::Helper*> Window::Helper::_ms_mopopHelpers = {};
/// Constructors & destructors:
Window::Window(void) : _m_bVisible(false), _m_opHelper(new Window::Helper){
}
Window::Window(Window const& window_) = default;
Window::Window(Window&& window_) = default;
Window::Window(std::string const& name_) : _m_bVisible(false), _m_opHelper(new Window::Helper), _m_oName(name_){
}
Window::Window(std::string&& name_) : _m_bVisible(false), _m_opHelper(new Window::Helper), _m_oName(std::move(name_)){
}
Window::~Window(void) = default;
/// Member functions:
bool const& Window::active(void) const noexcept{
return _m_opHelper->active;
}
Window& Window::save_changes(void){
// Create and register window class:
static bool __registered_class_window = false;
static WNDCLASSEX __class_window = {
sizeof(WNDCLASSEX),
CS_HREDRAW | CS_VREDRAW,
Window::Helper::handle_callback,
0, 0,
_m_opHelper->handle_instance,
LoadIcon(_m_opHelper->handle_instance, NULL),
LoadCursor(NULL, IDC_ARROW),
reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)),
NULL,
"Helixirr Widgets Window Class Basic",
LoadIcon(_m_opHelper->handle_instance, NULL)
};
if(!__registered_class_window){
RegisterClassEx(&__class_window);
__registered_class_window = true;
}
// If window hasn't been created yet:
if(!_m_opHelper->created_window){
_m_opHelper->created_window = true;
_m_opHelper->handle_window = CreateWindowEx(
0,
"Helixirr Widgets Window Class Basic",
_m_oName.c_str(),
WS_OVERLAPPEDWINDOW,
_m_uiPos[0], _m_uiPos[1],
_m_uiSize[0], _m_uiSize[1],
NULL, NULL, _m_opHelper->handle_instance, NULL
);
}
_m_opHelper->active = true;
return *this;
}
void Window::show(void){
if(_m_opHelper->active){
if(GetMessage(&_m_opHelper->message, NULL, 0, 0)){
// Handle messages:
TranslateMessage(&_m_opHelper->message);
DispatchMessage(&_m_opHelper->message);
// Handle window displaying:
ShowWindow(_m_opHelper->handle_window, SW_SHOWDEFAULT);
UpdateWindow(_m_opHelper->handle_window);
return;
}
}
}
мое окно по какой-то причине не открывается. После обрезки всех подключений к std :: map окно снова появляется просто отлично. Что может быть причиной этого странного явления? Трудно поверить, что есть какой-то конфликт.
Судя по вашему методу Window :: show, проблема может заключаться в том, что у вас нет цикла сообщений. Обычный цикл сообщений выглядит так:
MSG msg = {};
while (GetMessage(&msg, nullptr, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Но ваш метод Window :: show делает это только один раз, поэтому окно может не получать сообщения, необходимые для его отображения.
Других решений пока нет …