Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 使用SendMessageAPI获取检查列表框中项目的状态_Windows_Delphi_Winapi_Sendmessage - Fatal编程技术网

Windows 使用SendMessageAPI获取检查列表框中项目的状态

Windows 使用SendMessageAPI获取检查列表框中项目的状态,windows,delphi,winapi,sendmessage,Windows,Delphi,Winapi,Sendmessage,我正在使用一个软件来操作另一个软件,比如软件测试环境,目的是获取一些值并执行一些任务。为此,我使用SendMessageAPI,它在几乎所有Windows控件中都运行良好,除了在CheckListBox中。“从”软件是在Delphi中创建的,因此,我不确定该复选框是否是标准的Windows控件,无论如何,这是MS的文档: 在这个控件中,我可以获得项目的数量、文本、选择的文本以及许多其他信息,但我无法知道是否检查了项目。我尝试使用一些工具,如“针对Windows的辅助功能洞察”和AutoIt,但

我正在使用一个软件来操作另一个软件,比如软件测试环境,目的是获取一些值并执行一些任务。为此,我使用SendMessageAPI,它在几乎所有Windows控件中都运行良好,除了在CheckListBox中。“从”软件是在Delphi中创建的,因此,我不确定该复选框是否是标准的Windows控件,无论如何,这是MS的文档:

在这个控件中,我可以获得项目的数量、文本、选择的文本以及许多其他信息,但我无法知道是否检查了项目。我尝试使用一些工具,如“针对Windows的辅助功能洞察”和AutoIt,但没有结果。
您知道如何在Delphi复选框中获取复选框的状态吗?

提前感谢。

Delphi将选中的信息存储在
TCheckListBoxDataWrapper
对象中。指向该对象的指针存储在复选框项的常规“项数据”中。然后,该对象具有一个布尔属性
State
,您可以在偏移量8处找到该属性

注意:如果您的程序的特定Delphi版本的偏移量与8不同,请尝试-4、12、…-它不可能走得很远

要确定是否已选中某个项目,您需要:

  • 获取指向该项的
    TCheckListBoxDataWrapper
    的指针。这可以通过发送
    LB_GETITEMDATA
    消息来完成。如果返回零,它也将被视为未检查
  • 因为这个指针指向另一个进程中的内存,而不是您的内存,所以不能简单地取消对它的引用。相反,您需要使用
    ReadProcessMemory
    。知道
    状态
    属性位于偏移量8,您可以调用
    ReadProcessMemory(hProcess,itemData+8,&checked,1,NULL)
    将1个字节读入变量
    checked
    。(首先需要使用
    OpenProcess
    打开目标进程)
  • 然后您将在
    中检查项目的选中状态
    <代码>1表示选中,代码>0表示未选中


    如果以后还需要访问其他内部状态,另一个提示是:有一个窗口属性
    ControlOfxxxxxxxyyyyyyyy
    ,其中
    X
    是窗口所有者的
    HINSTANCE
    (基址)(通常
    00400000
    ),而
    Y
    是窗口所有者的(十六进制)线程ID(您可以使用
    GetWindowThreadProcessId
    获取该属性)。您可以使用
    GetProp
    获取该属性的值,该属性将是指向控件对象的指针(在本例中为
    TCheckListBox
    本身)。然后,您可以使用
    ReadProcessMemory
    来获取所需的其他数据。不过,您需要知道偏移量(但您可以使用调试器来尝试并找出它们)。使用相同的Delphi版本编译测试程序并在其中执行访问这些属性的函数非常有用,然后您可以调试自己的测试程序,并更轻松地计算偏移量


    一种更高级的方法是将自定义DLL(用相同的Delphi版本编写)注入目标进程,允许访问(读和写)这类数据更直接。我很久以前就写过。

    Delphi将选中的信息存储在
    TCheckListBoxDataWrapper
    对象中。指向该对象的指针存储在checkbox item的常规“item data”中。然后该对象具有布尔属性
    State
    ,您可以在偏移量8处找到该属性

    注意:如果您的程序的特定Delphi版本的偏移量与8的偏移量不同,请尝试附近的东西-4、12、…-它不会太远

    要确定是否已选中某个项目,您需要:

  • 获取指向该项的
    TCheckListBoxDataWrapper
    的指针。这可以通过发送
    LB_GETITEMDATA
    消息来完成。如果返回零,则它也被视为未选中
  • 由于此指针指向另一个进程中的内存,而不是您的内存,因此您不能简单地取消引用它。相反,您需要使用
    ReadProcessMemory
    。知道
    State
    属性位于偏移量8处,您可以调用
    ReadProcessMemory(hProcess,itemData+8,&checked,1,NULL)
    要在变量
    中读取1个字节,请选中
    (首先需要使用
    OpenProcess
    打开目标进程)
  • 然后您将在
    checked
    1
    中检查项目的选中状态,在
    0
    中检查项目的未选中状态


    如果以后还需要访问其他内部状态,另一个提示是:有一个窗口属性
    ControlOfxxxxxxxyyyyyyyy
    ,其中
    X
    是窗口所有者的
    HINSTANCE
    (基址)(通常
    00400000
    ),而
    Y
    是窗口所有者的(十六进制)线程ID(您可以使用
    GetWindowThreadProcessId
    获取该属性)。您可以使用
    GetProp
    获取该属性的值,该属性将是指向控件对象的指针(在本例中为
    TCheckListBox
    本身)。然后,您可以使用
    ReadProcessMemory
    来获取所需的其他数据。不过,您需要知道偏移量(但您可以使用调试器来尝试并找出它们)。使用相同的Delphi版本编译测试程序并在其中执行访问这些属性的函数非常有用,然后您可以调试自己的测试程序,并更轻松地计算偏移量


    一种更高级的方法是将自定义DLL(以相同的Delphi版本编写)注入目标进程,允许更直接地访问(读取和写入)此类数据。我很久以前就写过。

    正如@CherryDT发布的,这是访问CheckListBox状态的方法。我使用AutoIt
    ;------------------------------------------------------------------------------
    ;   Retuns the state of the indicated item in the CheckListBox control.
    ;   Parameter:
    ;       $iPID: process ID (PID)
    ;       $hWnd: the handle of the CheckListBox control
    ;       $iIndex: index of the item in the list (0 based)
    ;------------------------------------------------------------------------------
    Func CtrlListBox_GetState($iPID, $hWnd, $iIndex)
       Local $hProc                             ; Handle of the process.
       Local $pItem                             ; Pointer to the item.
       Local $pData = DllStructCreate("byte")   ; Data structure.
       Local $iQty                              ; Size of data read.
       Local Const $LB_STATE_SHIFT = 8          ; State position in the memory.
    
       $hProc = _WinAPI_OpenProcess(0x1F0FFF, False, $iPID)     ; 0x1F0FFF = PROCESS_ALL_ACCESS
       $pItem = _GUICtrlListBox_GetItemData($hWnd, $iIndex) + $LB_STATE_SHIFT
       _WinAPI_ReadProcessMemory($hProc, $pItem, DllStructGetPtr($pData), DllStructGetSize($pData), $iQty)
    
       Return DllStructGetData($pData, 1)
    EndFunc
    
    ;------------------------------------------------------------------------------
    ;   Retuns the state of the indicated item in the CheckListBox control.
    ;   Parameter:
    ;       $iPID: process ID (PID)
    ;       $hWnd: the handle of the CheckListBox control
    ;       $iIndex: index of the item in the list (0 based)
    ;       $bState: state deseired (true or false)
    ;------------------------------------------------------------------------------
    Func CtrlListBox_SetState($iPID, $hWnd, $iIndex, $bState)
       Local $hProc                             ; Handle of the process.
       Local $pItem                             ; Pointer to the item.
       Local $pData = DllStructCreate("byte")   ; Data structure.
       Local $iQty                              ; Size of data read.
       Local Const $LB_STATE_SHIFT = 8          ; State position in the memory.
    
       if($bState <> 0) Then
          DllStructSetData($pData, 1, True)
       Else
          DllStructSetData($pData, 1, False)
       EndIf
    
       $hProc = _WinAPI_OpenProcess(0x1F0FFF, False, $iPID)     ; 0x1F0FFF = PROCESS_ALL_ACCESS
       $pItem = _GUICtrlListBox_GetItemData($hWnd, $iIndex) + $LB_STATE_SHIFT
       _WinAPI_WriteProcessMemory($hProc, $pItem, DllStructGetPtr($pData), DllStructGetSize($pData), $iQty)
    
       Return DllStructGetData($pData, 1)
    EndFunc