opencv_tutorials icon indicating copy to clipboard operation
opencv_tutorials copied to clipboard

getdc()

Open shanelecuyer opened this issue 4 years ago • 3 comments

win32gui.GetDC() function retrieves a handle to a display device context for the client area of a specified window or for the entire screen. You can use the returned handle in subsequent GDI functions to draw in the device context.

This returns an area without toolbar etc. Should simplify the code some.

Im also working on iterating through a list of windows with the same class or name and checking their pid against the pid of a subprocess i started. This will let me find which game window of the same title to manipulate

I love these videos im learning a lot!

shanelecuyer avatar Jul 17 '20 15:07 shanelecuyer

Thanks for the info Shane, I'll definitely check that out! Glad these videos have been helpful for you. And feel free to share that game window finder code when you're happy with it. I'm sure it could help somebody else out, too.

learncodebygaming avatar Jul 18 '20 22:07 learncodebygaming

well im not quite happy with it yet... im still very new and the code is a mess. storing variables in a Dict is not ideal. had to make many workarounds due to that, i will learn to store them as objects and create a thread class also... but for now, this works (i can easily run 30+ oldschool runescape clients with a little mitm server intercepting the jav_config.ws http request to avoid advertisement errors... anyway, if you want to help me make this better... PLEASE DO

    def getScreen (self, account):
        #loop_time = time()
        t = threading.currentThread()
        while getattr(t, "loop", True):
            if account in procDict and procDict[account]['hwnd']:
                hwnd = procDict[account]['hwnd'][0]
                screenshot = wincap.get_screenshot(hwnd)
                if screenshot is not None:
                    cv.imshow(f'{account} screenshot', screenshot)
                    cv.waitKey(1)
            #print('FPS {}'.format(1 / (time() - loop_time)))
            #loop_time = time()
            sleep(.1)
            
    def cvLoop (self):
        global cvLoop
        while(cvLoop):
            windowVal = "Not Found"
            for account in list(procDict):
                if account in procDict and procDict[account]['dur'] and procDict[account]['proc']:
                    pid = procDict[account]['proc'].pid
                    hwnd = findWin(pid)
                    procDict[account]['hwnd'] = hwnd
                    if hwnd:
                        windowVal = hwnd
                        if not win32gui.IsWindow(hwnd[0]) or not win32gui.IsWindowVisible(hwnd[0]):
                            print('fucked up')
                            procDict[account]['hwnd'] = None
                        else:
                            if not account in threadNames():
                                t = Thread(target=self.getScreen, args=(account, ), daemon=True)
                                t.name = account
                                t.start()
                    else:
                        for killThread in threading.enumerate():
                            if killThread.name == account:
                                killThread.loop = False
                        cv.destroyWindow(f'{account} screenshot')
                for row in self.tv.treeview.get_children():
                    if self.tv.treeview.item(row,'text') == account:
                        self.tv.treeview.set(row, 'hwnd', windowVal)
            sleep(.5)

shanelecuyer avatar Jul 19 '20 00:07 shanelecuyer

def findWin (pid):
    def callback (hwnd, hwnds):
        if win32gui.IsWindowVisible (hwnd) and win32gui.IsWindowEnabled (hwnd):
            _, found_pid = win32process.GetWindowThreadProcessId (hwnd)
            if found_pid == pid:
                hwnds.append(hwnd)
                return True

    hwnds = []
    win32gui.EnumWindows (callback, hwnds)
    return hwnds

shanelecuyer avatar Jul 19 '20 01:07 shanelecuyer