// InvisibleWindow.h: InvisibleWindow and InvisibleWindowSink

#ifndef INVISIBLEWINDOW_H
#define INVISIBLEWINDOW_H

#include <assert.h>

class WindowClass
{
public:
    WindowClass(LPCTSTR pszClassName, WNDPROC pfnWndProc) : m_pszClassName(0)
    {
        HINSTANCE   hinst = GetModuleHandle(0);
        WNDCLASS    wc = { 0 };
        wc.lpfnWndProc = pfnWndProc;
        wc.hInstance = hinst;
        wc.lpszClassName = pszClassName;

        if( RegisterClass(&wc) )
        {
            m_pszClassName = new TCHAR[strlen(pszClassName) + 1];
            if( m_pszClassName )
            {
                strcpy(m_pszClassName, pszClassName);
            }
            else
            {
                UnregisterClass(pszClassName, hinst);
            }
        }
    }

    ~WindowClass()
    {
        if( m_pszClassName )
        {
            UnregisterClass(m_pszClassName, GetModuleHandle(0));
            delete[] m_pszClassName;
        }
    }

    LPCTSTR ClassName()
    {
        return m_pszClassName;
    }

    bool IsRegistered()
    {
        return (m_pszClassName != 0);
    }

private:
    LPTSTR  m_pszClassName;
};

class InvisibleWindowSink
{
public:
    virtual LRESULT OnWindowMessage(HWND hwnd, UINT nMsg, WPARAM wparam, LPARAM lparam)
    { return DefWindowProc(hwnd, nMsg, wparam, lparam); }
};

class InvisibleWindow
{
public:
    InvisibleWindow();
    ~InvisibleWindow();

    bool Create(InvisibleWindowSink* pSink);
    void Destroy();
    HWND GetHwnd();

private:
    HWND                m_hwnd;
    static WindowClass  s_wc;

    friend LRESULT CALLBACK
        InvisibleWindowProc(HWND hwnd, UINT nMsg, WPARAM wparam, LPARAM lparam);
};

inline
InvisibleWindow::InvisibleWindow()
: m_hwnd(0)
{}

inline
InvisibleWindow::~InvisibleWindow()
{ Destroy(); }

inline
void InvisibleWindow::Destroy()
{ if( m_hwnd ) { DestroyWindow(m_hwnd); m_hwnd = 0; } }

inline
HWND InvisibleWindow::GetHwnd()
{ return m_hwnd; }

#endif  // INVISIBLEWINDOW_H
