I have a problem with my Win32 message handling.
I'll just dump the code.
app.h
Code:
class App
{
public:
App();
~App();
int Run();
};
app.cpp
Code:
App::App()
{
INITCOMMONCONTROLSEX iccex;
iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
iccex.dwICC = ICC_BAR_CLASSES;
::InitCommonControlsEx(&iccex);
}
App::~App()
{
}
int App::Run()
{
MSG msg;
while (::GetMessage(&msg, 0, 0, 0) > 0)
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
return msg.wParam;
}
widget.h
Code:
class Widget
{
public:
Widget(Widget* parent, const std::string& title, LPSTR className,
const Point& pos, const Size& size, long style);
virtual ~Widget();
HWND GetHandle();
protected:
virtual LRESULT CALLBACK ProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
private:
static LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
HWND m_hwnd;
};
widget.cpp
Code:
Widget::Widget(Widget* parent, const std::string& title, LPSTR className,
const Point& pos, const Size& size, long style)
{
static bool registered = false;
if (!registered)
{
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_DBLCLKS;
wc.lpfnWndProc = WindowProcedure;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = ::GetModuleHandle(0);
wc.hIcon = static_cast<HICON>(::LoadImage(0, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE));
wc.hCursor = static_cast<HICON>(::LoadImage(0, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE));
wc.hbrBackground = static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH));
wc.lpszMenuName = 0;
wc.lpszClassName = "wx::msw::Widget";
wc.hIconSm = static_cast<HICON>(::LoadImage(0, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE));
if(!::RegisterClassEx(&wc))
throw wx::Exception("Unable to register the window class.", __FILE__, __LINE__);
registered = true;
}
HWND hparent;
if (parent)
hparent = parent->GetHandle();
else
hparent = 0;
m_hwnd = ::CreateWindowEx(0,
className,
title.c_str(),
style,
pos.x,
pos.y,
size.width,
size.height,
hparent,
0,
::GetModuleHandle(0),
this);
if (!m_hwnd)
throw Exception("Unable to create window.", __FILE__, __LINE__);
}
Widget::~Widget()
{
::DestroyWindow(m_hwnd);
}
HWND Widget::GetHandle()
{
return m_hwnd;
}
LRESULT CALLBACK Widget::ProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CLOSE:
{
::DestroyWindow(m_hwnd);
}
break;
case WM_DESTROY:
{
::PostQuitMessage(0);
}
break;
default:
return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK Widget::WindowProcedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_NCCREATE)
::SetWindowLongPtr(hwnd, GWL_USERDATA, reinterpret_cast<LONG_PTR>((LPCREATESTRUCT(lParam))->lpCreateParams));
Widget* widget = reinterpret_cast<Widget* >(::GetWindowLongPtr(hwnd, GWL_USERDATA));
if (widget)
return widget->ProcessMessage(hwnd, uMsg, wParam, lParam);
return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
}
statusbar.h
Code:
class StatusBar : public Widget
{
public:
StatusBar(Widget* parent);
~StatusBar();
int GetFieldCount();
std::string GetText(int field);
void SetFieldCount(int fields);
void SetText(const std::string& text, int field);
protected:
LRESULT CALLBACK ProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
};
statusbar.cpp
Code:
StatusBar::StatusBar(Widget* parent)
: Widget(parent, "", STATUSCLASSNAME, wx::Point(0, 0), wx::Size(0, 0), WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP)
{
}
StatusBar::~StatusBar()
{
}
int StatusBar::GetFieldCount()
{
return ::SendMessage(GetHandle(), SB_GETPARTS, 0, 0);
}
std::string StatusBar::GetText(int field)
{
const int textLength = ::SendMessage(GetHandle(), SB_GETTEXTLENGTH, field, 0);
char buffer[textLength];
::SendMessage(GetHandle(), SB_GETTEXT, field, reinterpret_cast<LPARAM>(buffer));
return std::string(buffer);
}
LRESULT CALLBACK StatusBar::ProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_SIZE:
{
::MessageBox(0, "StatusBar", "WM_SIZE", MB_OK);
::SendMessage(GetHandle(), WM_SIZE, 0, 0);
}
break;
default:
return Widget::ProcessMessage(hwnd, uMsg, wParam, lParam);
}
return 0;
}
void StatusBar::SetFieldCount(int fields)
{
::SendMessage(GetHandle(), SB_SETPARTS, fields, 0);
}
void StatusBar::SetText(const std::string& text, int field)
{
::SendMessage(GetHandle(), SB_SETTEXT, field, reinterpret_cast<LPARAM>(text.c_str()));
}
Then here is how I used it.
main.cpp
Code:
#include <windows.h>
.....
int main(int argc, char* argv[])
{
App app;
Widget w(0, "Test", "wx::msw::Widget", Point(50, 50), Size(760, 530), WS_OVERLAPPEDWINDOW);
w.Show();
StatusBar sb(&w);
return app.Run();
}
The problem is that my statusbar window procedure never gets called. What is going wrong?
I'm using MinGW 3.4.5 with Code::Blocks.