static BOOL CALLBACK enum_cb(HWND hwnd, LPARAM lparam) { RECT rect; unsigned short title[150]; LONG styles; int state; HWND parent; DWORD pid; int flags; char classname[32]; styles = GetWindowLong(hwnd, GWL_STYLE); if (!(styles & WS_VISIBLE)) return TRUE; /* Since WH_CALLWNDPROC is not effective on cmd.exe, make sure we ignore it during enumeration as well. Make sure to remove this when cmd.exe support has been added, though. */ if (GetClassName(hwnd, classname, sizeof(classname)) && !strcmp(classname, "ConsoleWindowClass")) return TRUE; if (styles & WS_POPUP) parent = (HWND) GetWindowLongPtr(hwnd, GWLP_HWNDPARENT); else parent = NULL; GetWindowThreadProcessId(hwnd, &pid); flags = 0; if (styles & DS_MODALFRAME) flags |= SEAMLESS_CREATE_MODAL; vchannel_write("CREATE", "0x%08lx,0x%08lx,0x%08lx,0x%08x", hwnd_to_long(hwnd), (long) pid, hwnd_to_long(parent), flags); if (!GetWindowRect(hwnd, &rect)) { debug("GetWindowRect failed!"); return TRUE; } vchannel_write("POSITION", "0x%08lx,%d,%d,%d,%d,0x%08x", hwnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0); GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title)); vchannel_write("TITLE", "0x%x,%s,0x%x", hwnd, vchannel_strfilter_unicode(title), 0); if (styles & WS_MAXIMIZE) state = 2; else if (styles & WS_MINIMIZE) state = 1; else state = 0; vchannel_write("STATE", "0x%08lx,0x%08x,0x%08x", hwnd, state, 0); return TRUE; }
static LRESULT CALLBACK wndprocret_hook_proc(int code, WPARAM cur_thread, LPARAM details) { HWND hwnd; UINT msg; WPARAM wparam; LPARAM lparam; LONG style; if (!g_wm_seamless_focus) goto end; if (code < 0) goto end; hwnd = ((CWPRETSTRUCT *) details)->hwnd; msg = ((CWPRETSTRUCT *) details)->message; wparam = ((CWPRETSTRUCT *) details)->wParam; lparam = ((CWPRETSTRUCT *) details)->lParam; if (!is_toplevel(hwnd)) { goto end; } style = GetWindowLong(hwnd, GWL_STYLE); switch (msg) { case WM_WINDOWPOSCHANGED: { WINDOWPOS *wp = (WINDOWPOS *) lparam; if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE)) break; if (!(wp->flags & SWP_NOZORDER)) update_zorder(hwnd); break; } case WM_SETTEXT: { unsigned short title[150]; if (!(style & WS_VISIBLE)) break; /* We cannot use the string in lparam because we need unicode. */ GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title)); vchannel_write("TITLE", "0x%08lx,%s,0x%08x", hwnd, vchannel_strfilter_unicode(title), 0); break; } case WM_SETICON: { HICON icon; if (!(style & WS_VISIBLE)) break; /* * Somehow, we never get WM_SETICON for the small icon. * So trigger a read of it every time the large one is * changed. */ icon = get_icon(hwnd, 0); if (icon) { update_icon(hwnd, icon, 0); DeleteObject(icon); } } default: break; } if (msg == g_wm_seamless_focus) { /* For some reason, SetForegroundWindow() on menus closes them. Ignore focus requests for menu windows. */ if ((GetForegroundWindow() != hwnd) && !is_menu(hwnd)) SetForegroundWindow(hwnd); vchannel_write("ACK", "%u", g_shdata->blocked_focus_serial); } end: return CallNextHookEx(g_wndprocret_hook, code, cur_thread, details); }
static LRESULT CALLBACK wndproc_hook_proc(int code, WPARAM cur_thread, LPARAM details) { HWND hwnd; UINT msg; WPARAM wparam; LPARAM lparam; LONG style; if (!g_wm_seamless_focus) goto end; if (code < 0) goto end; hwnd = ((CWPSTRUCT *) details)->hwnd; msg = ((CWPSTRUCT *) details)->message; wparam = ((CWPSTRUCT *) details)->wParam; lparam = ((CWPSTRUCT *) details)->lParam; if (!is_toplevel(hwnd)) { goto end; } style = GetWindowLong(hwnd, GWL_STYLE); switch (msg) { case WM_WINDOWPOSCHANGED: { WINDOWPOS *wp = (WINDOWPOS *) lparam; if (wp->flags & SWP_SHOWWINDOW) { unsigned short title[150]; int state; DWORD pid; int flags; HICON icon; LONG exstyle; exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); GetWindowThreadProcessId(hwnd, &pid); flags = 0; if (style & DS_MODALFRAME) flags |= SEAMLESS_CREATE_MODAL; // handle always on top if (exstyle & WS_EX_TOPMOST) flags |= SEAMLESS_CREATE_TOPMOST; vchannel_write("CREATE", "0x%08lx,0x%08lx,0x%08lx,0x%08x", hwnd_to_long(hwnd), (long) pid, hwnd_to_long(get_parent(hwnd)), flags); GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title)); vchannel_write("TITLE", "0x%08lx,%s,0x%08x", hwnd, vchannel_strfilter_unicode(title), 0); icon = get_icon(hwnd, 1); if (icon) { update_icon(hwnd, icon, 1); DeleteObject(icon); } icon = get_icon(hwnd, 0); if (icon) { update_icon(hwnd, icon, 0); DeleteObject(icon); } if (style & WS_MAXIMIZE) state = 2; else if (style & WS_MINIMIZE) state = 1; else state = 0; update_position(hwnd); vchannel_write("STATE", "0x%08lx,0x%08x,0x%08x", hwnd, state, 0); } if (wp->flags & SWP_HIDEWINDOW) vchannel_write("DESTROY", "0x%08lx,0x%08x", hwnd, 0); if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE)) break; if (!(wp->flags & SWP_NOMOVE && wp->flags & SWP_NOSIZE)) update_position(hwnd); break; } case WM_SETICON: if (!(style & WS_VISIBLE)) break; switch (wparam) { case ICON_BIG: if (lparam) update_icon(hwnd, (HICON) lparam, 1); else vchannel_write("DELICON", "0x%08lx,RGBA,32,32", hwnd); break; case ICON_SMALL: case 2: if (lparam) update_icon(hwnd, (HICON) lparam, 0); else vchannel_write("DELICON", "0x%08lx,RGBA,16,16", hwnd); break; default: debug("Weird icon size %d", (int) wparam); } break; case WM_SIZE: if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE)) break; update_position(hwnd); break; case WM_MOVE: if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE)) break; update_position(hwnd); break; case WM_DESTROY: if (!(style & WS_VISIBLE)) break; vchannel_write("DESTROY", "0x%08lx,0x%08x", hwnd, 0); break; default: break; } end: return CallNextHookEx(g_wndproc_hook, code, cur_thread, details); }
static LRESULT CALLBACK wndprocret_hook_proc(int code, WPARAM cur_thread, LPARAM details) { HWND hwnd; UINT msg; WPARAM wparam; LPARAM lparam; LONG style; if (code < 0) goto end; hwnd = ((CWPRETSTRUCT *) details)->hwnd; msg = ((CWPRETSTRUCT *) details)->message; wparam = ((CWPRETSTRUCT *) details)->wParam; lparam = ((CWPRETSTRUCT *) details)->lParam; if (!is_toplevel(hwnd) || is_seamless_internal_windows(hwnd)) { goto end; } style = GetWindowLong(hwnd, GWL_STYLE); switch (msg) { case WM_WINDOWPOSCHANGED: { WINDOWPOS *wp = (WINDOWPOS *) lparam; if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE)) break; if (!(wp->flags & SWP_NOZORDER)) //update_zorder(hwnd) --> WinDev applications bring if we do that; break; break; } case WM_SETTEXT: { if (!(style & WS_VISIBLE)) break; /* We cannot use the string in lparam because we need unicode. */ if (getWindowFromHistory(hwnd) == NULL){ create_window(hwnd); } else{ BOOLEAN titleIsTheSame = TRUE; int i = 0; unsigned short *title; node* window = getWindowFromHistory(hwnd); if (window == NULL) { break; } title = malloc(sizeof(unsigned short) * TITLE_SIZE); if (title == NULL) break; GetWindowTextW(hwnd, title, TITLE_SIZE); if (window->title != NULL) { for (i = 0; i < TITLE_SIZE; i++) { if (title[i] != window->title[i]) { titleIsTheSame = FALSE; break; } } } else { titleIsTheSame = FALSE; } if (titleIsTheSame) { free(title); break; } vchannel_write("TITLE", "0x%08lx,%s,0x%08x", hwnd, vchannel_strfilter_unicode(title), 0); if (window->title) { free(window->title); window->title; } window->title = title; } break; } case WM_SETICON: { HICON icon; /* * Somehow, we never get WM_SETICON for the small icon. * So trigger a read of it every time the large one is * changed. */ icon = get_icon(hwnd, 0); if (icon) { update_icon(hwnd, icon, 0); DeleteObject(icon); } break; } case WM_ACTIVATE: // http://msdn.microsoft.com/en-us/library/ms646274(VS.85).aspx if (wparam == 0) // WA_INACTIVE break; case WM_SETFOCUS: // Focus gained if (hwnd == g_last_focused_window) break; WaitForSingleObject(g_mutex, INFINITE); g_last_focused_window = hwnd; ReleaseMutex(g_mutex); { node* window; window = getWindowFromHistory(hwnd); if (window == NULL) { window = addHWDNToHistory(hwnd); if (window == NULL) goto end; window->focus = TRUE; goto end; } } vchannel_block(); vchannel_write("FOCUS", "0x%08lx", hwnd); vchannel_unblock(); break; default: break; } end: return CallNextHookEx(g_wndprocret_hook, code, cur_thread, details); }
static void create_window(HWND hwnd){ unsigned short *title; DWORD pid; int flags; HICON icon; LONG exstyle; LONG style; HWND parent; node* window; TCHAR classname[256]; window = getWindowFromHistory(hwnd); if (window != NULL) { if (window->is_shown) return; } else { window = addHWDNToHistory(hwnd); if (window == NULL) return; } window->is_shown = TRUE; style = GetWindowLong(hwnd, GWL_STYLE); vchannel_write("DEBUG","NEW WINDOWS"); exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); GetWindowThreadProcessId(hwnd, &pid); parent = get_parent(hwnd); if (getWindowFromHistory(parent) == NULL) parent = 0; flags = 0; if (style & DS_MODALFRAME || exstyle & WS_EX_DLGMODALFRAME) flags |= SEAMLESS_CREATE_MODAL; if (((style & WS_POPUP) || (exstyle & WS_EX_TOOLWINDOW)) && (style & WS_MINIMIZEBOX) == 0 && (style & WS_MAXIMIZEBOX) == 0) { flags |= SEAMLESS_CREATE_POPUP; if (! parent) parent = 0xffffffffL; if (GetClassName(hwnd, classname, 256)) { if ((strcmp(classname, TOOLTIPS_CLASS) == 0) || (strcmp(classname, "Net UI Tool Window") == 0) || (strcmp(classname, "OfficeTooltip") == 0) || (strcmp(classname, "DUIListViewHost") == 0)) { debug("%s", classname); flags |= SEAMLESS_CREATE_TOOLTIP; parent = 0xffffffffL; } else debug("Unknown classname: %s style: 0x%08lx exstyle: 0x%08lx", classname, style, exstyle); } } if (! (style & WS_SIZEBOX)) flags |= SEAMLESS_CREATE_FIXEDSIZE; // handle always on top if (exstyle & WS_EX_TOPMOST) flags |= SEAMLESS_CREATE_TOPMOST; vchannel_write("CREATE", "0x%08lx,0x%08lx,0x%08lx,0x%08x", (long) hwnd, (long) pid, (long) parent, flags); title = malloc(sizeof(unsigned short) * TITLE_SIZE); if (title != NULL) { GetWindowTextW(hwnd, title, TITLE_SIZE); vchannel_write("TITLE", "0x%08lx,%s,0x%08x", hwnd, vchannel_strfilter_unicode(title), 0); } if (window->title) { free(window->title); window->title = NULL; } window->title = title; icon = get_icon(hwnd, 1); if (icon) { update_icon(hwnd, icon, 1); DeleteObject(icon); } icon = get_icon(hwnd, 0); if (icon) { update_icon(hwnd, icon, 0); DeleteObject(icon); } if (style & WS_MAXIMIZE) window->state = 2; else if (style & WS_MINIMIZE) window->state = 1; else window->state = 0; update_position(hwnd); vchannel_write("STATE", "0x%08lx,0x%08x,0x%08x", hwnd, window->state, 0); if (window->focus) vchannel_write("FOCUS", "0x%08lx", hwnd); }
void SeamlessChannel_sendTitle(HWND hwnd, unsigned short *title, int flags) { vchannel_write("TITLE", "0x%08lx,%s,0x%08x", hwnd, vchannel_strfilter_unicode(title), flags); }