I have written a wx application to draw a rectangle around a section of the screen and subsequently OCR that section an put the resulting text on the clipboard. The section is defined by clicking the mouse down at the start of the desired rectangle and releasing it once the mouse has been moved to the opposite corner. This works. But, for example, if I do this over the developer studio’s window, I find I am selecting text in the developer studio as well as drawing the rectangle. So what is CaptureMouse doing? Note that I can draw the rectangle and grab the section without using CaptureMouse. I only use it because I thought it would stop mouse events going to other windows. But it doesn’t seem to do so. Here’s the code:
import wx
from enum import Enum, auto
class State(Enum):
    WAITING = auto()
    INITIAL = auto()
    MOUSE_DOWN = auto()
    CLOSE = auto()
class ScreenGrabber(wx.Frame):
    def __init__(self):
        super().__init__(None)
        self.state = State.WAITING
        self.origin = wx.Point()
        self.current = wx.Point()
        self.Bind(wx.EVT_MOUSE_CAPTURE_CHANGED,self.OnMouseCaptureChangedEvent)
        self.Bind(wx.EVT_MOUSE_CAPTURE_LOST,self.OnMouseCaptureLostEvent)
        self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvent)
        self.wantCapture = False
        self.log = []
    def Start(self):
        self.state = State.INITIAL
    def Stop(self):
        self.state = State.CLOSE
    def Log(self, text):
        self.log.append(text)
    def OnTimer(self):
        if self.wantCapture and not self.HasCapture():
            self.Log('CaptureMouse re-called')
            self.CaptureMouse()
        mouseState : wx.MouseState = wx.GetMouseState()
        if self.state == State.WAITING:
            wx.CallLater(500, self.OnTimer)
        elif self.state == State.INITIAL:
            if mouseState.LeftIsDown():
                self.Log('CaptureMouse called')
                self.CaptureMouse()
                self.wantCapture = True
                self.origin = self.current = mouseState.GetPosition()
                self.state = State.MOUSE_DOWN
            wx.CallLater(20, self.OnTimer)
        elif self.state == State.MOUSE_DOWN:
            self.current = mouseState.GetPosition()
            self.DrawSection()
            if mouseState.LeftIsDown():
                wx.CallLater(20, self.OnTimer)
            else:
                self.GrabScreenSection()
                self.state = State.WAITING
                self.origin = wx.Point()
                self.current = wx.Point()
                self.ReleaseMouse()
                self.Log('ReleaseMouse called')
                self.wantCapture = False
                wx.CallLater(20, self.OnTimer)
        elif self.state == State.CLOSE:
            self.Close()
        else:
            wx.CallLater(20, self.OnTimer)
    def OnMouseCaptureChangedEvent(self, event):
        self.Log('OnMouseCaptureChangedEvent occurred')
        pass
    def OnMouseCaptureLostEvent(self, event):
        self.ReleaseMouse()
        self.Log('OnMouseCaptureLostEvent called: mouse released')
        pass
    def OnMouseEvent(self, event):
        if self.wantCapture:
            self.Log('OnMouseEvent called')
        pass
    def DrawSection(self):
        dc = wx.ScreenDC()
        dc.SetBrush(wx.Brush('white', wx.BRUSHSTYLE_TRANSPARENT))
        dc.StartDrawingOnTop()
        dc.DrawRectangle(x=self.origin[0], y=self.origin[1], width=abs(self.origin[0] - self.current[0]),
                         height=abs(self.origin[1] - self.current[1]))
        dc.EndDrawingOnTop()
        pass
    def  GrabScreenSection(self):
        print('Screen section grabbed')
        pass
if __name__ == "__main__":
    app = wx.App(None)
    grabber = ScreenGrabber()
    grabber.Show()
    grabber.Start()
    grabber.OnTimer()
    app.MainLoop()
    pass
type or paste code here