purebasic.info

PureBasic forum
Текущее время: Чт апр 09, 2020 1:25 pm

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 15 ] 
Автор Сообщение
СообщениеДобавлено: Пт фев 22, 2019 1:58 am 
Не в сети
профессор

Зарегистрирован: Чт фев 09, 2017 10:37 am
Сообщений: 560
Благодарил (а): 37 раз.
Поблагодарили: 76 раз.
Пункты репутации: 2
Есть ли способ раскрыть дерево стороннего процесса? Например раскрыть реестр по заданному пути? Но желательно без перезапуска с методом вставки последнего пути в историю реестра. Допустим получили дескриптор элемента TreeView, далее нужно получить дочерние и в цикле искать нужный пункт среди дочерних и раскрывать его. На официальном сайте поискал примеры, но пока там работа со своим TreeView, для которого есть встроенные функции GetGadgetItemState.

Смотрю функции на майкрософт, смотрю функцию AutoIt3 допустим _GUICtrlTreeView_FindItemEx, открываю в Include файл GuiTreeView.au3, нахожу функцию и смотрю её устройство и мозг кипит, там всё написано на работе со структурами и памятью, которые я обычно не использовал.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
hwnd = FindWindowEx_(0, 0, "AutoIt v3 GUI", "Создание TreeView (UDF)")
If hwnd
;       MessageRequester("hwnd", Str(hwnd))
        hTree = FindWindowEx_(hwnd, 0, "SysTreeView32", 0)
        If hTree
                ret = SendMessage_(hTree, #TVM_GETCOUNT, 0, 0)
                MessageRequester("ret", Str(ret))
;               MessageRequester("hTree", Str(hTree))
;               SetGadgetItemState(hTree , 0, #PB_Tree_Expanded)
;               hItem = FindWindowEx_(hTree, 0, 0, 0)
;               MessageRequester("hItem", Str(hItem))
        EndIf
EndIf
; TV_CheckForCollapsed(0)
; LPTVITEMEX.TVITEMEX
; LPTVITEMEX\mask=#TVIF_TEXT
; LPTVITEMEX\hItem=hItem
; LPTVITEMEX\TextMax=4096



В AutoIt3 это делается так: запрос первого пункта, от него функция с приставкой Next получает следующий пункт, каждый раз проверяем совпадает ли текст пункта с нашим текстом, если да, то функция получить первый дочерний и от него опять Next-функция и сравнивается с текстом второго уровня и так пока не пройдёт до конца, и конечно при каждом найденном делается клик на пункте чтобы развернуть и функция видимости пункта, чтобы прокрутит пункт на верх. Через внутренние функции это выглядит так


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Пт фев 22, 2019 7:04 am 
Не в сети
МОДЕРАТОР

Зарегистрирован: Вт дек 05, 2006 8:46 am
Сообщений: 6611
Благодарил (а): 34 раз.
Поблагодарили: 229 раз.
Пункты репутации: 61
Дельфисты это делают так

1. Находим Regedit (если не найден, то запускаем и находим).
2. Сворачиваем все ветки реестра (30 раз повторяем нажатие кнопки влево).
3. Отправляем по буквам весь путь, указанный в параметре Key. Вместо символа '\' отправляем нажатие кнопки вправо.

Выглядит у них это так
Цитата:
Procedure JumpToKey(Key: string) ;
var i, n: Integer ;
hWin: HWND ;
ExecInfo: ShellExecuteInfoA ;
begin hWin:= FindWindowA(PChar('RegEdit_RegEdit'), nil);
If hWin = 0 then {If Regedit doesn't run then we launch it} begin FillChar(ExecInfo, 60, #0);
With ExecInfo do begin cbSize:= 60;
fMask:= SEE_MASK_NOCLOSEPROCESS ;
lpVerb:= PChar('open') ;
lpFile:= PChar('regedit.exe') ;
nShow:= 1 ;
End ;
ShellExecuteExA(@ExecInfo) ;
WaitForInputIdle(ExecInfo.hProcess, 200);
hWin:= FindWindowA(PChar('RegEdit_RegEdit'), nil);
End ;
ShowWindow(hWin, SW_SHOWNORMAL) ;
hWin:= FindWindowExA(hWin, 0, PChar('SysTreeView32'), nil);
SetForegroundWindow(hWin) ;
i:= 30 ;
Repeat SendMessageA(hWin, WM_KEYDOWN, VK_LEFT, 0) ;
Dec(i) ;
Until i = 0 ;
Sleep(500) ;
SendMessageA(hWin, WM_KEYDOWN, VK_RIGHT, 0) ;
Sleep(500) ;
i:= 1 ;
n:= Length(Key) ;
Repeat If (Key[i] = '\') then begin SendMessageA(hWin, WM_KEYDOWN, VK_RIGHT, 0);
Sleep(100) ;
End Else SendMessageA(hWin, WM_CHAR, Integer(Key[i]), 0) ;
i:= i + 1 ;
Until i = n ;
End ;


Всё на API, переписать не сложно.

_________________
read-only ¯\_(ツ)_/¯


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Пт фев 22, 2019 8:06 am 
Не в сети
МОДЕРАТОР

Зарегистрирован: Вт дек 05, 2006 8:46 am
Сообщений: 6611
Благодарил (а): 34 раз.
Поблагодарили: 229 раз.
Пункты репутации: 61
Вот:
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
 
Procedure JumpToKey(key.s)
  hWin = FindWindow_("RegEdit_RegEdit", #NUL);
  ShowWindow_(hWin, #SW_SHOWNORMAL) ;
  hWin= FindWindowEx_(hWin, 0, "SysTreeView32", 0);
  SetForegroundWindow_(hWin) ;
If hWin
   For i = 1 To 30
    SendMessage_(hWin, #WM_KEYDOWN, #VK_LEFT, 0) ;
   Next
  Sleep_(100) ;
  SendMessage_(hWin, #WM_KEYDOWN, #VK_RIGHT, 0) ;
  Sleep_(100)                                   ;
  n= Len(Key) ;
  For i = 1 To n
    char.s = Mid(Key,i,1)
    If char = "\"
      SendMessage_(hWin, #WM_KEYDOWN, #VK_RIGHT, 0);
      Sleep_(100)
    Else
      SendMessage_(hWin, #WM_CHAR, Asc(char), 0) ;
    EndIf
   
  Next
  ProcedureReturn 1
Else
  ProcedureReturn 0
EndIf
 
EndProcedure
 
;- Test programm
 
key.s="HKEY_CURRENT_USER\Software\Microsoft\Notepad"
 
If JumpToKey(key) > 0
 
Else
  If RunProgram ("regedit.exe")
     Sleep_(1000)
     JumpToKey(key)
  Else  
    MessageRequester("Сообщение","RegEdit не запущен")  
  EndIf
 
EndIf
 


_________________
read-only ¯\_(ツ)_/¯


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Пт фев 22, 2019 8:46 am 
Не в сети
профессор

Зарегистрирован: Чт фев 09, 2017 10:37 am
Сообщений: 560
Благодарил (а): 37 раз.
Поблагодарили: 76 раз.
Пункты репутации: 2
kvitaliy писал(а):
Вот

С клавишами тоже интересная идея...
Я попробовал, а там же появилась адресная строка... Похоже надо просто вставить в неё путь и эмулировать Enter, но это только для реестра а не вообще TreeGadget. С какой версии интересно появилось, в Win7 есть такая строка?


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Пт фев 22, 2019 8:54 am 
Не в сети
МОДЕРАТОР

Зарегистрирован: Вт дек 05, 2006 8:46 am
Сообщений: 6611
Благодарил (а): 34 раз.
Поблагодарили: 229 раз.
Пункты репутации: 61
AZJIO писал(а):
С какой версии интересно появилось, в Win7 есть такая строка?

В win7 строка состояния есть, включается в меню. Но она не редактируемая, и даже не копируемая, чисто для контроля.

_________________
read-only ¯\_(ツ)_/¯


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Пн фев 25, 2019 7:48 am 
Не в сети
профессор

Зарегистрирован: Чт фев 09, 2017 10:37 am
Сообщений: 560
Благодарил (а): 37 раз.
Поблагодарили: 76 раз.
Пункты репутации: 2
kvitaliy
Кажется при использовании WM_KEYDOWN должно заканчиваться WM_KEYUP. Я помню даже когда использовал AutoIt3, там была проблема залипания клавиши, допустим, модификатора и последующие клавиши вместо нужного как бы использовались с зажатым модификатором, поэтому делали в цикле проверку ненажатости клавиши каждые 30 мсек и в случае зажатости отправляли WM_KEYUP.

Я хочу вызвать диалог "Выполнить", и решил вызвать Win+R. Пробовал найти команду типа "rundll32.exe shell32.dll ...." не нашёл, но вроде должна быть, подумал может временно на вызове Win+R сделать.


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Пн фев 25, 2019 8:58 am 
Не в сети
МОДЕРАТОР

Зарегистрирован: Вт дек 05, 2006 8:46 am
Сообщений: 6611
Благодарил (а): 34 раз.
Поблагодарили: 229 раз.
Пункты репутации: 61
Когда мы имитируем нажатие клавиши с keybd_event, то да, там необходимо и отжатие делать.
А когда посылаем окну клавишу, то не требуется. По крайней мере работает ведь без залипаний.
Диалог "Выполнить"? А на кой он нам сдался, если есть RunProgram()

Ну если хочется запускать диалог "Выполнить", что бы запускать программы то можно :

Код:
1
RunProgram("RUNDLL32", "SHELL32.DLL,#61", "")


:D

_________________
read-only ¯\_(ツ)_/¯


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Пн фев 25, 2019 1:48 pm 
Не в сети
профессор

Зарегистрирован: Чт фев 09, 2017 10:37 am
Сообщений: 560
Благодарил (а): 37 раз.
Поблагодарили: 76 раз.
Пункты репутации: 2
kvitaliy писал(а):
Код:
1
RunProgram("RUNDLL32", "SHELL32.DLL,#61", "")


:D

А как вычислил SHELL32.DLL,#61 ? Я тут замучился гуглить, открывал системные папки, все cpl перенажимал, посмотрел что есть вызовы без cpl, то есть с dll, думаю тут я пас.

kvitaliy писал(а):
Диалог "Выполнить"? А на кой он нам сдался, если есть RunProgram()
столкнулся с тем что версия x86 не видит chkdsk, причём даже если он лежит рядом с прогой (в LiveCD), у меня предположение, что версия x86 берёт свою версию chkdsk из SysWOW64, а так как сборка LiveCD x64 урезана, то он просто не видит своего chkdsk. В теории папка программы является текущей и должен увидеть файл рядом лежащий, но не видит, эту проблему я встречал на AutoIt3, когда EXE был запучен через bat-файл и тогда рабочий каталог был там где лежит bat-файл, поэтому для проги надо было вручную указать текущую дерикторию. Так вот если я делаю экспорт команды в диалог "Выполнить", то я избегаю проблемы, что прога не видит файл из системной папки.

Посмотри ChkDskGui. Во первых на Win7 не работал вызов справки и я сделал условие если результат не получен то вызвать напрямую в cmd.exe. Вот к ней я хотел либо клавишами вызвать либо командой rundll32.exe, чтобы при любой проблеме нативно, родным способом сделать вызов проверки дисков.


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Пн фев 25, 2019 2:05 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11611
Благодарил (а): 4 раз.
Поблагодарили: 494 раз.
AZJIO писал(а):
столкнулся с тем что версия x86 не видит chkdsk, причём даже если он лежит рядом с прогой
Код:
1
RunProgram(GetPathPart(ProgramFilename())+"chkdsk.exe")


_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Пн фев 25, 2019 2:27 pm 
Не в сети
профессор

Зарегистрирован: Чт фев 09, 2017 10:37 am
Сообщений: 560
Благодарил (а): 37 раз.
Поблагодарили: 76 раз.
Пункты репутации: 2
Пётр писал(а):
AZJIO писал(а):
столкнулся с тем что версия x86 не видит chkdsk, причём даже если он лежит рядом с прогой
Код:
1
RunProgram(GetPathPart(ProgramFilename())+"chkdsk.exe")


а я только что додумался в 3-й параметр это добавить. Там же должна быть указана рабочая директория. А изначально chkdsk в системной папке. То есть при поиске файла он кроме системных папок обсмотрит ещё и рабочую папку программы.


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Пн фев 25, 2019 8:36 pm 
Не в сети
профессор

Зарегистрирован: Чт фев 09, 2017 10:37 am
Сообщений: 560
Благодарил (а): 37 раз.
Поблагодарили: 76 раз.
Пункты репутации: 2
kvitaliy писал(а):
Код:
1
RunProgram("RUNDLL32", "SHELL32.DLL,#61", "")

Немного не такое окно, в LiveCD даже с другим заголовком почему-то "Запуск программы", итоге либо под LiveCD подстраиваться, либо чередовать поиск окна в цикле, я сделал каждые 60мсек опрашивать появление окна, если сделать 300мсек, то заметна вставка и задержка, сделаешь меньше, вставляет до нарисовки окна и в пустоту отправляет. А если от админа, то там ещё значок админа.


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Пн фев 25, 2019 9:34 pm 
Не в сети
МОДЕРАТОР

Зарегистрирован: Вт дек 05, 2006 8:46 am
Сообщений: 6611
Благодарил (а): 34 раз.
Поблагодарили: 229 раз.
Пункты репутации: 61
Интересно, LiveCD какая система?
Я сам как то использовал что то из Линуха, т.к. Виндоузная не ко всем папкам доступ давала, личные папки не мог скопировать. А Linux по барабану, читает всё подряд, для копирования самое то.

_________________
read-only ¯\_(ツ)_/¯


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вт фев 26, 2019 4:15 am 
Не в сети
профессор

Зарегистрирован: Чт фев 09, 2017 10:37 am
Сообщений: 560
Благодарил (а): 37 раз.
Поблагодарили: 76 раз.
Пункты репутации: 2
kvitaliy писал(а):
Интересно, LiveCD какая система?
Я сам как то использовал что то из Линуха, т.к. Виндоузная не ко всем папкам доступ давала, личные папки не мог скопировать. А Linux по барабану, читает всё подряд, для копирования самое то.
Например эта.
А Linux я сам тоже использую, Mint, у него оболочка cinnamon и файловый менеджер Nemo, ближе всего похож на Windows. Кстати, под LiveCD стал компилировать, всё работает, единственно желательно из APPDATA конфиги скопировать, я уже сделал скрипт копирования конфигов браузера, чтобы сразу зарегистрированным заходить, надо сделать универсальный скрипт, чтобы показал заказные папки для копирования. У меня сначала Grub запускается, а с него я сделал либо Syslinux, либо виндовые. Вот только 2 разных линукса не получается с одной флешки запускать типа минт и федора


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Ср мар 06, 2019 6:02 pm 
Не в сети
профессор

Зарегистрирован: Чт фев 09, 2017 10:37 am
Сообщений: 560
Благодарил (а): 37 раз.
Поблагодарили: 76 раз.
Пункты репутации: 2
kvitaliy
ковыряю winapi_library и нашёл команду вызова окна "Выполнить"
Код:
1
SendMessage_(FindWindow_("Shell_TrayWnd",""),#WM_COMMAND,$191,0)



Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Ср мар 06, 2019 6:52 pm 
Не в сети
МОДЕРАТОР

Зарегистрирован: Вт дек 05, 2006 8:46 am
Сообщений: 6611
Благодарил (а): 34 раз.
Поблагодарили: 229 раз.
Пункты репутации: 61
AZJIO писал(а):

ковыряю winapi_library и нашёл команду вызова окна "Выполнить"
Код:
1
SendMessage_(FindWindow_("Shell_TrayWnd",""),#WM_COMMAND,$191,0)


Работает!

_________________
read-only ¯\_(ツ)_/¯


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 15 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 9


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group (блог о phpBB)
Сборка создана CMSart Studio
Русская поддержка phpBB