I'm here to ask for help on a recent problem I encountered with my program....
I am getting this error when I try to use BitBlt and CreateCompatibleBitmap: win32ui.error: BitBlt failed & CreateCompatibleBitmap, It's worth mentioning that this happens only when my program is calling these functions from different threads, probably at the same time.
Perhaps the methods of win32gui are not multithreaded compatible?
I am currently wrapping the calls in a try-except block to prevent the program from crashing, but apparently the threads are competing to use the methods BitBlt y CreateCompatibleBitmap
I thought about ignoring the error messages and letting the threads compete this race, but it really scares me that this could result in a poor program becoming slow or breaking something by avoiding millions of these errors.
I am calling BitBlt and CreateCompatibleBitmap constantly every 50 to 100 milliseconds.
Here's an example of the function I'm calling from multiple threads:
When I do it this way I get win32gui.error CreateCompatibleBitmap failed
def get_capture_icons():
hwndDC_icons = win32gui.GetWindowDC(game_client_hwnd)
mfcDC_icons = win32ui.CreateDCFromHandle(hwndDC_icons)
saveDC_icons = mfcDC_icons.CreateCompatibleDC()
saveBitMap_icons = win32ui.CreateBitmap()
saveBitMap_icons.CreateCompatibleBitmap(mfcDC_icons, 106, 11)
saveDC_icons.SelectObject(saveBitMap_icons)
saveDC_icons.BitBlt((-16, -39), (1366, 768), mfcDC_icons, (1191, 256), win32con.SRCCOPY)
img = Image.frombuffer('RGB', (106, 11), saveBitMap_icons.GetBitmapBits(True), 'raw', 'BGRX', 0, 1)
mfcDC_icons.DeleteDC()
saveDC_icons.DeleteDC()
win32gui.ReleaseDC(game_client_hwnd, hwndDC_icons)
win32gui.DeleteObject(saveBitMap_icons.GetHandle())
return img
But when I save the objects in global variables I get win32gui.error BitBlt failed
def load_capturer_icons():
global hwndDC_icons, mfcDC_icons, saveDC_icons, saveBitMap_icons
hwndDC_icons = win32gui.GetWindowDC(game_client_hwnd)
mfcDC_icons = win32ui.CreateDCFromHandle(hwndDC_icons)
saveDC_icons = mfcDC_icons.CreateCompatibleDC()
saveBitMap_icons = win32ui.CreateBitmap()
saveBitMap_icons.CreateCompatibleBitmap(mfcDC_icons, 106, 11)
saveDC_icons.SelectObject(saveBitMap_icons)
def get_capture_icons():
saveDC_icons.BitBlt((-16, -39), (1366, 768), mfcDC_icons, (1191, 256), win32con.SRCCOPY)
return Image.frombuffer('RGB', (106, 11), saveBitMap_icons.GetBitmapBits(True), 'raw', 'BGRX', 0, 1)
Extra Info:
I have 2 threads processing scripts
scripting.Thread(target=scripting.Thread.check_queue_scripts, name="Ekko").start()
scripting.Thread(target=scripting.Thread.check_queue_scripts, name="Zoe").start()
example of two scripts that make a call to get_capture_icons and generate the error explained at the beginning of this page
def callback(player, sleep):
get_capture_icons()#call example
script = Script("callback-1", 100)
script.add_callback(callback)
script.register(__name__)
script = Script("callback-2", 100)
script.add_callback(callback)
script.register(__name__)
If I delete one of these scripts so that only 1 remains, then the error no longer appears