 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Micahs
Joined: 01 Dec 2006 Posts: 338
|
Posted: Thu Mar 29, 2007 9:19 am Post subject: [SOLVED] Tab Caption with SysTabControl321 & TCM_GETITEM |
|
|
I'm having problems with getting the caption of tabs. This code tries to get tab 1 caption from SciTE, but only crashes SciTE and also Dr Watson.
The first SendMessage works and it gets the number of tabs, so the TabControl is responding. I think the problem is how the structure is set up for the TCM_GETITEM SendMessage. Is there something obvious that I'm missing?
| Code: | WinGetActiveTitle, aTitle
SendMessage, 0x1304, 0, 0, SysTabControl321, %aTitle% ahk_class SciTEWindow ;TCM_GETITEMCount
TabCount := ErrorLevel
;1 - byte0 - mask
;2 - byte4 - dwState
;3 - byte8 - dwStateMask
;4 - byte12 - pszText
;5 - byte16 - cchTextMax
;6 - byte20 - iImage
;7 - byte24 - lParam
VarSetCapacity(TabName,128,0) ;allocate var
VarSetCapacity(TCITEM, 100, 0) ;allocate var
InsertInteger(1, TCITEM, 0) ;Mask - TCIF_TEXT
InsertInteger(&TabName, TCITEM, 12) ;pszText
InsertInteger(128, TCITEM, 16) ;cchTextMax
SendMessage, 0x1305, 1, &TCITEM, SysTabControl321, %aTitle% ahk_class SciTEWindow ;TCM_GETITEM
msgbox,%ErrorLevel%`n%TabCount%`n%TabName%
|
Thanks! _________________
 |
|
| Back to top |
|
 |
Micahs
Joined: 01 Dec 2006 Posts: 338
|
Posted: Wed Apr 04, 2007 7:15 am Post subject: |
|
|
The problem was that for certain calls that require structures, you have to manage the memory space stuff yourself with OpenProcess and VirtualAllocEx.
The example returns the tab captions from the specified window in a comma-delimited string.
I made it a function for ease-of-use. You specifiy the window Title, ClassNN, TabControl ClassNN, and tab number:
| Code: | | getTabText(vTitle, vWin, vControl, vTabnum) |
| Code: | ;reference (thanks shimanov): http://www.autohotkey.com/forum/viewtopic.php?t=8840
aTitle := "AutoHotkey Help"
sWin := "HH Parent"
sControl := "SysTabControl321"
SendMessage, 0x1304, 0, 0, %sControl%, %aTitle% ahk_class %sWin% ;TCM_GETITEMCount
TabCount := ErrorLevel ;get number of tabs
tabs=
loop %TabCount%
{ sTabnum := A_Index - 1
vTab := getTabText(aTitle, sWin, sControl, sTabnum)
tabs .= vTab . ","
}
msgbox,%tabs%
Return
;vTitle=window title vWin=window class vControl=control ClassNN vTabNum=tab number
getTabText(vTitle, vWin, vControl, vTabnum)
{
global
WinGet, pid_target, PID, %vTitle% ahk_class %vWin%
;get handle to process inside pid_target ;0x38=PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE
remote_process := DllCall("OpenProcess", "uint", 0x38, "int", false, "uint", pid_target)
IfEqual, remote_process, , Goto errEnd
;get address allocated for foreign structure ;0x1000=MEM_COMMIT ;0x4=PAGE_READWRITE
remote_struct := DllCall("VirtualAllocEx", "uint", remote_process, "uint", 0, "uint", 20, "uint", 0x1000, "uint", 0x4)
IfEqual, remote_struct, , Goto errEnd
;get address allocated for foreign text buffer ;0x1000=MEM_COMMIT ;0x4=PAGE_READWRITE
remote_buffer := DllCall("VirtualAllocEx", "uint", remote_process, "uint", 0, "uint", 128, "uint", 0x1000, "uint", 0x4)
IfEqual, remote_buffer, , Goto errEnd
;create structure for TCM_GETITEM
VarSetCapacity(TCITEM, 20, 1) ;allocate var
InsertInteger(1, TCITEM, 0) ;Mask - TCIF_TEXT=1
InsertInteger(remote_buffer, TCITEM, 12) ;pszText
InsertInteger(128, TCITEM, 16) ;cchTextMax
;write structure to foreign address
res := DllCall( "WriteProcessMemory", "uint", remote_process, "uint", remote_struct, "uint", &TCITEM, "uint", 20, "uint", 0 )
SendMessage, 0x1305, %vTabnum%, remote_struct, %vControl%, ahk_pid %pid_target% ;TCM_GETITEM
getres = %ErrorLevel% ;get the info for the tab
VarSetCapacity(TabName, 128, 1) ;get the tab text
result := DllCall("ReadProcessMemory", "uint", remote_process, "uint", remote_buffer, "uint", &TabName, "uint", 128, "uint", 0)
free()
Return TabName
errEnd:
free()
Return "Fail"
}
free()
{
global
;free buffer
result := DllCall( "VirtualFreeEx", "uint", remote_process, "uint", remote_buffer, "uint", 0, "uint", 0x8000 ) ; MEM_RELEASE
;free structure
result := DllCall( "VirtualFreeEx", "uint", remote_process, "uint", remote_struct, "uint", 0, "uint", 0x8000 ) ; MEM_RELEASE
;free willy
result := DllCall( "CloseHandle", "uint", remote_process )
}
ExtractInteger(ByRef pSource, pOffset = 0, pIsSigned = false, pSize = 4)
; pSource is a string (buffer) whose memory area contains a raw/binary integer at pOffset.
; The caller should pass true for pSigned to interpret the result as signed vs. unsigned.
; pSize is the size of PSource's integer in bytes (e.g. 4 bytes for a DWORD or Int).
; pSource must be ByRef to avoid corruption during the formal-to-actual copying process
; (since pSource might contain valid data beyond its first binary zero).
{
Loop %pSize% ; Build the integer by adding up its bytes.
result += *(&pSource + pOffset + A_Index-1) << 8*(A_Index-1)
if (!pIsSigned OR pSize > 4 OR result < 0x80000000)
return result ; Signed vs. unsigned doesn't matter in these cases.
; Otherwise, convert the value (now known to be 32-bit) to its signed counterpart:
return -(0xFFFFFFFF - result + 1)
}
InsertInteger(pInteger, ByRef pDest, pOffset = 0, pSize = 4)
; The caller must ensure that pDest has sufficient capacity. To preserve any existing contents in pDest,
; only pSize number of bytes starting at pOffset are altered in it.
{
Loop %pSize% ; Copy each byte in the integer into the structure as raw binary data.
DllCall("RtlFillMemory", "UInt", &pDest + pOffset + A_Index-1, "UInt", 1, "UChar", pInteger >> 8*(A_Index-1) & 0xFF)
}
|
[EDIT]Fixed typo - thanks skrommel! _________________

Last edited by Micahs on Sat May 24, 2008 3:56 pm; edited 2 times in total |
|
| Back to top |
|
 |
skrommel
Joined: 30 Jul 2004 Posts: 177
|
Posted: Wed Jun 20, 2007 7:50 pm Post subject: small error |
|
|
There's a small typo in the 8th line in the code above:
| Code: | | TabCount := ErrorLevel - get number of tabs |
should read
| Code: | | TabCount := ErrorLevel ; get number of tabs |
_________________ www.1HourSoftware.com |
|
| Back to top |
|
 |
SanskritFritz
Joined: 17 Feb 2005 Posts: 283 Location: Hungary, Budapest
|
Posted: Thu Aug 09, 2007 9:34 am Post subject: |
|
|
I tried the script with Skrommel's correction, but still, it does not return the captions. What can be wrong? (yes AHK help window is open) _________________ Is there another word for synonym? |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|