Jump to content

_ArrayDisplay drifts away then returns blank


Recommended Posts

Hi all, I've been away from Autoit for awhile but now I'm back trying to progress the accounting project I stopped and started several years ago.

I've spent nearly two days trying to figure out this problem but alas I'm completely stumped.

After the $aReadThisShelf array is created all elements can be accessed, however not to _ArrayDisplay().

_ArrayDisplay() hangs for a short period and then returns blank and the array is gone. What have I done to screw this up?

All help will be most appreciated.

As always I have to give this disclaimer - Please remember I'm an accountant and not a programmer

Here's the code

#include <ComboConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Array.au3>
Opt('MustDeclareVars', 1)
Global $hCombo, $sThisShelf
Global $sMyTesterFile = "Tester.ini"
GUICreate("", 395, 78, 292, 124, $WS_POPUPWINDOW)
$hCombo = GUICtrlCreateCombo("", 16, 24, 176, 25, BitOR($CBS_DROPDOWN, $CBS_DROPDOWNLIST, $CBS_AUTOHSCROLL))
GUISetState(@SW_SHOW)
Local $var = IniReadSectionNames($sMyTesterFile)
Local $VenArray[$var[0] + 1]
For $i = 1 To UBound($var) - 1
$VenArray[$i] = $var[$i]
GUICtrlSetData(-1, $VenArray[$i])
Next
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
While 1
Local $nMsg
$nMsg = GUIGetMsg()
Switch $nMsg
  Case $GUI_EVENT_CLOSE
   Exit
EndSwitch
WEnd

Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
;#forceref $hWnd, $iMsg
Local $hWndFrom, $iIDFrom, $iCode, $hWndCombo
If Not IsHWnd($hCombo) Then $hWndCombo = GUICtrlGetHandle($hCombo)
$hWndFrom = $ilParam
$iIDFrom = BitAND($iwParam, 0xFFFF)
$iCode = BitShift($iwParam, 16)
Switch $hWndFrom
  Case $hCombo, $hWndCombo
   Switch $iCode
    Case $CBN_SELCHANGE
     $sThisShelf = GUICtrlRead($hCombo)
     Local $aReadThisShelf = IniReadSection($sMyTesterFile, $sThisShelf)
     _ArrayDisplay($aReadThisShelf, $sThisShelf & " has " & $aReadThisShelf[0][0] & " elements");here's the problem?????
   EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

Here's the tester.ini file

[SHELF#1]
Key1=Books
Key2=paper
Key3=shirts
Key4=hats
Key5=suits
Key6=paperclips
Key7=staples
Key8=pens
Key9=pencils
Key11=erasers
[SHELF#2]
Key1=glasses
Key2=plates
Key3=saucers
[SHELF#3]
Key1=spoons
Key2=knives
Key3=bowls
Link to comment
Share on other sites

Sorry, I don't know whats happening either, but the problem must be in the gui somewhere, writing to the console works for example:

#include <ComboConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Array.au3>
Opt('MustDeclareVars', 1)
Global $hCombo, $sThisShelf
Global $sMyTesterFile = "Tester.ini"
GUICreate("", 395, 78, 292, 124, $WS_POPUPWINDOW)
$hCombo = GUICtrlCreateCombo("", 16, 24, 176, 25, BitOR($CBS_DROPDOWN, $CBS_DROPDOWNLIST, $CBS_AUTOHSCROLL))
GUISetState(@SW_SHOW)
Local $var = IniReadSectionNames($sMyTesterFile)
Local $VenArray[$var[0] + 1]
For $i = 1 To UBound($var) - 1
$VenArray[$i] = $var[$i]
GUICtrlSetData(-1, $VenArray[$i])
Next
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
While 1
Local $nMsg
$nMsg = GUIGetMsg()
Switch $nMsg
  Case $GUI_EVENT_CLOSE
   Exit
EndSwitch
WEnd
Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
;#forceref $hWnd, $iMsg
Local $hWndFrom, $iIDFrom, $iCode, $hWndCombo
If Not IsHWnd($hCombo) Then $hWndCombo = GUICtrlGetHandle($hCombo)
$hWndFrom = $ilParam
$iIDFrom = BitAND($iwParam, 0xFFFF)
$iCode = BitShift($iwParam, 16)
Switch $hWndFrom
  Case $hCombo, $hWndCombo
   Switch $iCode
    Case $CBN_SELCHANGE
     $sThisShelf = GUICtrlRead($hCombo)
     Local $aReadThisShelf = IniReadSection($sMyTesterFile, $sThisShelf)
     _ConsoleArray($aReadThisShelf, true);here's the problem?????
   EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND
func _ConsoleArray($aArray, $xShowRowsCols=False)
Local $sMSG, $iYbound
Switch UBound($aArray,0)
case 0
  ConsoleWrite("Not an Array")
case 1
  for $x=0 to UBound($aArray)-1
   if $xShowRowsCols=True then $sMSG&='['&$x&']'&@TAB
   $sMSG&=$aArray[$x]&@LF
  Next
case 2
  $iYbound=UBound($aArray,2)-1
  for $x=-1 to UBound($aArray)-1
   if $xShowRowsCols=True then $sMSG&='['&$x&']'&@TAB
   for $y=0 to $iYbound
    if $x=-1 then
     if $xShowRowsCols=True then $sMSG&='['&$y&']'&@TAB
    Else
     $sMSG&=$aArray[$x][$y]
     if $y<>$iYbound then $sMSG&=@TAB
    EndIf
   Next
   $sMSG&=@LF
  Next
EndSwitch
ConsoleWrite(@lf&$sMSG&@LF)
EndFunc
Link to comment
Share on other sites

You can't use _ArrayDisplay in a Windows message function, it can deadlock the script. You should return the array once the WM_Command function has ended and then display it.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

According to these wiki pages:

http://www.autoitscript.com/wiki/GUIRegisterMsg

http://www.autoitscript.com/wiki/Interrupting_a_running_function

Here is fixed working GUI

#include <ComboConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Array.au3>


Opt('MustDeclareVars', 1)

Global $combochange_id, $hCombo, $sThisShelf
Global $sMyTesterFile = "Tester.ini"

GUICreate("", 395, 78, 292, 124, $WS_POPUPWINDOW)
$combochange_id = GUICtrlCreateDummy()
$hCombo = GUICtrlCreateCombo("", 16, 24, 176, 25, BitOR($CBS_DROPDOWN, $CBS_DROPDOWNLIST, $CBS_AUTOHSCROLL))
GUISetState(@SW_SHOW)

Local $var = IniReadSectionNames($sMyTesterFile)
Local $VenArray[$var[0] + 1]
For $i = 1 To UBound($var) - 1
    $VenArray[$i] = $var[$i]
    GUICtrlSetData(-1, $VenArray[$i])
Next

GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

While 1
    Local $nMsg
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $combochange_id
            OnComboChange(GUICtrlRead($combochange_id))
    EndSwitch
WEnd

Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
    ;#forceref $hWnd, $iMsg
    Local $hWndFrom, $iIDFrom, $iCode, $hWndCombo
    If Not IsHWnd($hCombo) Then $hWndCombo = GUICtrlGetHandle($hCombo)
    $hWndFrom = $ilParam
    $iIDFrom = BitAND($iwParam, 0xFFFF)
    $iCode = BitShift($iwParam, 16)
    Switch $hWndFrom
        Case $hCombo, $hWndCombo
            Switch $iCode
                Case $CBN_SELCHANGE
                    GUICtrlSendToDummy($combochange_id, GUICtrlRead($hCombo))
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

Func OnComboChange($combo_value)
    Local $aReadThisShelf = IniReadSection($sMyTesterFile, $combo_value)
    _ArrayDisplay($aReadThisShelf, $combo_value& " has " & $aReadThisShelf[0][0] & " elements");here's the problem?????
EndFunc

_ArrayDisplay in your script blocked WM_COMMAND message queue

EDIT: too slow :-(

Edited by Zedna
Link to comment
Share on other sites

about the "WM_COMMAND message queue" is there a tool to see what is going on there, or are you just speaking from experiencereference?

MSDN and experince.

Of course you can see messages by some clever tools like Winspector.

EDIT: In fact this non-blocking trick you can't see by Winspector. You must know what to do in this case.

Edited by Zedna
Link to comment
Share on other sites

By GUICtrlSendToDummy() here you generate your own user defined messages inside your application

and later catch them by GUIGetMsg().

EDIT: Another explanation:

Because you do long lasting command _ArrayDisplay() then

instead of direct calling OnComboChange(GUICtrlRead($hCombo)) from WM_COMMAND

you must do it by sending message about OnComboChange() through GUICtrlSendToDummy()

so application place this user message onto its message queue and finish its internal processing of WM_COMMAND.

Then your message is processed by GUIGetMsg() but first all system's messages are processed/finished.

Edited by Zedna
Link to comment
Share on other sites

I just recently posted an in the example scripts section showing how to use GUIRegisterMsg which might be of some help in showing how to use the windows messages.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

Thank you Zenda this is quite amazing, never in a million years would I be able to do anything like this.

I whizzed through everything and will look at it slowly in the morning. You’ve given me lots of homework to do but I promise I’ll do it. Thank you BrewManNH and Dicatorofthe USA for you contributions. I had looked at GuiRegisterMsg in the past but I guess I need a good refresher course. What threw me was that ArrayDisplay returned element values to the title but nothing else?

I’ll go through Zenda’s marvelous script tomorrow but in the mean time can you easily see a reason why on the third attempt at a combo selection, Autoit encounters a problem and needs to close? Maybe I’ll figure this out tomorrow.

Thanks again and as usual, you guys always come through.

Edited by 1905russell
Link to comment
Share on other sites

I’ll go through Zenda’s marvelous script tomorrow but in the mean time can you easily see a reason why on the third attempt at a combo selection, Autoit encounters a problem and needs to close? Maybe I’ll figure this out tomorrow.

You must run this from latest beta - it works OK.

In my older release 3.2.12.1 it crashes this way too, probably because there is not supported or bugged sending of parameters in GUICtrlSendToDummy().

EDIT: Of course there are several ways how to do this non-blocking trick (compatible also with older Autoit).

Edited by Zedna
Link to comment
Share on other sites

Here is version without using of parameters in GUICtrlSendToDummy()

so this one works also with older Autoit.

#include <ComboConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Array.au3>

Opt('MustDeclareVars', 1)

Global $combochange_id, $hCombo, $sThisShelf
Global $sMyTesterFile = "Tester.ini"

GUICreate("", 395, 78, 292, 124, $WS_POPUPWINDOW)
$combochange_id = GUICtrlCreateDummy()
$hCombo = GUICtrlCreateCombo("", 16, 24, 176, 25, BitOR($CBS_DROPDOWN, $CBS_DROPDOWNLIST, $CBS_AUTOHSCROLL))
GUISetState(@SW_SHOW)

Local $var = IniReadSectionNames($sMyTesterFile)
Local $VenArray[$var[0] + 1]
For $i = 1 To UBound($var) - 1
    $VenArray[$i] = $var[$i]
    GUICtrlSetData(-1, $VenArray[$i])
Next

GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

While 1
    Local $nMsg
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $combochange_id
            OnComboChange()
    EndSwitch
WEnd

Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
    ;#forceref $hWnd, $iMsg
    Local $hWndFrom, $iIDFrom, $iCode, $hWndCombo
    If Not IsHWnd($hCombo) Then $hWndCombo = GUICtrlGetHandle($hCombo)
    $hWndFrom = $ilParam
    $iIDFrom = BitAND($iwParam, 0xFFFF)
    $iCode = BitShift($iwParam, 16)
    Switch $hWndFrom
        Case $hCombo, $hWndCombo
            Switch $iCode
                Case $CBN_SELCHANGE
                    GUICtrlSendToDummy($combochange_id)
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

Func OnComboChange()
    Local $combo_value = GUICtrlRead($hCombo)
    Local $aReadThisShelf = IniReadSection($sMyTesterFile, $combo_value)
    _ArrayDisplay($aReadThisShelf, $combo_value& " has " & $aReadThisShelf[0][0] & " elements");here's the problem?????
EndFunc
Edited by Zedna
Link to comment
Share on other sites

Zenda what can I say, you have gone beyond the call of duty (we now have two versions). I now understand what you did and why you did it, for both versions. Even if somehow I figured out that I was using ArrayDisplay in the wrong place, I obviously would never have known about using GuiCtrlSendToDummy to “trick” the array out into ArrayDisplay. Anyway, I’ve learned much. Great, so now I can continue until I hit the next brick wall. Thanks again and adieu until next time…
Link to comment
Share on other sites

  • 5 years later...

Necromancing... I know.

The purpose is to both:

  • validate Zedna's elegant solution to the OP issue which still works in Windows 10, Autoit 3.3.14.2
  • offer the same code with OnEvent Mode enabled

I (improperly) also had an evidently *long* process in WM_COMMAND that was causing some odd behavior - read: illogical behavior. GUI updates firing out of order, intermittent lockups, @GUI_CtrlId not showing last Control ID fired, etc.

 

So, here is the OnEvent version:
 

;~ https://www.autoitscript.com/forum/topic/134978-_arraydisplay-drifts-away-then-returns-blank/
;~ https://www.autoitscript.com/forum/topic/90396-script-crashing-when-using-guigetmsg-and-wm_notify/
;~ GUIRegisterMessage: "Warning: ... the return to the system should be as fast as possible !!!".

#include <ComboConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Array.au3>


Opt('MustDeclareVars', 1)
Opt("GUIOnEventMode", 1)

Global Const $g_sMyTesterFile = @ScriptDir & "\Tester.ini"
Global $g_hGUI, $g_hDummyCombo, $g_hCombo

CreateGUI($g_hGUI)
GUISetState(@SW_SHOW, $g_hGUI)
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

While 1
    Sleep(300)
WEnd


;~ ____________________________________________________________________________
Func CreateGUI(ByRef $hGUI)
    $hGUI = GUICreate("", 220, 70, -1, -1, $WS_POPUPWINDOW)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
    $g_hDummyCombo = GUICtrlCreateDummy()
    $g_hCombo = GUICtrlCreateCombo("", 16, 24, 176, 25, BitOR($CBS_DROPDOWN, $CBS_DROPDOWNLIST, $CBS_AUTOHSCROLL))
    GUICtrlSetOnEvent($g_hCombo, "_OnComboChange")
    Local $aSectionNames = IniReadSectionNames($g_sMyTesterFile)
    For $i = 1 To UBound($aSectionNames) - 1
        GUICtrlSetData($g_hCombo, $aSectionNames[$i])
    Next
EndFunc
;~ ____________________________________________________________________________
Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
    ;#forceref $hWnd, $iMsg
    Local $hWndFrom, $iIDFrom, $iCode, $hWndCombo
    If Not IsHWnd($g_hCombo) Then $hWndCombo = GUICtrlGetHandle($g_hCombo)
    $hWndFrom = $ilParam
    $iIDFrom = BitAND($iwParam, 0xFFFF)
    $iCode = BitShift($iwParam, 16)
    Switch $hWndFrom
        Case $g_hCombo, $hWndCombo
            Switch $iCode
                Case $CBN_SELCHANGE
                    GUICtrlSendToDummy($g_hDummyCombo, GUICtrlRead($g_hCombo))
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND
;~ ____________________________________________________________________________
Func _OnComboChange()
    Local $vValue = GUICtrlRead(@GUI_CtrlId)
    Local $aReadThisShelf = IniReadSection($g_sMyTesterFile, $vValue)
    _ArrayDisplay($aReadThisShelf, $vValue & " has " & $aReadThisShelf[0][0] & " elements") ;here's the problem?????
EndFunc   ;==>_OnComboChange
;~ ____________________________________________________________________________
Func _Exit()
    GUIDelete($g_hGUI)
    Exit
EndFunc   ;==>_Exit
;~ ____________________________________________________________________________

 

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...