Veränderung eines Controls überwachen(WM_NOTIFY?)

  • Hallo alle zusammen!

    Ich arbeite gerade an einem Skript welches mir verschiedene Einträge in der Registry per Klick verändert. Z.B. Anzeige von versteckten Dateien, Mausgeschwindigkeit usw.
    Ich habe hierzu eine recht einfache GUI erstellt, worin ein paar Checkboxen sowie ein Speichern- und Beenden Button vorhanden ist. Soweit funktioniert fast alles perfekt.

    Zu Beginn ist der Speichern Button inaktiv, da es ja nix zu speichern gibt. Ich möchte nun meine relevanten Controls überwachen und sobald eine Statusänderung eintritt (checked, unchecked) soll der Button anklickbar werden.
    Zu Beginn habe ich einfach eine Klicküberwachung gemacht. Diese wird aber (logischerweise) auch ausgelöst, wenn der User irgendwo in der GUI die linke Maustaste betätigt - und somit wird der Speicher Button aktiv obwohl es nix zum Speichern gibt.

    Beim Recherchieren für eine komfortablere Lösung bin ich auf WM_NOTIFY gestoßen. Soweit ich das richtig verstanden habe, sendet WM_NOTIFY ja fast pausenlos Meldungen. Hier gilt es für mich die richtige herauszufiltern.
    Ist meine Info überhaupt richtig, oder gibt es einen einfacheren, besseren Weg um die Veränderung von Controls in AutoIt abzufragen?
    Angenommen, ich bin am richtigen Weg, könnte mir jemand einen Ansatz liefert, wie ich NOTIFY Meldungen auswerte? Ich meine, wie bekomme ich die Meldungen überhaupt in mein Skript?
    Durch noch mehr lesen und lesen bin ich auch auf DLLCall, DLL Konstrukte usw gestoßen. Damit bin ich aber (noch) überforfert.

    Bin für jede Hilfe dankbar.

    Einmal editiert, zuletzt von pPanther (25. März 2011 um 06:32)

    • Offizieller Beitrag

    Hi,
    WM_NOTIFY wäre möglich, ist aber nicht nötig.
    Wenn ich dich richtig verstanden habe, hast du doch die Controls selbst erstellt. Dann kannst du die Events dieser Ctrl doch direkt auswerten. Das hat doch keinen Bezug zu Mausklicks.
    Vielleicht verstehe ich dich auch nicht richtig. Es ist daher besser den Code zu posten, dann können wir auch konkret helfen.

  • Ja, die Controls erstelle ich selbst. Dazu packe ich die Beschriftungen in ein Array mit dazupassendem Tooltip nd übergebe das Array an passender Stelle meiner Funktion, welche sich dann um die Positionierung usw. kümmert.

    Spoiler anzeigen
    [autoit]

    ; includes
    #include <Misc.au3>
    #include <ButtonConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <StaticConstants.au3>
    #include <Constants.au3>
    #include <WindowsConstants.au3>
    #include <array.au3>
    #include <UpDownConstants.au3>
    #include <EditConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    ; only one instance of the programm is allowed
    Dim $title = 'Windowseinstellungen'
    If _Singleton($title, 1) = 0 Then
    MsgBox(48, $title, 'Es ist nur eine Instanz des Programms erlaubt!')
    Exit ;
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; constants used for DLL Call
    Const $UPDATEINIFILE = 0x01
    Const $SENDWININICHANGE = 0x02
    Const $BOTH = $UPDATEINIFILE + $SENDWININICHANGE

    [/autoit] [autoit][/autoit] [autoit]

    ; registry paths
    Dim $path_file = 'HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced'
    Dim $path_dekstop = 'HKEY_CURRENT_USER\Control Panel\Desktop'
    Dim $path_mouse = 'HKEY_CURRENT_USER\Control Panel\Mouse'

    [/autoit] [autoit][/autoit] [autoit]

    ; registry keys
    Dim $key_hidden = 'Hidden'
    Dim $key_superhidden = 'ShowSuperHidden'
    Dim $key_active_mouse = 'UserPreferencesMask'
    Dim $key_time_active_mouse = 'ActiveWndTrkTimeout'
    Dim $key_swap_buttons = 'SwapMouseButtons'

    [/autoit] [autoit][/autoit] [autoit]

    ; different registry types for values (dword, qdword, binary, etc)
    Dim $reg_type1 = 'REG_DWORD'
    Dim $reg_type2 = 'REG_BINARY'
    Dim $reg_type3 = 'REG_SZ'

    [/autoit] [autoit][/autoit] [autoit]

    ; horizontal and vertical shift for checkboxes
    Dim $bhs = 20
    Dim $bvs = 0

    [/autoit] [autoit][/autoit] [autoit]

    ; checkbox array
    Dim $box[5][2]
    $box[0][0] = 'Versteckte Dateien einblenden'
    $box[1][0] = 'Systemdateien einblenden'
    $box[2][0] = 'God Mode einschalten'
    $box[3][0] = 'Linkshändermodus aktivieren'
    $box[4][0] = 'Fensterverfolgung aktivieren'

    [/autoit] [autoit][/autoit] [autoit]

    ; mouseover hints
    $box[0][1] = 'Blendet versteckte Dateien im Explorer ein'
    $box[1][1] = 'Zeigt Systemdateien im Explorer an'
    $box[2][1] = 'Erstellt einen Ordner auf dem Systemlaufwerk, mit dem sehr viele Einstellungen freigeschaltet werden'
    $box[3][1] = 'Vertauscht die rechte mit der linken Maustaste'
    $box[4][1] = 'Macht inaktive Fenster bei Berührung aktiv und bringt sie in den Vordergrund'

    [/autoit] [autoit][/autoit] [autoit]

    ; menuitems
    Dim $menu[3][2] = [['Datei', 'Beenden'],['Ansicht', 'Minimieren'],['?', 'Über']]

    [/autoit] [autoit][/autoit] [autoit]

    ; trayoptions
    Opt('TrayMenuMode', 1)
    Opt('TrayAutoPause', 0)
    Opt('TrayIconHide', 1)
    Opt('GUICloseOnESC', 0)
    Dim $TrayShow = TrayCreateItem('Wiederherstellen')
    Dim $TrayExit = TrayCreateItem('Beenden')

    [/autoit] [autoit][/autoit] [autoit]

    ; starting to build the GUI (graphical user interface)
    Dim $GUI = GUICreate($title, 500, 500, -1, -1)
    GUISetBkColor(0xEEDC82)
    Dim $font = "Courier New"
    GUISetFont(11, 400, 0, $font)
    GUISetIcon('icon.ico')
    GUISetState(@SW_SHOW)
    WinSetTrans($title, "", 240)
    WinSetOnTop($title, "", 1)

    [/autoit] [autoit][/autoit] [autoit]

    ; create menu
    $Menu_Actions = CreateMenu($menu)

    [/autoit] [autoit][/autoit] [autoit]

    ; group file
    CreateGroup('Dateien + Ordner', 10, 10, 270, 90)
    $group1_box = CreateBox($box, 30, 20, 0, 2)

    [/autoit] [autoit][/autoit] [autoit]

    ; group mouse
    CreateGroup('Maus', 10, 110, 270, 130)
    $group2_box = CreateBox($box, 130, 20, 3, 4)

    [/autoit] [autoit][/autoit] [autoit]

    $input_updown = GUICtrlCreateInput('', 20, 180, 60, 20)
    $updown = GUICtrlCreateUpdown($input_updown, BitOR($UDS_NOTHOUSANDS, $ES_NUMBER, $ES_CENTER))
    GUICtrlCreateLabel('ms bis zur Aktivierung', 90, 180)
    GUICtrlSetLimit($updown, 5000, 200)

    [/autoit] [autoit][/autoit] [autoit]

    ; exit and save button
    Dim $btn_top_pos = 210
    Dim $Exit = GUICtrlCreateButton('Beenden', 100, $btn_top_pos, 90, 25)
    Dim $Save = GUICtrlCreateButton('Speichern', 210, $btn_top_pos, 90, 25)

    [/autoit] [autoit][/autoit] [autoit]

    ;GUICtrlSetState($Save, $Gui_Disable)

    [/autoit] [autoit][/autoit] [autoit]

    ; join all box-arrays for saving and reading function
    Dim $boxALL = $group1_box
    _ArrayConcatenate($boxALL, $group2_box)

    [/autoit] [autoit][/autoit] [autoit]

    ReadValues()

    [/autoit] [autoit][/autoit] [autoit]

    ;GUIRegisterMsg($WM_ACTIVATE, 'Save')

    [/autoit] [autoit][/autoit] [autoit]

    ; create the menu
    Func CreateMenu($array)
    Local $menu_1[1]
    Local $menu_2[1]
    For $i = 0 To UBound($array) - 1
    If $menu_1[UBound($menu_1) - 1] <> '' Then
    ReDim $menu_1[UBound($menu_1) + 1]
    EndIf
    $menu_1[$i] = GUICtrlCreateMenu($array[$i][0])
    For $n = 1 To UBound($array, 2) - 1
    If $menu_2[UBound($menu_2) - 1] <> '' Then
    ReDim $menu_2[UBound($menu_2) + 1]
    EndIf
    $menu_2[$i] = GUICtrlCreateMenuItem($array[$i][$n], $menu_1[$i])
    Next
    Next
    Return ($menu_2)
    EndFunc ;==>CreateMenu

    [/autoit] [autoit][/autoit] [autoit]

    ; create GUI groups
    Func CreateGroup($group_name, $left, $top, $width, $height)
    GUICtrlCreateGroup($group_name, $left, $top, $width, $height)
    GUICtrlSetFont(-1, 14)
    GUICtrlCreateGroup('', -99, -99, 1, 1)
    EndFunc ;==>CreateGroup

    [/autoit] [autoit][/autoit] [autoit]

    ; create checkboxes
    Func CreateBox($array, $vp, $hp, $startindex, $endindex)
    Local $checkbox[1]
    $end = $endindex - $startindex
    $i = $startindex
    For $n = 0 To $end
    If $checkbox[UBound($checkbox) - 1] <> '' Then
    ReDim $checkbox[UBound($checkbox) + 1]
    EndIf
    $checkbox[$n] = GUICtrlCreateCheckbox($array[$i][0], $hp, $vp)
    GUICtrlSetTip($checkbox[$n], $array[$i][1])
    $vp += 20
    $i += 1
    Next
    Return ($checkbox)
    EndFunc ;==>CreateBox

    [/autoit] [autoit][/autoit] [autoit]

    ; read all values from registry
    Func ReadValues()
    ; hidden files
    Local $hidden = RegRead($path_file, $key_hidden)
    If $hidden = 1 Then
    GUICtrlSetState($boxALL[0], $GUI_CHECKED)
    Else
    GUICtrlSetState($boxALL[0], $GUI_UNCHECKED)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; system files
    Local $superhidden = RegRead($path_file, $key_superhidden)
    If $superhidden = 1 Then
    GUICtrlSetState($boxALL[1], $GUI_CHECKED)
    Else
    GUICtrlSetState($boxALL[1], $GUI_UNCHECKED)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; god mode
    If FileExists(@HomeDrive & '\GodMode.{ED7BA470-8E54-465E-825C-99712043E01C}') Then
    GUICtrlSetState($boxALL[2], $GUI_CHECKED)
    Else
    GUICtrlSetState($boxALL[2], $GUI_UNCHECKED)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; swap mousebuttons
    Local $swap_mb = RegRead($path_mouse, $key_swap_buttons)
    If $swap_mb = 1 Then
    GUICtrlSetState($boxALL[3], $GUI_CHECKED)
    Else
    GUICtrlSetState($boxALL[3], $GUI_UNCHECKED)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; active switching
    Local $active_mouse = RegRead($path_dekstop, $key_active_mouse)
    If $active_mouse = '0xDF07801200000000' Then
    GUICtrlSetState($boxALL[4], $GUI_CHECKED)
    Else
    GUICtrlSetState($boxALL[4], $GUI_UNCHECKED)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; time for active mousetracking
    Local $ms_mouse = RegRead($path_dekstop, $key_time_active_mouse)
    GUICtrlSetData($input_updown, $ms_mouse)
    EndFunc ;==>ReadValues

    [/autoit] [autoit][/autoit] [autoit]

    ; write registry values
    Func WriteReg($path, $key, $type, $value)
    RegWrite($path, $key, $type, $value)
    EndFunc ;==>WriteReg

    [/autoit] [autoit][/autoit] [autoit]

    ;saves all changes made
    Func Save()
    If GUICtrlRead($boxALL[0]) = $GUI_CHECKED Then
    WriteReg($path_file, $key_hidden, $reg_type1, 1)
    Else
    WriteReg($path_file, $key_hidden, $reg_type1, 2)
    EndIf
    If GUICtrlRead($boxALL[1]) = $GUI_CHECKED Then
    WriteReg($path_file, $key_superhidden, $reg_type1, 1)
    WriteReg($path_file, $key_hidden, $reg_type1, 1)
    GUICtrlSetState($boxALL[0], $GUI_CHECKED)
    Else
    WriteReg($path_file, $key_superhidden, $reg_type1, 0)
    EndIf
    If GUICtrlRead($boxALL[2]) = $GUI_CHECKED Then
    DirCreate(@HomeDrive & '\GodMode.{ED7BA470-8E54-465E-825C-99712043E01C}')
    Else
    DirRemove(@HomeDrive & '\GodMode.{ED7BA470-8E54-465E-825C-99712043E01C}')
    EndIf
    If GUICtrlRead($boxALL[3]) = $GUI_CHECKED Then
    WriteReg($path_mouse, $key_swap_buttons, $reg_type3, '1')
    DllCall("user32.dll", "int", "SystemParametersInfo", "int", 0x0021, "bool", True, "int", 0, "int", $BOTH)
    Else
    WriteReg($path_mouse, $key_swap_buttons, $reg_type3, '0')
    DllCall("user32.dll", "int", "SystemParametersInfo", "int", 0x0021, "bool", False, "int", 0, "int", $BOTH)
    EndIf
    If GUICtrlRead($boxALL[4]) = $GUI_CHECKED Then
    WriteReg($path_dekstop, $key_active_mouse, $reg_type2, '0xDF07801200000000')
    DllCall("user32.dll", "int", "SystemParametersInfo", "int", 0x1001, "int", 0, "bool", True, "int", $BOTH)
    Else
    WriteReg($path_dekstop, $key_active_mouse, $reg_type2, '0xDE07801200000000')
    DllCall("user32.dll", "int", "SystemParametersInfo", "int", 0x1001, "int", 0, "bool", False, "int", $BOTH)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Local $wert = GUICtrlRead($input_updown)
    WriteReg($path_dekstop, $key_time_active_mouse, $reg_type1, $wert)
    DllCall("user32.dll", "int", "SystemParametersInfo", "int", 0x2003, "int", 0, "int", $wert, "int", $BOTH)

    [/autoit] [autoit][/autoit] [autoit]

    ;GUICtrlSetState($Save, $Gui_Disable)
    EndFunc ;==>Save

    [/autoit] [autoit][/autoit] [autoit]

    ; restore the window to full size and hide trayicon
    Func HideTray()
    Opt('TrayIconHide', 1)
    GUISetState(@SW_SHOW, $GUI)
    GUISetState(@SW_RESTORE, $GUI)
    EndFunc ;==>HideTray

    [/autoit] [autoit][/autoit] [autoit]

    ;minimize the programwindow to tray
    Func Minimize()
    Opt('TrayIconHide', 0)
    TrayTip('Information', 'Zum Maximieren ' & @CRLF & 'Doppeklicken', 10, 1)
    TraySetIcon('icon.ico') ;
    GUISetState(@SW_HIDE, $GUI)
    Sleep(3000)
    TrayTip('Clear', '', 0)
    While 2
    Switch TrayGetMsg()
    Case $TrayShow
    HideTray()
    ExitLoop
    Case $TRAY_EVENT_PRIMARYDOUBLE
    HideTray()
    ExitLoop
    Case $TrayExit
    Exit
    Case $GUI_EVENT_MINIMIZE
    Minimize()
    EndSwitch
    WEnd
    EndFunc ;==>Minimize

    [/autoit] [autoit][/autoit] [autoit]

    ; shows the info box
    Func ShowInfo()
    WinSetOnTop($title, '', 0)
    WinSetState($title, '', @SW_DISABLE)
    WinSetTrans($title, '', 150)
    $Infobox = MsgBox(0, 'Info', 'Autor: Paul')
    If $Infobox = 1 Then
    WinSetOnTop($title, '', 1)
    WinSetTrans($title, '', 240)
    WinSetState($title, '', @SW_ENABLE)
    EndIf
    EndFunc ;==>ShowInfo

    [/autoit] [autoit][/autoit] [autoit]

    Func EnableButton()
    GUICtrlSetState($Save, $Gui_Enable)
    EndFunc ;==>EnableButton

    [/autoit] [autoit][/autoit] [autoit]

    ; GUI Msg
    While 1
    Switch GUIGetMsg()
    Case $GUI_EVENT_MINIMIZE, $Menu_Actions[1]
    Minimize()
    Case $GUI_EVENT_CLOSE, $Menu_Actions[0], $Exit
    Exit
    Case $Menu_Actions[2]
    ShowInfo()
    Case $Save
    Save()
    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func Msg($text)
    MsgBox(-1, '', $text)
    EndFunc ;==>Msg

    [/autoit]


    Mein Ziel ist die maximale Flexibilität. Es werden ziemlich sicher noch einige Controls hinzukommen. Ich möchte mein Programm einfach Schritt für Shritt erweitern, und mich nicht jetzt schon auf die Anzahl der Controls festlegen.
    Abgesehen von WM_NOTIFY, wie kann ich sonst noch die Statusüberwachung meiner Controls realisieren?

    Einmal editiert, zuletzt von pPanther (25. März 2011 um 06:12)

    • Offizieller Beitrag

    Wenn die Anzahl der Control variabel ist, empfiehlt es sich diese in einem Array zu verwalten.
    In deiner While-Schleife mit GuiGetMsg() hängst du eine Iteration durch dein Controlarray ein.
    Dann kannst du dort deine gewünschte Aktion für das Event hinterlegen.
    Bsp.:

    Spoiler anzeigen
    [autoit]


    $gui = GUICreate('test')
    Local $aCtrl[4] = [ _
    GUICtrlCreateButton('Button1', 10,20,60,20), _
    GUICtrlCreateButton('Button2', 10,50,60,20), _
    GUICtrlCreateButton('Button3', 10,80,60,20), _
    GUICtrlCreateButton('Button4', 10,110,60,20)]
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    While True
    $msg = GUIGetMsg()
    For $i = 0 To 3
    If $msg = $aCtrl[$i] Then MsgBox(0, '', ControlGetText($gui, '', $aCtrl[$i]) & ' geklickt' )
    Next
    If $msg = -3 Then Exit
    WEnd

    [/autoit]
  • Wenn du das Programm veröffentlichst, bau bitte eine Warnung für den "GodMode" auf 64Bit Systemen ein.
    Ich habs selbst nicht ausprobiert, aber der kann offenbar schwere Probleme auslösen.

    Wer andern eine Bratwurst brät
    der hat ein Bratwurstbratgerät.

  • Danke BugFix.

    Eigentlich hätte ich selbst draufkommen müssen. Ich habe hier wohl ziemlich kompliziert gedacht, dabei ist die Lösung so einfach.


    Bezüglich des GodModes ist mir zwar nichts bekannt, dass er Probleme bereiten kann. Ich benutze Ihn auf mehreren Rechnern, alle W7 x64.
    Aber danke für den Hinweis.