static void update_position(HWND hwnd) { RECT rect, blocked; HWND blocked_hwnd; unsigned int serial; WaitForSingleObject(g_mutex, INFINITE); blocked_hwnd = long_to_hwnd(g_shdata->block_move_hwnd); serial = g_shdata->block_move_serial; memcpy(&blocked, &g_shdata->block_move, sizeof(RECT)); ReleaseMutex(g_mutex); vchannel_block(); if (!GetWindowRect(hwnd, &rect)) { debug("GetWindowRect failed!"); goto end; } if ((hwnd == blocked_hwnd) && (rect.left == blocked.left) && (rect.top == blocked.top) && (rect.right == blocked.right) && (rect.bottom == blocked.bottom)) goto end; 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); end: vchannel_unblock(); }
static void update_position(HWND hwnd) { RECT rect, blocked; HWND blocked_hwnd; unsigned int serial; WaitForSingleObject(g_mutex, INFINITE); blocked_hwnd = g_block_move_hwnd; serial = g_block_move_serial; memcpy(&blocked, &g_block_move, sizeof(RECT)); ReleaseMutex(g_mutex); vchannel_block(); if (IsZoomed(hwnd) || IsIconic(hwnd)) { goto end; } else { if (!GetWindowRect(hwnd, &rect)) { debug("GetWindowRect failed!\n"); goto end; } } if ((hwnd == blocked_hwnd) && (rect.left == blocked.left) && (rect.top == blocked.top) && (rect.right == blocked.right) && (rect.bottom == blocked.bottom)) goto end; if ((! IsZoomed(hwnd)) && (rect.left < 0 || rect.top < 0 || rect.bottom > g_screen_height || rect.right > g_screen_width)) { int w = rect.right - rect.left; int h = rect.bottom - rect.top; int x = ((g_screen_width - rect.left) < w) ? (g_screen_width - w) : rect.left; int y = ((g_screen_height - rect.top) < h) ? (g_screen_height - h) : rect.top; x = (rect.left < 0) ? 0 : x; y = (rect.top < 0) ? 0 : y; SetWindowPos(hwnd, NULL, x, y, w, h, SWP_NOACTIVATE | SWP_NOZORDER); goto end; } 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); end: vchannel_unblock(); }
static void do_sync(void) { vchannel_block(); vchannel_write("SYNCBEGIN", "0x0"); EnumWindows(enum_cb, 0); vchannel_write("SYNCEND", "0x0"); vchannel_unblock(); }
EXTERN void SafeSetState(unsigned int serial, HWND hwnd, int state) { LONG style; int curstate; if (!g_wm_seamless_focus) return; vchannel_block(); style = GetWindowLong(hwnd, GWL_STYLE); if (style & WS_MAXIMIZE) curstate = 2; else if (style & WS_MINIMIZE) curstate = 1; else curstate = 0; if (state == curstate) { vchannel_write("ACK", "%u", serial); vchannel_unblock(); return; } WaitForSingleObject(g_mutex, INFINITE); g_shdata->blocked_state_hwnd = hwnd_to_long(hwnd); g_shdata->blocked_state_serial = serial; g_shdata->blocked_state = state; ReleaseMutex(g_mutex); vchannel_unblock(); if (state == 0) ShowWindow(hwnd, SW_RESTORE); else if (state == 1) ShowWindow(hwnd, SW_MINIMIZE); else if (state == 2) ShowWindow(hwnd, SW_MAXIMIZE); else debug("Invalid state %d sent.", state); WaitForSingleObject(g_mutex, INFINITE); g_shdata->blocked_state_hwnd = 0; g_shdata->blocked_state = -1; ReleaseMutex(g_mutex); }
static void update_zorder(HWND hwnd) { HWND behind; HWND block_hwnd, block_behind; unsigned int serial; WaitForSingleObject(g_mutex, INFINITE); serial = g_blocked_zchange_serial; block_hwnd = g_blocked_zchange[0]; block_behind = g_blocked_zchange[1]; ReleaseMutex(g_mutex); vchannel_block(); behind = GetNextWindow(hwnd, GW_HWNDPREV); while (behind) { LONG style; style = GetWindowLong(behind, GWL_STYLE); if ((!(style & WS_CHILD) || (style & WS_POPUP)) && (style & WS_VISIBLE)) break; behind = GetNextWindow(behind, GW_HWNDPREV); } if ((hwnd == block_hwnd) && (behind == block_behind)) vchannel_write("ACK", "%u", serial); else { int flags = 0; LONG exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); // handle always on top if (exstyle & WS_EX_TOPMOST) flags |= SEAMLESS_CREATE_TOPMOST; vchannel_write("ZCHANGE", "0x%08lx,0x%08lx,0x%08x", hwnd, behind, flags); } vchannel_unblock(); }
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); }