Jump to content

GetDlgCtrlID


Recommended Posts

  • Moderators

Hi,

I was trying to solve another problem on the forums when I came across a small difficulty. I was trying to get a ControlID from a Windows handle - thanks to ResNullius in another thread I know that _WinAPI_GetDlgCtrlID should do this. However, I was dealing with a TreeView and it seems that this function does not work with TreeViewItems:

#include <WinAPI.au3>

GUICreate("GetDlgCtrlID Test")

$hButton = GUICtrlCreateButton("", 10, 10, 80, 30)
    $Button_handle = GUICtrlGetHandle($hButton)
    $Button_ID = _WinAPI_GetDlgCtrlID($Button_handle)
    ConsoleWrite($hButton & " - " & $Button_handle & " - " & $Button_ID & @CRLF & @CRLF)

$hTree = GUICtrlCreateTreeView(6, 6, 1920/3, 1200/3)
    $Tree_handle = GUICtrlGetHandle($hTree)
    $Tree_ID = _WinAPI_GetDlgCtrlID($Tree_handle)
    ConsoleWrite($hTree & " - " & $Tree_handle & " - " & $Tree_ID & @CRLF & @CRLF)

For $i = 0 To 5
    $TreeItem = GUICtrlCreateTreeViewItem($i, $hTree)
        $TreeItem_handle = GUICtrlGetHandle($TreeItem)
        $TreeItem_ID = _WinAPI_GetDlgCtrlID($TreeItem_handle)
        ConsoleWrite($TreeItem & " - " & $TreeItem_handle & " - " & $TreeItem_ID & @CRLF)
Next

Exit

As you can see from the output in SciTE, the button and the TreeView have ControlIDs which, when converted into a handle, then return the correct ControlID via the API call. However, although the TreeViewItems ControlIDs generate seemingly normal handles, these handles do not return the ControlID when passed through the API.

Although I got round the difficulty by creating an array containing the TreeViewitem handles and then searching that (which is what prompted ResNullius to tell me about _WinAPI_GetDlgCtrlID in the first place!), I would be grateful if anyone could explain why the API function fails in this case - and if it happens to other controls as well.

Thanks in advance,

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • 1 month later...

Hi,

I was trying to solve another problem on the forums when I came across a small difficulty. I was trying to get a ControlID from a Windows handle - thanks to ResNullius in another thread I know that _WinAPI_GetDlgCtrlID should do this. However, I was dealing with a TreeView and it seems that this function does not work with TreeViewItems:

#include <WinAPI.au3>

GUICreate("GetDlgCtrlID Test")

$hButton = GUICtrlCreateButton("", 10, 10, 80, 30)
    $Button_handle = GUICtrlGetHandle($hButton)
    $Button_ID = _WinAPI_GetDlgCtrlID($Button_handle)
    ConsoleWrite($hButton & " - " & $Button_handle & " - " & $Button_ID & @CRLF & @CRLF)

$hTree = GUICtrlCreateTreeView(6, 6, 1920/3, 1200/3)
    $Tree_handle = GUICtrlGetHandle($hTree)
    $Tree_ID = _WinAPI_GetDlgCtrlID($Tree_handle)
    ConsoleWrite($hTree & " - " & $Tree_handle & " - " & $Tree_ID & @CRLF & @CRLF)

For $i = 0 To 5
    $TreeItem = GUICtrlCreateTreeViewItem($i, $hTree)
        $TreeItem_handle = GUICtrlGetHandle($TreeItem)
        $TreeItem_ID = _WinAPI_GetDlgCtrlID($TreeItem_handle)
        ConsoleWrite($TreeItem & " - " & $TreeItem_handle & " - " & $TreeItem_ID & @CRLF)
Next

Exit

As you can see from the output in SciTE, the button and the TreeView have ControlIDs which, when converted into a handle, then return the correct ControlID via the API call. However, although the TreeViewItems ControlIDs generate seemingly normal handles, these handles do not return the ControlID when passed through the API.

Although I got round the difficulty by creating an array containing the TreeViewitem handles and then searching that (which is what prompted ResNullius to tell me about _WinAPI_GetDlgCtrlID in the first place!), I would be grateful if anyone could explain why the API function fails in this case - and if it happens to other controls as well.

Thanks in advance,

M23

I have the same problem. Their returning handles cannot "return" their IDs by using _WinAPI_GetDlgCtrlID or this function

Func GetControlID($hwnd)

Local $ID = DllCall('user32.dll', 'int', 'GetDlgCtrlID', 'hwnd', $hwnd)

if IsArray ($ID) Then Return $ID[0]

Return 0

EndFunc

Why is that and how to rezolv the "problem"?

Link to comment
Share on other sites

It's because it's a work of AutoIt to store tree view item (and thus list view items?) handles with the next available ID in the lparam of the item's structure:

#include <GuiTreeView.au3>
#include <WinAPI.au3>

GUICreate("GetDlgCtrlID Test")

$hButton = GUICtrlCreateButton("", 10, 10, 80, 30)
    $Button_handle = GUICtrlGetHandle($hButton)
    $Button_ID = _WinAPI_GetDlgCtrlID($Button_handle)
    ConsoleWrite($hButton & " - " & $Button_handle & " - " & $Button_ID & @CRLF & @CRLF)

$hTree = GUICtrlCreateTreeView(6, 6, 1920/3, 1200/3)
    $Tree_handle = GUICtrlGetHandle($hTree)
    $Tree_ID = _WinAPI_GetDlgCtrlID($Tree_handle)
    ConsoleWrite($hTree & " - " & $Tree_handle & " - " & $Tree_ID & @CRLF & @CRLF)

For $i = 0 To 5
    $TreeItem = GUICtrlCreateTreeViewItem($i, $hTree)
        $TreeItem_handle = GUICtrlGetHandle($TreeItem)
        $TreeItem_ID = _WinAPI_GetDlgCtrlID($TreeItem_handle)
        ConsoleWrite($TreeItem & " - " & $TreeItem_handle & " - " & $TreeItem_ID & @CRLF)
Next
    
ConsoleWrite(@LF & @LF)

For $i = 0 To 5
    $TreeItem = GUICtrlCreateTreeViewItem($i, $hTree)
    $TreeItem_handle = GUICtrlGetHandle($TreeItem)
    $TreeItem_ID = _GUICtrlTreeView_GetItemParam($Tree_handle, $TreeItem_handle)
    ConsoleWrite($TreeItem & " - " & $TreeItem_handle & " - " & $TreeItem_ID & @CRLF)
Next

Exit
Link to comment
Share on other sites

  • Moderators

Authenticity,

Thanks for the explanation - it had been puzzling me for a while.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

It's because it's a work of AutoIt to store tree view item (and thus list view items?) handles with the next available ID in the lparam of the item's structure:

#include <GuiTreeView.au3>
#include <WinAPI.au3>

GUICreate("GetDlgCtrlID Test")

$hButton = GUICtrlCreateButton("", 10, 10, 80, 30)
    $Button_handle = GUICtrlGetHandle($hButton)
    $Button_ID = _WinAPI_GetDlgCtrlID($Button_handle)
    ConsoleWrite($hButton & " - " & $Button_handle & " - " & $Button_ID & @CRLF & @CRLF)

$hTree = GUICtrlCreateTreeView(6, 6, 1920/3, 1200/3)
    $Tree_handle = GUICtrlGetHandle($hTree)
    $Tree_ID = _WinAPI_GetDlgCtrlID($Tree_handle)
    ConsoleWrite($hTree & " - " & $Tree_handle & " - " & $Tree_ID & @CRLF & @CRLF)

For $i = 0 To 5
    $TreeItem = GUICtrlCreateTreeViewItem($i, $hTree)
        $TreeItem_handle = GUICtrlGetHandle($TreeItem)
        $TreeItem_ID = _WinAPI_GetDlgCtrlID($TreeItem_handle)
        ConsoleWrite($TreeItem & " - " & $TreeItem_handle & " - " & $TreeItem_ID & @CRLF)
Next
    
ConsoleWrite(@LF & @LF)

For $i = 0 To 5
    $TreeItem = GUICtrlCreateTreeViewItem($i, $hTree)
    $TreeItem_handle = GUICtrlGetHandle($TreeItem)
    $TreeItem_ID = _GUICtrlTreeView_GetItemParam($Tree_handle, $TreeItem_handle)
    ConsoleWrite($TreeItem & " - " & $TreeItem_handle & " - " & $TreeItem_ID & @CRLF)
Next

Exit

What if i use _GUICtrlTreeView_Add() instead of GUICtrlCreateTreeViewItem() ? That's something i can't figure it out cause the first returns the handle and with _WinAPI_GetDlgCtrlID() it always returns 0x00000000. WHY IS THAT ?

_GUICtrlTreeView_GetItemParam($Tree_handle, $TreeItem_handle) also returns always 0. My params are handles of the tree/item so why is that 0 there ?

Edited by OmYcroN
Link to comment
Share on other sites

Tree view items have nothing to do with identifiers other than handles. lol I'm not AutoIt developer but if I remember correctly, one member of this forum noted this. And by doing 1+1 you can assume that creating tree-view items using GUICtrlCreateTreeView() and then creating it's items using _GUICtrlTreeView_AddItem you're actually breaking the functionality of GUICtrlRead with this tree-view control. But anyway, it's still possible to get selected item and item text using the _GUICtrlTreeView_* functions, you're working with handles as API is working ;].

Link to comment
Share on other sites

Tree view items have nothing to do with identifiers other than handles. lol I'm not AutoIt developer but if I remember correctly, one member of this forum noted this. And by doing 1+1 you can assume that creating tree-view items using GUICtrlCreateTreeView() and then creating it's items using _GUICtrlTreeView_AddItem you're actually breaking the functionality of GUICtrlRead with this tree-view control. But anyway, it's still possible to get selected item and item text using the _GUICtrlTreeView_* functions, you're working with handles as API is working ;].

OK ... _GUICtrlTreeView_AddItem() returns handles and GUICtrlCreateTreeViewItem() returns Ids ... How can i use handles in this case :

While True

$GUI_MSG = GUIGetMsg()

Switch $GUI_MSG

Case $GUI_EVENT_CLOSE

Exit

Case $hanadles[0] to $hanadles[n]

THIS IS EXECUTED FOREVER ... WHY ? ... with IDs it's working correctly, no loop ... i know what was clicked etc ... with handles i have no control

EndSwitch

WEnd

Link to comment
Share on other sites

You have, use GUIRegisterMsg($WM_NOTIFY, 'OnNotify'), or use GUIGetMsg(1)...

GUIGetMsg(1) returns an array and i m lookink for $array[0] right ?! ... But still in the switch case the code is executed forever and the return values of the array are always 0 ... a button or checkbox works normal but this ... don't understand why this is executed on running

Case $hanadles[0] to $hanadles[n]

It s because they are handles ?

Edited by OmYcroN
Link to comment
Share on other sites

Hi, sorry for late reply. I don't know why it's falling to this case but anyway, with handles it's as followed:

#include <GUITreeView.au3>
#include <WindowsConstants.au3>

Dim $hGUI = GUICreate('Test', 250, 300)
Dim $hTreeView = _GUICtrlTreeView_Create($hGUI, 0, 0, 250, 300)

_GUICtrlTreeView_BeginUpdate($hTreeView)
Dim $hParent = _GUICtrlTreeView_Add($hTreeView, 0, 'Parent')
For $i = 1 To 10
    _GUICtrlTreeView_AddChild($hTreeView, $hParent, 'Child #' & $i)
Next
_GUICtrlTreeView_EndUpdate($hTreeView)

GUIRegisterMsg($WM_NOTIFY, 'OnNotify')
GUISetState()

Do
    Sleep(20)
Until GUIGetMsg() = -3

_GUICtrlTreeView_Destroy($hTreeView)
GUIDelete()

Func OnNotify($hwnd, $iMsg, $iwParam, $ilParam)
    Local $tNMTV = DllStructCreate($tagNMTREEVIEW, $ilParam)
    Local $hwndFrom = DllStructGetData($tNMTV, 'hWndFrom')
    Local $iCode = DllStructGetData($tNMTV, 'Code')
    
    If $hwndFrom = $hTreeView And $iCode = $TVN_SELCHANGED Then
        ConsoleWrite(_GUICtrlTreeView_GetText($hTreeView, DllStructGetData($tNMTV, 'NewhItem')) & @LF)
    EndIf
EndFunc
Link to comment
Share on other sites

Hi, sorry for late reply. I don't know why it's falling to this case but anyway, with handles it's as followed:

#include <GUITreeView.au3>
#include <WindowsConstants.au3>

Dim $hGUI = GUICreate('Test', 250, 300)
Dim $hTreeView = _GUICtrlTreeView_Create($hGUI, 0, 0, 250, 300)

_GUICtrlTreeView_BeginUpdate($hTreeView)
Dim $hParent = _GUICtrlTreeView_Add($hTreeView, 0, 'Parent')
For $i = 1 To 10
    _GUICtrlTreeView_AddChild($hTreeView, $hParent, 'Child #' & $i)
Next
_GUICtrlTreeView_EndUpdate($hTreeView)

GUIRegisterMsg($WM_NOTIFY, 'OnNotify')
GUISetState()

Do
    Sleep(20)
Until GUIGetMsg() = -3

_GUICtrlTreeView_Destroy($hTreeView)
GUIDelete()

Func OnNotify($hwnd, $iMsg, $iwParam, $ilParam)
    Local $tNMTV = DllStructCreate($tagNMTREEVIEW, $ilParam)
    Local $hwndFrom = DllStructGetData($tNMTV, 'hWndFrom')
    Local $iCode = DllStructGetData($tNMTV, 'Code')
    
    If $hwndFrom = $hTreeView And $iCode = $TVN_SELCHANGED Then
        ConsoleWrite(_GUICtrlTreeView_GetText($hTreeView, DllStructGetData($tNMTV, 'NewhItem')) & @LF)
    EndIf
EndFunc

Looks good and works but how can i check if the parent is checked ($hParent) cause here i can see only if it's selected ? $TVN_SELCHANGED should be another value here ?!

Link to comment
Share on other sites

EXAMPLE :

$hTreeView = _GUICtrlTreeView_Create($hGUI, 5, 5, $GUI_WIDTH - 10, Int((90 * $GUI_HEIGHT) / 100), BitOR($TVS_HASBUTTONS, $TVS_HASLINES , $TVS_LINESATROOT, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES, $TVS_DISABLEDRAGDROP), $WS_EX_CLIENTEDGE)

_GUICtrlTreeView_BeginUpdate($hTreeView)

For $i = 0 To $n
    $hTreeViewParents[$i] = _GUICtrlTreeView_Add($hTreeView, 0, $t1[$i])

    For $j = 0 To $m    
        $hTreeViewChilds[$j] = _GUICtrlTreeView_AddChild($hTreeView, $hTreeViewParents[$i], $t2[$j])
    Next
Next

_GUICtrlTreeView_EndUpdate($hTreeView)

QUESTION :

How can i control $hTreeViewParents[$i] or $hTreeViewChilds[$j] with your function OnNotify($hwnd, $iMsg, $iwParam, $ilParam)

to see if one of $hTreeViewParents[$i] or $hTreeViewChilds[$j] is selected/checked etc ?

Edited by OmYcroN
Link to comment
Share on other sites

You can do a simple loop and check the 'NewhItem' of the structure but I don't see why you need to store the handles if you know all the things you need from the structure members...

Edit: Oh... checked/selected. You'll need to query their state when needed. Like when the user is willing to save changes or update something...

Edited by Authenticity
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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...