Module: wine Branch: refs/heads/master Commit: 10acd23b2cc89dc353677ef7abd11265dfe98a0e URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=10acd23b2cc89dc353677ef7...
Author: Jacek Caban jacek@codeweavers.com Date: Thu May 25 18:35:35 2006 +0200
urlmon: Call OnProgress in apartment thread.
---
dlls/urlmon/binding.c | 115 +++++++++++++++++++++++++++++++++++++++++++-- dlls/urlmon/urlmon_main.c | 4 ++ dlls/urlmon/urlmon_main.h | 2 + 3 files changed, 117 insertions(+), 4 deletions(-)
diff --git a/dlls/urlmon/binding.c b/dlls/urlmon/binding.c index 2a59b80..7de0847 100644 --- a/dlls/urlmon/binding.c +++ b/dlls/urlmon/binding.c @@ -53,6 +53,9 @@ typedef struct { DWORD bindf; LPWSTR mime; LPWSTR url; + + DWORD apartment_thread; + HWND notif_hwnd; } Binding;
struct ProtocolStream { @@ -74,6 +77,110 @@ #define SERVPROV(x) ((IServiceProvider*
#define STREAM(x) ((IStream*) &(x)->lpStreamVtbl)
+#define WM_MK_ONPROGRESS (WM_USER+100) + +typedef struct { + Binding *binding; + ULONG progress; + ULONG progress_max; + ULONG status_code; + LPWSTR status_text; +} on_progress_data; + +static LRESULT WINAPI notif_wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) { + case WM_MK_ONPROGRESS: { + on_progress_data *data = (on_progress_data*)lParam; + + TRACE("WM_MK_PROGRESS %p\n", data); + + IBindStatusCallback_OnProgress(data->binding->callback, data->progress, + data->progress_max, data->status_code, data->status_text); + + IBinding_Release(BINDING(data->binding)); + HeapFree(GetProcessHeap(), 0, data->status_text); + HeapFree(GetProcessHeap(), 0, data); + + return 0; + } + } + + return DefWindowProcW(hwnd, msg, wParam, lParam); +} + +static HWND get_notif_hwnd(void) +{ + static ATOM wnd_class = 0; + HWND hwnd; + + static const WCHAR wszURLMonikerNotificationWindow[] = + {'U','R','L',' ','M','o','n','i','k','e','r',' ', + 'N','o','t','i','f','i','c','a','t','i','o','n',' ','W','i','n','d','o','w',0}; + + if(!wnd_class) { + static WNDCLASSEXW wndclass = { + sizeof(wndclass), 0, + notif_wnd_proc, 0, 0, + NULL, NULL, NULL, NULL, NULL, + wszURLMonikerNotificationWindow, + NULL + }; + + wndclass.hInstance = URLMON_hInstance; + + wnd_class = RegisterClassExW(&wndclass); + } + + if(!urlmon_tls) + urlmon_tls = TlsAlloc(); + + hwnd = TlsGetValue(urlmon_tls); + if(hwnd) + return hwnd; + + hwnd = CreateWindowExW(0, MAKEINTATOMW(wnd_class), + wszURLMonikerNotificationWindow, 0, 0, 0, 0, 0, HWND_MESSAGE, + NULL, URLMON_hInstance, NULL); + TlsSetValue(urlmon_tls, hwnd); + + TRACE("hwnd = %p\n", hwnd); + + return hwnd; +} + +static void on_progress(Binding *This, ULONG progress, ULONG progress_max, + ULONG status_code, LPCWSTR status_text) +{ + on_progress_data *data; + + if(GetCurrentThreadId() == This->apartment_thread) { + IBindStatusCallback_OnProgress(This->callback, progress, progress_max, + status_code, status_text); + return; + } + + data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data)); + + IBinding_AddRef(BINDING(This)); + + data->binding = This; + data->progress = progress; + data->progress_max = progress_max; + data->status_code = status_code; + + if(status_text) { + DWORD size = (strlenW(status_text)+1)*sizeof(WCHAR); + + data->status_text = HeapAlloc(GetProcessHeap(), 0, size); + memcpy(data->status_text, status_text, size); + }else { + data->status_text = NULL; + } + + PostMessageW(This->notif_hwnd, WM_MK_ONPROGRESS, 0, (LPARAM)data); +} + static HRESULT WINAPI HttpNegotiate_QueryInterface(IHttpNegotiate2 *iface, REFIID riid, void **ppv) { @@ -543,12 +650,10 @@ static HRESULT WINAPI InternetProtocolSi break; } case BINDSTATUS_SENDINGREQUEST: - IBindStatusCallback_OnProgress(This->callback, 0, 0, BINDSTATUS_SENDINGREQUEST, - szStatusText); + on_progress(This, 0, 0, BINDSTATUS_SENDINGREQUEST, szStatusText); break; case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE: - IBindStatusCallback_OnProgress(This->callback, 0, 0, - BINDSTATUS_MIMETYPEAVAILABLE, szStatusText); + on_progress(This, 0, 0, BINDSTATUS_MIMETYPEAVAILABLE, szStatusText); break; case BINDSTATUS_CACHEFILENAMEAVAILABLE: break; @@ -847,6 +952,8 @@ static HRESULT Binding_Create(LPCWSTR ur ret->stream = NULL; ret->mime = NULL; ret->url = NULL; + ret->apartment_thread = GetCurrentThreadId(); + ret->notif_hwnd = get_notif_hwnd();
memset(&ret->bindinfo, 0, sizeof(BINDINFO)); ret->bindinfo.cbSize = sizeof(BINDINFO); diff --git a/dlls/urlmon/urlmon_main.c b/dlls/urlmon/urlmon_main.c index fa62409..edec353 100644 --- a/dlls/urlmon/urlmon_main.c +++ b/dlls/urlmon/urlmon_main.c @@ -42,6 +42,8 @@ LONG URLMON_refCount = 0;
HINSTANCE URLMON_hInstance = 0;
+DWORD urlmon_tls = 0; + /*********************************************************************** * DllMain (URLMON.init) */ @@ -56,6 +58,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, break;
case DLL_PROCESS_DETACH: + if(urlmon_tls) + TlsFree(urlmon_tls); URLMON_hInstance = 0; break; } diff --git a/dlls/urlmon/urlmon_main.h b/dlls/urlmon/urlmon_main.h index 0eb7db6..9b9f149 100644 --- a/dlls/urlmon/urlmon_main.h +++ b/dlls/urlmon/urlmon_main.h @@ -59,4 +59,6 @@ HRESULT get_protocol_handler(LPCWSTR url
HRESULT start_binding(LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv);
+extern DWORD urlmon_tls; + #endif /* __WINE_URLMON_MAIN_H */