Конференция "WinAPI" » TreeView в чужом приложении [D7, WinXP]
 
  • Master_Of_Puppets (08.02.08 01:08) [0]
    Передо мной возникла следующая проблемка. Есть некое приложение (к сожалению, не моё). В нем используется визуальный компонент TTreeView. Мне надо узнать текст выделенного узла и его "вложенность" (1, 2, 3 ... n -ий уровень). До самого компонента TTreeView я то добрался (используя FindWindowEx) а вот дальше я не знаю как...
  • ketmar © (08.02.08 05:23) [1]
    а дальше читать MSDN по поводу работы с ним. есть подозрение, что придётся код внедрять в чужое АП.

    ---
    Understanding is not required. Only obedience.
  • Бегущий человек © (08.02.08 05:32) [2]
    Сообщение TVM_GETITEM в Win32 SDK или MSDN
  • Бегущий человек © (08.02.08 05:37) [3]
    При этом стоит учесть опыт наших товарищей :
    http://bugtraq.ru/cgi-bin/forum.mcgi?type=sb&b=2&m=139940
  • Master_Of_Puppets (08.02.08 11:52) [4]
    Вот кусок кода, вроде бы правильно, но ничего не выводится в лейбле:

    with tvItem do
       begin
         mask := TVIF_TEXT;
         hItem := TreeView_GetSelection(hTreeView);
         cchTextMax := 100;
      end;
    TreeView_GetItem(hTreeView, tvItem);
    lblMeshText.Caption := tvItem.pszText;

    Хендл верен
  • ketmar © (08.02.08 12:16) [5]
    >[4] Master_Of_Puppets (2008-02-08 11:52:00)
    ты [3] внимательно прочёл? или по ссылкам ходить — дело не барское?

    ---
    Understanding is not required. Only obedience.
  • Dib@zol © (08.02.08 12:24) [6]
    tvItem.pszText тоже нужно заполнять. Заполнять указателем, который, как тебя уже ткнул носом г-н Кетмарь, возвернёт функция VirtualAlloc (хотя по мне GlobalAlloc предпочтительнее).
  • Dib@zol © (08.02.08 12:30) [7]
    Удалено модератором
  • Master_Of_Puppets (08.02.08 17:43) [8]
    Я думал, что нужен лиш код, который я привел в [4]. Пробывал сделать так как там, но Делфи ругается на хендл вот тут:

    procedure ReadItemFromBuff(var Item: TTVITEM);
         var Readed: DWORD;
       begin
    --> Win32Check(ReadProcessMemory(hTreeView, aRemBuff, @Item, SizeOf(Item), Readed));
         Win32Check(Readed = SizeOf(Item));
       end;

    А можно сделать другим способом (чуточку проще) или это единственный?
    Пробывал еще вот так (с учетом замечания [7]), но не работает:

    var str : String
    ...
    with tvItem do
      begin
        mask := TVIF_TEXT;
        hItem := TreeView_GetSelection(hTreeView);
        cchTextMax := 100;
        pszText := @str;
     end;
    TreeView_GetItem(hTreeView, tvItem);
    lblCap.Caption := str;
  • ketmar © (08.02.08 18:00) [9]
    >[8] Master_Of_Puppets (2008-02-08 17:43:00)
    бросай ты это дело. «Парфеша, куда тебе целоваться-то, ты ведь облеванный весь!» (ц) Даун Хаус

    ---
    Understanding is not required. Only obedience.
  • Dib@zol © (08.02.08 18:07) [10]
    Удалено модератором
  • Dib@zol © (08.02.08 18:09) [11]
    Удалено модератором
  • clickmaker © (08.02.08 18:10) [12]

    > LongInt(pszText) := GlobalAlloc(GMEM_FIXED, TSZ);

    а почему не pszText := PChar(GlobalAlloc(GMEM_FIXED, TSZ)) ?
  • Dib@zol © (08.02.08 18:11) [13]
    > а почему не pszText := PChar(GlobalAlloc(GMEM_FIXED, TSZ)
    > ) ?

    А какая сопстно разница? так или иначе - работает, окоянное :)
  • clickmaker © (08.02.08 18:17) [14]

    > [6] Dib@zol ©   (08.02.08 12:24)
    > tvItem.pszText тоже нужно заполнять. Заполнять указателем,
    > который, как тебя уже ткнул носом г-н Кетмарь, возвернёт
    > функция VirtualAlloc (хотя по мне GlobalAlloc предпочтительнее).

    LPVOID VirtualAllocEx(
     HANDLE hProcess,
     ...
    VirtualAllocEx function reserves or commits a region of memory within the virtual address space of a specified process

    vs

    HGLOBAL GlobalAlloc(
     UINT uFlags,
     SIZE_T dwBytes
    );

    ничего не смущает?
  • Dib@zol © (08.02.08 18:21) [15]
    The GlobalAlloc function allocates the specified number of bytes from the heap.

    Heap, в котором размещаем, надо считать, принадлежит вызывающему процессу. Или я опять чего-то невкурил? Ну тады просвещайте меня, тёмного :(
  • clickmaker © (08.02.08 18:23) [16]

    > Heap, в котором размещаем, надо считать, принадлежит вызывающему
    > процессу

    беда в том, что дерево в другом
  • Dib@zol © (08.02.08 18:32) [17]
    Удалено модератором
  • ketmar © (08.02.08 18:43) [18]
    >[15] Dib@zol © (2008-02-08 18:21:00)
    невнимательно. [0]: «Есть некое приложение (к сожалению, не моё)». отсюда однозначно следует, что процесс запущен и живёт в своём АП.

    ---
    Understanding is not required. Only obedience.
  • ketmar © (08.02.08 18:44) [19]
    Удалено модератором
  • Dib@zol © (08.02.08 18:56) [20]
    Удалено модератором
  • ketmar © (08.02.08 19:01) [21]
    Удалено модератором
  • ketmar © (08.02.08 19:02) [22]
    >[20] Dib@zol © (2008-02-08 18:56:00)
    так, FYI: обработчик WM_GETTEXT делает такие манипуляции для облегчения жизни функциям вида FindWindow().

    ---
    Understanding is not required. Only obedience.
  • Dib@zol © (08.02.08 19:12) [23]
    > так, FYI: обработчик WM_GETTEXT делает такие манипуляции
    > для облегчения жизни функциям вида FindWindow().

    эээ, што?
    Нахрена, звиняюсь, он это (якобы) так делает? Вызов функции FindWindow предполагает то, что хендл окна неизвестен, а известен его текст. WM_GETTEXT - наоборот. Где тут "облегчение жизни"?? Ведь совместный вызов возможен только для специфических ситуаций.

    Впрочем, прочитав подпись Understanding is not required. Only obedience, понимаешь, что к чему.

    ЗЫ так лень писать пример, а придётся ведь...
  • clickmaker © (08.02.08 19:53) [24]

    > Вызов функции FindWindow предполагает то, что хендл окна
    > неизвестен, а известен его текст. WM_GETTEXT - наоборот.
    > Где тут "облегчение жизни"??

    подозрение, что FindWindow это совокупление EnumWindows, WM_GETTEXT и GetClassName
  • ketmar © (08.02.08 20:22) [25]
    Удалено модератором
  • ketmar © (08.02.08 20:24) [26]
    >[24] clickmaker © (2008-02-08 19:53:00)
    примерно так оно и есть. именно потому, например, РИхтер не рекомендует для определения наличия уже запущеного экземпляра софтины использовать FindWindow() — она уходит в задумчивость, если какое-то приложение упорно не отвечает. может, в XP и починили (не уверен), а раньше — так. отсюда и «магия» в WM_GETTEXT. но наш энергичный оппонент книжек не читает, поэтому ему оно в офигенную новинку.

    ---
    Understanding is not required. Only obedience.
  • Master_Of_Puppets (08.02.08 21:01) [27]
    А можно, используя SendMessage и WM_GETTEXT для ТриВьюва узнать текст выделенного узла?
  • ketmar © (08.02.08 21:08) [28]
    Удалено модератором
  • Бегущий человек © (08.02.08 21:48) [29]
    >Master_Of_Puppets   (08.02.08 21:01) [27]
    Низя
  • Master_Of_Puppets (09.02.08 01:17) [30]
    Фуххх, заработало... Взял отсюда, может кому пригодится: http://www.delphikingdom.com/asp/answer.asp?IDAnswer=53339
  • ketmar © (09.02.08 11:14) [31]
    >[30] Master_Of_Puppets (2008-02-09 01:17:00)
    ты хоть понял, что там происходит, или просто кастанул заклинание из гримуара?

    ---
    Understanding is not required. Only obedience.
  • Master_Of_Puppets (09.02.08 12:26) [32]
    Понял, понял...Не всё, правда, но в том аспекте кода (который мне под себя надо было переделать) разобрался.
  • ketmar © (09.02.08 12:33) [33]
    >[32] Master_Of_Puppets (2008-02-09 12:26:00)
    >Понял, понял…

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

    ---
    Understanding is not required. Only obedience.
  • Master_Of_Puppets (09.02.08 19:42) [34]
    Угу, спасибо всем за помощь и советы!
 
Конференция "WinAPI" » TreeView в чужом приложении [D7, WinXP]
Есть новые Нет новых   [134431   +15][b:0][p:0.001]