With ControlGet, Is it possible to also get the column header names along with the items?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Ralf_Reddings200244
Posts: 110
Joined: 11 Mar 2023, 14:16

With ControlGet, Is it possible to also get the column header names along with the items?

Post by Ralf_Reddings200244 » 10 Feb 2024, 09:09

I am able to get the items of a SysListView321 using ControlGet:

Code: Select all

ControlGet, OutputVar, List,, SysListView321, Options ahk_class #32770 ahk_exe Ditto.exe
Console(OutputVar)
Console() outputs:

Code: Select all

	Apply Last Search
Alt + C	Cancel Filter
Alt + ENTER	Clip Properties
ESC	Close Window
Ctrl + F2	Compare Selected Clips
Ctrl + C	Copy Selection
	Decrease Transparency %
	Delete all non used clips
	Delete Clip Data
Ctrl + E	Edit Clip
	EMail, Clip Export As Attachment
	EMail, Content As Attachment
	EMail, Content In Body
	Export To Google Translate
	Export To Image File
	Export To QR Code
	Export To Text File
	Filter On Selected Clip
Shift + ESC	Force Close Window
	Global HotKeys
	Gmail
...
This is neat. But is it possible to also include the names of the column headers as well?

For example, in the WINDOW I am working with, the headers are Hot key and Command. I searched around but could not find anything.

Perhaps this is something that can be accomplished by another command? I am open to suggestion even if its an external library


Thank you for helping me.

User avatar
lmstearn
Posts: 698
Joined: 11 Aug 2016, 02:32
Contact:

Re: With ControlGet, Is it possible to also get the column header names along with the items?

Post by lmstearn » 11 Feb 2024, 01:43

Hi Ralf, sure it's possible, from the ControlGet docs:

Code: Select all

ControlGet, SelectedItems, List, Selected, SysListView321, ahk_exe Ditto.exe
Loop, Parse, SelectedItems, `n  ; Rows are delimited by linefeeds (`n).
{
    RowNumber := A_Index
    Loop, Parse, A_LoopField, %A_Tab%  ; Fields (columns) in each row are delimited by tabs (A_Tab).
        MsgBox Row #%RowNumber% Col #%A_Index% is %A_LoopField%.
}
Would it work for this LV?
:arrow: itros "ylbbub eht tuO kaerB" a ni kcuts m'I pleH

User avatar
boiler
Posts: 17390
Joined: 21 Dec 2014, 02:44

Re: With ControlGet, Is it possible to also get the column header names along with the items?

Post by boiler » 11 Feb 2024, 06:39

@lmstearn - That gets all the fields of the LV (and only the selected ones). It doesn't get the header row column names, which is what OP is trying to get.

User avatar
lmstearn
Posts: 698
Joined: 11 Aug 2016, 02:32
Contact:

Re: With ControlGet, Is it possible to also get the column header names along with the items?

Post by lmstearn » 11 Feb 2024, 10:09

Shuck! Docs example looked a lot more generous than it actually was. :shock:
Try LV_Ex from @just me.
:arrow: itros "ylbbub eht tuO kaerB" a ni kcuts m'I pleH

just me
Posts: 9574
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: With ControlGet, Is it possible to also get the column header names along with the items?

Post by just me » 11 Feb 2024, 10:16

LV_EX doesn't support remote ListViews. Only messages passing numeric values in WPARAM and LPARAM might work.

User avatar
lmstearn
Posts: 698
Joined: 11 Aug 2016, 02:32
Contact:

Re: With ControlGet, Is it possible to also get the column header names along with the items?

Post by lmstearn » 11 Feb 2024, 11:08

Noted, thanks.
A while back @cyruz posted a script which opens the process owning the Listview, it then has to write to the Listview with WriteProcessMemory to retrieve the info.
Should work, so long as the existing memory allocation of the control isn't increased or borked, else you'll know when there is a error writing memory exception. :)
:arrow: itros "ylbbub eht tuO kaerB" a ni kcuts m'I pleH

User avatar
boiler
Posts: 17390
Joined: 21 Dec 2014, 02:44

Re: With ControlGet, Is it possible to also get the column header names along with the items?

Post by boiler » 11 Feb 2024, 12:42

You might also try these: Acc Viewer, UIA Interface. There are other versions of those. The most up-to-date may be for v2, but you can search for potentially more updated/better v1 ones.

Ralf_Reddings200244
Posts: 110
Joined: 11 Mar 2023, 14:16

Re: With ControlGet, Is it possible to also get the column header names along with the items?

Post by Ralf_Reddings200244 » 12 Feb 2024, 09:04

@lmstearn
@boiler

I figured out how to do it thanks to this answer by Alguimist. Of all the potential solution's, theirs was the only one that would let me do it remotely, that is without activating the controls window.

It was critical that I achieve a means to do it 'remotely' as I was intending to use it for a PowerShell module that gets the values of various controls, such as combo box, button, edit etc.
Image


My humble developer endevours should now be slightly less painfull

Alguimist's source code:

Code: Select all

	;https://www.autohotkey.com/boards/viewtopic.php?p=231012#p231012
	; Returns an object containing the text and width of each item of a remote SysHeader32 control
	CTRL_GetHeader(hHeader){
		Static MAX_TEXT_LENGTH := 260
			, MAX_TEXT_SIZE := MAX_TEXT_LENGTH * (A_IsUnicode ? 2 : 1)

		WinGet PID, PID, ahk_id %hHeader%

		; Open the process for read/write and query info.
		; PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION
		If !(hProc := DllCall("OpenProcess", "UInt", 0x438, "Int", False, "UInt", PID, "Ptr")) {
			Return
		}

		; Should we use the 32-bit struct or the 64-bit struct?
		If (A_Is64bitOS) {
			Try DllCall("IsWow64Process", "Ptr", hProc, "int*", Is32bit := true)
		} Else {
			Is32bit := True
		}

		RPtrSize := Is32bit ? 4 : 8
		cbHDITEM := (4 [i] 6) + (RPtrSize [/i] 6)

		; Allocate a buffer in the (presumably) remote process.
		remote_item := DllCall("VirtualAllocEx", "Ptr", hProc, "Ptr", 0
									, "uPtr", cbHDITEM + MAX_TEXT_SIZE
									, "UInt", 0x1000, "UInt", 4, "Ptr") ; MEM_COMMIT, PAGE_READWRITE
		remote_text := remote_item + cbHDITEM

		; Prepare the HDITEM structure locally.
		VarSetCapacity(HDITEM, cbHDITEM, 0)
		NumPut(0x3, HDITEM, 0, "UInt") ; mask (HDI_WIDTH | HDI_TEXT)
		NumPut(remote_text, HDITEM, 8, "Ptr") ; pszText
		NumPut(MAX_TEXT_LENGTH, HDITEM, 8 + RPtrSize * 2, "Int") ; cchTextMax

		; Write the local structure into the remote buffer.
		DllCall("WriteProcessMemory", "Ptr", hProc, "Ptr", remote_item, "Ptr", &HDITEM, "uPtr", cbHDITEM, "Ptr", 0)

		HDInfo := {}
		VarSetCapacity(HDText, MAX_TEXT_SIZE)

		SendMessage 0x1200, 0, 0,, ahk_id %hHeader% ; HDM_GETITEMCOUNT
		Loop % (ErrorLevel != "FAIL") ? ErrorLevel : 0 {
			; Retrieve the item text.
			SendMessage, % (A_IsUnicode) ? 0x120B : 0x1203, A_Index [list]1, remote_item,, ahk_id %hHeader% ; HDM_GETITEMW[/list]
			If (ErrorLevel == 1) { ; Success
				DllCall("ReadProcessMemory", "Ptr", hProc, "Ptr", remote_item, "Ptr", &HDITEM, "uPtr", cbHDITEM, "Ptr", 0)
				DllCall("ReadProcessMemory", "Ptr", hProc, "Ptr", remote_text, "Ptr", &HDText, "uPtr", MAX_TEXT_SIZE, "Ptr", 0)
			} Else {
				HDText := ""
			}

			HDInfo.Push({"Width": NumGet(HDITEM, 4, "UInt"), "Text": HDText})
		}

		; Release the remote memory and handle.
		DllCall("VirtualFreeEx", "Ptr", hProc, "Ptr", remote_item, "UPtr", 0, "UInt", 0x8000) ; MEM_RELEASE
		DllCall("CloseHandle", "Ptr", hProc)

		Return HDInfo
	}

Post Reply

Return to “Ask for Help (v1)”