2016-05-25 11 views
0

Ich benutze die Demo win32gui_taskbar.py & von pywin32 und erweitere es, um einen Screenshot des Fensters zu machen, wenn ein bestimmtes Fenster gerade das aktive/Vordergrundfenster ist. Die screen_shot Funktion wird aufgerufen, wenn der Benutzer den linken Maustaste auf das TaskleistensymbolIst es möglich, das Vordergrundfenster aus einer Taskleiste App in Windows mit Python pywin32 zu bekommen?

import win32api, win32service 
import win32gui, win32ui 
import win32con, winerror 
import sys, os 
import time 
from PIL import Image 

class MainWindow: 
    def __init__(self): 
     msg_TaskbarRestart = win32gui.RegisterWindowMessage("TaskbarCreated"); 
     message_map = { 
       msg_TaskbarRestart: self.OnRestart, 
       win32con.WM_DESTROY: self.OnDestroy, 
       win32con.WM_COMMAND: self.OnCommand, 
       win32con.WM_USER+20 : self.OnTaskbarNotify, 
     } 
     # Register the Window class. 
     wc = win32gui.WNDCLASS() 
     hinst = wc.hInstance = win32api.GetModuleHandle(None) 
     wc.lpszClassName = "PythonTaskbarDemo" 
     wc.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW; 
     wc.hCursor = win32api.LoadCursor(0, win32con.IDC_ARROW) 
     wc.hbrBackground = win32con.COLOR_WINDOW 
     wc.lpfnWndProc = message_map # could also specify a wndproc. 

     # Don't blow up if class already registered to make testing easier 
     try: 
      classAtom = win32gui.RegisterClass(wc) 
     except win32gui.error, err_info: 
      if err_info.winerror!=winerror.ERROR_CLASS_ALREADY_EXISTS: 
       raise 

     # Create the Window. 
     style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU 
     self.hwnd = win32gui.CreateWindow(wc.lpszClassName, "Taskbar Demo", style, \ 
       0, 0, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, \ 
       0, 0, hinst, None) 
     win32gui.UpdateWindow(self.hwnd) 
     self._DoCreateIcons() 
    def _DoCreateIcons(self): 
     # Try and find a custom icon 
     hinst = win32api.GetModuleHandle(None) 
     iconPathName = os.path.abspath(os.path.join(os.path.split(sys.executable)[0], "pyc.ico")) 
     if not os.path.isfile(iconPathName): 
      # Look in DLLs dir, a-la py 2.5 
      iconPathName = os.path.abspath(os.path.join(os.path.split(sys.executable)[0], "DLLs", 

"pyc.ico")) 
     if not os.path.isfile(iconPathName): 
      # Look in the source tree. 
      iconPathName = os.path.abspath(os.path.join(os.path.split(sys.executable)[0], "..\\PC\ 

\pyc.ico")) 
     if os.path.isfile(iconPathName): 
      icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE 
      hicon = win32gui.LoadImage(hinst, iconPathName, win32con.IMAGE_ICON, 0, 0, icon_flags) 
     else: 
      print "Can't find a Python icon file - using default" 
      hicon = win32gui.LoadIcon(0, win32con.IDI_APPLICATION) 

     flags = win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP 
     nid = (self.hwnd, 0, flags, win32con.WM_USER+20, hicon, "Python Demo") 
     try: 
      win32gui.Shell_NotifyIcon(win32gui.NIM_ADD, nid) 
     except win32gui.error: 
      # This is common when windows is starting, and this code is hit 
      # before the taskbar has been created. 
      print "Failed to add the taskbar icon - is explorer running?" 
      # but keep running anyway - when explorer starts, we get the 
      # TaskbarCreated message. 

    def OnRestart(self, hwnd, msg, wparam, lparam): 
    print "In onrestart" 
     self._DoCreateIcons() 

    def OnDestroy(self, hwnd, msg, wparam, lparam): 
     nid = (self.hwnd, 0) 
     win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, nid) 
     win32gui.PostQuitMessage(0) # Terminate the app. 

    def OnTaskbarNotify(self, hwnd, msg, wparam, lparam): 
     if lparam==win32con.WM_LBUTTONUP: 
      print "You clicked me."    
      print win32gui.GetWindowText(hwnd) 
      print ".." + win32gui.GetWindowText(win32gui.GetForegroundWindow()) 
      self.screen_shoot() 
     elif lparam==win32con.WM_LBUTTONDBLCLK: 
      print "You double-clicked me - goodbye" 
      win32gui.DestroyWindow(self.hwnd) 
     elif lparam==win32con.WM_RBUTTONUP: 
      print "You right clicked me."    
     return 1 

    def screen_shot(self): 
     wndh = win32gui.GetForegroundWindow() 
    if "Notepad" in win32gui.GetWindowText(wndh): 
      print "Inside if" 
      hwndDC = win32gui.GetWindowDC(wndh) 
      mfcDC = win32ui.CreateDCFromHandle(hwndDC) 
      saveDC = mfcDC.CreateCompatibleDC() 
      saveBitMap = win32ui.CreateBitmap() 
      left, top, right, bot = win32gui.GetWindowRect(wndh) 
      w = right - left 
      h = bot - top 
      saveBitMap.CreateCompatibleBitmap(mfcDC, w, h) 
      saveDC.SelectObject(saveBitMap) 
      saveDC.BitBlt((0, 0), (w, h), mfcDC, (0, 0), win32con.SRCCOPY) 
     bmpinfo = saveBitMap.GetInfo() 
      bmpstr = saveBitMap.GetBitmapBits(True) 
      im = Image.frombuffer('RGB', (bmpinfo['bmWidth'], 
              bmpinfo['bmHeight']), 
              bmpstr, 'raw', 'BGRX', 0, 1) 
     win32gui.DeleteObject(saveBitMap.GetHandle()) 
      saveDC.DeleteDC() 
      mfcDC.DeleteDC() 
      win32gui.ReleaseDC(wndh, hwndDC) 
      im.save("c:\screenshot" + str(int(time.time())) + ".png") 


    def OnCommand(self, hwnd, msg, wparam, lparam): 
     id = win32api.LOWORD(wparam) 
     if id == 1023: 
      import win32gui_dialog 
      win32gui_dialog.DemoModal() 
     elif id == 1024: 
      print "Hello" 
     elif id == 1025: 
      print "Goodbye" 
      win32gui.DestroyWindow(self.hwnd) 
     else: 
      print "Unknown command -", id 

def main(): 
    w=MainWindow() 
    win32gui.PumpMessages() 

if __name__=='__main__': 
    main() 

In dem obigen Code die Kontrolle nie in der, wenn die Bedingung in der screen_shot Funktion geht. Wie kann dieses Programm funktionieren? Die gleiche Bildschirmlogik funktioniert gut, wenn sie als normale Anwendung ausgeführt wird.

+0

So versuchte man das Ergebnis von 'win32gui.GetWindowText (wndh)' Druck hat, um zu überprüfen? Was war es? – SiHa

+0

Ich habe versucht, es zu drucken, gibt mir einen Wert (Handle), aber entspricht nicht der Notepad-Anwendung. Der getwindowtext gibt eine leere Zeichenfolge zurück – vsnag

+0

Richtig, also das ist der Kern des Problems. Sie können mehr Hilfe erhalten, wenn Sie versuchen, das Problem auf einen [mcve] zu reduzieren. – SiHa

Antwort

1

Eigene Frage beantworten ... Nur realisierte Taskleiste ist auch ein anderes "Fenster" & nach Klicken auf das Taskleistensymbol wird der Fokus auf das Taskfenster verschoben. Welches ist, was als das Vordergrundfenster gemeldet wird & erhalten Fenstertext für dieses Fenster ist leere Zeichenfolge. Ich habe dies verifiziert, indem ich mein Programm leicht modifiziert habe. In der Mainwindow-Klasse init-Funktion nach dem win32gui.Shell_NotifyIcon(win32gui.NIM_ADD, nid) Anrufsymbol init hinzugefügt, um den folgenden Code es

while True: 
    time.sleep(0.1) 
    wndh = win32gui.GetForegroundWindow() 
    print "windowndh" + str(wndh) 
    if "Notepad" in win32gui.GetWindowText(wndh): 
     # Take screen shot 
     print "Inside if" 
Verwandte Themen