2015-01-11 5 views
1

pywin32를 사용하여 게임의 스크린 그랩을 & 파이 게임을 사용하여 표시하는 프로그램이 있습니다. 간헐적 인 충돌이나 매달림이 발생합니다. 프로그램이 평소에 "응답하지 않는"오류를 표시합니다. python.exe가 프로그램 실행 중 약 5-10 초 후에 응답하지 않는다고 말합니다.파이 게임에서 파이 게임이 pywin32 함수로 응답하지 않는 경우 "python.exe가 응답하지 않습니다"

나는 다음과 같은 기능을 좁혀 :

def screengrab(self): 
    hwnd = self.aoe_hwnd 
    left, top, right, bot = win32gui.GetClientRect(hwnd) 
    w = right - left 
    h = bot - top 
    #returns the device context (DC) for the entire window, including title bar, menus, and scroll bars. 
    hwndDC = win32gui.GetWindowDC(hwnd) 
    #Creates a DC object from an integer handle. 
    mfcDC = win32ui.CreateDCFromHandle(hwndDC) 
    #Creates a memory device context (DC) compatible with the specified device. 
    saveDC = mfcDC.CreateCompatibleDC() 
    saveDC.SetWindowOrg((w - self.map_w,h - self.map_h)) 
    #Creates bitmap Object 
    saveBitMap = win32ui.CreateBitmap() 
    #Creates a bitmap object from a HBITMAP. 
    saveBitMap.CreateCompatibleBitmap(mfcDC, self.map_w, self.map_h) 

    saveDC.SelectObject(saveBitMap) 

    # Change the line below depending on whether you want the whole window 
    # or just the client area. 
    #result = windll.user32.PrintWindow(hwnd, saveDC.GetSafeHdc(), 1) 
    result = windll.user32.PrintWindow(hwnd, saveDC.GetSafeHdc(), 1) 
    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(hwnd, hwndDC) 

    if result == 1: 
     tmp = cStringIO.StringIO() 
     im = im.resize(self.window_size) 
     im.save(tmp, "bmp") 
     tmp.seek(0) 
     return tmp 

내가 Win32에서의 API에 새로운 그리고 난 정말 그런 걸하는 원인이 될 수있는 것을 완전히 확실하지 않다. 이상한 점은 프로그램의 메인 루프 (screengrab()도 호출됩니다)에있는 print 문이 프로그램이 응답하지 않거나 응답하지 않는 동안 계속 실행된다는 것입니다. 요점에

전체 프로그램은 : https://gist.github.com/Andygmb/f8ae761e689788136fc0

답변

1

우리는 IRC 이전에 이야기했다.

귀하의 문제는 windll.user32.PrintWindow의 사용과 관련이 있다고 생각합니다. Microsoft documentation for this function 보면,이 라인은 내 관심 잡은 :.

"이것은 차단 또는 동기 기능 참고 반환하지 않을 수 있습니다을 바로이 함수가 리턴 요인 등 네트워크 상태로 실행 시간에 따라 얼마나 빨리, 인쇄 서버 구성 및 프린터 드라이버 구현 - 응용 프로그램을 작성할 때 을 예측할 수없는 경우 이 사용자 인터페이스와의 상호 작용을 관리하는 스레드에서이 함수를 호출하면 응용 프로그램이 응답하지 않을 수 있습니다. "

아마도 이와 관련이 있습니다.

While running 루프의 하단에 time.sleep (1)을 추가하면 시스템에서 충돌을 방지하는 것처럼 보입니다. 따라서 작동하는 경우 1 초 지연이 허용됩니다. 선택권.

정말로 원하는 것은 PrintWindow를 백그라운드에서 호출하고 PrintWindow가 반환 할 때 화면을 업데이트 할 수 있지만 파일 읽기/쓰기 잠금 및/또는 스레딩을 통해 바보 같은 사업을해야 할 수도 있습니다. 따라서 이것이 무엇을위한 것이며 무엇이 더 중요한지에 달려 있습니다.

+0

이게 문제가 된 것 같습니다. Printwindow 기능을 주 루프와는 별도의 스레드에 넣었습니다.이 루프는 모든 충돌 문제를 중지 시켰습니다. 정말 고마워요. – AndyB