diff options
Diffstat (limited to 'Src/Winamp/setup/httpgrab.cpp')
-rw-r--r-- | Src/Winamp/setup/httpgrab.cpp | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/Src/Winamp/setup/httpgrab.cpp b/Src/Winamp/setup/httpgrab.cpp new file mode 100644 index 00000000..6f45914a --- /dev/null +++ b/Src/Winamp/setup/httpgrab.cpp @@ -0,0 +1,183 @@ +#include "main.h" +#include "./httpgrab.h" + + +static HHOOK g_hook = NULL; +static HWND g_hook_host = NULL; +static HWND g_hook_fwd = NULL; +static DWORD g_hook_flags = 0; +static HWND *g_hook_phwnd =NULL; + +static LRESULT CALLBACK TargetWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +static LRESULT CALLBACK LabelWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + +static BOOL IsDialog(HWND hwnd) +{ + wchar_t szName[256] = {0}; + return (GetClassNameW(hwnd, szName, sizeof(szName)/sizeof(wchar_t)) && + CSTR_EQUAL == CompareStringW(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT), + NORM_IGNORECASE, szName, -1, L"#32770", -1)); +} + +static LRESULT CALLBACK HookProc(int code, WPARAM wParam, LPARAM lParam) +{ + if (HCBT_CREATEWND == code && IsDialog((HWND)wParam) && ((CBT_CREATEWND*)lParam)->lpcs->hwndParent == g_hook_host) + { + LRESULT result; + + result = CallNextHookEx(g_hook, code, wParam, lParam); + UnhookWindowsHookEx(g_hook); + g_hook = NULL; + + if (0 == result) + { + ((CBT_CREATEWND*)lParam)->lpcs->style &= ~WS_VISIBLE; + WNDPROC oldProc = (WNDPROC)SetWindowLongPtrW((HWND)wParam, GWLP_WNDPROC, (LONG_PTR)TargetWndProc); + if (oldProc) + { + SetPropW((HWND)wParam, L"WNDPROC", oldProc); + if (g_hook_fwd) SetPropW((HWND)wParam, L"FWDHWND", g_hook_fwd); + if (g_hook_flags) SetPropW((HWND)wParam, L"FLAGS", (HANDLE)(INT_PTR)g_hook_flags); + if (g_hook_phwnd) *g_hook_phwnd = (HWND)wParam; + } + } + else if (g_hook_host && IsWindow(g_hook_host)) DestroyWindow(g_hook_host); + + g_hook_fwd = NULL; + g_hook_flags = 0; + g_hook_host = NULL; + return result; + } + return CallNextHookEx(g_hook, code, wParam, lParam); +} + +HWND BeginGrabHTTPText(HWND hwndFwd, UINT flags, HWND *phwndTarget) +{ + + g_hook_host = CreateWindowExW(0x08000000/*WS_EX_NOACTIVATE*/ | WS_EX_NOPARENTNOTIFY, L"STATIC", L"", WS_DISABLED | WS_POPUP, -10000, -10000, 0, 0, NULL, NULL, NULL, NULL); + if (!g_hook_host) return NULL; + + g_hook = SetWindowsHookEx(WH_CBT, HookProc, NULL, GetCurrentThreadId()); + if (!g_hook) + { + if (g_hook_host) DestroyWindow(g_hook_host); + g_hook_host = NULL; + g_hook_fwd = NULL; + g_hook_flags = 0; + g_hook_phwnd = NULL; + } + else + { + g_hook_fwd = hwndFwd; + g_hook_flags = flags; + g_hook_phwnd = phwndTarget; + } + return g_hook_host; +} + +void EndGrabHTTPText(HWND hwndHost) +{ + if (g_hook_host == hwndHost) + { + if (g_hook) UnhookWindowsHookEx(g_hook); + g_hook = NULL; + g_hook_host = NULL; + g_hook_fwd = NULL; + g_hook_flags = 0; + } + if (IsWindow(hwndHost)) DestroyWindow(hwndHost); +} + +static LRESULT CALLBACK TargetWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + WNDPROC fnOldProc = (WNDPROC)GetPropW(hwnd, L"WNDPROC"); + + switch(uMsg) + { + case WM_INITDIALOG: + { + HWND hwndFwd; + + hwndFwd = (HWND)GetPropW(hwnd, L"FWDHWND"); + DWORD flags = (DWORD)(INT_PTR)GetPropW(hwnd, L"FLAGS"); + RemovePropW(hwnd, L"FLAGS"); + RemovePropW(hwnd, L"FWDHWND"); + + if (hwndFwd) + { + HWND hwndText; + if (HTTPGRAB_USESTATUSTEXT & flags) + { + hwndText = GetDlgItem(hwnd, 1180/*IDC_STATUS*/); + WNDPROC oldProc = (WNDPROC)SetWindowLongPtrW(hwndText, GWLP_WNDPROC, (LONG_PTR)LabelWndProc); + if (oldProc) SetPropW(hwndText, L"WNDPROC", oldProc); + else hwndText = hwnd; + } + else hwndText = hwnd; + SetPropW(hwndText, L"FWDTEXT", hwndFwd); + + WCHAR szText[256] = {0}; + GetWindowTextW(hwndText, szText, sizeof(szText)/sizeof(wchar_t)); + SetWindowTextW(hwndFwd, szText); + } + } + break; + case WM_DESTROY: + { + RemovePropW(hwnd, L"WNDPROC"); + RemovePropW(hwnd, L"FWDTEXT"); + if (fnOldProc) SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)fnOldProc); + HWND hwndOwner; + hwndOwner = GetWindow(hwnd, GW_OWNER); + if (hwndOwner) DestroyWindow(hwndOwner); + } + break; + case WM_STYLECHANGING: + if (GWL_STYLE & wParam) ((STYLESTRUCT*)lParam)->styleNew &= ~WS_VISIBLE; + return 0; + case WM_STYLECHANGED: + if ((GWL_STYLE & wParam) && (WS_VISIBLE & ((STYLESTRUCT*)lParam)->styleNew)) + SetWindowLongPtrW(hwnd, GWL_STYLE, (((STYLESTRUCT*)lParam)->styleNew & ~WS_VISIBLE)); + return 0; + case WM_WINDOWPOSCHANGING: + ((WINDOWPOS*)lParam)->flags = (((WINDOWPOS*)lParam)->flags & ~(SWP_SHOWWINDOW | SWP_FRAMECHANGED)) | SWP_NOACTIVATE | SWP_NOZORDER; + return 0; + case WM_SETTEXT: + { + HWND hwndFwd = (HWND)GetPropW(hwnd, L"FWDTEXT"); + if (hwndFwd) + { + (IsWindowUnicode(hwndFwd)) ? SendMessageW(hwndFwd, WM_SETTEXT, wParam, lParam) : + SendMessageA(hwndFwd, WM_SETTEXT, wParam, lParam); + } + } + break; + } + if (!fnOldProc) return DefWindowProc(hwnd, uMsg, wParam, lParam); + return (IsWindowUnicode(hwnd)) ? CallWindowProcW(fnOldProc, hwnd, uMsg, wParam, lParam) : CallWindowProcA(fnOldProc, hwnd, uMsg, wParam, lParam); +} + +static LRESULT CALLBACK LabelWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + WNDPROC fnOldProc = (WNDPROC)GetPropW(hwnd, L"WNDPROC"); + + switch(uMsg) + { + case WM_SETTEXT: + { + HWND hwndFwd = (HWND)GetPropW(hwnd, L"FWDTEXT"); + if (hwndFwd) + { + (IsWindowUnicode(hwndFwd)) ? SendMessageW(hwndFwd, WM_SETTEXT, wParam, lParam) : + SendMessageA(hwndFwd, WM_SETTEXT, wParam, lParam); + } + } + case WM_DESTROY: + RemovePropW(hwnd, L"WNDPROC"); + RemovePropW(hwnd, L"FWDTEXT"); + if (fnOldProc) SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)fnOldProc); + break; + } + if (!fnOldProc) return DefWindowProc(hwnd, uMsg, wParam, lParam); + return (IsWindowUnicode(hwnd)) ? CallWindowProcW(fnOldProc, hwnd, uMsg, wParam, lParam) : CallWindowProcA(fnOldProc, hwnd, uMsg, wParam, lParam); +} |