API чтение значений из списка

 

Добрый день!


Пытаюсь зачитать значения из списка ОПТИМИЗАЦИЯ, считываю количестов элементов

а вот зачитать сами значения не получается


//+------------------------------------------------------------------+
//|                                            ApiGetOPTIMIZATOR.mq4 |
//|                 Copyright 2006-2013, YURAZ yzh@mail.ru Developer |
//|           http://forum.masterforex-v.org/index.php?showforum=199 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2006-2013, YURAZ yzh@mail.ru Developer"
#property link      "http://forum.masterforex-v.org/index.php?showforum=199"
#property version   "1.00"
//#property strict

#define LVM_GETITEMCOUNT 0x1004
#define LVM_GETITEMTEXT 0x1045



#define LVIF_TEXT  0x0001
#define LVIF_IMAGE 0x0002
#define LVIF_PARAM  0x0004
#define LVIF_STATE  0x0008
#define LVIF_INDENT  0x0010
#define LVIF_GROUPID  0x0100
#define LVIF_COLUMNS  0x0200


#import "kernel32.dll"
int lstrcpyn(string a,string b,int count);       // используем для получения адреса строки
int lstrcpynA(int aa[],int ba[],int count);        // используем для получения адреса массива int
int lstrcpynW(double &aw[],double &bw[],int count);  // используем для получения адреса массива double
#import


#import "user32.dll"
int      SendMessageW(int hWnd,int Msg,int wParam,string lParam);
int      GetAncestor(int hWnd,int gaFlags);
int      GetDlgItem(int hDlg,int nIDDlgItem);
int CharPrevW( string lpszStart, string lpszCurrent ); // используем для получения адреса строки
int CharPrevW( int lpszStart[], int lpszCurrent[] );   // используем для получения адреса массива целых чисел
#import



 


static string textbuffer="АбвгдежзийклмнопрстуфхцчшщъыьэюяАбвгдежзийклмнопрстуфхцчшщъыьэюяАбвгдежзийклмнопрстуфхцчшщъыьэюяАбвгдежзийклмнопрстуфхцчшщъыьэюяАбвгдежзийклмнопрстуфхцчшщъыьэюяАбвгдежзийклмнопрстуфхцчшщъыьэюяАбвгдежзийклмнопрстуфхцчшщъыьэюяАбвгдежзийклмнопрстуфхцчшщъыьэю";
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   int hMetaTrader;
   int hTerminal;
   int hwnd;
   int hTester;
   int hOptimization;
   int Count;

   hMetaTrader=GetAncestor(WindowHandle(Symbol(),Period()),2);              // Дескриптор основного окна терминала
   printf(" hMetaTrader   = %s ",DecToHex(hMetaTrader));
   hTerminal=GetDlgItem(hMetaTrader,0xE81E); // Нашли историю счета
   printf(" hTerminal     = %s ",DecToHex(hTerminal));
   hTester=GetDlgItem(hTerminal,0x053);  // Тестер
   printf(" hTester       = %s ",DecToHex(hTester));
   hOptimization=GetDlgItem(hTester,0x81C2);  // Optimization
   printf(" hOptimization = %s ",DecToHex(hOptimization));
   Count=SendMessageW(hOptimization,LVM_GETITEMCOUNT,0,0); // получили количество элементов списка
   printf("Кол ОПТИМИЗАЦИЯ %d ",Count);

   int LVITEM[10];
   int LVITEM_address=CharPrevW(LVITEM,LVITEM); // получаем адрес массива
   int textbuffer_int=CharPrevW(textbuffer,textbuffer); // получаем адрес текстового буфера

   printf("LVITEM_address= %s ",DecToHex(LVITEM_address));

   printf("textbuffer_int= %s ",textbuffer_int);


   LVITEM[0] =  LVIF_TEXT;
   LVITEM[1] = 1;
   LVITEM[2] = 0;
   LVITEM[5] = textbuffer_int;
   LVITEM[6]=255; // textmask

   int ret=SendMessageW(hwnd,LVM_GETITEMTEXT,0,LVITEM_address);
   
   printf("[%s]",textbuffer);

//---
   return(INIT_SUCCEEDED);
  }

string DecToHex(int n)
  {
   string s = "", c;
   while(n != 0)
     {
      if(n%16<10)
         c=CharToStr(n%16+'0');
      else
         c=CharToStr(n%16+'A'-10);
      s = c + s;
      n = n / 16;
     }
   return(s);
  }


 
не легче ли сохранить в файл, а потом его парсить?
 
FAQ:
не легче ли сохранить в файл, а потом его парсить?

Руслан, да можно, знаю..


Но мне нужно зачитать значения из списка!

 
Юра, ты сначала скажи для чего тебе это.
По себе знаю, самый простой способ самый эффективный в большинстве случаев.
 

Юрий, можете попробовать помучаться, но не факт что будет успех.

метаквоты позакрывали эти информационные дырки на важных вкладках.

можете получать только число столбцев или строк, но инфа из них недоступна по API. ибо вероятней всего у них на вкладках - пользовательская отрисовка текста, с хранением текста не в стандартных буферах.


Единственный вариант - если вкладка подерживает Ctrl+A/Ctrl+C, то идите через буфер обмена.

иначе никак.

 
sergeev:

Юрий, можете попробовать помучаться, но не факт что будет успех.

метаквоты позакрывали эти информационные дырки на важных вкладках.

можете получать только число столбцев или строк, но инфа из них недоступна по API. ибо вероятней всего у них на вкладках - пользовательская отрисовка текста, с хранением текста не в стандартных буферах.


Единственный вариант - если вкладка подерживает Ctrl+A/Ctrl+C, то идите через буфер обмена.

иначе никак.


через CTRL+C, да это решаемо... это пробовал

еще вариант сохранять HTML

но мне нужно это без парсинга - без доп изваращений

--

попробую задать вопрос в METAQUOTES

 
Debugger:
Юра, ты сначала скажи для чего тебе это.
По себе знаю, самый простой способ самый эффективный в большинстве случаев.

быстрое получение и использование результатов оптимизации прямо из эксперта
 
Самый простой способ - сохранить в файл\зачитать из него. Где тут извращения непонятно.
 
FAQ:
Самый простой способ - сохранить в файл\зачитать из него. Где тут извращения непонятно.

:-) уже обсудили - не подходит!

да знаю этот способ, знаю что ты знаешь, ты знаешь - что все знают - все знают, что мне надо именно из списка...

( Руслан это юмор такой - надеюсь ты воспринял его с улыбкой - не надо доставать шашку турецкую )

нашел тут старую тему - похожую https://www.mql5.com/ru/forum/124134

 

Лазил по инету вычитал вот что

Итак:

Нужно прочитать syslistview32 в чужом приложении и записать в свой listbox

procedure GetListViewGrid(ALVHandle: HWND; AColumnCount, AItemCount: Integer; ADataGrid: TStringGrid);
const
cchTextMax=255;
var
  hProcess: THandle;
  dwProcessID: DWORD;
  dwWriten: DWORD;
  LVItemCount: Integer;
  i, j, nTextLength: Integer;
  pLVItem: ^LV_ITEM;
  LVItem: LV_ITEM;
  pszText: PChar;
  svText: ShortString;
begin
  if ALVHandle = 0 then Exit;
  // Получаем количество строк
  LVItemCount := ListView_GetItemCount(ALVHandle);
 if AItemCount > LVItemCount then exit;
 if AItemCount > 0 then LVItemCount:=AItemCount;
 //Получаем ID процесса, которому принадлежит найденное окно
 dwProcessID := 0;
  GetWindowThreadProcessId(ALVHandle, @dwProcessID);
 if dwProcessID = 0 then
  ExitProcess(GetLastError);
  // Открываем процесс
  hProcess := 0;
  hProcess := OpenProcess(PROCESS_ALL_ACCESS, True, dwProcessID);
  if hProcess = 0 then
  ExitProcess(GetLastError);
  // Выделяем в нем память под текстовый буффер
  pszText := VirtualAllocEx(hProcess, nil, cchTextMax,
                            MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
   // Выделяем в нем память под структуру LVITEM
  pLVItem := VirtualAllocEx(hProcess, nil, SizeOf(LV_ITEM),
                                     MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);

  //Устанавливаем колич строк и столбцов в TStringGrid
  ADataGrid.RowCount := LVItemCount ;
  ADataGrid.ColCount := AColumnCount ;

  // Заполняем структуру
  ZeroMemory(@LVItem, SizeOf(LV_ITEM));
  LVItem.mask := LVIF_TEXT;
  LVItem.pszText := pszText;
  LVItem.cchTextMax := cchTextMax;

  //Считываем строки
  for i := 0 to LVItemCount - 1 do
  begin
    LVItem.iSubItem := 0;
    // Пишем ее в память удаленного процесса
    if not WriteProcessMemory(hProcess, pLVItem, @LVItem,
                 SizeOf(LV_ITEM), dwWriten) then Exit;
    nTextLength := SendMessage(ALVHandle, LVM_GETITEMTEXT,
                               i, Integer(pLVItem));
    // Читаем результат
    ZeroMemory(@svText, cchTextMax);
    ReadProcessMemory(hProcess, LVItem.pszText, @svText[1],
     nTextLength, dwWriten);
     //заполняем строки TStringGrid
    ADataGrid.Cells[1, i + 1] := StrPas(PChar(@svText[1]));
   //Считываем столбцы
   for j := 0 to AColumnCount - 1 do
    begin
      LVItem.iSubItem := j;
      // Пишем ее в память удаленного процесса
      if not WriteProcessMemory(hProcess, pLVItem, @LVItem,
                                SizeOf(LV_ITEM), dwWriten) then Exit;
      nTextLength := SendMessage(ALVHandle, LVM_GETITEMTEXT,
                                 i, Integer(pLVItem));
      // Читаем результат
      ZeroMemory(@svText, cchTextMax);
      ReadProcessMemory(hProcess, LVItem.pszText,
                        @svText[1], nTextLength, dwWriten);
      //заполняем столбцы TStringGrid
      ADataGrid.Cells[j + 1, i + 1] := StrPas(PChar(@svText[1]));
    end;
  end;

  // Освобождаем ранее выделенную память
  VirtualFreeEx(hProcess, pszText, 0, MEM_RELEASE);
  VirtualFreeEx(hProcess, pLVItem, 0, MEM_RELEASE);
  // Закрываем описатель процесса
  CloseHandle(hProcess);
end;

т е по сути

1-чтение количества строк в гриде получается

2 а вот добыть данные из строк из столбцов никак

согласно примера выходит мне нужно выделить память в чужом приложении т е в мт4 и считывая строку из грида копировать уже к себе

парни кто знает API на хорошем уровне подсобите

хочу зачитывать данные оптимизатора


 
Есть класс у меня для работы с контролами из любого процесса. Если хочешь, пришлю.
Причина обращения: