Sign in to follow this  
Followers 0
devilyn

MSC Crash when trying to get text

7 posts in this topic

I'm trying to get the text of an highlighted item in the treeview of the "Computer Management Console"

On XP: it gets the text and then crash the Console

On 7: it doesn't get the text and does not crash the Console

i narrowed the crash to the specific line and it seems to be related to the _SendMessage function for a Unicode control.

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include-once
#include "TreeViewConstants.au3"
#include "GuiImageList.au3"
#include "Memory.au3"
#include "WinAPI.au3"
#include "StructureConstants.au3"
#include "SendMessage.au3"
#include "UDFGlobalID.au3"

Global $__ghTVLastWnd
Global $Debug_TV = False
Global Const $__TREEVIEWCONSTANT_ClassName = "SysTreeView32"

$hWnd = ControlGetHandle("Computer Management", '', 12785)


$hItemFound = _GUICtrlTreeView_GetSelection($hWnd)
ConsoleWrite($hItemFound&@CRLF)
$Text = _GUICtrlTreeView_GetText($hWnd, $hItemFound)
ConsoleWrite($Text&@CRLF)




Func _GUICtrlTreeView_GetText($hWnd, $hItem = 0)
    If $Debug_TV Then __UDF_ValidateClassName($hWnd, $__TREEVIEWCONSTANT_ClassName)
    If Not IsHWnd($hItem) Then $hItem = _GUICtrlTreeView_GetItemHandle($hWnd, $hItem)
    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)
    If $hItem = 0x00000000 Then Return SetError(1, 1, "")
    Local $tTVITEM = DllStructCreate($tagTVITEMEX)
    Local $tText
    Local $fUnicode = _GUICtrlTreeView_GetUnicodeFormat($hWnd)
    If $fUnicode Then
        $tText = DllStructCreate("wchar Buffer[4096]"); create a text 'area' for receiving the text
    Else
        $tText = DllStructCreate("char Buffer[4096]"); create a text 'area' for receiving the text
    EndIf
    Local $pBuffer = DllStructGetPtr($tText)
    Local $pItem = DllStructGetPtr($tTVITEM)
    DllStructSetData($tTVITEM, "Mask", $TVIF_TEXT)
    DllStructSetData($tTVITEM, "hItem", $hItem)
    DllStructSetData($tTVITEM, "TextMax", 4096)

    If _WinAPI_InProcess($hWnd, $__ghTVLastWnd) Then
        DllStructSetData($tTVITEM, "Text", $pBuffer)

        _SendMessage($hWnd, $TVM_GETITEMW, 0, $pItem, 0, "wparam", "ptr")

        Else

        Local $iItem = DllStructGetSize($tTVITEM)

        Local $tMemMap

        Local $pMemory = _MemInit($hWnd, $iItem + 4096, $tMemMap)

        Local $pText = $pMemory + $iItem

        DllStructSetData($tTVITEM, "Text", $pText)

        _MemWrite($tMemMap, $pItem, $pMemory, $iItem)

        If $fUnicode Then
            
            
            _SendMessage($hWnd, $TVM_GETITEMW, 0, $pMemory, 0, "wparam", "ptr");;;!!!!!This is where i get the crash!!!!!!!!!!!!!
        Else
            
            _SendMessage($hWnd, $TVM_GETITEMA, 0, $pMemory, 0, "wparam", "ptr")
        EndIf

        _MemRead($tMemMap, $pText, $pBuffer, 4096)

        _MemFree($tMemMap)

    EndIf

    Return DllStructGetData($tText, "Buffer")
EndFunc


Func _GUICtrlTreeView_GetUnicodeFormat($hWnd)
    If $Debug_TV Then __UDF_ValidateClassName($hWnd, $__TREEVIEWCONSTANT_ClassName)
    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)
    Return _SendMessage($hWnd, $TVM_GETUNICODEFORMAT) <> 0
EndFunc   ;==>_GUICtrlTreeView_GetUnicodeFormat


Func _GUICtrlTreeView_GetItemHandle($hWnd, $hItem = 0)
    If $Debug_TV Then __UDF_ValidateClassName($hWnd, $__TREEVIEWCONSTANT_ClassName)
    If $hItem = 0 Then $hItem = 0x00000000
    If IsHWnd($hWnd) Then
        If $hItem = 0x00000000 Then $hItem = _SendMessage($hWnd, $TVM_GETNEXTITEM, $TVGN_ROOT, 0, 0, "wparam", "lparam", "handle")
    Else
        If $hItem = 0x00000000 Then
            $hItem = GUICtrlSendMsg($hWnd, $TVM_GETNEXTITEM, $TVGN_ROOT, 0)
        Else
            Local $hTempItem = GUICtrlGetHandle($hItem)
            If $hTempItem <> 0x00000000 Then $hItem = $hTempItem
        EndIf
    EndIf
    Return $hItem
EndFunc   ;==>_GUICtrlTreeView_GetItemHandle


Func _GUICtrlTreeView_GetSelection($hWnd)
    If $Debug_TV Then __UDF_ValidateClassName($hWnd, $__TREEVIEWCONSTANT_ClassName)
    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)
    Return _SendMessage($hWnd, $TVM_GETNEXTITEM, $TVGN_CARET, 0, 0, "wparam", "handle", "handle")
EndFunc   ;==>_GUICtrlTreeView_GetSelection

Thanks in advance.

Share this post


Link to post
Share on other sites



You might be interested in this failed experiment: Using the automation interface for MMC

It worked fine within the MMC itself, and only failed once it drilled down to a different interface (CertMgr).

:blink:


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

You might be interested in this failed experiment: Using the automation interface for MMC

It worked fine within the MMC itself, and only failed once it drilled down to a different interface (CertMgr).

:blink:

Thanks that helped a bit but i think i will try a different approach.

is there a way to extract all the text data of a tab control (only one tab/instance) for every branch in the treeview?

Thanks in advance

Share this post


Link to post
Share on other sites

Not in one line. It requires a recursive search, just like with directory tree.

:blink:


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

Not in one line. It requires a recursive search, just like with directory tree.

:blink:

Thanks for your answer. i'm not looking for a one line solution but i'm looking for a seamless solution (no gui)

is that possible?

I do remember seeing some script that can extract all text from all control but i cannot find it.

Thanks in advance

Share this post


Link to post
Share on other sites

Sounds painful.

Everything represented on computer manager comes from other management applications and APIs. It would be better to be more specific about what you want and drill down into into with the proper tools.

:blink:


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

I found "fix" bug with MMC: need use non-Unicode instead Unicode version functions.

I change only one line, from

Local $fUnicode = _GUICtrlTreeView_GetUnicodeFormat($hWnd)

to

Local $fUnicode = Not (_GUICtrlTreeView_GetUnicodeFormat($hWnd))

Full text:

Func __GUICtrlTreeView_GetText($hWnd, $hItem = 0)
If $Debug_TV Then __UDF_ValidateClassName($hWnd, $__TREEVIEWCONSTANT_ClassName)
If Not IsHWnd($hItem) Then $hItem = _GUICtrlTreeView_GetItemHandle($hWnd, $hItem)
If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)
If $hItem = 0x00000000 Then Return SetError(1, 1, "")
Local $tTVITEM = DllStructCreate($tagTVITEMEX)
Local $tText
Local $fUnicode = Not (_GUICtrlTreeView_GetUnicodeFormat($hWnd))   ;Correct crash with MMC: inserted NOT
If $fUnicode Then
  $tText = DllStructCreate("wchar Buffer[4096]"); create a text 'area' for receiving the text
Else
  $tText = DllStructCreate("char Buffer[4096]"); create a text 'area' for receiving the text
EndIf
DllStructSetData($tTVITEM, "Mask", $TVIF_TEXT)
DllStructSetData($tTVITEM, "hItem", $hItem)
DllStructSetData($tTVITEM, "TextMax", 4096)
If _WinAPI_InProcess($hWnd, $__ghTVLastWnd) Then
  DllStructSetData($tTVITEM, "Text", DllStructGetPtr($tText))
  _SendMessage($hWnd, $TVM_GETITEMW, 0, $tTVITEM, 0, "wparam", "struct*")
Else
  Local $iItem = DllStructGetSize($tTVITEM)
  Local $tMemMap
  Local $pMemory = _MemInit($hWnd, $iItem + 4096, $tMemMap)
  Local $pText = $pMemory + $iItem
  DllStructSetData($tTVITEM, "Text", $pText)
  _MemWrite($tMemMap, $tTVITEM, $pMemory, $iItem)
  If $fUnicode Then
   _SendMessage($hWnd, $TVM_GETITEMW, 0, $pMemory, 0, "wparam", "ptr")
  Else
   _SendMessage($hWnd, $TVM_GETITEMA, 0, $pMemory, 0, "wparam", "ptr")
  EndIf
  _MemRead($tMemMap, $pText, $tText, 4096)
  _MemFree($tMemMap)
EndIf
Return DllStructGetData($tText, "Buffer")
EndFunc   ;==>_GUICtrlTreeView_GetText

P.S. Sorry for my bad english.

Share this post


Link to post
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
Sign in to follow this  
Followers 0