private void renderPanel_Paint(object sender, PaintEventArgs e) { Graphics gfx = e.Graphics; // skip repainting if we're refreshing window state // because we might not be the only callers the check is here if (windowRefresh) { return; } Brush textColor; Pen outlineColor; float x; float y; float width; float height; Point cursor = renderPanel.PointToClient(Cursor.Position); // make the cursor panel space double distance = 0; double closestDistance = double.MaxValue; WindowInfo nearest = null; float scaleX = renderPanel.DisplayRectangle.Width / (float)(maxBounds.Width); float scaleY = renderPanel.DisplayRectangle.Height / (float)(maxBounds.Height); if (!mouseDown) { //calc closest foreach (WindowInfo window in windowData) { //ignore if minimised if (window.screenPosition.X == -32000 && window.screenPosition.Y == -32000) { continue; } //prevent hilarous bug if (window.hwnd == Handle) { continue; } x = (maxBounds.X + window.screenPosition.X + window.screenPosition.Width / 2) * scaleX; y = (maxBounds.Y + window.screenPosition.Y + window.screenPosition.Height / 2) * scaleY; distance = Distance(cursor, x, y); if (distance < closestDistance) { nearest = window; closestDistance = distance; } } if (closestDistance < maxDistanceToSelectClosest) { closest = nearest; // ya ya } else { closest = null; } } foreach (WindowInfo window in windowData) { window.UpdateLocation(); //ignore if minimised if (window.screenPosition.X == -32000 && window.screenPosition.Y == -32000) { continue; } //draw the closest last if (window == closest) { continue; } outlineColor = windowNormalOutlinePen; textColor = windowNormalNameBrush; if (window.hwnd == Handle) { outlineColor = Pens.Gray; textColor = Brushes.Gray; } x = (maxBounds.X + window.screenPosition.X) * scaleX; y = (maxBounds.Y + window.screenPosition.Y) * scaleY; width = window.screenPosition.Width * scaleX; height = window.screenPosition.Height * scaleY; gfx.DrawRectangle(outlineColor, x, y, width, height); //cross gfx.DrawLine(outlineColor, x + (width / 2) - 5, y + (height / 2) - 5, x + (width / 2) + 5, y + (height / 2) + 5); gfx.DrawLine(outlineColor, x + (width / 2) + 5, y + (height / 2) - 5, x + (width / 2) - 5, y + (height / 2) + 5); gfx.DrawString(window.windowName, smallWindowFont, textColor, x, y); distance = Distance(cursor, x + (window.screenPosition.Width / 2 * scaleX), y + (window.screenPosition.Height / 2 * scaleY)); gfx.DrawString(Math.Round(distance).ToString(), smallWindowFont, textColor, x, y + 15); } if (closest != null) { x = (maxBounds.X + closest.screenPosition.X) * scaleX; y = (maxBounds.Y + closest.screenPosition.Y) * scaleY; width = closest.screenPosition.Width * scaleX; height = closest.screenPosition.Height * scaleY; outlineColor = windowCloestOutlinePen; textColor = windowClosestNameBrush; if (mouseDown) { //cursor which is in panel space //but scale is based on the panel and max bounds not screen //ie we need to scale back up if (grabPointOffset == Point.Empty) { grabPointOffset.X = (int)(cursor.X - x); grabPointOffset.Y = (int)(cursor.Y - y); } int newPosX = (int)((cursor.X - grabPointOffset.X) / scaleX); int newPosY = (int)((cursor.Y - grabPointOffset.Y) / scaleY); //currently in max bound space but SetWindowPos uses screen space //since maxBounds is a superset of screenspace we just need to adjust it with an offset Win32Interop.SetWindowPos(closest.hwnd, 0, newPosX - maxBounds.X, newPosY - maxBounds.Y, 0, 0, Win32Interop.SWP_NOACTIVATE | Win32Interop.SWP_NOSIZE | Win32Interop.SWP_NOZORDER | Win32Interop.SWP_NOOWNERZORDER | Win32Interop.SWP_DEFERERASE); outlineColor = windowMovingOutlinePen; textColor = windowMovingNameBrush; } gfx.FillRectangle(new SolidBrush(Color.FromArgb(180, backgroundColor)), x, y, width, height); //cross gfx.DrawLine(outlineColor, x + (width / 2) - 5, y + (height / 2) - 5, x + (width / 2) + 5, y + (height / 2) + 5); gfx.DrawLine(outlineColor, x + (width / 2) + 5, y + (height / 2) - 5, x + (width / 2) - 5, y + (height / 2) + 5); gfx.DrawString(closest.windowName, smallWindowFont, textColor, x, y); gfx.DrawRectangle(outlineColor, x, y, width, height); distance = Distance(cursor, x + (closest.screenPosition.Width / 2 * scaleX), y + (closest.screenPosition.Height / 2 * scaleY)); gfx.DrawString(Math.Round(distance).ToString(), smallWindowFont, textColor, x, y + 15); Win32Interop.WINDOWINFO info = new Win32Interop.WINDOWINFO(); info.cbSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(info); Win32Interop.GetWindowInfo(closest.hwnd, ref info); gfx.DrawString("Styles: " + Win32Interop.WindowStyles(info.dwStyle), smallWindowFont, textColor, x, y + 30); gfx.DrawString("ExStyles: " + Win32Interop.WindowExStyles(info.dwExStyle), smallWindowFont, textColor, x, y + 45); gfx.DrawString("Atom: " + info.atomWindowType.ToString(), smallWindowFont, textColor, x, y + 60); bool visible = Win32Interop.IsWindowVisible(closest.hwnd); gfx.DrawString("Visible: " + visible.ToString(), smallWindowFont, textColor, x, y + 75); Win32Interop.WINDOWPLACEMENT placement = new Win32Interop.WINDOWPLACEMENT(); placement.length = System.Runtime.InteropServices.Marshal.SizeOf(placement); if (Win32Interop.GetWindowPlacement(closest.hwnd, ref placement)) { gfx.DrawString("State: " + Win32Interop.WindowState(placement.showCmd), smallWindowFont, textColor, x, y + 90); } gfx.DrawLine(windowCloestOutlinePen, cursor.X, cursor.Y, (maxBounds.X + closest.screenPosition.X + closest.screenPosition.Width / 2) * scaleX, (maxBounds.Y + closest.screenPosition.Y + closest.screenPosition.Height / 2) * scaleY); } //screens if (maxBounds.Size != desktopBounds.Size) { gfx.DrawRectangle(virtualScreenOutlinePen, (initialOffset.X) * scaleX, (initialOffset.Y) * scaleY, desktopBounds.Width * scaleX, desktopBounds.Height * scaleY); } foreach (Rectangle scr in screens) { gfx.DrawRectangle(Pens.Pink, (scr.X) * scaleX, (scr.Y) * scaleY, scr.Width * scaleX, scr.Height * scaleY); } }
private bool EnumWindowsProc(IntPtr hWnd, int lParam) { string windowText = ""; string className = ""; Rectangle rect; Win32Interop.WINDOWINFO info = new Win32Interop.WINDOWINFO(); info.cbSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(info); // if we already have it simply skip foreach (WindowInfo window in windowData) { if (window.hwnd == hWnd) { window.exists = true; return(true); } } StringBuilder sb = new StringBuilder(254); Win32Interop.GetWindowText(hWnd, sb, 255); if (sb.Length > 0) { windowText = sb.ToString(); } sb.Clear(); if (windowText.Length > 0 && Win32Interop.GetWindowInfo(hWnd, ref info)) { // "Real" windows if (HasOpt(info.dwStyle, Win32Interop.WS_VISIBLE) && HasOpt(info.dwStyle, Win32Interop.WS_THICKFRAME) && HasOpt(info.dwStyle, Win32Interop.WS_SYSMENU) && HasOpt(info.dwStyle, Win32Interop.WS_OVERLAPPED) && HasOpt(info.dwStyle, Win32Interop.WS_BORDER)) { WindowInfo window = new WindowInfo(); window.hwnd = hWnd; window.windowName = windowText; window.SetRect(info.rcWindow); newWindows.Add(window); } // "Popup" dialogs, like find, open etc. if (HasOpt(info.dwStyle, Win32Interop.WS_POPUP) && HasOpt(info.dwStyle, Win32Interop.WS_SYSMENU) && HasOpt(info.dwStyle, Win32Interop.WS_OVERLAPPED) && HasOpt(info.dwStyle, Win32Interop.WS_BORDER) && !HasOpt(info.dwStyle, Win32Interop.WS_THICKFRAME) && // removes hidden weird things info.rcWindow.X != 0 && info.rcWindow.Y != 0) { WindowInfo window = new WindowInfo(); window.hwnd = hWnd; window.windowName = windowText; window.SetRect(info.rcWindow); newWindows.Add(window); } } return(true); }