public static T RecursiveFindWindow <T>(IntPtr x, Func <WinComponent, T> f, Func <T, T, T> g) where T : class { var list = new List <T>(); if (x == IntPtr.Zero) { return(null); } var r = x; var stk = new Stack <T>(); var node = r; while (true) { var n = f(FromHandle(node)); stk.Push(n); var node_child = PInvoke.GetWindow(node, (uint)PInvoke.GetWindowFlags.GW_CHILD); if (node_child != IntPtr.Zero) { node = node_child; // walk down } else { IntPtr node_next; while (true) { if (node == r) { var res = stk.Pop(); return(res); } node_next = PInvoke.GetWindow(node, (uint)PInvoke.GetWindowFlags.GW_HWNDNEXT); if (node_next != IntPtr.Zero) { break; } var xn = stk.Pop(); var e = stk.Pop(); e = g(e, xn); stk.Push(e); node = PInvoke.GetParent(node); // walk up } var xn0 = stk.Pop(); var e1 = stk.Pop(); e1 = g(e1, xn0); stk.Push(e1); node = node_next; // PInvoke.GetWindow(node, (uint)PInvoke.GetWindowFlags.GW_HWNDNEXT); // ... and right } } }
public static void ScrollIntoView(IntPtr hWnd) { PInvoke.RECT rc, rpc; IntPtr hwndParent = PInvoke.GetParent(hWnd); if (hwndParent == IntPtr.Zero) { // no parent, cannot be scrolled return; } // is the parent window vertically or horizontally scrollable? var style = (PInvoke.WindowStyles)PInvoke.GetWindowLong(hwndParent, -16 /*GWL_STYLE*/); var vscroll = (style & PInvoke.WindowStyles.WS_VSCROLL) != 0; var hscroll = (style & PInvoke.WindowStyles.WS_HSCROLL) != 0; ComputeRectRelativeToParent(hWnd, hwndParent, out rpc, out rc); while (hscroll && rc.Left < rpc.Left) { Scroll(hwndParent, 0, 1); // move right ComputeRectRelativeToParent(hWnd, hwndParent, out rpc, out rc); } while (vscroll && rc.Top < rpc.Top) { Scroll(hwndParent, 1, 0); // move up ComputeRectRelativeToParent(hWnd, hwndParent, out rpc, out rc); } while (hscroll && rc.Right > rpc.Right) { Scroll(hwndParent, 0, -1); // move leftP ComputeRectRelativeToParent(hWnd, hwndParent, out rpc, out rc); } while (vscroll && rc.Bottom > rpc.Bottom) { Scroll(hwndParent, -1, 0); // move down ComputeRectRelativeToParent(hWnd, hwndParent, out rpc, out rc); } }