# HG changeset patch # User Jordan Miner # Date 1247899026 18000 # Node ID 7a7e5f9bd1aeb83cf50e9fb6973f2502bd5e7f23 # Parent df1c8e659b75156ba9d425cc7666a172b8dc837f Implement invoke() and invokeNow() on Windows. diff -r df1c8e659b75 -r 7a7e5f9bd1ae dynamin/c/windows.d --- a/dynamin/c/windows.d Thu Jul 16 18:18:22 2009 -0500 +++ b/dynamin/c/windows.d Sat Jul 18 01:37:06 2009 -0500 @@ -813,7 +813,11 @@ void PostQuitMessage(int nExitCode); -LRESULT SendMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +LRESULT SendMessageW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); + +BOOL InSendMessage(); + +BOOL ReplyMessage(LRESULT lResult); //}}} //{{{ clipboard functions @@ -1590,6 +1594,7 @@ //}}} version(UNICODE) { + alias MessageBoxW MessageBox; alias RegisterClassExW RegisterClassEx; alias CreateWindowExW CreateWindowEx; alias DefWindowProcW DefWindowProc; @@ -1607,6 +1612,7 @@ alias GetSaveFileNameW GetSaveFileName; alias GetMessageW GetMessage; alias DispatchMessageW DispatchMessage; + alias SendMessageW SendMessage; alias LoadImageW LoadImage; alias GetObjectW GetObject; alias EnumFontFamiliesExW EnumFontFamiliesEx; @@ -1629,6 +1635,7 @@ alias TEXTMETRICW TEXTMETRIC; alias OSVERSIONINFOW OSVERSIONINFO; } else { + alias MessageBoxA MessageBox; alias RegisterClassExA RegisterClassEx; alias CreateWindowExA CreateWindowEx; alias DefWindowProcA DefWindowProc; @@ -1646,6 +1653,7 @@ alias GetSaveFileNameA GetSaveFileName; alias GetMessageA GetMessage; alias DispatchMessageA DispatchMessage; + alias SendMessageA SendMessage; alias LoadImageA LoadImage; alias EnumFontFamiliesExA EnumFontFamiliesEx; alias SystemParametersInfoA SystemParametersInfo; diff -r df1c8e659b75 -r 7a7e5f9bd1ae dynamin/gui/window.d --- a/dynamin/gui/window.d Thu Jul 16 18:18:22 2009 -0500 +++ b/dynamin/gui/window.d Sat Jul 18 01:37:06 2009 -0500 @@ -37,10 +37,12 @@ import tango.core.Exception; import tango.core.Thread; +/// static class Application { static: mixin ApplicationBackend; package Thread eventThread; + /// Starts event processing. Must be called from main(). void run(Window w = null) { Window.hasProcessedEvents = true; @@ -51,12 +53,25 @@ backend_run(w); } - //void invoke(void delegate() dg) { - // - //} - //void invokeNow(void delegate() dg) + /** + * Calls the specified delegate on the event thread and returns without + * waiting for the delegate to finish. Since the delegate is not called + * immediately, it must not live on the stack. Instead, it could be a + * method of a class. In D2, delegates generally are on the heap. + */ + void invoke(void delegate() dg) { + backend_invoke(dg); + } + /** + * Calls the specified delegate on the event thread and blocks until + * the delegate finishes. + */ + void invokeNow(void delegate() dg) { + backend_invokeNow(dg); + } } +/// enum DialogResult { /// OK, @@ -223,7 +238,7 @@ recreateHandle(); assert(Thread.getThis() is Application.eventThread || Application.eventThread is null, - "controls must be accessed and changed only on the event thread"); + "Controls must be accessed and changed only on the event thread. Use invokeNow() from other threads."); return _handle; } diff -r df1c8e659b75 -r 7a7e5f9bd1ae dynamin/gui/windows_window.d --- a/dynamin/gui/windows_window.d Thu Jul 16 18:18:22 2009 -0500 +++ b/dynamin/gui/windows_window.d Sat Jul 18 01:37:06 2009 -0500 @@ -34,6 +34,7 @@ public import dynamin.gui.key; public import dynamin.all_painting; public import tango.io.Stdout; +public import tango.core.sync.Semaphore; /// enum WindowsVersion { @@ -117,8 +118,16 @@ DispatchMessage(&msg); } } + void backend_invoke(void delegate() dg) { + PostMessage(msgWnd, WM_USER + 7, + cast(word)dg.ptr, cast(word)dg.funcptr); + } + void backend_invokeNow(void delegate() dg) { + SendMessage(msgWnd, WM_USER + 7, + cast(word)dg.ptr, cast(word)dg.funcptr); + } + } - /* * The reason backends use the backend_ prefix and: * mixin Backend(); @@ -966,6 +975,12 @@ if(wParam == PBT_APMRESUMESUSPEND || wParam == PBT_APMRESUMECRITICAL) Environment.backend_increaseTimerRes(); return 0; + case WM_USER + 7: + void delegate() dg; + dg.ptr = cast(void*)wParam; + dg.funcptr = cast(void function())lParam; + dg(); + return 0; case WM_TIMER: case WM_CHANGECBCHAIN: case WM_DRAWCLIPBOARD: