Как получить список открытых окон 1С

Как получить список открытых окон 1С

В 1С есть возможность перебрать все открытые окна и проанализировать их содержимое. Рассмотрим работу с открытыми окнами на примере.

Предположим, что стоит задача при нажатии на кнопку анализировать открыта ли обработка «Моя обработка». Если обработка открыта и в ней не заполнен реквизит «Контрагент», то необходимо активизировать ее форму, в остальных случаях следует создать и открыть новую форму обработки. Данную задачу нельзя решить при помощи параметров метода ОткрытьФорму () .

Ниже представлен код для решения поставленной задачи:

Список открытых окон получается при помощи функции ПолучитьОкна () . Далее происходит обход открытых окон и анализ заголовков. Текст заголовков анализируется не по точному соответствию, а по вхождению необходимых слов, т.к. при изменении реквизитов в форме к заголовку может добавиться признак модифицированности — постфикс » *».

При нахождении нужного заголовка происходит получение управляемой формы и анализ реквизита «Контрагент». Если контрагент пустой, то текущее окно активизируется методом Активизировать () и выполнение процедуры прекращается.

Если нет открытых окон с требуемым заголовком и пустым реквизитом «Контрагент», происходит открытие нового окна при помощи метода ОткрытьФорму () . Четвертым параметром в метод передается уникальный идентификатор; это необходимо для того, чтобы в любом случае было открыто новое окно.

Остались вопросы?
Спросите в комментариях к статье.

2 комментария

Здравствуйте, при написании этого кода:
Процедура СохранитьДанныеКлиенскогоПриложения()
Окна = ПолучитьОкна();
Для каждого Окно Из Окна Цикл
Формы = Окно.Содержимое;
Для каждого Форма из Формы Цикл
Если Форма.Модифицировать Тогда
Файл = Новый ЗаписьXML
ФАйл.ОткрытьФайл0(«D:/Working»+Форма,ИмяФормы».xml»);
СериализаторXDTO.ЗаписатьXML(Файл,Форма.Объект);
Файл.Закрыть();
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры

После уго запуска высвечивает ошибку:
Поле объекта не обнаружено (Содержимое)

Добрый день!
Возможно, Вы пробуете выполнить код в режиме обычного приложения. В этом случае метод ПолучитьОкна() возвращает значение Неопределено. Данный метод работает только в режиме управляемого приложения. К тому же, «Окно» — это зарезервированная переменная в режиме управляемого приложения, необходимо использовать другую переменную.

Источник



Найти окно стороннего приложения по заголовку

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Записать строку в окно стороннего приложения
Здравствуйте, столкнулся с подобной задачей. Необходимо найти программу, чтоб сделать её активной.

Как сделать окно стороннего приложения активным?
Как сделать окно стороннего приложения активным. Например окно Game называется. Здесь на форуме.

Как сделать окно стороннего приложения поверх всех окон?
Имеется Handle стороннего приложения. Пытался использовать SetWindowPos(handle, 0, 0, 0, 0, 0.

Найти окно стороннего приложения зная его id и нажать 1 кнопку, но без использования user32.dll
Доброго времени суток, форумчане. Возникла следующая трудность. Есть консольное приложение.

Записывайтесь на профессиональные IT-курсы здесь

Лучший ответСообщение было отмечено Злобный Зайц как решение

Решение

По правде сказать, тут уже буквально ничего не понял. Это уже слишком глубоко для меня.
Ваш пример, кстати, помог, не пришлось вводить глобальную переменную для передачи через неё результата. Правда, выглядит для меня очень запутанно и не очень понятно. Что это за запись такая, я пока не понимаю (надеюсь, что когда-нибудь и это освою). Пока просто беру отовсюду то, что работает и применяю в своих корыстных целях. Если понятно — хорошо, если нет — делаю некоторые посильные попытки вкурить, а, если сильно плющит мозг, то оставляю понимание на будущее.

ЗЫ: Слово PInvoke, кстати пока непонятно. Щас погуглю.

Обучайтесь IT-профессиям с гарантией трудоустройства здесь.

Поместить окно стороннего приложения на форму
WPF проект. VS 2008. С# Требуется программно (по нажатию кнопки) запустить внешнее приложение.

Вывод текста в окно стороннего приложения
Подскажите есть игра и в ней нужно по координатам вывести текст или что нибудь нарисовать. Какими.

Клик в свернутое окно стороннего приложения
Вообщем, мне нужно сделать клик в форму которая свернутая. Например Skype. Он у меня свернутый а.

Как проверить открыто ли окно стороннего приложения?
Я не знаю как написать программу, которая бы проверяла (т.е. if окно в фокусе then), помогите, мне.

Отправка нажатий клавиш в окно стороннего приложения
Есть код на C++, в нём реализован поиск нужного окна по известному классу, эмуляция нажатий клавиш.

Как программно эмулировать Drag&drop файла на окно стороннего приложения
ну собственно вопрос в названии к окну никакого отношения не имею и оно не на net, просто найдено.

Изучайте английский язык в крупнейшей европейской школе Skyeng

Источник

Найти окно заголовок элемент

В прошлом параграфе мы добрались до окна нашего проекта — формы, просто использовав свойство .hWnd, которое выложило нам на тарелечке хендл окна. Но что делать, если нам надо добраться до чужого окна? Давайте продолжим исследование окон.

Читайте также:  Учредители ООО ДЗЕРЖИНСКИЙ ЗАВОД ОКОН

А сейчас по пытаемся найти окно и сбить, т.е. я хотел сказать, произведем с ним какие-то действия. Для этого сделаем себе учебную цель. Создадим новый exe-проект, изменим свойство формы Form1.Caption=»F-16 Fighter» и откомпилируем (то бишь создадим исполняемый файл exe). Запустим наш проект и пусть полученное окно болтается на Десктопе до поры.

Теперь создадим новый exe-проект. Для наших экспериментов нам потребуются четыре кнопки Command, один CheckBox, один таймер Timer1 и пять текстбоксов, причем для Text1 желательно включить свойства Multiline=True и ScrollBars=2 (Вертикаль).

В форме объявим две переменные, которые будут у нас использоваться для: HandleWin — хранения хендла (чего делать нельзя, я имею ввиду хранить нельзя, это мы отметим ниже особо) и KillWin — куда будут возвращать свои значения функции (хотел ее назвать KillBill, потом KillGates, но перепутал и стало лень менять. Но тоже по существу).

Option Explicit
Dim HandleWin As Long
Dim KillWin As Long

Примечание: При работе с API использование Option Explicit уже не просто рекомендовано, а крайне необходимо и сугубо обязательно! Во всех модулях и формах.
Далее, в процедуре загрузки формы очистим текстбоксы, в для Text2 присвоим значение нашего учебного окна «F-16 Fighter». Кроме того установим интервал таймера и выключим его (он пока не нужен).
Еще примечание: Да, ты уж извини, но я не буду писать свойство .Text для текстбоксов. Пора уже отвыкать есть руками, раз уж полезли в API. Свойста, являющиеся главными для объектов понимаются по умолчанию и их явно писать не обязательно(.Text для текстбоксов, .Capture для лейблов и т. д.)

Private Sub Form_Load()
Text1 = «»
Text2 = «F-16 Fighter»
Text3 = «»
Text4 = «»
Text5 = «»
Timer1.Interval = 100
Timer1 = False
End Sub

Попробуем получить хендл окна по его (окна естественно) заголовку. Заголовок — это все то, что выводится в синенькой верхней полосочке почти в каждом окне. Для нашего окна-мишени это — Form1.Caption = «F-16 Fighter». Используем функцию FindWindow. Давай добавим в проект стандартный модуль и объявим ее (все что пишется в модуле я буду выделять коричневым цветом):

Public Declare Function FindWindow Lib «user32» Alias «FindWindowA» (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Как мы видим, в этой функции есть два аргумента, по которым можно найти окно: по имени класса ( lpClassName ) и по имени заголовка ( lpWindowName ). Как правило окно ищется по одному какому-нибудь аргументу. Поскольку мы не знаем имя класса искомого окна (да и вообще не знаем, что это такое), а знаем заголовок, то его и надо подставить в функцию вместо. Но и второе значение ( lpClassName ) нельзя пускать на самотек. Ему надо передать ноль (в API всегда надо чего-то передавать). Но аргумент этот имеет строковый тип, поэтому нужно использовать константу vbNullString. Так как заголовок окна мы храним в Text2, то использование функции будет выглядеть очень просто:
HandleWin = FindWindow(vbNullString, Text2)
В переменную HandleWin мы получим искомый хендл искомого окна. Напишем теперь процедуру:

Private Sub Command1_Click()
HandleWin = FindWindow(vbNullString, Text2)
Text1 = Text1 & «Хендл окна с именем » & Text2 & » » & HandleWin & vbCrLf
Text3 = HandleWin
End Sub

Нажимая на кнопку Command1, мы получаем хендл того окна, чей заголовок прописан в Text2. При этом в Text1 будет выводится общая информация о найденом окне.
Теперь попробуем произвести кое-какие манипуляции с окном по его хендлу: уничтожить, свернуть и развернуть. Для этого используются следующие функции
DestroyWindow — убивает окно. В Windows XP эта функция не работает. Она в общем-то и в Win98 тоже не хочет убивать окно. Ну я решил, что и черт с ней. Но пусть остается для примера.
CloseWindow — сворачивает окно
OpenIcon — восстанавливает свернутое окно
Их объявление совершенно идентично и смысл их использования сводится лишь к подстановке вместо аргумента переменной, содержащей хендл. Объявим их в модуле:

Public Declare Function DestroyWindow& Lib «user32» (ByVal hwnd As Long)
Public Declare Function CloseWindow Lib «user32» (ByVal hwnd As Long) As Long
Public Declare Function OpenIcon Lib «user32» (ByVal hwnd As Long) As Long

Обрати внимание, что первая функия объявлена с применением значка типа & вместо As Long в конце. Такое объявление ничем не отличается по смыслу и работе от двух других. Теперь пропишем каждую в свои процедуры соответствующих кнопок Command2, Command3 и Command4. Кроме того, мы еще и проанализируем результат действия каждой функции по возвращаемому значению (если ноль, то действие не удалось) и выведем соответствующее сообщения в Text1:

Читайте также:  Организация ООО КОРПОРАЦИЯ ОКНА 21 ВЕКА

Private Sub Command2_Click()
KillWin = DestroyWindow&(HandleWin)
If KillWin = 0 Then
Text1 = Text1 & » Убийство окна » & HandleWin & » не удалось!» & vbCrLf
Else
Text1 = Text1 & » Мы убили окно » & HandleWin & vbCrLf
End If
End Sub

Private Sub Command3_Click()
KillWin = CloseWindow(HandleWin)
If KillWin = 0 Then
Text1 = Text1 & » Свернуть окно » & HandleWin & » не удалось!» & vbCrLf
Else
Text1 = Text1 & » Мы свернули окно » & HandleWin & vbCrLf
End If
End Sub

Private Su b Command4_Click()
KillWin = OpenIcon(HandleWin)
If KillWin = 0 Then
Text1 = Text1 & » Восстановить окно » & HandleWin & » не удалось!» & vbCrLf
Else
Text1 = Text1 & » Мы восстановили окно » & HandleWin & vbCrLf
End If
End Sub

Теперь я еще раз объясню, почему так делать нельзя. В процедуре Command1 мы нашли и сохранили в переменной HandleWin хендл окна. А используем его совершенно в другой процедуре по другому событию Command_Click. Между двумя нажатиями пользователем на кнопки может произойти черт знает что. Если ты определишь хендл , а затем закроешь и снова откроешь программку «F-16 Fighter», то ее окно будет иметь уже совершенно иной хендл и сделать с ним ничего будет нельзя, до тех пор, пока не определишь его новый хендл. Поэтому действия с окнами должны производится сразу же после определения хендла. Но я нарочно так сделал, чтобы для простоты разделить функции по процедурам и иметь показательный отрицательный пример под рукой.

Далее мы сделаем так, чтобы указав на окно курсором мыши мы могли посмотреть (не получить для использования, а именно посмотреть), какой у окна хендл и какой у него заголовок. Реализуется это с помощью функции WindowFromPoint, которая возвращает хендл окна по точке на этом окне. Точкой этой будут координаты курсора мыши. Получить их можно с помощью функции GetCursorPos. Вот с нее и начнем. Точнее начнем с процедуры, которая будет включать весь этот наш механизм. И процедура эта будет для Check1. Он лучше кнопки, так как имеет два положения включено и выключено. Именно здесь мы будем включать и выключать таймер. Зачем он нам нужен? А нужен он для того, чтобы не пытаться найти событие, которое происходит при наведении мыши на окно. Так как в нашем проекте его и не происходит. А таймер исправно , через каждые 100 миллисекунд будет нам включать наш механизм определения хендла окна, на котором находится курсор мыши.
Итак начнем. Короткая процедура для включения-выключения таймера:

Private Sub Check1_Click()
If Check1 = 0 Then Timer1 = False
If Check1 = 1 Then Timer1 = True
End Sub

И теперь самое интересное — процедура самого таймера.
Private Sub Timer1_Timer()
‘объявим тройку нужных нам переменных
Dim PosCur As Long
Dim DlinaTexta As Long
Dim WindowCaption As String

В модуле объявим функцию для определения координат мыши:

Public Declare Function GetCursorPos Lib «user32» (lpPoint As POINTAPI) As Long

И опааа, видим всего один аргумент, в то время координат должно быть две. А дело в том, что lpPoint представляет структуру POINTAPI, которая содержит как раз эти две координаты. Структура — это по-сути тот же пользовательский тип данных, который мы разбирали в Главе 17 первой части самоучителя, только задан жестко и никаких здесь вольностей быть не должно. Поэтому в модуле объявляем тип POINTAPI так как это требуется для API-функций:
Type POINTAPI
X As Long
Y As Long
End Type

и затем объявляем какую-нибудь переменную с типом POINTAPI, например MouseCoordinat:
Public MouseCoordinat As POINTAPI
Вот теперь, возвращаемся к нашей процедуре таймера в форме и получаем, наконец, координаты мыши:

PosCur = GetCursorPos(MouseCoordinat)
‘записываем координаты в текстбоксы для большей наглядности
Text4 = MouseCoordinat.X
Text5 = MouseCoordinat.Y

Теперь нам надо по этим координатам получить хендл окна. Объявим в модуле функцию:

Public Declare Function WindowFromPoint Lib «user32» (ByVal xPoint As Long, ByVal yPoint As Long) As Long

Ну здесь все просто, как апельсин. Два аргумента — две координаты, что еще нужно джигиту, чтобы встретить старость. Пишем в нашей процедуре:

Читайте также:  Соединитель для пластиковых окон между собой

HandleWin = WindowFromPoint(MouseCoordinat.X, MouseCoordinat.Y)
Text3 = HandleWin

Теперь у нас в переменной HandleWin есть хендл и еще по нему мы можем узнать заголовок экрана с помощью функции GetWindowText. Объявим ее в модуле:

Public Declare Function GetWindowText Lib «user32» Alias «GetWindowTextA» (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long

Ну с первым аргументом ( hwnd ) — хендлом понятно, мы его имеем. Второй аргумент ( lpString ), это как раз то, что мы хотим получить, т.е. заголовок , а третий ( cch )- длина этого самого заголовка. Поскольку мы этой длины не знаем, то ставим по-максимуму -255 (вряд ли заголовок будет более 256 символов). А вот что касается второго аргумента, тут дело несколько сложнее. Если мы подставим просто нашу переменную WindowCaption, которую мы и объявили для заголовка окна
DlinaTexta = GetWindowText(HandleWin, WindowCaption, 255)
то это результатов не даст. Дело в том, что строковые аргументы API-функций требуют, чтобы для них был в памяти зарезервирован буфер размером не меньше строки, которую мы хотим получить. А для этого надо передать в функцию строку пробелов, соответствующую размеру буфера. Короче, смысл в том , что мы присваиваем переменной строку пробелов, а вместо нее получаем строку данных. И если строка пробелов длинее , например «____________», чем строка данных «123», то мы получим «123_____________», т.е. данные плюс лишние пробелы, а если строка пробелов короче, то данные усекутся по длине строки пробелов. Исходя из этих мудреных рассуждений возвращаемся опять к нашей процедуре и резервируем буфер (на самом деле просто присваиваем переменной WindowCaption строку пробелов по-длинее

WindowCaption = Space(256)

и теперь используем функцию по-правильному

DlinaTexta = GetWindowText(HandleWin, WindowCaption, 255)

Теперь, раз у нас есть длина заголовка (это как раз то, что возвратила функция), мы можем отсечь ненужные нам пробелы и вывести даныые в текстбокс

Text2 = Left(WindowCaption, DlinaTexta)
End Sub

На этом пока все. В это параграфе мы разобрали технику использования API. Теперь ты можещь, двигая мышью узнавать хендл любых окон и их заголовки (если есть). Причем на собственной форме ты увидишь содержимое текстов, названия кнопок и т.п. Исходник примера можно скачать вверху страницы.

Источник

УФ, новый объект, обработка заполнения не выполняется

УФ, обработка заполнения справочника конфигурации Документооборот ПРОФ ВходящиеДокументы. Почему то заполняются реквизиты объекта только лишь после того, как записать новый объект, закрыть и открыть снова.
Если создать новый объект, его записать и сразу выполнить обработку заполнения, то ничего не заполняется. Где-то туплю с Окнами, но где?

Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначенияМассив) Экспорт
//Спросим у пользователя разрешение на продолжение обработки
Режим = РежимДиалогаВопрос.ДаНет;
Текст = «Текущие данные документа будут заменены новыми без возможности восстановления.
|Продолжить?»;
Ответ = Вопрос(Текст, Режим, 0);
Если Ответ = КодВозвратаДиалога.Да Тогда

//Если пользователь дал разрешение на продолжение, то начнем перебирать все
//документы, у которых мы планируем заполнить табличную часть
Для каждого Элемент из ОбъектыНазначенияМассив Цикл

//Зададим ключ поиска документа, из которого вызвана данная обработка,
//чтобы получить ссылку на редактирумый документ в удобном виде для
//функции ОткрытьФорму()
КлючПоиска = Новый Структура(«Ключ», Элемент);

//Но нам не надо открывать новую форму (окно) для изменяемого документа, а
//Нам надо все изменения показать в уже открытых у клиента окнах
Окна = ПолучитьОкна();
Для каждого Окно из Окна Цикл

//Окно изменяемого документа будет точно не основным, а вспомогательным, поэтому
//сразу пропускаем основное окно, а далее идем на не очень хороший способ поиска открытого окна
//изменяемого документа. Мы просто переберем все окна, а в заголовке, которых будет встречаться
//Наименование, номер и дата нужного документа — будем изменять
//Если НЕ Окно.Основное
// И Найти(Окно.Заголовок, Элемент) Тогда
Если Найти(Окно.Заголовок, Элемент) Тогда
////Передадим ключ поиска (можно сказать ссылку на объект) и данные о найденном открытом окне
////в функцию ОткрытьФорму()
////Код находится в цикле на тот случай, если открытых окон изменяемого документа больше одного
//Форма = ОткрытьФорму(«Справочник.ВходящиеДокументы.Форма.ФормаЭлемента»,КлючПоиска. Окно);
Форма = ПолучитьФорму(«Справочник.ВходящиеДокументы.Форма.ФормаЭлемента»,КлючПоиска. Окно);

//////Далее мы получаем объект только, что повторно открытой формы и помещаем её в переменную
//////В объекте содержатся все реквизиты (элементы) формы
НовыйОбъект = Форма.Объект;

////Мы помещаем объект формы в переменную,
////так как должны передать её в процедуру на сервере,
////где нельзя изменять объект формы, зато можно править переменную содержащую его
//ЗаполнитьОбъект(НовыйОбъект);
ЗаполнитьОбъект(НовыйОбъект);

////После выполнения процедуры на сервере мы получаем изменную переменную НовыйОбъект,
////которую необходимо передать в уже полученную нами форму
КопироватьДанныеФормы(НовыйОбъект, Форма.Объект);

Источник

Related Post

Регулировка пластиковых окон REHAU зачем и какРегулировка пластиковых окон REHAU зачем и как

Регулировка пластиковых окон REHAU: зачем и как Настройка пластиковых окон требуется при их неправильной установке и обслуживании, осаждении здания, изнашивании уплотнительной резины, проникновении мусора в оконный проем. Предлагаем несколько простых

Как работают дефлекторы боковых оконКак работают дефлекторы боковых окон

Как работают дефлекторы боковых окон? Если идет дождь, открытая форточка означает брызги в лицо и капли по всему подлокотнику. А если вам нужно оставить машину летом, под прямыми солнечными лучами,

Adblock
detector