This is the revised version of the Window Creation Wrapper Class. I tried to improve the code due to the remarks of @user1118321 (see posted link) and I hope for further reviews. For instance, you could give advice about using C++11 more strictly.createWindow is now a factory method. For creating a window with prior set up you should use create instead. Furthermore the func pointers are revised, more events deliver a standard behaviour (e.g. onPaint will be called between BeginPaint and EndPaint) and the OpaquePtr struct is now an unique_ptr (copy/move constructor, copy/move assignment operator is also available). Some minor fixes and changes have been made additionally.XoursWindow.h#ifndef __XOURSWINDOW_H#define __XOURSWINDOW_H#include <Windows.h>#include <memory>enum XWINDOW_ERROR {    XWINDOW_SUCCESS = 1,    XWINDOW_FAILURE,    /*  registerWindowClass    */  //  ERRORS    XWINDOW_WNDCLASS_ATOM_ALREADY_SET,    /*  setWindowClassAtom    */  //  ERRORS    XWINDOW_SET_WNDCLASSATOM_FAILED,    /*  createWindow    */  //  WARNINGS    XWINDOW_WNDCLASS_ALREADY_EXISTS,        //  ERRORS    XWINDOW_WNDCLASS_INCOMPATIBLE,    XWINDOW_WINDOW_ALREADY_CREATED,    XWINDOW_CREATING_WINDOW_FAILED};#define XWINDOW_USERDATA_OFFSET         4class XoursWindow {public:    XoursWindow ();    XoursWindow (const XoursWindow&);    XoursWindow (XoursWindow&&);    XoursWindow& operator=(const XoursWindow&);    XoursWindow& operator=(XoursWindow&&);    virtual ~XoursWindow ();    void setWindowClassAtom (ATOM);    ATOM getWindowClassAtom ();    void create (DWORD, wchar_t*, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, int);    void create (wchar_t*, int, int, int, int, HINSTANCE, int);    void create (wchar_t*, HINSTANCE, int);    static XoursWindow* createWindow (DWORD, WNDCLASSEX*, wchar_t*, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, int);    static XoursWindow* createWindow (wchar_t*, int, int, int, int, HINSTANCE, int);    static XoursWindow* createWindow (wchar_t*, HINSTANCE, int);    int destroy ();    void setAdditionalData (void*);     // setter for additional window data    void* getAdditionalData ();         // getter for additional window data    LRESULT (*onCreate) (HWND, LPCREATESTRUCT);    LRESULT (*onEraseBkgnd) (HWND, HDC);    LRESULT (*onPaint) (HWND, HDC, LPPAINTSTRUCT);    LRESULT (*onMove) (HWND, LPPOINTS);    LRESULT (*onGetMinMaxInfo) (HWND, LPMINMAXINFO);    LRESULT (*onSize) (HWND, WPARAM, LPARAM);    LRESULT (*onCommand) (HWND, WPARAM, LPARAM);    LRESULT (*onNotify) (HWND, WPARAM, LPARAM);    LRESULT (*onTimer) (HWND, WPARAM, LPARAM);    LRESULT (*onClose) (HWND);    LRESULT (*onDestroy) (HWND);    LRESULT (*onQuit) (HWND, WPARAM);    WNDPROC eventHandler;    HWND getWindowHandle ();    int getLastError ();private:    struct OpaquePtr;    std::unique_ptr<OpaquePtr> optr;};#endif // __XOURSWINDOW_HXoursWindow.cpp:#include header/XoursWindow_OpaquePtr.h       // contains XoursWindow.hXoursWindow::XoursWindow (): optr (new OpaquePtr) {    this->optr->init_helper (*this);}XoursWindow::XoursWindow (const XoursWindow& origin) : optr (new OpaquePtr (*(origin).optr)) {    XoursWindow::OpaquePtr::copy_helper (*this, origin);}XoursWindow::XoursWindow (XoursWindow&& origin) : optr (new OpaquePtr (std::move (*(origin).optr))) {    XoursWindow::OpaquePtr::copy_helper (*this, origin);    if (this->getWindowHandle () != NULL)        SetWindowLongPtr (this->getWindowHandle (), XWINDOW_USERDATA_OFFSET, (LONG_PTR) this);    this->optr->init_helper (origin);   // due to the object has been moved re-initialize origin}XoursWindow& XoursWindow::operator=(const XoursWindow& origin)  {    *optr = *origin.optr;    XoursWindow::OpaquePtr::copy_helper (*this, origin);    return *this;}XoursWindow& XoursWindow::operator=(XoursWindow&& origin)  {    *optr = std::move (*origin.optr);    XoursWindow::OpaquePtr::copy_helper (*this, origin);    if (this->getWindowHandle () != NULL)        SetWindowLongPtr (this->getWindowHandle (), XWINDOW_USERDATA_OFFSET, (LONG_PTR) this);    this->optr->init_helper (origin);   // due to the object has been moved re-initialize origin    return *this;}XoursWindow::~XoursWindow () {}void XoursWindow::create (DWORD dwStyleEx, wchar_t* strTitle, DWORD dwStyle, int posX, int posY, int width, int height, HWND hWndParent, HMENU hMenu, HINSTANCE hInst, int cmdShow) {    this->optr->create_window_helper (*this, dwStyleEx, strTitle, dwStyle, posX, posY, width, height, hWndParent, hMenu, hInst, cmdShow);}void XoursWindow::create (wchar_t* strTitle, int posX, int posY, int width, int height, HINSTANCE hInst, int cmdShow) {    this->optr->create_window_helper (*this, NULL, strTitle, WS_OVERLAPPEDWINDOW, posX, posY, width, height, NULL, NULL, hInst, cmdShow);}void XoursWindow::create (wchar_t* strTitle, HINSTANCE hInst, int cmdShow) {    this->optr->create_window_helper (*this, NULL, strTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, cmdShow);}XoursWindow* XoursWindow::createWindow (DWORD dwStyleEx, WNDCLASSEX* wincl, wchar_t* strTitle, DWORD dwStyle, int posX, int posY, int width, int height, HWND hWndParent, HMENU hMenu, HINSTANCE hInst, int cmdShow) {    XoursWindow *factory = new XoursWindow;    if (wincl != NULL) {        wincl->hInstance = hInst;        factory->optr->register_wndclass_helper (wincl);        if (factory->optr->classAtom == 0) {            delete factory;            return nullptr;        }    }    factory->optr->create_window_helper (*factory, dwStyleEx, strTitle, dwStyle, posX, posY, width, height, hWndParent, hMenu, hInst, cmdShow);    if (factory->getLastError () == XWINDOW_CREATING_WINDOW_FAILED) {        delete factory;        return nullptr;    }    return factory;}XoursWindow* XoursWindow::createWindow (wchar_t* strTitle, int posX, int posY, int width, int height, HINSTANCE hInst, int cmdShow) {    return XoursWindow::createWindow (NULL, NULL, strTitle, WS_OVERLAPPEDWINDOW, posX, posY, width, height, NULL, NULL, hInst, cmdShow);}XoursWindow* XoursWindow::createWindow (wchar_t* strTitle, HINSTANCE hInst, int cmdShow) {    return XoursWindow::createWindow (NULL, NULL, strTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, cmdShow);}int XoursWindow::destroy () {    DestroyWindow (this->getWindowHandle ());    this->optr->init_helper (*this);    return 0;}void XoursWindow::setAdditionalData (void* data) {    this->optr->windowData = data;}void* XoursWindow::getAdditionalData () {    return this->optr->windowData;}HWND XoursWindow::getWindowHandle () {    return this->optr->window;}int XoursWindow::getLastError () {    return this->optr->xwnd_err;}XoursWindow_OpaquePtr.h#ifndef __XOURSWINDOW_OPAQUEPTR_H#define __XOURSWINDOW_OPAQUEPTR_H#include XoursWindow.hstruct XoursWindow::OpaquePtr {    wchar_t className[128];    ATOM classAtom;    static unsigned long objectCounter;    DWORD objectId = 0;    void* windowData = NULL;    HWND window = NULL;    XWINDOW_ERROR xwnd_err = XWINDOW_SUCCESS;    OpaquePtr () = default;    OpaquePtr (const OpaquePtr&);    OpaquePtr (OpaquePtr&&);    OpaquePtr& operator= (const OpaquePtr&);    OpaquePtr& operator= (OpaquePtr&&);    ~OpaquePtr () {};    static void copy_helper (XoursWindow&, const XoursWindow&);    void init_helper (XoursWindow&);    void create_window_helper (XoursWindow&, DWORD, wchar_t*, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, int);    ATOM register_wndclass_helper (HINSTANCE);          // registers standard class for XOURSWINDOW    ATOM register_wndclass_helper (WNDCLASSEX*);            // registers custom class with WNDCLASSEX    static LRESULT CALLBACK initialProc (HWND, UINT, WPARAM, LPARAM);                                   // callback function for window initializing    static LRESULT CALLBACK messageForwardingProc (HWND, UINT, WPARAM, LPARAM, UINT_PTR, DWORD_PTR);    // subclassing routine for message forwarding to eventProc    LRESULT CALLBACK eventProc (const XoursWindow&, UINT, WPARAM, LPARAM);                              // intern event handler    static LRESULT CALLBACK eventHandling (HWND, UINT, WPARAM, LPARAM);                                 // standard event handler, per default: eventHandler = eventHandling    /* this callback method will be deleted in release version    let's call it an undocumented possibility to have ultimate freedom */    static LRESULT CALLBACK preCreationEventHandling (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {        return DefWindowProc (hwnd, msg, wParam, lParam);    };};#endif // __XOURSWINDOW_OPAQUEPTR_HXoursWindow_OpaquePtr.cpp#include header/XoursWindow_OpaquePtr.h#include <CommCtrl.h>unsigned long XoursWindow::OpaquePtr::objectCounter = 0;XoursWindow::OpaquePtr::OpaquePtr (const XoursWindow::OpaquePtr& origin) {    *this = origin;}XoursWindow::OpaquePtr::OpaquePtr (XoursWindow::OpaquePtr&& origin) {    *this = std::move (origin);}XoursWindow::OpaquePtr& XoursWindow::OpaquePtr::operator= (const XoursWindow::OpaquePtr& origin) {    this->classAtom = origin.classAtom;    lstrcpy (this->className, origin.className);    this->windowData = origin.windowData;    return *this;}XoursWindow::OpaquePtr& XoursWindow::OpaquePtr::operator= (XoursWindow::OpaquePtr&& origin) {    this->classAtom = origin.classAtom;    lstrcpy (this->className, origin.className);    this->objectId = origin.objectId;    this->window = origin.window;    this->windowData = origin.windowData;    return *this;}void XoursWindow::OpaquePtr::copy_helper (XoursWindow& dest, const XoursWindow& src) {    dest.onCreate = src.onCreate;    dest.onPaint = src.onPaint;    dest.onEraseBkgnd = src.onEraseBkgnd;    dest.onSize = src.onSize;    dest.onMove = src.onMove;    dest.onGetMinMaxInfo = src.onGetMinMaxInfo;    dest.onCommand = src.onCommand;    dest.onNotify = src.onNotify;    dest.onTimer = src.onTimer;    dest.onClose = src.onClose;    dest.onDestroy = src.onDestroy;    dest.onQuit = src.onQuit;    dest.eventHandler = src.eventHandler;}void XoursWindow::OpaquePtr::init_helper (XoursWindow& ownerInstancePtr) {      /* unset object data (window/window class will not be destroyed!) */    ownerInstancePtr.onCreate = NULL;    ownerInstancePtr.onPaint = NULL;    ownerInstancePtr.onEraseBkgnd = NULL;    ownerInstancePtr.onSize = NULL;    ownerInstancePtr.onMove = NULL;    ownerInstancePtr.onGetMinMaxInfo = NULL;    ownerInstancePtr.onCommand = ownerInstancePtr.onNotify = NULL;    ownerInstancePtr.onTimer = NULL;    ownerInstancePtr.onClose = NULL;    ownerInstancePtr.onDestroy = NULL;    ownerInstancePtr.onQuit = NULL;    ownerInstancePtr.eventHandler = XoursWindow::OpaquePtr::eventHandling;    XoursWindow::OpaquePtr::objectCounter++;  // won't be decremented (currently)    ownerInstancePtr.optr->objectId = 1000 + XoursWindow::OpaquePtr::objectCounter;    ownerInstancePtr.optr->windowData = NULL;    ownerInstancePtr.optr->classAtom = 0;    memset (ownerInstancePtr.optr->className, 0, sizeof (wchar_t) * 128);    lstrcpy (ownerInstancePtr.optr->className, LXoursWindow Standard Window Class\0);    ownerInstancePtr.optr->window = NULL;    ownerInstancePtr.optr->xwnd_err = XWINDOW_SUCCESS;}void XoursWindow::OpaquePtr::create_window_helper (XoursWindow& ownerInstancePtr, DWORD dwStyleEx, wchar_t* strTitle, DWORD dwStyle, int posX, int posY, int width, int height, HWND hWndParent, HMENU hMenu, HINSTANCE hInst, int cmdShow) {    ownerInstancePtr.optr->xwnd_err = XWINDOW_WINDOW_ALREADY_CREATED;   /* pre-set error to save a few code lines */    /* not really neccessary, GetLastError would return ERROR_MOD_NOT_FOUND otherwise */    if (ownerInstancePtr.optr->window != NULL)        return;    /* something to do when this->classAtom hasn't been set yet */    if (ownerInstancePtr.optr->classAtom == 0) {        /* try to register a standard window class or fail */        if (ownerInstancePtr.optr->register_wndclass_helper (hInst) == 0) {            ownerInstancePtr.optr->xwnd_err = XWINDOW_FAILURE;  /* so it failed */            /* okay, last chance ... but only when the class has been registered already */            int lastError = GetLastError ();            if (lastError == ERROR_CLASS_ALREADY_EXISTS) {                ownerInstancePtr.optr->xwnd_err = XWINDOW_WNDCLASS_ALREADY_EXISTS;                /* find window handle for retrieving ATOM */                HWND tmpWnd = FindWindow (ownerInstancePtr.optr->className, NULL);                if (tmpWnd == NULL)                    return;                if (GetClassLongPtr (tmpWnd, GCL_CBWNDEXTRA) != (XWINDOW_USERDATA_OFFSET + sizeof (XoursWindow*))) {                    ownerInstancePtr.optr->xwnd_err = XWINDOW_WNDCLASS_INCOMPATIBLE;                    return;                }                /* retrieve ATOM to set classAtom of this class instance */                ownerInstancePtr.optr->classAtom = (ATOM) GetClassLong (tmpWnd, GCW_ATOM);                if (ownerInstancePtr.optr->classAtom == 0)                    return;            }            else    /* unexpected error */                return;        }    }    /* create the window */    ownerInstancePtr.optr->xwnd_err = XWINDOW_CREATING_WINDOW_FAILED;   /* pre-set error ... again */    CreateWindowEx (dwStyleEx, MAKEINTATOM (ownerInstancePtr.optr->classAtom), strTitle, dwStyle, posX, posY, width, height, hWndParent, hMenu, hInst, &ownerInstancePtr);    if (ownerInstancePtr.optr->window != NULL) {        /* this->window should be successfully filled by magic */        ShowWindow (ownerInstancePtr.optr->window, cmdShow);        UpdateWindow (ownerInstancePtr.optr->window);        ownerInstancePtr.optr->xwnd_err = XWINDOW_SUCCESS; /* seems to be successful ... */    }    /* ... otherwise end with error set */}ATOM XoursWindow::OpaquePtr::register_wndclass_helper (HINSTANCE hInst) {       /* standard window class registration */    this->xwnd_err = XWINDOW_SUCCESS;    if (this->classAtom != 0){        this->xwnd_err = XWINDOW_WNDCLASS_ATOM_ALREADY_SET;        return 0;    }    WNDCLASSEX wincl;    wincl.hInstance = hInst;    wincl.lpszClassName = this->className;    wincl.lpfnWndProc = XoursWindow::OpaquePtr::initialProc;    wincl.style = CS_DBLCLKS;    wincl.cbSize = sizeof (WNDCLASSEX);    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);    wincl.lpszMenuName = NULL;    wincl.cbClsExtra = 0;    wincl.cbWndExtra = XWINDOW_USERDATA_OFFSET + sizeof (XoursWindow*);    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND + 1;    return (this->classAtom = RegisterClassEx (&wincl));}ATOM XoursWindow::OpaquePtr::register_wndclass_helper (WNDCLASSEX* wincl) {     /* register user defined window class (with limits) */    this->xwnd_err = XWINDOW_SUCCESS;    if (this->classAtom != 0) {        this->xwnd_err = XWINDOW_WNDCLASS_ATOM_ALREADY_SET;        return 0;    }    lstrcpy (this->className, wincl->lpszClassName);    /* force the use of our window callback procedure to ensure magic */    wincl->lpfnWndProc = XoursWindow::OpaquePtr::initialProc;    wincl->cbWndExtra = XWINDOW_USERDATA_OFFSET + sizeof (XoursWindow*);    return (this->classAtom = RegisterClassEx (wincl));}LRESULT CALLBACK XoursWindow::OpaquePtr::initialProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {    /* prepare magic when non-client area is going to be created */    if (msg == WM_NCCREATE) {        /* create param should be filled with this-pointer */        LPCREATESTRUCT lpcs = (LPCREATESTRUCT) lParam;        void * lpCreateParam = lpcs->lpCreateParams;        /* get class object .. */        XoursWindow* xinstance = (XoursWindow*) (lpCreateParam);        if (xinstance->optr->window != 0)       /* ... or fail */            return 0;        /* fill window handle (magic moment) */        xinstance->optr->window = hwnd;        /* set instance as user data of the window */        SetWindowLongPtr (hwnd, XWINDOW_USERDATA_OFFSET, (LONG_PTR) xinstance);        /* subclass window to allow generic event handling */        SetWindowSubclass (hwnd, XoursWindow::OpaquePtr::messageForwardingProc, xinstance->optr->objectId, 0);        /* call the event handler */        return xinstance->optr->eventProc (*xinstance, msg, wParam, lParam);    }    /* other things than creation of non-client area is none of our buisness at this point, but ... */    /* we call an ugly undocumented hack to allow message handling before CreateWindow returns */    return XoursWindow::OpaquePtr::preCreationEventHandling (hwnd, msg, wParam, lParam);    /* only called until subclassing was successful */}LRESULT CALLBACK XoursWindow::OpaquePtr::messageForwardingProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) {    /* prepare for message forwarding and get associated object */    LONG_PTR lpUserData = GetWindowLongPtr (hwnd, XWINDOW_USERDATA_OFFSET);    XoursWindow* xinstance = (XoursWindow*) lpUserData;    if (xinstance == NULL || hwnd != xinstance->optr->window)       /* check if retrieved object is valid and verify the window handle */        return -1;    /* call the event handler */    return xinstance->optr->eventProc (*xinstance, msg, wParam, lParam);}LRESULT CALLBACK XoursWindow::OpaquePtr::eventProc (const XoursWindow &ownerInstancePtr, UINT msg, WPARAM wParam, LPARAM lParam) {    /* let's handle our events */    switch (msg)    {        case WM_CREATE: {            /* when window is going to be created we have to retrieve the object ... */            LPCREATESTRUCT lpcs = (LPCREATESTRUCT) lParam;            void* lpCreateParam = lpcs->lpCreateParams;            XoursWindow* xinstance = (XoursWindow*) lpCreateParam;            /* ... and check for sanity */            if (xinstance != &ownerInstancePtr)                return -1;            if (ownerInstancePtr.onCreate != NULL)                return ownerInstancePtr.onCreate (this->window, (LPCREATESTRUCT) lParam);            return ownerInstancePtr.eventHandler (this->window, msg, wParam, lParam);        } break;        case WM_PAINT: {            if (ownerInstancePtr.onPaint != NULL) {                PAINTSTRUCT ps;                HDC hdc = BeginPaint (this->window, &ps);                    LRESULT result = ownerInstancePtr.onPaint (this->window, hdc, &ps);                EndPaint (this->window, &ps);                return result;            }            else                return ownerInstancePtr.eventHandler (this->window, msg, wParam, lParam);        } break;        case WM_ERASEBKGND: {            if (ownerInstancePtr.onEraseBkgnd != NULL)                return ownerInstancePtr.onEraseBkgnd (this->window, (HDC) wParam);            return ownerInstancePtr.eventHandler (this->window, msg, wParam, lParam);        } break;        case WM_SIZE: {            if (ownerInstancePtr.onSize != NULL)                return ownerInstancePtr.onSize (this->window, wParam, lParam);            return ownerInstancePtr.eventHandler (this->window, msg, wParam, lParam);        } break;        case WM_MOVE: {            if (ownerInstancePtr.onMove != NULL)                return ownerInstancePtr.onMove (this->window, (LPPOINTS) &MAKEPOINTS (lParam));            return ownerInstancePtr.eventHandler (this->window, msg, wParam, lParam);        } break;        case WM_GETMINMAXINFO: {            if (ownerInstancePtr.onGetMinMaxInfo != NULL)                return ownerInstancePtr.onGetMinMaxInfo (this->window, (LPMINMAXINFO) lParam);            return ownerInstancePtr.eventHandler (this->window, msg, wParam, lParam);        } break;        case WM_COMMAND: {            if (ownerInstancePtr.onCommand != NULL)                return ownerInstancePtr.onCommand (this->window, wParam, lParam);            return ownerInstancePtr.eventHandler (this->window, msg, wParam, lParam);        } break;        case WM_NOTIFY: {            if (ownerInstancePtr.onNotify != NULL)                return ownerInstancePtr.onNotify (this->window, wParam, lParam);            return ownerInstancePtr.eventHandler (this->window, msg, wParam, lParam);        } break;        case WM_TIMER: {            if (ownerInstancePtr.onTimer != NULL)                return ownerInstancePtr.onTimer (this->window, wParam, lParam);            return ownerInstancePtr.eventHandler (this->window, msg, wParam, lParam);        } break;        case WM_CLOSE: {            if (ownerInstancePtr.onClose != NULL)                return ownerInstancePtr.onClose (this->window);            return ownerInstancePtr.eventHandler (this->window, msg, wParam, lParam);        } break;        case WM_DESTROY: {            if (ownerInstancePtr.onDestroy != NULL)                return ownerInstancePtr.onDestroy (this->window);            else {                PostQuitMessage (0);                return 0;            }            return ownerInstancePtr.eventHandler (this->window, msg, wParam, lParam);        } break;        case WM_QUIT: {            if (ownerInstancePtr.onQuit != NULL)            /* call onQuit */                ownerInstancePtr.onQuit (this->window, wParam);            else if (ownerInstancePtr.eventHandler != NULL)     /* when onQuit is unset, try to call eventHandling */                ownerInstancePtr.eventHandler (this->window, msg, wParam, lParam);            /* it's pretty important to remove the subclass properly */            RemoveWindowSubclass (this->window, XoursWindow::OpaquePtr::messageForwardingProc, this->objectId);        } break;        default: {            return ownerInstancePtr.eventHandler (this->window, msg, wParam, lParam);        } break;    }    return 0;}LRESULT CALLBACK XoursWindow::OpaquePtr::eventHandling (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {    /* standard event handling means calling DefWindowProc */    return DefWindowProc (hwnd, msg, wParam, lParam);}main.cpp (example)#include <Windows.h>#include XoursWindow/header/XoursWindow.hLRESULT destroyEvent (HWND hwnd) {    ShowWindow (hwnd, SW_HIDE);    return 0;}LRESULT moveEvent (HWND hwnd, LPPOINTS pt) {    ShowWindow (hwnd, SW_HIDE);    Sleep (100);    ShowWindow (hwnd, SW_SHOW);    return 0;}LRESULT closeEvent (HWND hwnd) {    if (MessageBox (NULL, LAre you sure?, LLast chance, MB_YESNO) == IDNO)        return 0;    DestroyWindow (hwnd);    return 0;}LRESULT paintEvent (HWND hwnd, HDC hdc, LPPAINTSTRUCT ps) {    TextOut (hdc, 20, 20, LPaint event has been triggered., lstrlen (LPaint event has been triggered.));    return 0;}int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow){    wchar_t buf[50];    lstrcpy (buf, LXoursWindow Standard Window Class 1\0);    XoursWindow *window = XoursWindow::createWindow (buf, hThisInstance, SW_SHOW);    if (window == nullptr)        return -1;    window->onPaint = paintEvent;    window->onDestroy = destroyEvent;    XoursWindow second (*window);    second.create (Lsecond, hThisInstance, SW_SHOW);    second.onClose = closeEvent;    second.onDestroy = NULL;        // due to onDestroy has been copied from window we have to reset it here    window->onMove = moveEvent;    MSG messages;    while (GetMessage (&messages, NULL, 0, 0))    {        TranslateMessage (&messages);        DispatchMessage (&messages);    }    return (int) messages.wParam;}
Follow-up: Window Creation Wrapper Class
c++;object oriented;c++11;wrapper;winapi