![]() |
![]() |
|
Как активизировать окно 1с программно | ☑ | ||
---|---|---|---|---|
0
Ardi
14.02.06
✎
22:15
|
например при срабатывании ОбработкаВнешнегоСобытия()
|
|||
1
PaulBC
15.02.06
✎
00:45
|
Set WshShell = CreateObject("WScript.Shell")
Res = WshShell.AppActivate("1С:Предприятие") |
|||
2
smaharbA
15.02.06
✎
06:50
|
(0)(1) Лучче определить ProcessID и AppActivate(ProcessID)
|
|||
3
Ardi
15.02.06
✎
22:15
|
Не получается: Другие приложения активируются, а "1С:Предприятие" и другие куски из его заголовка не берет. Код выдает -1 и 0
Процедура Сформировать() WshShell = CreateObject("WScript.Shell"); Res = WshShell.AppActivate("Конфигуратор"); Сообщить(Res); Для ъ=1 По 300000 Цикл КонецЦикла; WshShell = CreateObject("WScript.Shell"); Res = WshShell.AppActivate("1C:Предприятие"); Сообщить(Res); КонецПроцедуры |
|||
4
smaharbA
15.02.06
✎
22:54
|
-1 это сработало, 0 нет, а меня что непослушал ?
И уж если по заголовку то примерно так WSHShell = СоздатьОбъект("WScript.Shell"); ПолныйЗаголовок="1С: Предприятие - "+СокрЛП(Метаданные.Идентификатор)+": "+ЗаголовокСистемы(); wshShell.appActivate(ПолныйЗаголовок); |
|||
5
smaharbA
15.02.06
✎
22:55
|
И посмотри чем отличаются
"1C:Предприятие... и "1С: Предприятие... |
|||
6
romix
модератор
15.02.06
✎
23:14
|
Внешняя компонента DialMail содержит метод для активизации текущего окна 1С.
Ее работоспособность может зависеть от версии виндов: в новых виндах Microsoft стремится такие возможности ограничить и прикрыть, чтобы левые окна не мешали юзерам работать со своим основным окном (описание темы - в книге Рихтера). |
|||
7
smaharbA
15.02.06
✎
23:16
|
(6) 8 строк и железно активизирует, но... активное еще не значит что фореграунд...
|
|||
8
Ardi
15.02.06
✎
23:22
|
(4) (5) Не помогает.
А как ProcessID определить? |
|||
9
romix
модератор
15.02.06
✎
23:23
|
(7) Я думаю (0) хочет фореграунд, например, когда считался штрихкод. Хотя наверное проще забить на такие предъявы, чем их выполнять (имхо системное ограничение самих виндов). DialMail некими забавными трюками (я смотрел отладчиком) это ограничение обходил, но не факт что это работает во всех виндах.
|
|||
10
Ardi
15.02.06
✎
23:25
|
Как страшно жить на свете.
|
|||
11
smaharbA
15.02.06
✎
23:29
|
(8) Должно помоч, посмотри заголовок и ту строку что создается в (4) совпадают ?
+ WSHShell = СоздатьОбъект("WScript.Shell"); l = СоздатьОбъект("WBemScripting.SWbemLocator"); s = l.connectserver(); oExec = WSHShell.Exec("rundll32 kernel32,SleepEx"); ProcessID=s.get("Win32_process.Handle="+oExec.ProcessID).ParentProcessID; oExec.Terminate(); WSHShell.appactivate(ProcessID); |
|||
12
Ardi
15.02.06
✎
23:57
|
(11) Не хочет. Другие приложения через WSHShell.appactivate(ProcessID) активирует, а само себя не хочет.
Стоит WinXP sp2. |
|||
13
smaharbA
15.02.06
✎
23:59
|
(12) Ну тогда только через внешнее с задержкой... напишу счас и коду немного
Да, а при выполнении в панели мигает ? |
|||
14
smaharbA
16.02.06
✎
00:03
|
Вот счас попробовал...
//******************************************* Процедура Сформировать() WSHShell = СоздатьОбъект("WScript.Shell"); l = СоздатьОбъект("WBemScripting.SWbemLocator"); s = l.connectserver(); oExec = WSHShell.Exec("rundll32 kernel32,SleepEx"); ProcessID=s.get("Win32_process.Handle="+oExec.ProcessID).ParentProcessID; oExec.Terminate(); WSHShell.appactivate(ProcessID); КонецПроцедуры Процедура ПриОткрытии() Форма.ОбработкаОжидания("Сформировать",20); КонецПроцедуры // ПриОткрытии ... Работает... |
|||
15
Ardi
16.02.06
✎
00:04
|
не мигает.
Сообщить(WSHShell.appactivate(220)); открывает TotalCommader Сообщить(WSHShell.appactivate(ProcessID)); выдает 0; |
|||
16
MMF
16.02.06
✎
00:07
|
hWnd := GetForegroundWindow;
if hWnd = Application.Handle then Exit; SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, @OldTimeOut, 0); SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Pointer(000), 0); SetForegroundWindow(Application.Handle); SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Pointer(OldTimeOut), 0); |
|||
17
smaharbA
16.02.06
✎
00:10
|
(16) Ну так и я могу,.... а "мурку" можешь...(с) ;)
|
|||
18
romix
модератор
16.02.06
✎
00:13
|
(16) что-то мне этот хакерский набор вызовов напоминает DialMail (там работало, но в более новых Windows уже не работало).
(13) Возможно, системная блокировка на автоактивацию своего собственного окна распространяется и на дочерние процессы? |
|||
19
romix
модератор
16.02.06
✎
00:17
|
Предлагаю сделать фоново запущенную (из Автозагрузки) прогу, которая опрашивает признак (например, наличие файла) и в зависимости от него активизирует окно. :-)
|
|||
20
smaharbA
16.02.06
✎
00:19
|
(18) Не не влияет, у него выходит так внешнеесобытие еще не отработало, а управление уже попало в 1с, тут нужна задержка и все...Проверить просто перед этим вставить код ВвестиСтроку("","",0,3) к примеру...только не предупреждение, у него тайминг когда окно неактивно стоит...
|
|||
21
smaharbA
16.02.06
✎
00:20
|
(19) Да все просче и со внешним, простое создается скрипт хоть объектом текст туда передают пид и задержку секунды две и все... Но можно и без скрипта обойтись...
|
|||
22
Ardi
16.02.06
✎
00:21
|
(14) Мигает. Но видимым не становится.
У тебя какой виндовс? ОбработкаВнешнегоСобытия() сейчас проверить не могу. |
|||
23
MMF
16.02.06
✎
00:24
|
дети, читаем азбуку :-)
A process can set the foreground window only if one of the following conditions is true: The process is the foreground process. The process was started by the foreground process. The process received the last input event. There is no foreground process. The foreground process is being debugged. The foreground is not locked (see LockSetForegroundWindow). The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo). Windows 2000/XP: No menus are active. With this change, an application cannot force a window to the foreground while the user is working with another window. Instead, Foreground and Background Windows will activate the window (see SetActiveWindow) and call the function to notify the user. However, on Microsoft Windows 98 and Windows Millennium Edition (Windows Me), if a nonforeground thread calls SetForegroundWindow and passes the handle of a window that was not created by the calling thread, the window is not flashed on the taskbar. To have SetForegroundWindow behave the same as it did on Windows 95 and Microsoft Windows NT 4.0, change the foreground lock timeout value when the application is installed. This can be done from the setup or installation application with the following function call: SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)0, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE); This method allows SetForegroundWindow on Windows 98/Windows Me and Windows 2000/Windows XP to behave the same as Windows 95 and Windows NT 4.0, respectively, for all applications. |
|||
24
MMF
16.02.06
✎
00:26
|
(23+) хотите гарантировано стать верхним окном и не мигать на панели - см. 16. Кроме того, возможно, следует подумать об остановке скринсейвера.
|
|||
25
smaharbA
16.02.06
✎
00:30
|
(24) Этт все ясно Михаил, но ведь хотся подручными средствами, конечно смогу, но вот как человеку помоч реально ?
Можно конечно из подручных динврап предложить, или еще какой врап, можно как я люблю вордом обойтись(но этт тяжеловато для такой простой задачи ;)) |
|||
26
MMF
16.02.06
✎
00:34
|
(25) дык пусть напишет малюсенькую внешнюю компоненту из одного метода. Еще когда-нить будет тесно в рамках 1С - добавит еще что-нить.
|
|||
27
smaharbA
16.02.06
✎
00:35
|
(26) А вобщемто верно, может эта малюсенькая ВК и другому народу пользительна станет...
|
|||
28
romix
модератор
16.02.06
✎
00:38
|
Щас напишу... С разрешения Михаила
|
|||
29
MMF
16.02.06
✎
00:40
|
(28) до кучи - остановка скринсейвера
var uiAction, uiParam, fWinIni: integer; pvParam: boolean; begin uiAction:= SPI_GETSCREENSAVEACTIVE; fWinIni:= SPIF_UPDATEINIFILE; SystemParametersInfo(uiAction, uiParam, @pvParam, fWinIni); if pvParam then begin uiAction:= SPI_SETSCREENSAVEACTIVE; pvParam:= false; SystemParametersInfo(uiAction, uiParam, @pvParam, fWinIni); end; |
|||
30
Ardi
16.02.06
✎
00:51
|
(29) Я дико извиняюсь, но что с этим делать?
|
|||
31
MMF
16.02.06
✎
00:55
|
(30) ну вон (28) грозится сделать ВК. А тебе останется только написать ОбъектВК.СкринСейверСдохни() и ОбъектВК.НуКаВверх()... хотя, возможно названия методов не будут столь поэтичными
|
|||
32
romix
модератор
16.02.06
✎
01:08
|
(31) Окно пару раз подмигивает, но не активизируется. Windows 2000, SP4.
////////////////////////////////////////////////// procedure Activate1C(); var OldTimeOut: DWORD; var hWnd: DWORD; begin //Активизирует окно 1С (с) MMF hWnd := GetForegroundWindow; if hWnd = MainWindow then Exit; SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, @OldTimeOut, 0); SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Pointer(000), 0); //SetForegroundWindow(Application.Handle); SetForegroundWindow(MainWindow); SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Pointer(OldTimeOut), 0); end; |
|||
33
romix
модератор
16.02.06
✎
01:12
|
function AddInObject.Init(pConnection: IDispatch): HResult; stdcall;
... iExtWindows:=nil; pConnection.QueryInterface(IID_IExtWndsSupport,iExtWindows); iExtWindows.GetAppMainFrame(MainWindow); |
|||
34
MMF
16.02.06
✎
01:17
|
(33) iExtWindows.GetAppMDIFrame(MainWindow);
|
|||
35
romix
модератор
16.02.06
✎
01:19
|
(34) То же самое. Мигает 2 или 3 раза. Щас перепроверю.
|
|||
36
romix
модератор
16.02.06
✎
01:21
|
(+35) Перепроверил путем втыкания мессаджбокса (он кстати вылазит 2 раза - видимо инит проходит 2 раза.
pConnection.QueryInterface(IID_IExtWndsSupport,iExtWindows); //iExtWindows.GetAppMainFrame(MainWindow); iExtWindows.GetAppMDIFrame(MainWindow); MessageBox(0,'hi','',0); |
|||
37
MMF
16.02.06
✎
01:23
|
(36) дык ясен пень, Init выполняется два раза (у тебя ж компонента экспортирует один объект). procedure Activate1C() как вызывается?
|
|||
38
romix
модератор
16.02.06
✎
01:25
|
Видимо, разработчики виндов тоже прочитали эту азбуку, и решили прикрыть и эту лазейку. :-) Остается поюзать "There is no foreground process". Может, сначала свернуть все окна, подождать секунду, и развернуть окно 1С? :-)
|
|||
39
romix
модератор
16.02.06
✎
01:26
|
methActivate1C: begin
//StopScreennSaver(); Activate1C(); end; |
|||
40
romix
модератор
16.02.06
✎
01:26
|
из
function AddInObject.CallAsFunc(lMethodNum: Integer; var pvarRetValue: OleVariant; var paParams: PSafeArray): HResult; stdcall; |
|||
41
MMF
16.02.06
✎
01:30
|
(40) щас я уже выключил Дельфи, но я приводил код из работающих сырцов. Завтра попробую собрать компоненту, авось получится
|
|||
42
romix
модератор
16.02.06
✎
01:32
|
Может у тебя процесс был "Being debugged", и поэтому все работало?
|
|||
43
smaharbA
16.02.06
✎
01:32
|
Да блин, что вордом сделать ?
|
|||
44
romix
модератор
16.02.06
✎
01:37
|
(43) Пока ничего - имхо это все не работает... Ибо разработчики виндов этот лаз похоже прикрыли в 2000 SP4.
|
|||
45
smaharbA
16.02.06
✎
03:06
|
Ну что вышел каменный цветок, вот тупенький но железный метод...
... Перем ProcessID,WSHShell,Shell; //******************************************* Процедура Сформировать() Shell.UndoMinimizeAll(); WSHShell.appactivate(ProcessID); КонецПроцедуры Процедура ПриОткрытии() Форма.ОбработкаОжидания("Сформировать",5); КонецПроцедуры // ПриОткрытии Shell=СоздатьОбъект("Shell.Application"); WSHShell = СоздатьОбъект("WScript.Shell"); l = СоздатьОбъект("WBemScripting.SWbemLocator"); s = l.connectserver(); oExec = WSHShell.Exec("rundll32 kernel32,SleepEx"); ProcessID=s.get("Win32_process.Handle="+oExec.ProcessID).ParentProcessID; oExec.Terminate(); ... |
|||
46
romix
модератор
16.02.06
✎
11:21
|
(45) Прикольно, но не работает.
Раз в 5 секунд 1С в трее 3 раза подмигивает... Имхо задача не решается... Хотя можно попробовать такой изврат: запустить из ВК маленькую оконную прогу в debug-режиме, и ее окно станет Foreground. А из нее уже активизировать что хочется... |
|||
47
smaharbA
16.02.06
✎
12:11
|
(46) Работает, только задержку надо воткнуть между
Shell.UndoMinimizeAll(); WSHShell.appactivate(ProcessID); |
|||
48
smaharbA
16.02.06
✎
12:11
|
+ (47) У меня послабее будет машина ;)
|
|||
49
romix
модератор
16.02.06
✎
12:16
|
(47) Так что ли:
Shell.UndoMinimizeAll(); для й=1 по 100000 Цикл КонецЦикла; WSHShell.appactivate(ProcessID); У меня опять мигает в таскбаре, но не активизируется. Имхо ограничение виндовс. У меня XP SP2. |
|||
50
smaharbA
16.02.06
✎
12:19
|
(49) Я на 2003 пробовал, можно еще так
Shell.TogleDesktop(); Задержка(); Shell.TogleDesktop(); WSHShell.appactivate(ProcessID); |
|||
51
smaharbA
16.02.06
✎
12:23
|
Можно еще извратнее, но через АПИ, сделать вообще топмост... тогда больше ниодно приложение не покажется ;) гдето у меня такое было...
|
|||
52
swa
16.02.06
✎
12:43
|
Мда, не я один такой...
Одно из решений - сначала "свернуть" окно, потом "развернуть" (RESTORE или MAXIMIZE), а потом уже SetForegroundWindow. Результат - окно "впереди" других. Но тоже в нек. ситуациях не срабатывает. (18) так категорично :) . В каких версиях операционок не работает? Проверял на XP, 2000 prof. |
|||
53
evGenius
16.02.06
✎
12:50
|
Вот есть рабочий кусочек на сях:
Как утверждает документация, SetForegroundWindow работает как нам нужно, только если вызывающий её процесс является активным. А активен тот процесс, чей поток обрабатывает пользовательский ввод. Оказывается, наш процесс может "прикинуться" активным, подключив свой поток к обработке пользовательского ввода. Это осуществляется при помощи функции AttachThreadInput. После вызова SetForegroundWindow можно будет отключиться от чужого потока, используя ту же функцию (но передавая в качестве третьего параметра FALSE, а не TRUE). Реализация этой идеи выглядит так. HWND hCurrWnd; int iMyTID; int iCurrTID; hCurrWnd = ::GetForegroundWindow(); iMyTID = GetCurrentThreadId(); iCurrTID = GetWindowThreadProcessId(hCurrWnd,0); AttachThreadInput(iMyTID, iCurrTID, TRUE); // hWnd - дескриптор окна. SetForegroundWindow(hWnd); AttachThreadInput(iMyTID, iCurrTID, FALSE); |
|||
54
smaharbA
16.02.06
✎
13:05
|
(53) Уже прошли это...
Вот подделал и ввод активизировал, работает ведь... ... Перем ProcessID,WSHShell,Shell; //******************************************* Процедура Сформировать() Shell.UndoMinimizeAll(); ВвестиСтроку("","",1,0,1); WSHShell.appactivate(ProcessID); КонецПроцедуры Процедура ПриОткрытии() Форма.ОбработкаОжидания("Сформировать",5); КонецПроцедуры // ПриОткрытии Shell=СоздатьОбъект("Shell.Application"); WSHShell = СоздатьОбъект("WScript.Shell"); l = СоздатьОбъект("WBemScripting.SWbemLocator"); s = l.connectserver(); oExec = WSHShell.Exec("rundll32 kernel32,SleepEx"); ProcessID=s.get("Win32_process.Handle="+oExec.ProcessID).ParentProcessID; oExec.Terminate(); ... |
|||
55
evGenius
16.02.06
✎
13:39
|
(54) Где прошли?
|
|||
56
swa
16.02.06
✎
20:53
|
(53) Замечательный способ! А почему (с) не проставлены?
http://www.rsdn.ru/article/qna/ui/wndsetfg.xml |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |