Custom Query


Show under each result:

Results (19 - 21 of 3841)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Ticket Resolution Summary Owner Reporter
#3930 No Bug DllStructs created in one scope gets dropped if chained with a function that returns a re-structured-by-pointer version of it AutoXenon

Original thread:

Local $unreliable_data, $reliable_data, $intermediate_ref, $labelunreliable = GUICtrlCreateLabel('',0,0,400,25), $labelreliable = GUICtrlCreateLabel('',0,30,400,25)
While True
      $unreliable_data = parseStruct(createStruct())  ; struct technically goes out of scope, this saves a "slave struct" but the master struct gets dropped when it goes out of parseStruct's scope
      $intermediate_ref = createStruct()              ; struct scope gets transferred, this is a "master struct"
      $reliable_data = parseStruct($intermediate_ref) ; a "slave struct" of a master struct that is scoped here
      Sleep(100)                                      ; wait some time for garbage to get written into the freed memory 

Func createStruct()
     Local $struct = DllStructCreate('char[16]')
     DllStructSetData($struct,1,'hello world')
     Return $struct

Func parseStruct($struct)
     Return DllStructCreate('char msg[16]',DllStructGetPtr($struct))

Func quit()

The question is, should create-by-pointer structs count as valid references? I can imagine that if it is change to be so, it might cause headaches with ad-hoc throwaway "lens" structs unintentionally preventing the memory from being freed if the programmer is expecting it to not count as valid references. I guess it's up to you to decide on which tradeoff to pick.

#3928 Works For Me WinWaitActive() prevents Raw Input's WM_INPUT messages from queueing up (drops messages?), resulting in poor responsiveness nurupo

Calling into WinWaitActive() somehow results in 1) fewer WM_INPUT messages being delivered and 2) in WM_INPUT messages not queueing up at all.

To illustrate this problem, here is a minimal reproducible example I came up with. I will further explain what it does and how to use it.

#include <AutoItConstants.au3>
#include <WinAPISys.au3>
#include <WindowsConstants.au3>

Opt("MustDeclareVars", 1)
Opt("WinWaitDelay", 0)

Local $hForm = GUICreate("")
Local $tRID = DllStructCreate($tagRAWINPUTDEVICE)
DllStructSetData($tRID, 'UsagePage', 0x01)
DllStructSetData($tRID, 'Usage', 0x02)
DllStructSetData($tRID, 'Flags', $RIDEV_INPUTSINK)
DllStructSetData($tRID, 'hTarget', $hForm)

While 1

Func WM_INPUT($hWnd, $iMsg, $wParam, $lParam)
    #forceref $iMsg, $wParam
    If $hWnd <> $hForm Then Return
    Local $tRIM = DllStructCreate($tagRAWINPUTMOUSE)
    If Not _WinAPI_GetRawInputData($lParam, $tRIM, DllStructGetSize($tRIM), $RID_INPUT) Then Return
    Local $iFlags = DllStructGetData($tRIM, 'ButtonFlags')
    If BitAND($iFlags, $RI_MOUSE_WHEEL) Then

Func OnMouseWheel()
    Local Static $iCount = 0
    Local Static $iSec = @SEC
    If $iSec <> @SEC Then
        ConsoleWrite("Counted " & $iCount & " mouse wheel scrolls in the past second" & @CRLF)
        $iCount = 0
        $iSec = @SEC
    $iCount += 1
    ;Local $iDelay = ? ; <-- set to the ms number you get in console when running LessResponsive()

Func LessResponsive()
    Local $hWndCurrent = WinGetHandle("[ACTIVE]")
    Local $hWndNotepad = WinActivate("[CLASS:Notepad]")
    Local $hTimer = TimerInit()
    WinWaitActive($hWndNotepad, "", 1)
    Local $iTimerDiff1 = TimerDiff($hTimer)
    ControlSend($hWndNotepad, "", "Edit1", @MSEC & "{Enter}")
    $hTimer = TimerInit()
    WinWaitActive($hWndCurrent, "", 1)
    Local $iTimerDiff2 = TimerDiff($hTimer)
    ConsoleWrite("LessResponsive: Waited on window for " & ($iTimerDiff1+$iTimerDiff2)/2 & "ms" & @CRLF)

Func MoreResponsive($iDelay)
    Local $hWndCurrent = WinGetHandle("[ACTIVE]")
    Local $hWndNotepad = WinActivate("[CLASS:Notepad]")
    Local $hTimer = TimerInit()
    _WinWaitActive($hWndNotepad, "", 1, $iDelay)
    Local $iTimerDiff1 = TimerDiff($hTimer)
    ControlSend($hWndNotepad, "", "Edit1", @MSEC & "{Enter}")
    $hTimer = TimerInit()
    _WinWaitActive($hWndCurrent, "", 1, $iDelay)
    Local $iTimerDiff2 = TimerDiff($hTimer)
    ConsoleWrite("MoreResponsive: Waited on window for " & ($iTimerDiff1+$iTimerDiff2)/2 & "ms" & @CRLF)

Func _WinWaitActive($hWnd, $unused, $iTimeout, $iDelay)
    Local $iActiveFlag = Null
    $iTimeout *= 1000
    Local $hTimer = TimerInit()
        Local $iState = WinGetState($hWnd)
        $iActiveFlag = BitAND($iState, $WIN_STATE_ACTIVE)
    Until $iActiveFlag Or TimerDiff($hTimer) >= $iTimeout
    If $iActiveFlag Then
    Return $iActiveFlag ? $hWnd : 0

; Seelps in intervals of 1ms for total of $delay ms
Func _Sleep($delay)
    Local $iLeftToSleep = $delay
    Local $hTimer
    If $iLeftToSleep > 1 Then ; sleep in 1ms intervals
        Local Static $hNtdll = DllOpen("ntdll.dll")
        Local Static $hWinmmdll = DllOpen("winmm.dll")
        DllCall($hWinmmdll, "int", "timeBeginPeriod", "int", 1)
        Local $iTimerDiff
            $hTimer = TimerInit()
            DllCall($hNtdll, "dword", "NtDelayExecution", "int", 0, "int64*", -5000)
            $iTimerDiff = TimerDiff($hTimer)
            $iLeftToSleep -= $iTimerDiff
        Until $iLeftToSleep <= $iTimerDiff
        DllCall($hWinmmdll, "int", "timeEndPeriod", "int", 1)
    ; hot loop for the remaining <= 1ms
    If $iLeftToSleep > 0 Then
        $hTimer = TimerInit()
        Until TimerDiff($hTimer) >= $iLeftToSleep

What the example above does

The example above expects a Notepad to be running and you focus SciTE window before scrolling the mouse wheel. Whenever you scroll the mouse wheel, OnMouseWheel() gets called, recording how many scrolls you have done during the current second, printing that out to the console on the next second. OnMouseWheel() also calls into LessResponsive() or MoreResponsive(), if one of them is uncommented. They both activate the Notepad window, send some text to it and activate the SciTE window back. The difference is that LessResponsive() uses WinWaitActive(), while MoreResponsive() uses my own imitation version of WinWaitActive() called _WinWaitActive().


How to use the example

Firstly, just run it as it is.

  1. Open Notepad, run the script and click on SciTE to make the SciTE window active
  2. Start scrolling the mouse wheel in a consistent manner that is comfortable to you, such that you could reproduce it later
  3. You should see the script activating Notepad back, writing current @MSEC into it, and activating the SciTE window back over and over again
  4. Take a note of how many scrolls per second you do on average by reading out the console output
  5. Terminate the script

(I typically get around 10 scrolls per second)

Now uncomment the LessResponsive() call and redo the same 1-5 steps. Notice how the number of scrolls per second has reduced. For me it went from 10 when LessResponsive() was commented out, to 4 with LessResponsive() uncommented. Take note of the window wait time being printed to the console. (I get around 19ms window wait time).

Now comment out LessResponsive() and uncomment MoreResponsive(). Set $iDelay to the window wait time you got when running LessResponsive(), e.g. I have set mine to 19. Redo steps 1-5 and notice how you get a lot more scrolls per second now. I went from 4 back to 10 as it was before LessResponsive() and MoreResponsive() were uncommented. That's a huge increase in responsiveness! What is more, if you scroll too fast, it will start queueing the unprocessed WM_INPUT messages, i.e. you can stop scrolling and the OnMouseWheel() will continue to get called until all the queued up messages are processed! This didn't happen with LessResponsive(), somehow WinWaitActive() prevented the messages from queueing up.


You could say "Why don't you just use your _WinWaitActive() then?". Well, the issue is that while my _WinWaitActive() is a lot more responsive than AutoIt's WinWaitActive(), it's not really comparable in functionality to WinWaitActive(), it's pretty much just a custom Sleep() function that happened to check if a window is in the active state. It doesn't know when a window becomes active the same way WinWaitActive() does. Window's state is always set to active, visible and enabled right after calling WinActivate() on it, so if not for the custom sleep, _WinWaitActive() would have returned right away (under 0.1ms), while WinWaitActive() is somehow able to wait just the right amount of time for the window to get activates, drawn and be ready to receive keyboard input (around 19ms on my computer). As such, _WinWaitActive() is not very usable to me because it doesn't know how long to wait for, and while WinWaitActive() knows for how long to wait for, it's also not very unusable to me but due to it resulting in sluggish message processing and no message queueing. (I assume that WinWaitActivate() knows how long to wait for, it would be funny if it's too just a glorified wrapper for a Sleep() call with an arbitrarily chosen sleep time).

Could you fix WinWaitActive() so that 1) the message processing doesn't become as sluggish and 2) the messages queue properly?

#3926 Fixed _GUICtrlTreeView_SetChildren functionality has changed Jpm office@…

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Note: See TracQuery for help on using queries.