Имя: Пароль:
1C
 
v7: Получение списка дочерних окон 1С
0 Андрюха
 
23.03.09
07:31
Вызываю через DynamicWrapper, не могу сообразить как из 1С передать туда вторым параметром указатель на функцию :(
1 Rie
 
23.03.09
07:36
(0) А разве DynWrapper предусматривает возможность параметров-функций?
2 Андрюха
 
23.03.09
07:41
{'p', sizeof(void*), VT_PTR}, // p pointer
А уж функция там или переменная или еще какая хрень должна разбираться dspsdftvfz API функция
3 smaharbA
 
23.03.09
07:42
нужны окна только или процессы и модули ?
4 smaharbA
 
23.03.09
07:42
+(3) и рекурсивно надо ?
5 Андрюха
 
23.03.09
07:46
(3) Нужно найти только дочернее окно в 1С по заголовку
6 smaharbA
 
23.03.09
07:48
(5) тогда ненадо тебе енумератор, но на сколько помню сперва тебе нужно будет mdi окно найти (главное) а потом уж в нем все остальные
7 smaharbA
 
23.03.09
07:50
что то типа

   function EnumWindow(parent)
       on error resume next
       dim a(),Wrap
       redim a(-1)
       Set Wrap=CreateObject("DynamicWrapper")
       Wrap.Register "user32.dll", "FindWindowW", "i=ll", "f=s", "r=l"
       Wrap.Register "user32.dll", "GetWindow", "i=ll", "f=s", "r=l"
       Wrap.Register "user32.dll", "GetParent", "i=l", "f=s", "r=l"
       Wrap.Register "user32.dll", "IsWindowVisible", "i=l", "f=s", "r=l"
       Wrap.Register "user32.dll", "IsWindowEnabled", "i=l", "f=s", "r=l"
       hwnd = Wrap.FindWindowW(0, 0)
       Do While hwnd <> 0
           if Wrap.GetParent(hwnd)=parent and Wrap.IsWindowVisible(hwnd) then
               txt = getWindowText(hwnd)
               txt = trim(replace(txt,chr(0),""))
               if trim(txt)<>"" and trim(txt)<>"Program Manager" and trim(txt)<>document.title and instr(trim(txt),"Выбор действия")<>1 then
                   redim preserve a(ubound(a)+1)
                   a(ubound(a))=cstr(txt) & chr(0) & hwnd & chr(0)
               end if
           end if
           hwnd = Wrap.GetWindow(hwnd, GW_HWNDNEXT)
       Loop
       Set Wrap=Nothing
       EnumWindow=ArraySort(a,chr(0))
   end function
8 Андрюха
 
23.03.09
07:50
(6) Это я нахожу:
Wrapper = CreateObject("DynamicWrapper");
Wrapper.Register("USER32.DLL", "FindWindow","i=ls", "f=s", "r=l");
hwnd = Wrapper.FindWindow(0, "Контрагент");
Если hwnd > 0 Тогда
   Сообщить("Хендл окна: " + hwnd);
Иначе
   Сообщить("Не найдено");
КонецЕсли;
9 smaharbA
 
23.03.09
07:51
ну тут поиск от десктопа, а тебе сперва по классу надо найти мди, и его первым в обход
10 smaharbA
 
23.03.09
07:53
там функция получения заголовка еще, ну это можно потом
11 Sadovnikov
 
23.03.09
07:55
Формэкс:
СписокВсехОткрытыхОкон()
СИНТАКСИС:
СписокВсехОткрытыхОкон()
НАЗНАЧЕНИЕ:
возвращает список значений со всеми открытыми формами
12 Кириллка
 
23.03.09
07:56
+10 ::GetWindowText(hWnd, pBuf, sizeof(pBuf))
13 smaharbA
 
23.03.09
07:56
(11) Такую песню испортил. (с)
:)
14 Sadovnikov
 
23.03.09
08:01
(13) Щас еще больше испорчу :)
Искать лучше не по заголовку. А завести в модуле переменную и определять ее наличие.
///********************************Олег (RiK тел. 213-15-29) 24.09.2008
// 0 - закрыто, 1 - открыто на переднем плане, 2 - открыто НЕ на переднем плане
///********************************Олег (RiK тел. 213-15-29) 24.09.2008
Функция КакОткрытоОкноЧата()
   фРежимОткрытия = 0;
   
   оИнформатор    = СоздатьОбъект("Информатор");
   оСервис        = СоздатьОбъект("Сервис");
   сзОкна        = оСервис.СписокВсехОткрытыхОкон();
   
   Для Н = 1 По сзОкна.РазмерСписка() Цикл
       КонтекстОкна    = сзОкна.ПолучитьЗначение(Н);
       Если оИнформатор.СвойствоСуществует(КонтекстОкна, "фЭтоОкноЧата") = 1 Тогда
           Если Н = 1 Тогда
               фРежимОткрытия = 1;
           Иначе
               фРежимОткрытия = 2;
           КонецЕсли;
       КонецЕсли;
   КонецЦикла;
   
   
   Возврат фРежимОткрытия;
КонецФункции
///********************************Олег (RiK тел. 213-15-29) 24.09.2008
15 smaharbA
 
23.03.09
08:04
(14) а это уже и штатно делается
вообще список и все, все окна всегда под рукой )))
16 Sadovnikov
 
23.03.09
08:04
(15) "вообще список и все, все окна всегда под рукой " - поясни?
17 smaharbA
 
23.03.09
08:07
(16)
Процедура ПриОткрытии()
СписокОкон.ДобавитьЗначение(Контекст);
...
ну там с проверкой конечно и не в прямую в приоткрытии, а через функцию
18 Sadovnikov
 
23.03.09
08:08
(17) Зачем так напрягаться и перелопачивать всю конфу? Если есть СписокВсехОткрытыхОкон.
19 smaharbA
 
23.03.09
08:08
+(17) текст на форме ИмяФормы
20 smaharbA
 
23.03.09
08:09
(18) пусть оба будут, это во мне антогонизъм )))
21 Sadovnikov
 
23.03.09
08:09
(20) А... Понял :)
22 Андрюха
 
23.03.09
08:25
Ого, понаписали :))))

У меня всё получилось, за исключением того, что не могу получить заголовок окна по хендлу:
       Wrapper = CreateObject("DynamicWrapper");
       Wrapper.Register("user32.dll", "FindWindowW", "i=ll", "f=s", "r=l");
       Wrapper.Register("user32.dll", "FindWindow","i=ls", "f=s", "r=l");
       Wrapper.Register("user32.dll", "GetWindow", "i=ll", "f=s", "r=l");
       Wrapper.Register("user32.dll", "GetParent", "i=l", "f=s", "r=l");
       Wrapper.Register("user32.dll", "GetWindowTextW", "i=hWl");

       hwndParent = Wrapper.FindWindow(0, ТекущийЗаголовок);
       hwnd = Wrapper.FindWindowW(0, 0);
       Пока hwnd <> 0 Цикл
           ЗаголовокОкна = "";
           Для Сч = 1 По 256 Цикл
               ЗаголовокОкна = ЗаголовокОкна + " ";
           КонецЦикла;
           Wrapper.getWindowTextW(hwnd, ЗаголовокОкна, 256);
           
           Если Wrapper.GetParent(hwnd) = hwndParent Тогда
               FormEx_ИконкаПредупреждения
               
               Сообщить(Строка(hwnd) + ": " + ЗаголовокОкна);
           КонецЕсли;
           
           hwnd = Wrapper.GetWindow(hwnd, 2);
       КонецЦикла;
23 Андрюха
 
23.03.09
08:26
FormEx_ИконкаПредупреждения - затесалось, надо выкинуть
24 Андрюха
 
23.03.09
08:34
(14) Отлично, а как активировать дочернее окно по контексту?
25 Sadovnikov
 
23.03.09
08:35
(24) ОткрытьФорму?
26 Андрюха
 
23.03.09
08:36
(25) Предположим, что форма уже открыта, нужно ее переместить на фронт.
27 Sadovnikov
 
23.03.09
08:37
(26) Что за форма? Документ? Элемент справочника? Обработка?
28 Андрюха
 
23.03.09
08:40
(27) Обработка
29 Sadovnikov
 
23.03.09
08:41
(28) ОткрытьФорму
30 Андрюха
 
23.03.09
08:46
(29) У меня не получится, т.к. я с помощью ВК RBrowser открываю в дочернем окне 1С файл Excel. Теперь нужно при поворном его открытии активизировать (по заголовку) уже открытое окно.
31 Андрюха
 
23.03.09
08:47
Всё что мне нужно, это найти по заголовку дочернее окно и сделать его активным.
32 Андрюха
 
23.03.09
08:51
(31) Окно открытое RBrowser в СписокВсехОткрытыхОкон() не попадает
33 Sadovnikov
 
23.03.09
08:53
(31)
КонтФормы.Активизировать("");
34 Андрюха
 
23.03.09
08:54
(33) -> (32) :(((
35 Rie
 
23.03.09
08:56
(30) О, кстати, та же проблема!

Но только не уверен, что решаемо "в лоб" через dll. Я пробовал писать для этой цели собственную ВК, но обломился: именно из-под _1С_ не работает, при запуске того же кода из MS Word, а также тестовых приложений на Delphi окно "всплывало". Из 1С - тоже "всплывало", но тут же поверх него ложилось окно 1С.
36 Андрюха
 
23.03.09
09:00
(35) Я стал открывать через RBrowser - всё отлично, только при повторном открытии Excel матюкается, вот и хочу искать дочернее окно по заголовку и активизировать его. В (22) проблема бы решилась, но не могу получить заголовок открытого дочернего окна, GetWindowText и GetWindowTextW возрращают пустую строку.
37 Rie
 
23.03.09
09:02
(36) У меня - Excel запускался через OLE.
Далее находил окно по заголовку и поднимал наверх.
После этого оно на доли секунды было видно, потом поверх него наползала 1С.
38 Андрюха
 
23.03.09
09:03
(37) Такая же фигня была, попробуй через RBrowser - симатично получается, за искл повторного открытия
39 Sadovnikov
 
23.03.09
09:04
(32) Тыды упс... Ни разу не работал с RBrowser.
40 Андрюха
 
23.03.09
09:08
(39) Может быть тогда добавить в 1С++ возможность открытия в качестве дочернего окна IE ну и в нем файла кончено же?
41 Rie
 
23.03.09
09:08
(38) Спасибо,RBrowser попробую.

Но хотелось бы понять, как именно это делается. То, что я вижу сейчас - там пусть free, но "голая" dll. А исходников, случаем, не водится?
42 smaharbA
 
23.03.09
09:09
Так пойдет ?

Процедура Сформировать()
   Скрипт=СоздатьОбъект("MSScriptControl.ScriptControl");
   Скрипт.language="javascript";
   Скрипт.AddCode("
   |function getWindowText(hwnd) {
   |var i = 0,text = '';
   |for (i = 0; i<1024; i++) {
   |text += ' ';
   |}
   |var wrap = new ActiveXObject('DynamicWrapper');
   |wrap.Register('User32.dll', 'GetWindowTextW', 'i=hwl', 'f=s', 'r=l');
   |wrap.GetWindowTextW(hwnd, text, 1024);
   |var wrap=0,i=0;
   |return (new String(text).replace(/\x00/g,''));
   |}
   |function getWindowClass(hwnd) {
   |var i = 0,text = '';
   |for (i = 0; i<1024; i++) {
   |text += ' ';
   |}
   |var wrap = new ActiveXObject('DynamicWrapper');
   |wrap.Register('User32.dll', 'GetClassNameW', 'i=hwl', 'f=s', 'r=l');
   |wrap.GetClassNameW(hwnd, text, 1024);
   |var wrap=0,i=0;
   |return (new String(text).replace(/\x00/g,''));
   |}
   |");
   Враппер = СоздатьОбъект("DynamicWrapper");
   Враппер.Register("user32.dll", "FindWindowW", "i=ll", "f=s", "r=l");
   Враппер.Register("user32.dll", "GetWindow", "i=ll", "f=s", "r=l");
   Враппер.Register("user32.dll", "GetParent", "i=l", "f=s", "r=l");
   ТЗОкон=СоздатьОбъект("ТаблицаЗначений");
   ТЗОкон.НоваяКолонка("Хендл");
   ТЗОкон.НоваяКолонка("Заголовок");
   ТЗОкон.НоваяКолонка("Класс");
   Хендл = Враппер.FindWindowW(0, 0);
   Пока Хендл <> 0 Цикл
       ЗаголовокОкна = СокрЛП(Скрипт.CodeObject.getWindowText(Хендл));
       КлассОкна = СокрЛП(Скрипт.CodeObject.getWindowClass(Хендл));
       ТЗОкон.НоваяСтрока();
       ТЗОкон.Хендл = Хендл;
       ТЗОкон.Заголовок = ЗаголовокОкна;
       ТЗОкон.Класс = КлассОкна;
       Хендл = Враппер.GetWindow(Хендл, 2);
   КонецЦикла;
   ТЗОкон.ВыбратьСтроку();
КонецПроцедуры
43 smaharbA
 
23.03.09
09:11
ИЕ или веббраузер можно открыть как активикс или тупо сделать дочерним тойже рамке текста вот тебе и будет окно на форме, правдо тут надо будет отслеживать события вмпаинт
44 Андрюха
 
23.03.09
09:20
(42) В качестве заголовка нужного окна постоянно возвращается "Вид", а не фактический заголовок. Вот.
45 smaharbA
 
23.03.09
10:44
(44) это даст окна системы
сейчас дам перечисление окон в главном окне 1с
46 smaharbA
 
23.03.09
14:58
Был занят воткой )))
вот гдето так, упрощять только надо, приблизить к адинэс

//*******************************************
Процедура Сформировать()
   Скрипт=СоздатьОбъект("MSScriptControl.ScriptControl");
   Скрипт.language="javascript";
   Скрипт.AddCode("
   |function getWindowText(hwnd) {
   |var i = 0,text = '';
   |for (i = 0; i<1024; i++) {
   |text += ' ';
   |}
   |var wrap = new ActiveXObject('DynamicWrapper');
   |wrap.Register('User32.dll', 'GetWindowTextW', 'i=hwl', 'f=s', 'r=l');
   |wrap.GetWindowTextW(hwnd, text, 1024);
   |var wrap=0,i=0;
   |return (new String(text).replace(/\x00/g,''));
   |}
   |function getWindowClass(hwnd) {
   |    var i = 0,text = '';
   |    for (i = 0; i<1024; i++) {
   |        text += ' ';
   |        }
   |    var wrap = new ActiveXObject('DynamicWrapper');
   |    wrap.Register('User32.dll', 'GetClassNameW', 'i=hwl', 'f=s', 'r=l');
   |    wrap.GetClassNameW(hwnd, text, 1024);
   |    var wrap=0,i=0;
   |    return (new String(text).replace(/\x00/g,''));
   |    }
   |");
   Враппер = СоздатьОбъект("DynamicWrapper");
   Враппер.Register("user32.dll", "FindWindowW", "i=ll", "f=s", "r=l");
   Враппер.Register("user32.dll", "GetWindow", "i=ll", "f=s", "r=l");
   Враппер.Register("user32.dll", "GetParent", "i=l", "f=s", "r=l");
   Враппер.Register("kernel32.dll", "GetCurrentProcessId", "f=s", "r=l");
   Враппер.Register("kernel32.dll", "GetCurrentThreadId", "f=s", "r=l");
   Враппер.Register("User32.dll", "GetWindowThreadProcessId", "i=ll", "f=s", "r=l");
   Хендл = Враппер.FindWindowW(0, 0);
   Пока Хендл <> 0 Цикл
       Если Враппер.GetParent(Хендл)=0 Тогда
           Нить=Враппер.GetWindowThreadProcessId(Хендл, 0);
           Если Нить=Враппер.GetCurrentThreadId() Тогда
               Прервать;
           КонецЕсли;
       КонецЕсли;
       Хендл = Враппер.GetWindow(Хендл, 2);
   КонецЦикла;
   ТЗОкон=СоздатьОбъект("ТаблицаЗначений");
   ТЗОкон.НоваяКолонка("Хендл");
   ТЗОкон.НоваяКолонка("Заголовок");
   ТЗОкон.НоваяКолонка("Класс");
   Хендл=Враппер.GetWindow(Хендл,5);
   Пока Хендл <> 0 Цикл
       ЗаголовокОкна = СокрЛП(Скрипт.CodeObject.getWindowText(Хендл));
       КлассОкна = СокрЛП(Скрипт.CodeObject.getWindowClass(Хендл));
       Если КлассОкна="MDIClient" Тогда
           Прервать;
       КонецЕсли;
       Хендл = Враппер.GetWindow(Хендл, 2);
   КонецЦикла;
   Хендл=Враппер.GetWindow(Хендл,5);
   Пока Хендл <> 0 Цикл
       ЗаголовокОкна = СокрЛП(Скрипт.CodeObject.getWindowText(Хендл));
       КлассОкна = СокрЛП(Скрипт.CodeObject.getWindowClass(Хендл));
       ТЗОкон.НоваяСтрока();
       ТЗОкон.Хендл = Хендл;
       ТЗОкон.Заголовок = ЗаголовокОкна;
       ТЗОкон.Класс = КлассОкна;
       Хендл = Враппер.GetWindow(Хендл, 2);
   КонецЦикла;
   ТЗОкон.ВыбратьСтроку();
КонецПроцедуры
47 H A D G E H O G s
 
23.03.09
15:00
Нда.
** тихо уполз из ветки, поджав хвост.
48 Андрюха
 
24.03.09
04:51
Благодаря уважаемому smaharbA родился следующий код получения таблицы всех дочерних окон, с указанием хендла, заголовка и класса:
   Скрипт = СоздатьОбъект("MSScriptControl.ScriptControl");
   Скрипт.language = "javascript";
   Скрипт.AddCode("Текст=Array(1024).join(' ');
   |function getWindowText(Хендл){Враппер.GetWindowTextW(Хендл,Текст,1024);return(Текст)}
   |function getWindowClass(Хендл){Враппер.GetClassNameW(Хендл,Текст,1024);return(Текст)}");
   Враппер = СоздатьОбъект("DynamicWrapper");
   Враппер.Register("user32.dll",        "FindWindowExA",            "i=llsl",    "f=s", "r=l");
   Враппер.Register("user32.dll",        "FindWindowW",                "i=ll",        "f=s", "r=l");
   Враппер.Register("user32.dll",        "GetWindow",                "i=ll",        "f=s", "r=l");
   Враппер.Register("user32.dll",        "GetParent",                "i=l",        "f=s", "r=l");
   Враппер.Register("kernel32.dll",    "GetCurrentThreadId",        "f=s",        "r=l"        );
   Враппер.Register("User32.dll",        "GetWindowThreadProcessId",    "i=ll",        "f=s", "r=l");
   Враппер.Register("User32.dll",        "GetWindowTextW",            "i=hwl",    "f=s", "r=l");
   Враппер.Register("User32.dll",        "GetClassNameW",            "i=hwl",    "f=s", "r=l");
   Скрипт.AddObject("Враппер",Враппер);
   Хендл = Враппер.FindWindowW(0, 0);
   Пока Хендл <> 0 Цикл
       Если Враппер.GetParent(Хендл)=0 Тогда
           Нить=Враппер.GetWindowThreadProcessId(Хендл, 0);
           Если Нить=Враппер.GetCurrentThreadId() Тогда
               Прервать;
           КонецЕсли;
       КонецЕсли;
       Хендл = Враппер.GetWindow(Хендл, 2);
   КонецЦикла;
   Хендл=Враппер.FindWindowExA(Хендл,0,"MDIClient",0);
   ТаблицаОкон = СоздатьОбъект("ТаблицаЗначений");
   ТаблицаОкон.НоваяКолонка("Хендл");
   ТаблицаОкон.НоваяКолонка("Заголовок");
   ТаблицаОкон.НоваяКолонка("Класс");
   Хендл = Враппер.GetWindow(Хендл,5);
   Пока Хендл <> 0 Цикл
       ЗаголовокОкна = СокрЛП(Скрипт.CodeObject.getWindowText(Хендл));
       КлассОкна = СокрЛП(Скрипт.CodeObject.getWindowClass(Хендл));
       ТаблицаОкон.НоваяСтрока();
       ТаблицаОкон.Хендл = Хендл;
       ТаблицаОкон.Заголовок = ЗаголовокОкна;
       ТаблицаОкон.Класс = КлассОкна;
       Хендл = Враппер.GetWindow(Хендл, 2);
   КонецЦикла;
   ТаблицаОкон.ВыбратьСтроку();

С удовольствием добавляю его в базу знаний.
Есть два вида языков, одни постоянно ругают, а вторыми никто не пользуется.