In Win32 API a window has the pointer to a user defined version of WndProc function that handling its messages.
There are some ways to cover this low-level mechanism with a solution like MFC message map and so on.
In my very little app I'm looking for a way to encapsulate this low-level thing with a object oriented solution.
I tried to create a C++ map with HWND key and "MyWindowClass" item and when I created an object of the MyClass I added a pair to the map and then looking for the MyWindowClass object by HWN. But the problem is after CreateWindowEx called Win32 internally send a WM_CREATE message to the just created window so I can't add pair in the map before this message and can't control WM_CREATE through passing it to the object instanced WndProc.
The code is:
#ifndef NOTIFYWINDOW_H
#define NOTIFYWINDOW_H
#include "Bacn.h"
class NotifyWindow
{
private:
HWND m_hWnd;
Gdiplus::Graphics* m_graphics;
protected:
static std::map<HWND, NotifyWindow*> s_NotifyWindows;
static LRESULT CALLBACK s_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
static void s_WndMessageLoop();
LRESULT WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
void Initialize();
void OnPaint();
void OnCreate();
public:
NotifyWindow();
~NotifyWindow();
};
#endif //NOTIFYWINDOW_H
And its implementation:
#include "NotifyWindow.h"
using namespace Gdiplus;
using namespace std;
map<HWND*, NotifyWindow> NotifyWindow::s_NotifyWindows;
LRESULT CALLBACK NotifyWindow::s_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
map<HWND, NotifyWindow*>::iterator search = s_NotifyWindows.find(hWnd);
if (search != s_NotifyWindows.end())
{
search->second->WndProc(uMsg, wParam, lParam);
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
void NotifyWindow::s_WndMessageLoop()
{
}
LRESULT NotifyWindow::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
OnCreate();
break;
case WM_PAINT:
OnPaint();
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_SIZE:
break;
case WM_SETFOCUS:
break;
case WM_KILLFOCUS:
break;
case WM_MOUSEMOVE:
break;
default:
return DefWindowProc(m_hWnd, uMsg, wParam, lParam);
}
return 0;
}
void NotifyWindow::Initialize()
{
WNDCLASSEX wc;
const wchar_t *className = L"BacnNotifyWindowClass";
const wchar_t *windowName = L"BacnNotifyWindow";
HINSTANCE hInstance = GetModuleHandle(NULL);
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpszClassName = className;
wc.lpfnWndProc = NotifyWindow::s_WndProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = NULL;
wc.hIconSm = NULL;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
RegisterClassEx(&wc);
DWORD dwExtStyle = WS_EX_TOPMOST;
DWORD dwStyle = WS_POPUP | WS_SYSMENU;
m_hWnd = CreateWindowEx(
dwExtStyle,
className,
windowName,
dwStyle,
300,
300,
100,
100,
NULL,
NULL,
hInstance,
NULL);
s_NotifyWindows.insert(pair<HWND, NotifyWindow*>(m_hWnd, this));
ShowWindow(m_hWnd, SW_SHOW);
}
NotifyWindow::NotifyWindow()
{
Initialize();
}
NotifyWindow::~NotifyWindow()
{
}
void NotifyWindow::OnPaint()
{
}
void NotifyWindow::OnCreate()
{
}