#0
by 247tsm
Добрый день, У меня такой вопрос. Как программно послать символ "*" с правой дополнительной клавиатуры в буфер обмена? С помощью WHS или по-другому. Вообще была поставлена задача: в 1с7.7 при открытии справочника Номенклатура должно полностью раскрываться дерево групп. Вручную это делается так: становимся мышкой на самый верхний элемент дерева групп и нажимаем на "*" (но только с дополнительной правой клавиатуры). Я так понимаю, что в этом случае в буфер обмена попадает не символ "*" с кодом 42, а что-то другое. В разделе для 1с7.7, к сожалению, мне не смогли помочь. Вот попытаю счастье здесь. Спасибо.
#3
by 247tsm
есть, но нет почти никаких команд. А я не могу именно программно иммитировать нажатие "*" с правой дополнительной клавиатуры.
#7
by 247tsm
использовал SendKey. Но что посылать? Вот программный код: addon=CreateObject("addon1c.commands"); addon.SendKeys("+{TAB}"); addon.SendKeys("*"); Командой addon.SendKeys("+{TAB}") я иммитирую активацию (переход на дерево групп). А командой addon.SendKeys("*") пытаюсь раскрыть это дерево. Но не срабатывает, потому что символ "*" с левой клавиатуры и с правой дополнительной клавиатуры, очевидно, разные, но когда программно вывожу коды этих символов - они одинаковые 42. Значит еще какой-то код присутствует.
#8
by 247tsm
и , Вы поймите, что я знаю про команду ИерархическийСписок(1,1), ну и что? Она не решает мою задачу
#9
by kotletka
тогда опиши чем именно тебя не устраивает и в чем плюс твоего метода, из плюсов не видно
#10
by 247tsm
Я предполагаю, что на низком уровне 1С различает символ "*" с левой и правой клавиатуры. Но чем они отличаются в деталях я не знаю, поэтому и решил спросить у знатоков.
#13
by 247tsm
в том то и дело, что в 1С нет возможности программно открыть все уровни дерева групп. Только интерактивно "руками". А я хочу программно. Поэтому и спрашиваю, как?
#19
by 247tsm
А как с помощью SendKeys послать код клавиши "*" с правой клавиатуры? Или по-другому. Как отловить и увидеть, что делается после нажатия "*" на правой клавиатуре? И как то же самое послать в буфер с помощью SendKeys или как-нибудь по-другому?
#20
by 247tsm
+ т.е., как запустить тот же механизм 1С, что и при нажатии на "*" на правой клавиатуре?
#24
by 247tsm
А вообще, дерево групп имеет какое-нибудь системное имя, как элемент формы, чтобы к нему программно обратиться и сделать его активным, т.е., как будто установили на него курсор мышки?
#29
by palpetrovich
хз, почему у тебя "1С нет возможности программно открыть все уровни дерева групп" спецом попробовал, все работает Процедура ПриОткрытии // в форме списка ИерархическийСписок; КонецПроцедуры
#32
by andrewks
я так понял, основной косяк с получателем события. вчера баловался через DynamicWrapper - нажатия клавиш проходят, но 1С-ка их не получает. например, NumLock зажигается, т.е. какой-то глобальный контекст их обрабатывает, а в 1с-ку не приходит
#34
by andrewks
причём пробовал и через PostMessage, и keybd_event, и с EnableWindow/SetFocus, и без, однохерственно нажатия проходят, глобальный контекст изменяется, а в 1с ничего не происходит
#37
by 247tsm
я попробовал - не работает, т.е. при открытии справочника номенклатура дерево не раскрывается автоматически.
#38
by andrewks
да дело-то не в том, что {MULTIPLY} не работает, а в том, что вообще посланные по WinAPI нажатия клавиш не приходят в 1с вообще (либо, как вариант, не обрабатываются ей)
#39
by PR
Почему? Shell = Новый COMОбъект("WScript.Shell"); Shell.SendKeys("*"); прекрасно работает например.
#41
by 247tsm
Небольшое замечание. Нужно не просто послать {MULTIPLY}, а сначала спозиционироваться на дереве, а затем послать {MULTIPLY}. Но у меня так: Процедура ПриОткрытии Shell = CreateObject("WScript.Shell"); Shell.SendKeys("{MULTIPLY}"); КонецПроцедуры и на второй строке останавливается: Shell.SendKeys("{MULTIPLY}"); {Справочник.Номенклатура.ФормаСписка.ФормаСписка.Модуль}: : т.е. не принимает название клавиши. Но сначала все же нужно спозиционироваться на дереве.
#42
by 247tsm
Сначала перемещался, а теперь не хочет, но почему - не могу понять. Я делал так. Ws = CreateObject("WScript.Shell"); Ws.SendKeys ("+{TAB}"); Ws.SendKeys ("+{TAB}"); и так addon=CreateObject("addon1c.commands"); addon.SendKeys("+{TAB}"); addon.SendKeys("+{TAB}"); То, что перемещался - это 100%. Затем начал экспериментировать и в какой-то момент перестал перемещаться. Я попробовал перерегистрировать addon1c.dll, но не помогло.
#43
by 247tsm
+ я два раза посылаю SendKeys("+{TAB}"), потому что на форме списка есть еще элементы. Количество SendKeys("+{TAB}") я определил экспериментально - проделал сначала вручную эти операции, а затем попробовал программно - т.е. как макрос в Excel.
#44
by 247tsm
Прошу прощения, просчитался. Следующий код работает 100% - позиционирует на дереве: Shell = CreateObject("WScript.Shell"); Shell.SendKeys ("+{TAB}"); Shell.SendKeys ("+{TAB}"); Shell.SendKeys ("+{TAB}"); Shell.SendKeys ("+{TAB}"); Нужно аккуратно посчитать, сколько раз послать SendKeys("+{TAB}"). Теперь осталось решить с {MULTIPLY}.
#45
by andrewks
в том-то и дело, что с "WScript.Shell" ты с MULTIPLY не решишь, ибо его там просто нет. я попытался сделать через WinAPI, но там вообще всё глухо, как в танке
#46
by 247tsm
В принципе, одно решение, кажется, нашел: Shell = CreateObject("WScript.Shell"); Shell.SendKeys ("+{TAB}"); Shell.SendKeys ("+{TAB}"); Shell.SendKeys ("+{TAB}"); Shell.SendKeys ("+{TAB}"); Для нн = 1 по 10 Цикл Shell.SendKeys("{RIGHT}"); Shell.SendKeys("{DOWN}"); КонецЦикла; Но для цикла нужно указать число не больше, чем папок+элементов в дереве, а иначе почему-то дерево не раскрывается, а курсор улетает на табличную часть. Хотя, когда я проделываю то же вручную - могу хоть 100 раз нажать {RIGHT} {DOWN} и курсор не выходит за рамки дерева. Не понятно, почему?
#48
by 247tsm
Срабатывает и так: . . . Для нн = 1 по 10 Цикл Shell.SendKeys("{RIGHT}{DOWN}"); КонецЦикла;
#49
by 247tsm
Вот только не удается указать коэффициент: для одной клавиши понятно {RIGHT 10}, а как указать для группы клавишей?
#50
by 247tsm
да, немного поизвращался - но что делать, если в 1С такое дерево. Есть другой вариант - воспользоваться FormEx - там есть "дерево+таблица", но уверяю, что кода там будет в 3 раза больше, а мне всего-то нужно раскрыть дерево и все.
#51
by 247tsm
Работает и такой вариант: addon=CreateObject("addon1c.commands"); addon.SendKeys("+{TAB}"); addon.SendKeys("+{TAB}"); addon.SendKeys("+{TAB}"); addon.SendKeys("+{TAB}"); Для нн = 1 по 10 Цикл addon.SendKeys("{RIGHT}{DOWN}"); КонецЦикла;
#56
by 247tsm
Пока самый короткий вариант: addon=CreateObject("addon1c.commands"); addon.SendKeys("+{TAB 4}"); Для нн = 1 по 10 Цикл addon.SendKeys("{RIGHT}{DOWN}"); КонецЦикла;
#57
by 247tsm
Интересно, какой вариант лучше: WScript.Shell или addon1c.commands? (без тормозов ... или может есть подводные камни)
#58
by catena
"addon.SendKeys("+{TAB}"); " Кто-нибудь изменит порядок обхода на форме и полетит весь твой код за синей птицей...
#59
by Torquader
Ну, там же стандартное дерево - пишем dll, которая по идентификатору окна находит это "дерево" и шлёт ему команду развернуть. Сообщение TVM_EXPAND - но его нужно слать для каждого элемента. Если DLL в адресном просотранстве 1С (ActiveX from DLL), то спокойно можно получать элементы и делать с ними всё, что душа пожелает. Только желательно помнить, что "умные" элементы управления шлют нотификацию своему окну, которую 1С будет обрабатывать - то есть нужно будет слать сообщения из отдельного потока, чтобы не мешать 1С их обрабатывать.
#60
by PR
Скажите мне кто-нить pls, почему все-таки не пашет {MULTIPLY}? Это же вроде как вполне себе официальный параметр SendKeys?
#61
by Torquader
Я когда смотрел SendKeys выяснил, что оно неправильно использует символы клавиатуры, то есть * транслируется именно в клавишу * вне зависимости, от того, что ты хочешь. kbd_event спасёт, наверное.
#62
by andrewks
в описании SendKeys есть закрытый перечень виртуальных кодов, и MULTIPLY среди них нет. зато есть в .NET'овском варианте kbd_event не взлетает, см
#63
by Torquader
kbd_event - это запись события в буфер клавиатуры ещё до распределения сообщения - если оно не взлетает, то не взлетит вообще ничего, так как сообщение не доходит до получателя. P.S. а слать нужно через SendMessage, так как PostMessage обрабатывается при исполнении кода как ожидание Esc для его прерывания (в момент перехода с одной строки на другую), кстати, ваши SendKeys тож идут к тому же самому коту под хвост. Посылать сообщения нужно не из потока 1С, а от кого-то другого.
#64
by andrewks
"Посылать сообщения нужно не из потока 1С, а от кого-то другого." т.е. PostMessage тоже не взлетит?
#66
by Torquader
Насколько я помню, WScript вставляет коды клавиш в буфер клавиатуры, но не ожидает их обработки, то есть код продолжает исполняться. Кроме того, любой объект из 1С исполняется не в её коде (то есть при вызове любого объекта исполнение кода 1С прерывается до окончания вызова). А почему не прошло SendMessage WM_KEYDOWN самому элементу с деревом - у меня всегда проходило - я даже автосоздавалку объектов в конфиругаторе писал через него - 20тыс. справочников она за ночь сделала.
#68
by andrewks
делаю так: в форме списка справочника в ПриОткрытии HWND=WinAPI.GetActiveWindow; WinAPI.EnableWindow(HWND,-1); WinAPI.SetFocus(HWND); WinAPI.SendMessage(HWND,WM_KEYDOWN,VK_TAB,1); WinAPI.SendMessage(HWND,WM_KEYUP,VK_TAB,1); и так: ScanCode=WinAPI.MapVirtualKey(VK_TAB,0); // MAPVK_VK_TO_VSC WinAPI.keybd_event(VK_TAB,ScanCode,0,0); WinAPI.keybd_event(VK_TAB,ScanCode,2,0); 1с-ка ничего не обрабатывает. хотя, если делаю так: ScanCode=WinAPI.MapVirtualKey(VK_NUMLOCK,0); // MAPVK_VK_TO_VSC WinAPI.keybd_event(VK_NUMLOCK,ScanCode,0,0); WinAPI.keybd_event(VK_NUMLOCK,ScanCode,2,0); то NumLock загорается/тухнет
#69
by Torquader
Ну, тогда нужно взять и сделать Trace сообщений и посмотреть, что происходит. Может быть, на некоторые сообщения просто акселераторы стоят, которые в потоке основого окна по Hook-процедуре ловятся - CommonControls, например, всплывающие подсказки именно так и ловит - тут уже нужно Hook найти и "скормить" ему то, что он хочет.
#70
by Torquader
Какого "ПриОткрытии" - в лес! При открытии - у тебя ещё формы нет - она будет только тогда, когда откроется. Иди читай про ложное закрытие и не мучайся.
#71
by andrewks
"При открытии - у тебя ещё формы нет" ну как же нет? есть, и это можно увидеть, если поставить задержку, а потом закрыть форму. на экране увидишь родимую форму
#73
by Torquader
Тогда пробуй просто получить список окон через GetWindow - и послать сообщение твоему несчастному окну через PostMessage или SendMessage, например.
#74
by andrewks
т.е., возможно, сообщение уходит главному окну, вместо окна списка справочника? была такая мысль, надо попробовать
#75
by Torquader
Сообщение клавиатуры посылается тому, у кого выполнен SetFocus, но на время выполнения кода активность формы выключается, чтобы пользователь не нажал чего лишнего. P.S. через обработку ожидания можно послать - она, если в глобальнике, то в другом потоке выполняется.
#76
by 247tsm
Извините, что прерываю, но снова непонятка. Если я вставляю какой-то программный код перед этими действиями по разворачиванию дерева, то дерево не раскрывается. Этот код не работает: // Определяем кол-во папок Спр=СоздатьОбъект("Справочник.Номенклатура"); Спр.ВыбратьЭлементы; КолПапок = 0; Пока спр.ПолучитьЭлемент=1 Цикл Если спр.ЭтоГруппа=1 Тогда КолПапок = КолПапок + 1; КонецЕсли; КонецЦикла; // КОНЕЦ Определяем количество папок // Раскрываем дерево addon=CreateObject("addon1c.commands"); addon.SendKeys("^{HOME}"); addon.SendKeys("+{TAB 4}"); //КолПапок = 10; Для нн = 1 по КолПапок Цикл addon.SendKeys("{RIGHT}{DOWN}"); КонецЦикла; А следующий работает: // Раскрываем дерево addon=CreateObject("addon1c.commands"); addon.SendKeys("^{HOME}"); addon.SendKeys("+{TAB 4}"); КолПапок = 10; Для нн = 1 по КолПапок Цикл addon.SendKeys("{RIGHT}{DOWN}"); КонецЦикла; В чем секрет?
#77
by 247tsm
Вопрос решил - вывел из процедуры в тело модуля формы списка подсчет количества папок и снова заработало.
Тэги: Математика и алгоритмы
Ответить:
Комментарии доступны только авторизированным пользователям
Похожие вопросы 1С
- А можно создать программно новый объект метаданных?
- Как скопировать в буфер обмена область таблицы (программно)?
- Как программно скопировать данные в буфер обмена из 1С?
- Как программно сохранить ТаблицуЗначений в буфер обмена
- 1С и буфер обмена (из буфера обмена в СписокЗначений)
- Программно добавить обработчик события к программно добавленному элементу формы
- OFF: как ворде наложить символ на символ
- Как перегнать программно печатную форму в формат JPG
- v8: СКД: программно добавить системное поле
- V8.2. Какя разница между доп. сведения и доп. реквизиты
- Как программно установить владельца программно созданной колонке
- Как в 1с программно очистить буфер обмена Word
В этой группе 1С
- В запросе получить выборку месяцев за интервал
- Надо ли покупать сервер 1С Предприятия, если..
- Закрытие месяца - ошибка по 26 счету
- Запрос в динамическом списке справочника управляемой формы
- Откуда РСВ-1 в БП8 берет код тарифа страховых взносов?
- как списать 20счет на 90.02.1 ?
- Перенести субконто в плане счетов
- Запрос во внешней обработке 8.1
- Как программно из внешней печатной формы закрыть форму документа ?
- v7: Долгое проведение реализации 1с ТиС 7.7 sql
- v8: как убрать лишнее из панели функций в ЗУПе
- Получение остатка на начало из регистра накопления
- Ошибка получения объекта COM: Moniker cannot open file
- Загрузка из Excel в 1с
- v7: RemoteApp + 1С 77
- 1НДФЛ (раздел №3): указан непредусмотренный код стандартного налогового вычета
- v8: Корректировка поступления БП 2.0
- Странная ошибка при проведении поступления. ссылается на субконто..
- Нужна книга конфигурирование в системе 1С предприятие: решение расчетных задач
- СКД: в одной колонке на разные показатели