Homes32 Posted March 17, 2011 Share Posted March 17, 2011 (edited) Hi all,I am developing a gui app that captures a wim image using a DllCall to wimgapi.dll; the capture process uses a callback to notify my app on the progress of the capture and update the progressbar as appropriate.my issue arises during the capture if the you try to interact with the GUI (ie. click on the window/a control/etc) the window will freeze and not update any controls, as well as trigger windows to flag the window as "(Not Responding)". and will cease to update the gui until the end of the capture process. I have tried putting GUIGetMsg() inside my callback to force the window to be polled for events, but it does not help.does anybody have any suggestions or explanations on how to correct this issue?my callback fuction looks like this:expandcollapse popupFunc CallBack($msgId, $param1, $param2, $<img src='http://www.autoitscript.com/forum/public/style_emoticons/<#EMO_DIR#>/cool.png' class='bbc_emoticon' alt='B)' /> Switch $msgId Case $WIM_MSG_PROGRESS ; get progress % and time remaining $Percent = $param1 If $param2 = 0 Then $rTime = "" Else $rTime = StringFormat('Remaining: %i sec.', $param2 / 1000) EndIf Case $WIM_MSG_PROCESS ; get the file name being processed $Str = DllStructCreate('ushort[1024]', $param1) $filePath = '' $i = 1 While 1 $Tmp = DllStructGetData($Str, 1, $i) If $Tmp = 0 Then ExitLoop $filePath &= ChrW($Tmp) $i += 1 WEnd Case $WIM_MSG_STEPIT ; Total files processed so far $FilesProcessed += 1 Case $WIM_MSG_SETRANGE ; Total number of files to process If $param2 = 0 Then $FilesTotal = '' Else $FilesTotal = $param2 EndIf EndSwitch ;ProgressSet($Percent, StringFormat('%3i%% completed. %s\n\n %s', $Percent, $rTime, _StringRightStr($filePath, '\', -1)), 'Capture ' & _StringRightStr($sWimFile, '\', -1)) ;GUICtrlSetData($LBL_Processing,"Processing: " & _StringRightStr($filePath, '\', -1)) ControlSetText($FRM_Progress, "", $LBL_Processing,"Processing: " & _StringRightStr($filePath, '\', -1)) WinSetTitle($FRM_Progress, "", $ProgramName & " - " & $Percent & "% complete") GUICtrlSetData($PB_Progress, $Percent) ControlSetText($FRM_Progress, "", $LBL_TRemain, $rTime) ControlSetText($FRM_Progress, "", $LBL_Files, "Files: " & $FilesProcessed & "/" & $FilesTotal) Return $WIM_MSG_SUCCESS EndFunc ;==>CallBackthanks,Homes32 Edited March 17, 2011 by Homes32 Link to comment Share on other sites More sharing options...
trancexx Posted March 17, 2011 Share Posted March 17, 2011 (edited) You can't correct it. It's the limitation of the current callback implementation. You can minimize the negative effect by smarter coding. Unfortunately, the code you posted is unreadable to help you further. edit: ok, you corrected the code tags in the mean time. Will see now. ... except for that WIM_MSG_PROCESS that loops unnecessary, all looks fine. Maybe it wold be better to call lstrlenW and make wchar buffer then and do just one reading. Also should you process lparam ($B ) for this message? Edited March 17, 2011 by trancexx ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
Homes32 Posted March 18, 2011 Author Share Posted March 18, 2011 You can't correct it. It's the limitation of the current callback implementation. I was afraid it was something like that.quite annoying as it pretty much make the GUI useless when even switching to another window to do something while the capture is running will freeze the progress GUI. people tend to develop an annoying habit of immediately trying to kill off any process they think is hung more than 30 sec. much less 2-4 minutes to capture a .wim ... except for that WIM_MSG_PROCESS that loops unnecessary, all looks fine. Maybe it wold be better to call lstrlenW and make wchar buffer then and do just one reading. Also should you process lparam ($B ) for this message?I'll play around with this idea and see if I can't make it work. I'm pretty new to the whole struct business...thanks for the reply.regards,Homes32 Link to comment Share on other sites More sharing options...
ProgAndy Posted March 18, 2011 Share Posted March 18, 2011 (edited) Maybe you should try this: remove all ControlSetText from the loop, set the data to global variables and then use AdlibRegsiter with an interval of 500ms to update the labels or so. Make only the absolutely necessary things in the callback. Global $giWIM_PERCENT, $giWIM_TIME, $gsWIM_FILE, $giWIM_FILES_PROCESSED, $giWIM_FILES_TOTAL Func CallBack($msgId, $param1, $param2, $B) Switch $msgId Case $WIM_MSG_PROGRESS ; get progress % and time remaining $giWIM_PERCENT = $param1 $giWIM_TIME = $param2 Case $WIM_MSG_PROCESS ; get the file name being processed Local $aLen = DllCall("kernel32.dll", "int", "lstrlenW", "ptr", $param1) If Not @error Then Local $tData = DllStructCreate("wchar[" & $aLen[0] & "]") $gsWIM_FILE = DllStructGetData($tData, 1) EndIf Case $WIM_MSG_STEPIT ; Total files processed so far $giWIM_FILES_PROGRESSED += 1 Case $WIM_MSG_SETRANGE ; Total number of files to process $giWIM_FILES_TOTAL = $param2 EndSwitch Return $WIM_MSG_SUCCESS EndFunc ;==>CallBack Func _UpdateLabels() ; Function for adlib ; Update labels here EndFunc Or write a DLL that implements the callback. PS: How does that DLLCall to wimimg.dll work? If it blocks the script until it is finished you can ignore the content of this post. Then you will have to live with the current behaviour or create a DLL which starts a thread and then in this thread starts the capture. Edited March 18, 2011 by ProgAndy *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes Link to comment Share on other sites More sharing options...
Homes32 Posted March 20, 2011 Author Share Posted March 20, 2011 Maybe you should try this: remove all ControlSetText from the loop, set the data to global variables and then use AdlibRegsiter with an interval of 500ms to update the labels or so. Make only the absolutely necessary things in the callback. Global $giWIM_PERCENT, $giWIM_TIME, $gsWIM_FILE, $giWIM_FILES_PROCESSED, $giWIM_FILES_TOTAL Func CallBack($msgId, $param1, $param2, $B) Switch $msgId Case $WIM_MSG_PROGRESS ; get progress % and time remaining $giWIM_PERCENT = $param1 $giWIM_TIME = $param2 Case $WIM_MSG_PROCESS ; get the file name being processed Local $aLen = DllCall("kernel32.dll", "int", "lstrlenW", "ptr", $param1) If Not @error Then Local $tData = DllStructCreate("wchar[" & $aLen[0] & "]") $gsWIM_FILE = DllStructGetData($tData, 1) EndIf Case $WIM_MSG_STEPIT ; Total files processed so far $giWIM_FILES_PROGRESSED += 1 Case $WIM_MSG_SETRANGE ; Total number of files to process $giWIM_FILES_TOTAL = $param2 EndSwitch Return $WIM_MSG_SUCCESS EndFunc ;==>CallBack Func _UpdateLabels() ; Function for adlib ; Update labels here EndFunc Or write a DLL that implements the callback. PS: How does that DLLCall to wimimg.dll work? If it blocks the script until it is finished you can ignore the content of this post. Then you will have to live with the current behaviour or create a DLL which starts a thread and then in this thread starts the capture. yeah. WIMCaptureImge is a blocking function and uses the callback to relay information. I tried using Case $WIM_MSG_PROCESS ; get the file name being processed Local $aLen = DllCall("kernel32.dll", "int", "lstrlenW", "ptr", $param1) If Not @error Then Local $tData = DllStructCreate("wchar[" & $aLen[0] & "]") $gsWIM_FILE = DllStructGetData($tData, 1) EndIfbut $aLen returns NULL so I can't get the filename. m$ sample implantation is: expandcollapse popup// //Callback function: // DWORD WINAPI SampleCaptureCallback( IN DWORD msgId, //message ID IN WPARAM param1, //usually file name INOUT LPARAM param2, //usually error code IN void *unused ) { //First parameter: full file path for if WIM_MSG_PROCESS, message string for others TCHAR *message = (TCHAR *) param1; TCHAR *filePath = (TCHAR *) param1; DWORD percent = (DWORD) param1; //Second parameter: message back to caller if WIM_MSG_PROCESS, error code for others DWORD errorCode = param2; DWORD *msg_back = (DWORD *) param2; switch ( msgId ) { case WIM_MSG_PROCESS: //This message is sent for each file, capturing to see if callee intends to //capture the file or not. // //If you do not intend to capture this file, then assign FALSE in msg_back //and still return WIM_MSG_SUCCESS. //Default is TRUE. // //In this example, print out the file name being applied // _tprintf(TEXT("FilePath: %s\n"), filePath); break; ... Link to comment Share on other sites More sharing options...
martin Posted March 20, 2011 Share Posted March 20, 2011 (edited) Couldn't you have another script which calls the dll and run that script when you want the capture. It can have a small window which is never shown. In the callback of the extra script it can send a message to the main script with the update information. Then the main script won't freeze and it can still show the progress. Edited March 20, 2011 by martin Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
Homes32 Posted March 21, 2011 Author Share Posted March 21, 2011 Couldn't you have another script which calls the dll and run that script when you want the capture. It can have a small window which is never shown. In the callback of the extra script it can send a message to the main script with the update information. Then the main script won't freeze and it can still show the progress.thats an interesting thought...I'll have to play around with the idea. Link to comment Share on other sites More sharing options...
trancexx Posted March 21, 2011 Share Posted March 21, 2011 thats an interesting thought...I'll have to play around with the idea.When you do, you'll see that it's not. ProgAndy's is. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
martin Posted March 22, 2011 Share Posted March 22, 2011 When you do, you'll see that it's not. ProgAndy's is.I don't doubt you're right trancexx but I expected that if there is a call back then the callback function could send a message to another script before it returned. Why couldn't that be done? Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
trancexx Posted March 22, 2011 Share Posted March 22, 2011 I don't doubt you're right trancexx but I expected that if there is a call back then the callback function could send a message to another script before it returned. Why couldn't that be done?And the purpose of the dll in that case would be? ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
martin Posted March 22, 2011 Share Posted March 22, 2011 And the purpose of the dll in that case would be?The same as before. I imagined that the script calls a function in the dll and that dll function calls the callback function and passes back information on the progress but the gui freezes. So, assuming the callback works and information is passed back on the progress (I understood from the first post that it did) then if another script calls the dll function instead then the gui won't be frozen and the update information could be passed. Hopefully in that you will understand my faulty logic and explain it to me. Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
trancexx Posted March 23, 2011 Share Posted March 23, 2011 The same as before. I imagined that the script calls a function in the dll and that dll function calls the callback function and passes back information on the progress but the gui freezes. So, assuming the callback works and information is passed back on the progress (I understood from the first post that it did) then if another script calls the dll function instead then the gui won't be frozen and the update information could be passed. Hopefully in that you will understand my faulty logic and explain it to me.No, that's fine. I misunderstood you previously. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
martin Posted March 23, 2011 Share Posted March 23, 2011 No, that's fine. I misunderstood you previously.ok. Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now