|
Как программно послать символ "*" с правой доп. клавиатуры в буфер обмена? | ☑ | ||
---|---|---|---|---|
0
247tsm
18.04.12
✎
20:07
|
Добрый день,
У меня такой вопрос. Как программно послать символ "*" с правой дополнительной клавиатуры в буфер обмена? С помощью WHS или по-другому. Вообще была поставлена задача: в 1с7.7 при открытии справочника Номенклатура должно полностью раскрываться дерево групп. Вручную это делается так: становимся мышкой на самый верхний элемент дерева групп и нажимаем на "*" (но только с дополнительной правой клавиатуры). Я так понимаю, что в этом случае в буфер обмена попадает не символ "*" с кодом 42, а что-то другое. В разделе для 1с7.7, к сожалению, мне не смогли помочь. Вот попытаю счастье здесь. Спасибо. |
|||
1
Один С
18.04.12
✎
20:12
|
РежимСправочника.Иерархический или както так, разве нет в семерке?
|
|||
2
andrewks
18.04.12
✎
20:13
|
SendKey()
|
|||
3
247tsm
18.04.12
✎
20:16
|
(1) есть, но нет почти никаких команд. А я не могу именно программно иммитировать нажатие "*" с правой дополнительной клавиатуры.
|
|||
4
palpetrovich
18.04.12
✎
20:16
|
мда уж, горе от ума :)
|
|||
5
palpetrovich
18.04.12
✎
20:17
|
(3) забудь о иммитировать нажатие "*" , сконцентрируйся на (1)
|
|||
6
Скользящий
18.04.12
✎
20:20
|
блин, зачем тебе имитировать "*"?? В СП посмотри ИерархическийСписок()
|
|||
7
247tsm
18.04.12
✎
20:21
|
(2) использовал SendKey(). Но что посылать?
Вот программный код: addon=CreateObject("addon1c.commands"); addon.SendKeys("+{TAB}"); addon.SendKeys("*"); Командой addon.SendKeys("+{TAB}") я иммитирую активацию (переход на дерево групп). А командой addon.SendKeys("*") пытаюсь раскрыть это дерево. Но не срабатывает, потому что символ "*" с левой клавиатуры и с правой дополнительной клавиатуры, очевидно, разные, но когда программно вывожу коды этих символов - они одинаковые 42. Значит еще какой-то код присутствует. |
|||
8
247tsm
18.04.12
✎
20:22
|
(5) и (6), Вы поймите, что я знаю про команду ИерархическийСписок(1,1), ну и что? Она не решает мою задачу
|
|||
9
kotletka
18.04.12
✎
20:24
|
тогда опиши чем именно тебя не устраивает (1) и в чем плюс твоего метода, из (0) плюсов не видно
|
|||
10
247tsm
18.04.12
✎
20:25
|
Я предполагаю, что на низком уровне 1С различает символ "*" с левой и правой клавиатуры. Но чем они отличаются в деталях я не знаю, поэтому и решил спросить у знатоков.
|
|||
11
andrewks
18.04.12
✎
20:26
|
(7) 0x6A
|
|||
12
Один С
18.04.12
✎
20:28
|
(10) конечно она их различает, потомучто у них разные коды символа..
|
|||
13
247tsm
18.04.12
✎
20:28
|
(9) в том то и дело, что в 1С нет возможности программно открыть все уровни дерева групп. Только интерактивно "руками". А я хочу программно. Поэтому и спрашиваю, как?
|
|||
14
andrewks
18.04.12
✎
20:29
|
(12) коды символа одинаковые. а вот коды клавиш разные
(10) и различает их не 1С, а ось |
|||
15
PR
18.04.12
✎
20:29
|
(7) NUM, а не TAB
|
|||
16
247tsm
18.04.12
✎
20:37
|
(11) а как 0х6А записать с помощью SendKeys()?
|
|||
17
247tsm
18.04.12
✎
20:39
|
(15) "+{TAB}" = SHIFT-TAB это для установки курсора на дерево групп.
|
|||
18
vis_tmp
18.04.12
✎
20:40
|
(16)6*16+10 ?
|
|||
19
247tsm
18.04.12
✎
20:56
|
(14) А как с помощью SendKeys() послать код клавиши "*" с правой клавиатуры? Или по-другому. Как отловить и увидеть, что делается после нажатия "*" на правой клавиатуре? И как то же самое послать в буфер с помощью SendKeys() или как-нибудь по-другому?
|
|||
20
247tsm
18.04.12
✎
20:58
|
(19)+ т.е., как запустить тот же механизм 1С, что и при нажатии на "*" на правой клавиатуре?
|
|||
21
247tsm
18.04.12
✎
21:00
|
(18) пробую, но пока никак.
|
|||
22
PR
18.04.12
✎
21:32
|
||||
23
247tsm
19.04.12
✎
00:06
|
(22) посмотрел, но не понял, как можно использовать.
|
|||
24
247tsm
19.04.12
✎
01:29
|
А вообще, дерево групп имеет какое-нибудь системное имя, как элемент формы, чтобы к нему программно обратиться и сделать его активным, т.е., как будто установили на него курсор мышки?
|
|||
25
andrewks
19.04.12
✎
08:03
|
(24) нет
|
|||
26
andrewks
19.04.12
✎
08:17
|
(24) а у тебя вообще курсор на дерево перемещается после твоих манипуляций?
|
|||
27
PR
19.04.12
✎
11:01
|
(23) Там собсно и написано, что никак.
В http://sargaev.ru/?p=608 написано, что {MULTIPLY}, но что-то не пашет. |
|||
28
PR
19.04.12
✎
11:02
|
(26) Не в этом дело. Я в восьмерке пробовал, тоже не пашет.
|
|||
29
palpetrovich
19.04.12
✎
11:02
|
(13) хз, почему у тебя "1С нет возможности программно открыть все уровни дерева групп"
спецом попробовал, все работает Процедура ПриОткрытии() // в форме списка ИерархическийСписок(0); КонецПроцедуры |
|||
30
andrewks
19.04.12
✎
11:03
|
(28) а ты как пробовал? через DynamicWrapper, или VBS?
|
|||
31
PR
19.04.12
✎
11:04
|
(30) Shell = Новый COMОбъект("WScript.Shell");
Shell.SendKeys("{MULTIPLY}"); |
|||
32
andrewks
19.04.12
✎
11:06
|
(31) я так понял, основной косяк с получателем события.
вчера баловался через DynamicWrapper - нажатия клавиш проходят, но 1С-ка их не получает. например, NumLock зажигается, т.е. какой-то глобальный контекст их обрабатывает, а в 1с-ку не приходит |
|||
33
andrewks
19.04.12
✎
12:36
|
(31) что думаешь по этому поводу?
|
|||
34
andrewks
19.04.12
✎
12:38
|
причём пробовал и через PostMessage, и keybd_event, и с EnableWindow/SetFocus, и без, однохерственно
нажатия проходят, глобальный контекст изменяется, а в 1с ничего не происходит |
|||
35
PR
19.04.12
✎
12:58
|
(33) Думаю, что непонятно, почему не пашет {MULTIPLY}. Странно это.
|
|||
36
247tsm
19.04.12
✎
13:14
|
(24) Сначала перемещался, а теперь не хочет, но почему - не могу понять
|
|||
37
247tsm
19.04.12
✎
13:28
|
(29) я попробовал - не работает, т.е. при открытии справочника номенклатура дерево не раскрывается автоматически.
|
|||
38
andrewks
19.04.12
✎
13:29
|
(35) да дело-то не в том, что {MULTIPLY} не работает, а в том, что вообще посланные по WinAPI нажатия клавиш не приходят в 1с вообще (либо, как вариант, не обрабатываются ей)
|
|||
39
PR
19.04.12
✎
13:31
|
(38) Почему?
Shell = Новый COMОбъект("WScript.Shell"); Shell.SendKeys("*"); прекрасно работает например. |
|||
40
andrewks
19.04.12
✎
13:33
|
(39) я про вызовы WinAPI в (34)
|
|||
41
247tsm
19.04.12
✎
13:45
|
(31) Небольшое замечание. Нужно не просто послать {MULTIPLY}, а сначала спозиционироваться на дереве, а затем послать {MULTIPLY}. Но у меня так:
Процедура ПриОткрытии() Shell = CreateObject("WScript.Shell"); Shell.SendKeys("{MULTIPLY}"); КонецПроцедуры и на второй строке останавливается: Shell.SendKeys("{MULTIPLY}"); {Справочник.Номенклатура.ФормаСписка.ФормаСписка.Модуль(171)}: : т.е. не принимает название клавиши. Но сначала все же нужно спозиционироваться на дереве. |
|||
42
247tsm
19.04.12
✎
13:55
|
(26) Сначала перемещался, а теперь не хочет, но почему - не могу понять. Я делал так.
Ws = CreateObject("WScript.Shell"); Ws.SendKeys ("+{TAB}"); Ws.SendKeys ("+{TAB}"); и так addon=CreateObject("addon1c.commands"); addon.SendKeys("+{TAB}"); addon.SendKeys("+{TAB}"); То, что перемещался - это 100%. Затем начал экспериментировать и в какой-то момент перестал перемещаться. Я попробовал перерегистрировать addon1c.dll, но не помогло. |
|||
43
247tsm
19.04.12
✎
13:58
|
(42)+ я два раза посылаю SendKeys("+{TAB}"), потому что на форме списка есть еще элементы. Количество SendKeys("+{TAB}") я определил экспериментально - проделал сначала вручную эти операции, а затем попробовал программно - т.е. как макрос в Excel.
|
|||
44
247tsm
19.04.12
✎
14:09
|
Прошу прощения, просчитался. Следующий код работает 100% - позиционирует на дереве:
Shell = CreateObject("WScript.Shell"); Shell.SendKeys ("+{TAB}"); Shell.SendKeys ("+{TAB}"); Shell.SendKeys ("+{TAB}"); Shell.SendKeys ("+{TAB}"); Нужно аккуратно посчитать, сколько раз послать SendKeys("+{TAB}"). Теперь осталось решить с {MULTIPLY}. |
|||
45
andrewks
19.04.12
✎
14:20
|
(44) в том-то и дело, что с "WScript.Shell" ты с MULTIPLY не решишь, ибо его там просто нет. я попытался сделать через WinAPI, но там вообще всё глухо, как в танке
|
|||
46
247tsm
19.04.12
✎
14:27
|
В принципе, одно решение, кажется, нашел:
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
andrewks
19.04.12
✎
14:29
|
(46) во изврат...
|
|||
48
247tsm
19.04.12
✎
14:29
|
Срабатывает и так:
. . . Для нн = 1 по 10 Цикл Shell.SendKeys("{RIGHT}{DOWN}"); КонецЦикла; |
|||
49
247tsm
19.04.12
✎
14:31
|
Вот только не удается указать коэффициент:
для одной клавиши понятно {RIGHT 10}, а как указать для группы клавишей? |
|||
50
247tsm
19.04.12
✎
14:37
|
(47) да, немного поизвращался - но что делать, если в 1С такое дерево.
Есть другой вариант - воспользоваться FormEx - там есть "дерево+таблица", но уверяю, что кода там будет в 3 раза больше, а мне всего-то нужно раскрыть дерево и все. |
|||
51
247tsm
19.04.12
✎
14:40
|
Работает и такой вариант:
addon=CreateObject("addon1c.commands"); addon.SendKeys("+{TAB}"); addon.SendKeys("+{TAB}"); addon.SendKeys("+{TAB}"); addon.SendKeys("+{TAB}"); Для нн = 1 по 10 Цикл addon.SendKeys("{RIGHT}{DOWN}"); КонецЦикла; |
|||
52
247tsm
19.04.12
✎
14:40
|
Но все же хотелось бы сделать красиво с {MULTIPLY}
|
|||
53
247tsm
19.04.12
✎
14:41
|
... и вместо цикла с коэффициентом.
|
|||
54
247tsm
19.04.12
✎
14:42
|
(53) ... или вместо цикла с коэффициентом
|
|||
55
andrewks
19.04.12
✎
14:43
|
||||
56
247tsm
19.04.12
✎
14:44
|
Пока самый короткий вариант:
addon=CreateObject("addon1c.commands"); addon.SendKeys("+{TAB 4}"); Для нн = 1 по 10 Цикл addon.SendKeys("{RIGHT}{DOWN}"); КонецЦикла; |
|||
57
247tsm
19.04.12
✎
14:56
|
Интересно, какой вариант лучше: WScript.Shell или addon1c.commands? (без тормозов ... или может есть подводные камни)
|
|||
58
catena
19.04.12
✎
19:20
|
"addon.SendKeys("+{TAB}"); "
Кто-нибудь изменит порядок обхода на форме и полетит весь твой код за синей птицей... |
|||
59
Torquader
19.04.12
✎
19:54
|
Ну, там же стандартное дерево - пишем dll, которая по идентификатору окна находит это "дерево" и шлёт ему команду развернуть.
Сообщение TVM_EXPAND - но его нужно слать для каждого элемента. Если DLL в адресном просотранстве 1С (ActiveX from DLL), то спокойно можно получать элементы и делать с ними всё, что душа пожелает. Только желательно помнить, что "умные" элементы управления шлют нотификацию своему окну, которую 1С будет обрабатывать - то есть нужно будет слать сообщения из отдельного потока, чтобы не мешать 1С их обрабатывать. |
|||
60
PR
19.04.12
✎
20:09
|
Скажите мне кто-нить pls, почему все-таки не пашет {MULTIPLY}?
Это же вроде как вполне себе официальный параметр SendKeys? |
|||
61
Torquader
19.04.12
✎
20:14
|
(60) Я когда смотрел SendKeys выяснил, что оно неправильно использует символы клавиатуры, то есть * транслируется именно в клавишу * вне зависимости, от того, что ты хочешь.
kbd_event спасёт, наверное. http://www.nncron.ru/help/RU/add_info/keys_mnemonics.htm |
|||
62
andrewks
19.04.12
✎
21:17
|
(60) в описании SendKeys есть закрытый перечень виртуальных кодов, и MULTIPLY среди них нет. зато есть в .NET'овском варианте
(61) kbd_event не взлетает, см (34) |
|||
63
Torquader
19.04.12
✎
21:34
|
(62) kbd_event - это запись события в буфер клавиатуры ещё до распределения сообщения - если оно не взлетает, то не взлетит вообще ничего, так как сообщение не доходит до получателя.
P.S. а слать нужно через SendMessage, так как PostMessage обрабатывается при исполнении кода как ожидание Esc для его прерывания (в момент перехода с одной строки на другую), кстати, ваши SendKeys тож идут к тому же самому коту под хвост. Посылать сообщения нужно не из потока 1С, а от кого-то другого. |
|||
64
andrewks
19.04.12
✎
21:37
|
(63) "Посылать сообщения нужно не из потока 1С, а от кого-то другого." т.е. PostMessage тоже не взлетит?
|
|||
65
andrewks
19.04.12
✎
21:38
|
а "WScript.Shell" взлетает только потому, что клавиши идут от скриптовой длл-ки?
|
|||
66
Torquader
19.04.12
✎
21:43
|
(65) Насколько я помню, WScript вставляет коды клавиш в буфер клавиатуры, но не ожидает их обработки, то есть код продолжает исполняться.
Кроме того, любой объект из 1С исполняется не в её коде (то есть при вызове любого объекта исполнение кода 1С прерывается до окончания вызова). А почему не прошло SendMessage WM_KEYDOWN самому элементу с деревом - у меня всегда проходило - я даже автосоздавалку объектов в конфиругаторе писал через него - 20тыс. справочников она за ночь сделала. |
|||
67
andrewks
19.04.12
✎
21:45
|
SendMessage - аналогично, не взлетает
|
|||
68
andrewks
19.04.12
✎
21:48
|
делаю так:
в форме списка справочника в ПриОткрытии() 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
Torquader
19.04.12
✎
21:50
|
(67) Ну, тогда нужно взять и сделать Trace сообщений и посмотреть, что происходит.
Может быть, на некоторые сообщения просто акселераторы стоят, которые в потоке основого окна по Hook-процедуре ловятся - CommonControls, например, всплывающие подсказки именно так и ловит - тут уже нужно Hook найти и "скормить" ему то, что он хочет. |
|||
70
Torquader
19.04.12
✎
21:51
|
(68) Какого "ПриОткрытии" - в лес!
При открытии - у тебя ещё формы нет - она будет только тогда, когда откроется. Иди читай про ложное закрытие и не мучайся. |
|||
71
andrewks
19.04.12
✎
21:52
|
(70) "При открытии - у тебя ещё формы нет" ну как же нет? есть, и это можно увидеть, если поставить задержку, а потом закрыть форму. на экране увидишь родимую форму
|
|||
72
andrewks
19.04.12
✎
21:53
|
кстати, из других мест тоже пробовал, аналогично, так что дело не в этом
|
|||
73
Torquader
19.04.12
✎
21:56
|
Тогда пробуй просто получить список окон через GetWindow - и послать сообщение твоему несчастному окну через PostMessage или SendMessage, например.
|
|||
74
andrewks
19.04.12
✎
21:58
|
(73) т.е., возможно, сообщение уходит главному окну, вместо окна списка справочника? была такая мысль, надо попробовать
|
|||
75
Torquader
19.04.12
✎
22:00
|
(74) Сообщение клавиатуры посылается тому, у кого выполнен SetFocus, но на время выполнения кода активность формы выключается, чтобы пользователь не нажал чего лишнего.
P.S. через обработку ожидания можно послать - она, если в глобальнике, то в другом потоке выполняется. |
|||
76
247tsm
20.04.12
✎
00:00
|
Извините, что прерываю, но снова непонятка.
Если я вставляю какой-то программный код перед этими действиями по разворачиванию дерева, то дерево не раскрывается. Этот код не работает: // Определяем кол-во папок Спр=СоздатьОбъект("Справочник.Номенклатура"); Спр.ВыбратьЭлементы(); КолПапок = 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
247tsm
20.04.12
✎
00:09
|
Вопрос решил - вывел из процедуры в тело модуля формы списка подсчет количества папок и снова заработало.
|
|||
78
SUA
20.04.12
✎
19:02
|
sendkeys(Символ(106)) не поможет?
|
|||
79
smaharbA
20.04.12
✎
19:05
|
сканкоды не предлагали еще ?
|
|||
80
andrewks
20.04.12
✎
19:16
|
(79) если сможешь их заслать в 1сину без использования внешней dll - то предлагай
|
|||
81
smaharbA
20.04.12
✎
19:49
|
(80) debug.exe
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |