def BestWindowFromPoint(point): x, y = point foundWindow = WindowFromPoint(POINT(x, y)) hWnds = GetWindowChildsList(GetAncestor(foundWindow, GA_ROOT), True) if not hWnds: return foundWindow foundWindowArea = sys.maxint rect = RECT() clientPoint = POINT() for hWnd in hWnds: GetWindowRect(hWnd, byref(rect)) if ( x >= rect.left and x <= rect.right and y >= rect.top and y <= rect.bottom ): hdc = GetDC(hWnd) clientPoint.x, clientPoint.y = x, y ScreenToClient(hWnd, byref(clientPoint)) if PtVisible(hdc, clientPoint.x, clientPoint.y): area = (rect.right - rect.left) * (rect.bottom - rect.top) if area < foundWindowArea: foundWindow = hWnd foundWindowArea = area ReleaseDC(hWnd, hdc) return foundWindow
def HighlightWindow(hWnd): """ Draws an inverted rectangle around a window to inform the user about the currently selected window. """ UpdateWindow(hWnd) # Retrieve location of window on-screen. rect = RECT() GetWindowRect(hWnd, byref(rect)) # Get a device context that allows us to write anywhere within the window. hdc = GetWindowDC(hWnd) # Save the original device context attributes. SaveDC(hdc) # To guarantee that the frame will be visible, tell Windows to draw the # frame using the inverse screen color. SetROP2(hdc, R2_NOT) # Create a pen that is three times the width of a nonsizeable border. The # color will not be used to draw the frame, so its value could be # anything. PS_INSIDEFRAME tells windows that the entire frame should be # enclosed within the window. hpen = CreatePen(PS_INSIDEFRAME, _H_BORDERWIDTH, _H_BORDERCOLOUR) SelectObject(hdc, hpen) # We must select a NULL brush so that the contents of the window will not # be overwritten. SelectObject(hdc, GetStockObject(NULL_BRUSH)) # Draw the frame. Because the device context is relative to the window, # the top-left corner is (0, 0) and the lower right corner is (width of # window, height of window). Rectangle(hdc, 0, 0, rect.right - rect.left, rect.bottom - rect.top) # Restore the original attributes and release the device context. RestoreDC(hdc, -1) ReleaseDC(hWnd, hdc) # We can destroy the pen only AFTER we have restored the DC because the DC # must have valid objects selected into it at all times. DeleteObject(hpen)