On 5/22/2013 8:49 PM, evilrat wrote:
On Wednesday, 22 May 2013 at 21:42:32 UTC, D-sturbed wrote:

Yes I'm in the "multiple Window case", every window is wraped in a
class and has its own message handler. I know that Win, in its
callback system, often lets you retrieve a pointer to something, and I
haven't get it was possible in this case...(which is you seem to
describe). I will try this tomorrow.

you can't really make it without static wndproc. if you don't know how
to do it just go google some wndproc in a class tutors for c++, i can
even recommend you one(i had used my own port of this in D before i
switched to crossplatform lib for my needs) -
http://blogs.msdn.com/b/oldnewthing/archive/2005/04/22/410773.aspx


I had a partial port of WTL over to D which worked well enough for what I needed, the core of the WndProc handling is down below. Each HWND is owned by the thread it was created on, so assigning it into D associative array (which is thread local) can do the trick. It involved a hack, before any call to the Win32 CreateWindow/CreateWindowEx APIs, to capture the association with the new HWND and to remove them when they get cleaned up. There is probably a better way but this worked enough to get started, and should work with multiple windows reasonably well.






CWindowInterface g_CreatingWindow;
CWindowInterface[HWND] g_HWNDtoObject;


extern (Windows)
int CWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    int WindowProcReturnValue = 0;

/*
    auto EventMsg = appender!string();
formattedWrite(EventMsg, "EventMsg (hWnd=%1$s) (uMsg=%2$s) (wParam=%3$s) (lParam=%4$s)\n", cast(DWORD)hWnd, cast(DWORD)uMsg, cast(DWORD)wParam, cast(DWORD)lParam);
    OutputDebugString(toUTFz!(const(wchar)*)(EventMsg.data));
*/

    if (g_CreatingWindow)
    {
        g_HWNDtoObject[hWnd] = g_CreatingWindow;
        g_CreatingWindow = null;
    }
    auto Window = g_HWNDtoObject[cast(HANDLE)hWnd];
    if (Window is null)
    {
        WindowProcReturnValue = DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    else
    {
WindowProcReturnValue = Window.WindowProc(hWnd, uMsg, wParam, lParam);
    }
    if (uMsg == WM_NCDESTROY)
    {
        g_HWNDtoObject.remove(hWnd);
    }
    return WindowProcReturnValue;
}

Reply via email to