Sheri Posted May 23, 2008 Share Posted May 23, 2008 I'm new to scripting in AutoIt. I'm not a programmer but am not a complete newbie to script writing. I'd like to get the text in part 3 of a Delphi app's. The Class Name for a standard Delphi statusbar is TStatusBar. I have the handle to one as $statusbar. I know that if you can be in the same process space it would respond to normal windows statusbar messages. This doesn't work: $sbtext = StatusbarGetText ( $statusbar , "", 3 ) It looked like maybe this would work: $sbtext = _GuiCtrlStatusBar_GetText ($statusbar, 3) but it generated the following error. Btw, when I look at the referenced file and function, it looks like it DOES have an EndFunc. I have not attempted to figure out how or why this got called, but I assume I would need to do something to allow access to the app's process before _GuiCtrlStatusBar_GetText ($statusbar, 3) would work? Line 59 (File "C:\Program Files\AutoIt3\Include\Security.au3"): Func _Security_AdjustTokenPrivileges($hToken, $DisableAll, $pNewState, $BufferLen, $pPrevState = 0, $pRequired = 0) Error: "Func" statement has no matching "EndFunc". Thanks, Sheri Link to comment Share on other sites More sharing options...
Zedna Posted May 23, 2008 Share Posted May 23, 2008 Delphi uses non-standard StatusBar so these AutoIt's StatusBar functions couldn't be used.I don't know how to retrieve such text. Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
Sheri Posted May 25, 2008 Author Share Posted May 25, 2008 (edited) I did solve this btw, but I did it using process, memory, and dllstruct functions to get around the other process issue. After that just needed a simple SB_GetText SendMessage to the TStatusBar control. I thought AutoIt would have a simple function for this but apparently the StatusbarGetText function is restricted to a specific class name of msctls_statusbar32 for a statusbar. Autoit's function could probably be enhanced to remove the restriction and let you give the handle to the statusbar whose text you want. Edited May 25, 2008 by Sheri Link to comment Share on other sites More sharing options...
Zedna Posted May 25, 2008 Share Posted May 25, 2008 I did solve this btw, but I did it using process, memory, and dllstruct functions to get around the other process issue. After that just needed a simple SB_GetText SendMessage to the TStatusBar control.Can you post this script? I'm interested in this solution. Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
Sheri Posted May 25, 2008 Author Share Posted May 25, 2008 Can you post this script? I'm interested in this solution. OK, it took awhile for me to adapt it for more general purpose than what I had done and since I'm new to AutoIt I was fighting syntax errors (which I still don't understand what was causing them ). Plus I don't want to mislead, I got a lot of the "how" from what others did with other scripting tools. This is GeneralStatusBarText.au3: expandcollapse popup#cs ---------------------------------------------------------------------------- AutoIt Version: 3.2.12.0 Author: Sheri Pierce Script Function: General Function to get status bar text $mainhwnd is handle to the main application window $statusbarhwnd is handle to the statusbar control $panel is the zero-based part of the status bar whose text is wanted #ce ---------------------------------------------------------------------------- #Include <Memory.au3> Func _GetStandardStatusBarText($mainhwnd, $statusbarhwnd, $panel) $WM_USER = 0x0400 $SB_GETTEXTLENGTH = $WM_USER + 3 $SB_GETTEXT = $WM_USER + 2 $PROCESS_ALL_ACCESS = 0x1F0FFF Local $len = _SendMessage ($statusbarhwnd, $SB_GETTEXTLENGTH, $panel, 0) Local $draw = _WinAPI_HiWord($len) if ($draw <> 0) Then $statusbartext = "" Else Local $processid = WinGetProcess ( $mainhwnd ) Local $phan = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, 0, $processid) Local $mem = _MemVirtualAllocEx($phan, 0, $len, $MEM_COMMIT, $PAGE_READWRITE) Local $retrievemem=DllStructCreate("char buffer[" & $len & "]") Local $retrieveptr=DllStructGetPtr ( $retrievemem ) _SendMessage($statusbarhwnd, $SB_GETTEXT, $panel, $mem) Local $iRead _WinAPI_ReadProcessMemory ($phan, $mem, $retrieveptr, $len, $iRead) _MemVirtualFreeEx ($phan, $mem, $len, $MEM_RELEASE) _WinAPI_CloseHandle ($phan) Local $sbtext = DllStructGetData ($retrievemem, "buffer" ) Local $statusbartext = DllStructGetData ($retrievemem, "buffer" ) $retrievemem = 0 Return $statusbartext EndIf EndFunc Here is a sample script to use it. You will press Ctrl+W to see the status bar panel texts of the active window. Strangely some windows have multiple instances of status bar controls. The sample script looks at the first instance only. #Include "GeneralStatusBarText.au3" HotKeySet ("^w", "CC") While 1 Sleep(100) WEnd Func CC() Local $WM_USER = 0x0400 Local $SB_GETPARTS = $WM_USER + 6 Local $mainhwnd = WinGetHandle("Active") Local $statusbarhwnd = ControlGetHandle ($mainhwnd, "", "[REGEXPCLASS:(?i).*StatusBar.*; INSTANCE:1]") Local $panelcount = _SendMessage($statusbarhwnd, $SB_GETPARTS, 0, 0) Local $statusbartext Local $panel For $panel = 0 to $panelcount-1 $statusbartext = $statusbartext & @CRLF & $panel & ": " & _ _GetStandardStatusBarText($mainhwnd, $statusbarhwnd, $panel) Next MsgBox("0", "GeneralStatusBarText Demo", WingetTitle($mainhwnd) & @CRLF & $statusbartext) Return EndFunc Link to comment Share on other sites More sharing options...
Zedna Posted May 25, 2008 Share Posted May 25, 2008 @Sheri Many thanks for posting your stuff. It works GREAT!! I just corrected code to work also on WIN9x systems. As you can see in _MemInit() UDF there are different _MemVirtualAlloc() / _MemVirtualFree() functions on WINXP/ WIN9x systems. Here is your chaanged UDF: Func _GetStandardStatusBarText($mainhwnd, $statusbarhwnd, $panel) ;~ $WM_USER = 0x0400 ;~ $PROCESS_ALL_ACCESS = 0x1F0FFF $SB_GETTEXTLENGTH = $WM_USER + 3 $SB_GETTEXT = $WM_USER + 2 Local $len = _SendMessage ($statusbarhwnd, $SB_GETTEXTLENGTH, $panel, 0) Local $draw = _WinAPI_HiWord($len) if ($draw <> 0) Then $statusbartext = "" Else Local $processid = WinGetProcess ( $mainhwnd ) Local $phan = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, 0, $processid) If @OSTYPE = "WIN32_WINDOWS" Then Local $mem = _MemVirtualAlloc(0, $len, BitOR($MEM_RESERVE, $MEM_COMMIT, $MEM_SHARED), $PAGE_READWRITE) Else Local $mem = _MemVirtualAllocEx($phan, 0, $len, $MEM_COMMIT, $PAGE_READWRITE) EndIf Local $retrievemem=DllStructCreate("char buffer[" & $len & "]") Local $retrieveptr=DllStructGetPtr ( $retrievemem ) _SendMessage($statusbarhwnd, $SB_GETTEXT, $panel, $mem) Local $iRead _WinAPI_ReadProcessMemory ($phan, $mem, $retrieveptr, $len, $iRead) If @OSTYPE = "WIN32_WINDOWS" Then _MemVirtualFree ($mem, $len, $MEM_RELEASE) Else _MemVirtualFreeEx ($phan, $mem, $len, $MEM_RELEASE) EndIf _WinAPI_CloseHandle ($phan) Local $sbtext = DllStructGetData ($retrievemem, "buffer" ) Local $statusbartext = DllStructGetData ($retrievemem, "buffer" ) $retrievemem = 0 Return $statusbartext EndIf EndFunc Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
Siao Posted May 25, 2008 Share Posted May 25, 2008 I don't think it's any different from what _GuiCtrlStatusBar_GetText does. "be smart, drink your wine" Link to comment Share on other sites More sharing options...
Zedna Posted May 25, 2008 Share Posted May 25, 2008 I don't think it's any different from what _GuiCtrlStatusBar_GetText does.Yeah you are right. He accidentally reinvented the wheel.I'm courious about that because AutoIt's internal StatusbarGetText() doesn't work in this case but _GUICtrlStatusBar_GetText() works! Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
Sheri Posted May 25, 2008 Author Share Posted May 25, 2008 I don't think it's any different from what _GuiCtrlStatusBar_GetText does.The status bar text I get with that function is truncated/incomplete. Are you sure it is working for you? Link to comment Share on other sites More sharing options...
Zedna Posted May 25, 2008 Share Posted May 25, 2008 The status bar text I get with that function is truncated/incomplete. Are you sure it is working for you? It works fine for me (no truncation). #include <GUIStatusBar.au3> MsgBox(0,'StatusBar_GetText_All',StatusBar_GetText_All(ControlGetHandle('My title','','TStatusBar1'))) Func StatusBar_GetText_All($statusbarhwnd) Local $statusbartext Local $panelcount = _SendMessage($statusbarhwnd, $SB_GETPARTS, 0, 0) For $panel = 0 to $panelcount-1 $statusbartext &= $panel & ": " & _GUICtrlStatusBar_GetText($statusbarhwnd, $panel) & @CRLF Next Return $statusbartext EndFunc Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
Sheri Posted May 25, 2008 Author Share Posted May 25, 2008 It works fine for me (no truncation). #include <GUIStatusBar.au3> MsgBox(0,'StatusBar_GetText_All',StatusBar_GetText_All(ControlGetHandle('My title','','TStatusBar1'))) Func StatusBar_GetText_All($statusbarhwnd) Local $statusbartext Local $panelcount = _SendMessage($statusbarhwnd, $SB_GETPARTS, 0, 0) For $panel = 0 to $panelcount-1 $statusbartext &= $panel & ": " & _GUICtrlStatusBar_GetText($statusbarhwnd, $panel) & @CRLF Next Return $statusbartext EndFunc (sorry, reposting cos just learning to use the forum software) Totally every panel is truncated for me. Example output of your (Zedna's) scriptlet accessing PSPad: --------------------------- StatusBar_GetText_All --------------------------- 0: 16 : 28 ( 1: 2: 3: 4: 5: T 8 6: Powe 7: D 8: Code page: AN --------------------------- OK --------------------------- Link to comment Share on other sites More sharing options...
Zedna Posted May 25, 2008 Share Posted May 25, 2008 (edited) I tested it on my WIN98SE with AutoIt 3.2.10. You probably use Unicode. Try to run it on AutoIt 3.2.11.xx beta or 3.2.12 where are corrected UDFs also for Unicode. Func _GUICtrlStatusBar_GetText($hWnd, $iPart) If $Debug_SB Then _GUICtrlStatusBar_ValidateClassName($hWnd) Local $iBuffer, $pBuffer, $tBuffer, $pMemory, $tMemMap $iBuffer = _GUICtrlStatusBar_GetTextLength($hWnd, $iPart) If $iBuffer = 0 Then Return "" If @AutoItUnicode Then $tBuffer = DllStructCreate("wchar Text[" & $iBuffer & "]") Else $tBuffer = DllStructCreate("char Text[" & $iBuffer & "]") EndIf $pBuffer = DllStructGetPtr($tBuffer) If _WinAPI_InProcess($hWnd, $__ghSBLastWnd) Then If @AutoItUnicode Then _SendMessage($hWnd, $SB_GETTEXTW, $iPart, $pBuffer, 0, "wparam", "ptr") Else _SendMessage($hWnd, $SB_GETTEXT, $iPart, $pBuffer, 0, "wparam", "ptr") EndIf Else $pMemory = _MemInit($hWnd, $iBuffer, $tMemMap) If @AutoItUnicode Then _SendMessage($hWnd, $SB_GETTEXTW, $iPart, $pMemory, 0, "wparam", "ptr") Else _SendMessage($hWnd, $SB_GETTEXT, $iPart, $pMemory, 0, "wparam", "ptr") EndIf _MemRead($tMemMap, $pMemory, $pBuffer, $iBuffer) _MemFree($tMemMap) EndIf Return DllStructGetData($tBuffer, "Text") EndFunc ;==>_GUICtrlStatusBar_GetText Edited May 25, 2008 by Zedna Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
Sheri Posted May 25, 2008 Author Share Posted May 25, 2008 I tested it on my WIN98SE. You probably use Unicode. Try to run it on AutoIt 3.2.11.xx beta or 3.2.12 where are corrected UDFs also for Unicode. I'm using AutoIt Release 3.2.12.0 (only version I have). I get the same truncation even on apps where use of Ansi sendmessage works in an altered version of my function. (so I don't see how it could be a unicode issue.) I'm on XP SP3. Link to comment Share on other sites More sharing options...
Siao Posted May 25, 2008 Share Posted May 25, 2008 (edited) The status bar text I get with that function is truncated/incomplete. Are you sure it is working for you? I'm not using it. I just said it does pretty much the same what you did, and is supposed to work. If it doesn't work, then it could be a bug, so write a short example to reproduce the problem and report it to Bug Tracker. The point is not that I think these official UDF packages are the best thing ever and you've just wasted your time rewriting some of it on your own, it's the opposite. They are not perfect, but if the powers that be think that they must be included in standard package, then the only thing left is to improve them. Now I took a glance at it and do see a problem in current _GUICtrlStatusBar_GetText() which could cause truncation running on Unicode version of AutoIt (because count of chars sized memory buffer is allocated, instead of count*2 for wchar buffer). To fix it, open GuiStatusBar.au3, and in function _GUICtrlStatusBar_GetText, make this change: If @AutoItUnicode Then $tBuffer = DllStructCreate("wchar Text[" & $iBuffer & "]") $iBuffer *= 2;adjust buffer size for _MemInit() Else $tBuffer = DllStructCreate("char Text[" & $iBuffer & "]") EndIf Edited May 25, 2008 by Siao "be smart, drink your wine" Link to comment Share on other sites More sharing options...
Zedna Posted May 25, 2008 Share Posted May 25, 2008 I'm using AutoIt Release 3.2.12.0 (only version I have). I get the same truncation even on apps where use of Ansi sendmessage works in an altered version of my function. (so I don't see how it could be a unicode issue.) I'm on XP SP3. Then try to observe what part of UDF's sources give wrong values. Func _GUICtrlStatusBar_GetTextFlags($hWnd, $iPart) If $Debug_SB Then _GUICtrlStatusBar_ValidateClassName($hWnd) If @AutoItUnicode Then Return _SendMessage($hWnd, $SB_GETTEXTLENGTHW, $iPart) Else Return _SendMessage($hWnd, $SB_GETTEXTLENGTH, $iPart) EndIf EndFunc ;==>_GUICtrlStatusBar_GetTextFlags Func _GUICtrlStatusBar_GetTextLength($hWnd, $iPart) Return _WinAPI_LoWord(_GUICtrlStatusBar_GetTextFlags($hWnd, $iPart)) EndFunc ;==>_GUICtrlStatusBar_GetTextLength If _GUICtrlStatusBar_GetTextLength() gives wrong or good values. Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
Zedna Posted May 25, 2008 Share Posted May 25, 2008 Now I took a glance at it and do see a problem in current _GUICtrlStatusBar_GetText() which could cause truncation running on Unicode version of AutoIt (because count of chars sized memory buffer is allocated, instead of count*2 for wchar buffer). To fix it, open GuiStatusBar.au3, and in function _GUICtrlStatusBar_GetText, make this change: If @AutoItUnicode Then $tBuffer = DllStructCreate("wchar Text[" & $iBuffer & "]") $iBuffer *= 2 Else $tBuffer = DllStructCreate("char Text[" & $iBuffer & "]") EndIf Look at my post #12. This bug (in 3.2.10) was corrected in 3.2.11.xx beta already. He uses 3.2.12 version. Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
Siao Posted May 25, 2008 Share Posted May 25, 2008 Look at my post #12.This bug (in 3.2.10) was corrected in 3.2.11.xx beta already. He uses 3.2.12 version.I don't need to look at your posts.I use 3.2.12.0 myself, I just tested to see if it's an issue, saw that it is, and offered a fix. "be smart, drink your wine" Link to comment Share on other sites More sharing options...
Zedna Posted May 25, 2008 Share Posted May 25, 2008 (edited) I don't need to look at your posts.I use 3.2.12.0 myself, I just tested to see if it's an issue, saw that it is, and offered a fix.Oh sorry. Now I see the point from your fix code suggestion.I saw some unicode correction in this UDF in 3.2.11.xx beta but there is still bug as you said.EDIT: Will you create BUG track ticket for this bug? Edited May 25, 2008 by Zedna Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
Sheri Posted May 26, 2008 Author Share Posted May 26, 2008 I'm not using it. I just said it does pretty much the same what you did, and is supposed to work. If it doesn't work, then it could be a bug, so write a short example to reproduce the problem and report it to Bug Tracker. The point is not that I think these official UDF packages are the best thing ever and you've just wasted your time rewriting some of it on your own, it's the opposite. They are not perfect, but if the powers that be think that they must be included in standard package, then the only thing left is to improve them. I didn't rewrite anything that was there. I started from scratch and managed to get results and learn some things on my own. Then Zedna wanted to see how I solved it which is the only reason I formulated it into a function and posted it. I was subsequently surprised to see truncated rather than no result from the _GuiCtrlStatusBar_GetText function. Possibly I was not using a zero-based panel number when I first tried to use that function. This thread is in the General Help and Support Topic. If you read from the beginning you would know that I'm new and that I found and tried to use the provided functions. I would certainly have been much happier if the provided functions worked out of the box or if someone like yourself had kept me from needing to "waste time". Now I took a glance at it and do see a problem in current _GUICtrlStatusBar_GetText() which could cause truncation running on Unicode version of AutoIt (because count of chars sized memory buffer is allocated, instead of count*2 for wchar buffer). To fix it, open GuiStatusBar.au3, and in function _GUICtrlStatusBar_GetText, make this change: If @AutoItUnicode Then $tBuffer = DllStructCreate("wchar Text[" & $iBuffer & "]") $iBuffer *= 2;adjust buffer size for _MemInit() Else $tBuffer = DllStructCreate("char Text[" & $iBuffer & "]") EndIf Yes, with that change, _GUICtrlStatusBar_GetText now works for me. If its true that the _Gui functions are intended for use only with Guis made with AutoIt, it would be helpful if StatusbarGetText() also worked. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now