I have a WinApi function with a CancelEvent
parameter but I don't know what I have to pass there?
HRESULT WINAPI DismUnmountImage(
_In_ PCWSTR MountPath,
_In_ DWORD Flags,
_In_opt_ HANDLE CancelEvent,
_In_opt_ DISM_PROGRESS_CALLBACK Progress,
_In_opt_ PVOID UserData
);
https://msdn.microsoft.com/en-us/library/windows/desktop/hh824802(v=vs.85).aspx
I'm working with python 3.6 on Windows 10. The function is working properly, the progress dialog too. I used QProgressDialog widget to display progress state, I only have to implement the CancelEvent. The reDefinition:
from ctypes import *
import win32con, win32api
def UnmountImage(self, MountPath, Flags=DISM_DISCARD_IMAGE, CancelEvent=None, Progress=None, UserData=None):
self.hDism.DismUnmountImage.restype = HRESULT
try:
return self.hDism.DismUnmountImage(MountPath, Flags, CancelEvent, Progress, UserData)
except OSError as e:
print("DismUnmountImage failed: %s\nErrorCode: %s" % (e.strerror, e))
return self.GetLastErrorMessage()
And the pyqt part:
def canceled(self):
print("canceled")
@pyqtSlot(QVariant)
def unmount_image(self, json_data):
dism_progress_callback = dism_manager.DISM_PROGRESS_CALLBACK(self.dism_progress_callback)
data = json.loads(json_data)
self.progdialog = QProgressDialog("", "Cancel", 0, 100, None)
self.progdialog.setWindowTitle("Unmounting Image...")
self.progdialog.setModal(True)
self.progdialog.canceled.connect(self.canceled)
self.progdialog.show()
for image in data:
dism_manager.UnmountImage(MountPath=image['MountPath'], Progress=dism_progress_callback, CancelEvent=self.progdialog.winId())
I tried to pass the handle of the qtWindow but I get an error message ..can't convert parameter 3..
. What does the function expect? A windows handle? I really have no idea and I'm not familar with C++.
Btw: The QProgressdialog is a window with a QProgress and a QButton. When I click on the Cancel button, my def canceled(self):
method is emitted and the window will be closed for a second and then the progress continues.
EDIT:
After zett42 suggestions I came up with this:
DISM_CANCEl_EVENT = CreateEvent(None, False, False, None)
And:
def canceled(self):
print("canceled")
SetEvent(dism_manager.DISM_CANCEl_EVENT)
...
for image in data:
dism_manager.UnmountImage(MountPath=image['MountPath'], Progress=dism_progress_callback, CancelEvent=dism_manager.DISM_CANCEl_EVENT)
I get this error message:
ctypes.ArgumentError: argument 3: <class 'TypeError'>: Don't know how to convert parameter 3
Do you have any idea, what I am missing?
EDIT2:
I got it:
def canceled(self):
self.progdialog.cancel()
SetEvent(self.cancel_event)
self.cancel_event = dism_manager.DISM_CANCEl_EVENT.Detach()
for image in data:
dism_manager.UnmountImage(MountPath=image['MountPath'], Progress=dism_progress_callback, CancelEvent=self.cancel_event)
The only problem I have: The cancelevent needs round about 2 seconds to be performed so that meanwhile the dism_progress_callback forces the window to popup again, although i called self.progdialog.cancel()
which closes the window...hope you can follow me. Do you have any suggestions how i can control this?
Solved:
I got a final solution: I called self.progdialog.canceled.disconnect()
before self.progdialog.canceled.connect(self.dism_cancel_event)
to overwrite the canceled() signal and prevent the call of cancel().