#935 closed Bug (No Bug)
WinSetState() lags
Reported by: | trancexx | Owned by: | |
---|---|---|---|
Milestone: | Component: | AutoIt | |
Version: | 3.3.0.0 | Severity: | None |
Keywords: | Cc: |
Description
I tested this on various systems and the result is the same. This function lags for some reason. I read the documentation and couldn't find explanation for this strange behaviour. So, if someone would check if this is intended because it's really unexpected and kind of weird (probably there is some better word to describe it).
I wrote a little script to demonstrate it. Did try to be as far away as I could from native functions made for making guis to eliminate possible shortcuts and still to be compact:
Global $hGui = GUICreate("Test", 300, 300, 20, 100) GUICtrlCreateLabel("WinSetState functions:", 15, 70, 130) Global $hButtonShowWindow_AutoIt = GUICtrlCreateButton("ShowWindow", 20, 100, 100, 25) Global $hButtonHideWindow_AutoIt = GUICtrlCreateButton("HideWindow", 20, 150, 100, 25) GUICtrlCreateLabel("DllCall:", 190, 70, 130) Global $hButtonShowWindow_DllCall = GUICtrlCreateButton("ShowWindow", 170, 100, 100, 25) Global $hButtonHideWindow_DllCall = GUICtrlCreateButton("HideWindow", 170, 150, 100, 25) ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Global $bDialog = "0x0100FFFF00000000000004004C0ACC80040000000000A2005F00000000004100" & _ "750074006F0049007400200049006E00700075007400200042006F0078000000" & _ "0800000000014D00530020005300680065006C006C00200044006C0067000000" & _ "0000000000000000000002500700070093002C00EA030000FFFF820050007200" & _ "6F006D0070007400000000000000000000000000800081500700380093000C00" & _ "E9030000FFFF8100000000000000000000000000010001501000490032000E00" & _ "01000000FFFF80004F004B000000000000000000000000000000015057004900" & _ "32000E0002000000FFFF8000430061006E00630065006C0000000000" Global $tDialog = DllStructCreate("byte[" & BinaryLen($bDialog) & "]") DllStructSetData($tDialog, 1, $bDialog) Global $aCall = DllCall("user32.dll", "hwnd", "CreateDialogIndirectParamW", _ "hwnd", 0, _ "ptr", DllStructGetPtr($tDialog), _ "hwnd", $hGui, _ "ptr", 0, _ "lparam", 0) Global $hDialog = $aCall[0] ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX GUISetState() While 1 Switch GUIGetMsg() Case - 3 Exit Case $hButtonShowWindow_AutoIt WinSetState($hDialog, 0, @SW_SHOW) Case $hButtonShowWindow_DllCall DllCall("user32.dll", "int", "ShowWindow", "hwnd", $hDialog, "int", @SW_SHOW) Case $hButtonHideWindow_AutoIt WinSetState($hDialog, 0, @SW_HIDE) Case $hButtonHideWindow_DllCall DllCall("user32.dll", "int", "ShowWindow", "hwnd", $hDialog, "int", @SW_HIDE) EndSwitch WEnd
I did manage to find out that WinSetState() eventually calls ShowWindow function the same way I did in that script and that the lag is likely with what comes after that.
Thanks.
Attachments (0)
Change History (4)
comment:1 Changed 16 years ago by Jpm
comment:2 Changed 16 years ago by trancexx
Yes, sory for me not being more descriptive.
It's not the same for me. When I click ShowWindow on the left window shows and after some time controls are drawn (there is some short time when window is without controls).
... it's that sleep 250 that you call for some reason. I guess that makes it intended behaviour and my original question is answered.
Is that sleep needed?
comment:3 Changed 16 years ago by Jpm
- Resolution set to No Bug
- Status changed from new to closed
In fact all Win...() are suppose to respect the Opt("WinWaitDelay") which is 250 by default.
That's the reason you get the Sleep(250).
use Op('"WinWaitDelay",0) if you don't like it.
I am curious to see how you find a sleep(250) was occuring.
comment:4 Changed 16 years ago by trancexx
Well, if I tell you I will have to kill you. And that's bad because likely I'm gonna need you more.
... no I used method described by monoceres in this topic http://www.autoitscript.com/forum/index.php?showtopic=84936
This is the code that suited my needs to intercept AutoIt's calls to Sleep:
#NoTrayIcon #include <WinAPI.au3> ;Opt("WinWaitDelay", 0) Global $hSleepCallback = DllCallbackRegister("_Intercept_Sleep", "none", "dword") If _AddHookApi("kernel32.dll", "Sleep", DllCallbackGetPtr($hSleepCallback)) Then ConsoleWrite("All OK. Sleep is caught. Calls other than 0 or 10 follows:" & @CRLF) Else ConsoleWrite("!Failed to intercept calls to Sleep function." & @CRLF) EndIf Global $hGui = GUICreate("Test", 300, 300, 20, 100) GUICtrlCreateLabel("WinSetState functions:", 15, 70, 130) Global $hButtonShowWindow_AutoIt = GUICtrlCreateButton("ShowWindow", 20, 100, 100, 25) Global $hButtonHideWindow_AutoIt = GUICtrlCreateButton("HideWindow", 20, 150, 100, 25) GUICtrlCreateLabel("DllCall:", 190, 70, 130) Global $hButtonShowWindow_DllCall = GUICtrlCreateButton("ShowWindow", 170, 100, 100, 25) Global $hButtonHideWindow_DllCall = GUICtrlCreateButton("HideWindow", 170, 150, 100, 25) ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Global $bDialog = "0x0100FFFF00000000000004004C0ACC80040000000000A2005F00000000004100" & _ "750074006F0049007400200049006E00700075007400200042006F0078000000" & _ "0800000000014D00530020005300680065006C006C00200044006C0067000000" & _ "0000000000000000000002500700070093002C00EA030000FFFF820050007200" & _ "6F006D0070007400000000000000000000000000800081500700380093000C00" & _ "E9030000FFFF8100000000000000000000000000010001501000490032000E00" & _ "01000000FFFF80004F004B000000000000000000000000000000015057004900" & _ "32000E0002000000FFFF8000430061006E00630065006C0000000000" Global $tDialog = DllStructCreate("byte[" & BinaryLen($bDialog) & "]") DllStructSetData($tDialog, 1, $bDialog) Global $aCall = DllCall("user32.dll", "hwnd", "CreateDialogIndirectParamW", _ "hwnd", 0, _ "ptr", DllStructGetPtr($tDialog), _ "hwnd", 0, _ "ptr", 0, _ "lparam", 0) Global $hDialog = $aCall[0] ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX GUISetState() While 1 Switch GUIGetMsg() Case - 3 Exit Case $hButtonShowWindow_AutoIt WinSetState($hDialog, 0, @SW_SHOW) Case $hButtonShowWindow_DllCall DllCall("user32.dll", "int", "ShowWindow", "hwnd", $hDialog, "int", @SW_SHOW) Case $hButtonHideWindow_AutoIt WinSetState($hDialog, 0, @SW_HIDE) Case $hButtonHideWindow_DllCall DllCall("user32.dll", "int", "ShowWindow", "hwnd", $hDialog, "int", @SW_HIDE) EndSwitch WEnd ;DllCallbackFree($hSleepCallback) ;The End Func _Intercept_Sleep($iMilisec) ToolTip("Sleep(" & $iMilisec & ")") If $iMilisec And $iMilisec <> 10 Then ConsoleWrite("! Sleep(" & $iMilisec & ")" & @CRLF) EndIf DllCall("kernel32.dll", "none", "Sleep", "dword", $iMilisec) EndFunc ;==>_Intercept_Sleep Func _AddHookApi($sModuleName, $sFunctionName, $pNewProcAddress) Local $hInstance = _WinAPI_GetModuleHandle(0) Local $aCall = DllCall("Dbghelp.dll", "ptr", "ImageDirectoryEntryToData", _ "ptr", $hInstance, _ "int", 1, _ ; as an image "ushort", 1, _ ; IMAGE_DIRECTORY_ENTRY_IMPORT "dword*", 0) Local $pImportDirectory = $aCall[0] Local $tIMAGE_IMPORT_MODULE_DIRECTORY Local $tModuleName While 1 $tIMAGE_IMPORT_MODULE_DIRECTORY = DllStructCreate("dword RVAOriginalFirstThunk;" & _ "dword TimeDateStamp;" & _ "dword ForwarderChain;" & _ "dword RVAModuleName;" & _ "dword RVAFirstThunk", _ $pImportDirectory) If Not DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAFirstThunk") Then ; the end ExitLoop EndIf $tModuleName = DllStructCreate("char Name[64]", $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAModuleName")) If DllStructGetData($tModuleName, "Name") = $sModuleName Then ; function from this module Local $iInitialOffset = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAFirstThunk") Local $iInitialOffset2 = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAOriginalFirstThunk") Local $iOffset2 = 0 Local $tBufferOffset2, $iBufferOffset2 Local $tBuffer While 1 $tBufferOffset2 = DllStructCreate("dword", $iInitialOffset2 + $iOffset2) $iBufferOffset2 = DllStructGetData($tBufferOffset2, 1) If Not $iBufferOffset2 Then ; zero value is the end ExitLoop EndIf $tBuffer = DllStructCreate("ushort Ordinal; char Name[64]", $hInstance + $iBufferOffset2) If DllStructGetData($tBuffer, 2) == $sFunctionName Then ; wanted function Local $tBufferOffset = DllStructCreate("dword", $iInitialOffset + $iOffset2) ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Local $tMEMORY_BASIC_INFORMATION = DllStructCreate("ptr BaseAddress;" & _ "ptr AllocationBase;" & _ "ptr AllocationProtect;" & _ "dword RegionSize;" & _ "dword State;" & _ "dword Protect;" & _ "dword Type") DllCall("kernel32.dll", "dword", "VirtualQuery", _ "ptr", DllStructGetPtr($tBufferOffset), _ "ptr", DllStructGetPtr($tMEMORY_BASIC_INFORMATION), _ "dword", DllStructGetSize($tMEMORY_BASIC_INFORMATION)) DllCall("kernel32.dll", "int", "VirtualProtect", _ "ptr", DllStructGetData($tMEMORY_BASIC_INFORMATION, "BaseAddress"), _ "dword", DllStructGetData($tMEMORY_BASIC_INFORMATION, "RegionSize"), _ "dword", 4, _ ; PAGE_READWRITE "dword*", 0) DllStructSetData($tBufferOffset, 1, $pNewProcAddress) ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Return 1 ; All OK! EndIf $iOffset2 += 4 ; size of $tBufferOffset2 WEnd ExitLoop EndIf $pImportDirectory += 20 ; size of $tIMAGE_IMPORT_MODULE_DIRECTORY WEnd EndFunc ;==>_AddHookApi
Btw, thanks for the explanation and solution of course. Sometimes even the obvious things are not so obvious at all.
Guidelines for posting comments:
- You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
- In-depth discussions should take place on the forum.
For more information see the full version of the ticket guidelines here.
Cannot you explain for a non english native what the difference of behavior you demonstrate?
I don't understand "lag"
For me clicking winsetstate buttons or dllcall ones do the same under Vista.