Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If you want to find the correct handle to a particular SysListView32 window, you need to start with the right window hierarchy. From the code snippet, it doesn't appear that you're actually finding the correct handle to retrieve a quote from the SysListView32 window. This is why you're receiving null values back. You would do well to run spy++ and determine the correct windows structure of the Metatrader terminal for your specific broker and build. I've found that the classes are different between builds for some of the windows, and also between some brokers, though to a lesser extent.</p> <p>You're looking for the specific quote window hierarchy like this: </p> <pre><code>Metatrader -&gt; Market Watch -&gt; Market Watch -&gt; SysListView32 </code></pre> <p>By contrast, currently you're looking here in your code: </p> <pre><code>Metatrader -&gt; Terminal -&gt; (many sub-windows with SysListView32 class) </code></pre> <p>Where each level to the right is a child window of the window to the left.</p> <p>Find the parent "Metatrader" window then chain down looking for the child window until you get to SysListView32. If you use spy++ you can read the class for the SysListView32 parent window (market watch), and use that to enumerate the windows to find the correct SysListView32 window. FYI the correct Market Watch class name for build 419 is:</p> <pre><code>Afx:00400000:b:00010003:00000000:00000000 </code></pre> <p>Once you find the correct window, you may be able to extract its contents using your current component. I haven't tried that and am looking to port some code from VB6 from a ListView module that does in fact involve epic hackery. ;) I may take a look at the .NET Managed Windows API to see if this can help make the process simpler.</p> <p>But in the mean time, if you do have to go low-level, the following VB6 source should help you get an idea of what is involved. This is fairly advanced material so good luck!</p> <pre><code>Public Function GetListviewItem(ByVal hWindow As Long, ByVal pColumn As Long, ByVal pRow As Long) As String Dim result As Long Dim myItem As LV_ITEMA Dim pHandle As Long Dim pStrBufferMemory As Long Dim pMyItemMemory As Long Dim strBuffer() As Byte Dim index As Long Dim tmpString As String Dim strLength As Long Dim ProcessID As Long, ThreadID As Long ThreadID = GetWindowThreadProcessId(hWindow, ProcessID) '********************** 'init the string buffer '********************** ReDim strBuffer(MAX_LVMSTRING) '*********************************************************** 'open a handle to the process and allocate the string buffer '*********************************************************** pHandle = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, ProcessID) pStrBufferMemory = VirtualAllocEx(pHandle, 0, MAX_LVMSTRING, MEM_COMMIT, PAGE_READWRITE) '************************************************************************************ 'initialize the local LV_ITEM structure 'The myItem.iSubItem member is set to the index of the column that is being retrieved '************************************************************************************ myItem.mask = LVIF_TEXT myItem.iSubItem = pColumn myItem.pszText = pStrBufferMemory myItem.cchTextMax = MAX_LVMSTRING '********************************************************** 'write the structure into the remote process's memory space '********************************************************** pMyItemMemory = VirtualAllocEx(pHandle, 0, Len(myItem), MEM_COMMIT, PAGE_READWRITE) result = WriteProcessMemory(pHandle, pMyItemMemory, myItem, Len(myItem), 0) '************************************************************* 'send the get the item message and write back the memory space '************************************************************* result = SendMessage(hWindow, LVM_GETITEMTEXT, pRow, ByVal pMyItemMemory) result = ReadProcessMemory(pHandle, pStrBufferMemory, strBuffer(0), MAX_LVMSTRING, 0) result = ReadProcessMemory(pHandle, pMyItemMemory, myItem, Len(myItem), 0) '************************************************** 'turn the byte array into a string and send it back '************************************************** For index = LBound(strBuffer) To UBound(strBuffer) If Chr(strBuffer(index)) = vbNullChar Then Exit For tmpString = tmpString &amp; Chr(strBuffer(index)) Next index tmpString = Trim(tmpString) '************************************************** 'deallocate the memory and close the process handle '************************************************** result = VirtualFreeEx(pHandle, pStrBufferMemory, 0, MEM_RELEASE) result = VirtualFreeEx(pHandle, pMyItemMemory, 0, MEM_RELEASE) result = CloseHandle(pHandle) If Len(tmpString) &gt; 0 Then GetListviewItem = tmpString End Function </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload