Как программно послать символ "*" с правой доп. клавиатуры в буфер обмена? #606825


#0 by 247tsm
Добрый день, У меня такой вопрос. Как программно послать символ "*" с правой дополнительной клавиатуры в буфер обмена? С помощью WHS или по-другому. Вообще была поставлена задача: в 1с7.7 при открытии справочника Номенклатура должно полностью раскрываться дерево групп. Вручную это делается так: становимся мышкой на самый верхний элемент дерева групп и нажимаем на "*" (но только с дополнительной правой клавиатуры). Я так понимаю, что в этом случае в буфер обмена попадает не символ "*" с кодом 42, а что-то другое. В разделе для 1с7.7, к сожалению, мне не смогли помочь. Вот попытаю счастье здесь. Спасибо.
#1 by Один С
РежимСправочника.Иерархический или както так, разве нет в семерке?
#2 by andrewks
SendKey
#3 by 247tsm
есть, но нет почти никаких команд. А я не могу именно программно иммитировать нажатие "*" с правой дополнительной клавиатуры.
#4 by palpetrovich
мда уж, горе от ума  :)
#5 by palpetrovich
забудь о иммитировать нажатие "*" , сконцентрируйся на
#6 by Скользящий
блин, зачем тебе имитировать "*"?? В СП посмотри ИерархическийСписок
#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С различает символ "*" с левой и правой клавиатуры. Но чем они отличаются в деталях я не знаю, поэтому и решил спросить у знатоков.
#11 by andrewks
0x6A
#12 by Один С
конечно она их различает, потомучто у них разные коды символа..
#13 by 247tsm
в том то и дело, что в 1С нет возможности программно открыть все уровни дерева групп. Только интерактивно "руками". А я хочу программно. Поэтому и спрашиваю, как?
#14 by andrewks
коды символа одинаковые. а вот коды клавиш разные и различает их не 1С, а ось
#15 by PR
NUM, а не TAB
#16 by 247tsm
а как 0х6А записать с помощью SendKeys?
#17 by 247tsm
"+{TAB}" = SHIFT-TAB   это для установки курсора на дерево групп.
#18 by vis_tmp
6*16+10 ?
#19 by 247tsm
А как с помощью SendKeys послать код клавиши "*" с правой клавиатуры? Или по-другому. Как отловить и увидеть, что делается после нажатия "*" на правой клавиатуре? И как то же самое послать в буфер с помощью SendKeys или как-нибудь по-другому?
#20 by 247tsm
+ т.е., как запустить тот же механизм 1С, что и при нажатии на "*" на правой клавиатуре?
#21 by 247tsm
пробую, но пока никак.
#23 by 247tsm
посмотрел, но не понял, как можно использовать.
#24 by 247tsm
А вообще, дерево групп имеет какое-нибудь системное имя, как элемент формы, чтобы к нему программно обратиться и сделать его активным, т.е., как будто установили на него курсор мышки?
#25 by andrewks
нет
#26 by andrewks
а у тебя вообще курсор на дерево перемещается после твоих манипуляций?
#27 by PR
Там собсно и написано, что никак. В написано, что {MULTIPLY}, но что-то не пашет.
#28 by PR
Не в этом дело. Я в восьмерке пробовал, тоже не пашет.
#29 by palpetrovich
хз, почему у тебя "1С нет возможности программно открыть все уровни дерева групп" спецом попробовал, все работает   Процедура ПриОткрытии // в форме списка    ИерархическийСписок; КонецПроцедуры
#30 by andrewks
а ты как пробовал? через DynamicWrapper, или VBS?
#31 by PR
Shell = Новый COMОбъект("WScript.Shell"); Shell.SendKeys("{MULTIPLY}");
#32 by andrewks
я так понял, основной косяк с получателем события. вчера баловался через DynamicWrapper - нажатия клавиш проходят, но 1С-ка их не получает. например, NumLock зажигается, т.е. какой-то глобальный контекст их обрабатывает, а в 1с-ку не приходит
#33 by andrewks
что думаешь по этому поводу?
#34 by andrewks
причём пробовал и через PostMessage, и keybd_event, и с EnableWindow/SetFocus, и без, однохерственно нажатия проходят, глобальный контекст изменяется, а в 1с ничего не происходит
#35 by PR
Думаю, что непонятно, почему не пашет {MULTIPLY}. Странно это.
#36 by 247tsm
Сначала перемещался, а теперь не хочет, но почему - не могу понять
#37 by 247tsm
я попробовал - не работает, т.е. при открытии справочника номенклатура дерево не раскрывается автоматически.
#38 by andrewks
да дело-то не в том, что {MULTIPLY} не работает, а в том, что вообще посланные по WinAPI нажатия клавиш не приходят в 1с вообще (либо, как вариант, не обрабатываются ей)
#39 by PR
Почему? Shell = Новый COMОбъект("WScript.Shell"); Shell.SendKeys("*"); прекрасно работает например.
#40 by andrewks
я про вызовы WinAPI в
#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} и курсор не выходит за рамки дерева. Не понятно, почему?
#47 by andrewks
во изврат...
#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}");    КонецЦикла;
#52 by 247tsm
Но все же хотелось бы сделать красиво с {MULTIPLY}
#53 by 247tsm
... и вместо цикла с коэффициентом.
#54 by 247tsm
... или вместо цикла с коэффициентом
#55 by andrewks
есть на .NET
#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 тоже не взлетит?
#65 by andrewks
а "WScript.Shell" взлетает только потому, что клавиши идут от скриптовой длл-ки?
#66 by Torquader
Насколько я помню, WScript вставляет коды клавиш в буфер клавиатуры, но не ожидает их обработки, то есть код продолжает исполняться. Кроме того, любой объект из 1С исполняется не в её коде (то есть при вызове любого объекта исполнение кода 1С прерывается до окончания вызова). А почему не прошло SendMessage WM_KEYDOWN самому элементу с деревом - у меня всегда проходило - я даже автосоздавалку объектов в конфиругаторе писал через него - 20тыс. справочников она за ночь сделала.
#67 by andrewks
SendMessage - аналогично, не взлетает
#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
"При открытии - у тебя ещё формы нет"  ну как же нет? есть, и это можно увидеть, если поставить задержку, а потом закрыть форму. на экране увидишь родимую форму
#72 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
Вопрос решил - вывел из процедуры в тело модуля формы списка подсчет количества папок и снова заработало.
#78 by SUA
sendkeys(Символ) не поможет?
#79 by smaharbA
сканкоды не предлагали еще ?
#80 by andrewks
если сможешь их заслать в 1сину без использования внешней dll - то предлагай
#81 by smaharbA
debug.exe
Тэги: Математика и алгоритмы
Ответить:
Комментарии доступны только авторизированным пользователям

В этой группе 1С