Что такое код getactivewindow


GetActiveWindow

GetActiveWindow() я поставил для того, чтобы не показывалась кнопка на панели задач от модального окна, ну и соответственно чтобы родительское окно было не доступно.
Первый раз, при запуске, все работает, отображается модальное окно, родительское окно не доступно и на панели задач кнопки модального окна нет. Даже если закрыть модальное окно и снова открыть, все работает.
Но как только закроешь родительское окно, а потом откроешь, и в нем же откроешь модельное, тут же валится ошибка мол «Access violation at address. »
Если быть кратким. Если закрыть окно, которое позади модального и снова открыть, а потом снова открыть модальное вылетает ошибка.

Что не так? Пробовал GetForegroundWindow — использовать, то же самое.

Добавлено через 28 минут
Вроде бы решил, проблема вроде бы в многократном использовании

15.07.2011, 23:18

Как совместить GetActiveWindow() и GetFocus() ?
Есть такая Api-функция GetActiveWindow(), и есть еще одна-GetFocus(). Вопрос: как совместить эти.

Что такое код getactivewindow

Здесь обсуждаются вопросы по языку Visual Basic 1-6 (а так же по схожим языкам, как, например, PowerBASIC).
Вопросы по Visual Basic .NET (это который входит в состав Visual Studio 2002/2003/2005/2008+, для тех, кто не в курсе) обсуждаются в разделе .NET.

Обратите внимание:
1. Прежде чем начать новую тему или отправить сообщение, убедитесь, что Вы не нарушаете правил форума!
2. Обязательно воспользуйтесь поиском. Возможно, Ваш вопрос уже обсуждали. Полезные ссылки приведены ниже.
3. Темы с просьбой выполнить какую-либо работу за автора в этом разделе не обсуждаются. Студенты, вам сюда: ПОМОЩЬ СТУДЕНТАМ !
4. Используйте теги [ code=vba ] . текст программы. [ /code ] для выделения текста программы подсветкой.
5. Помните, здесь телепатов нет. Формулируйте свой вопрос максимально грамотно и чётко: Как правильно задавать вопросы
6. Запрещено отвечать в темы месячной (и более) давности, без веских на то причин.

Использование GetActiveWindow ()

У меня есть таймер в моем приложении (timer1). Когда таймер выключается, он вызывает подпрограмму, которая обновляет мой DataGridView. Перед вызовом обновления к югу, я использую GetActiveWindow () от user32 Lib, чтобы проверить, если форма является активным окном. Это работает, как ожидалось. Вот код, я использую для проверки активного окна.

Я включил MessageBox просто дать мне визуальный, что это действительно работает, когда активное окно не мое применение.

То, что мне не хватает, хотя, я хотел бы назвать gridRefresh () к югу, как только мой Application снова становится активным окном.

Моя первая мысль была бы не использовать Do Until цикла и он ничего не делать, пока он не станет активным окном снова выглядеть примерно так:

Но когда я пытаюсь это решение он никогда не выходит из цикла.

Edit: Интервал таймера 1 минута. Поэтому я хочу, чтобы обновить, когда он снова становится активным является поэтому пользователю не придется ждать целую минуту, чтобы увидеть, если что-то было добавлено в GridView

Вы не делаете это правильно, Winforms уже поддерживает все это. Нет необходимости в PInvoke, вы можете использовать свойство Form.ActiveForm. И активировать и деактивировать события вам сказать, что форма де / активизирован. Поместите этот код в форме, которая содержит сетку:

Вы можете добавить два Boolean поля в форме класса, называется Active и RefreshRequired .

Затем добавить обработчики к форме в Activated и Deactivate событий. Deactivate Обработчик события просто устанавливает Active ложь. Activated Обработчик событий выглядит следующим образом :

Наконец, вы перезаписать исходный код, как:

Окна на чистом WinAPI. Или просто о сложном

Казалось бы, что WinAPI уходит в прошлое. Давно уже существует огромное количество кросс-платформенных фреймфорков, Windows не только на десктопах, да и сами Microsoft в свой магазин не жалуют приложения, которые используют этого монстра. Помимо этого статей о том, как создать окошки на WinAPI, не только здесь, но и по всему интернету, исчисляется тысячами по уровню от дошколят и выше. Весь этот процесс разобран уже даже не по атомам, а по субатомным частицам. Что может быть проще и понятнее? А тут я еще…

Но не все так просто, как кажется.

Почему о WinAPI сейчас?

В один прекрасный момент, изучая потроха одной из игр в весьма неплохом эмуляторе NES, я подумал: Вроде неплохой такой эмуль, а в отладчике нет такой простой вещи, как навигация по кнопкам клавиатуры, которая есть в любом нормальном отладчике.


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

О чем это я? А вот об этом кусочке кода:

Таким образом, авторы хотели добавить поддержку клавиатуры, но суровая реальность недр архитектуры диалоговых окон в Windows жестко пресекла такую самодеятельность. Те, кто пользовался эмулятором и отладчиком в нем, хоть раз видели это сообщение?
В чем же проблема?

Ответ такой: так делать нельзя!

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

О проблеме

Диалоговые окна упрощают работу с GUI, одновременно лишая нас возможности сделать что-то самостоятельно. Например, сообщения WM_KEYDOWN/WM_KEYUP, приходящие в оконную процедуру, «съедаются» в недрах DefDlgProc, беря на себя такие вещи, как: Навигация по Tab, обработка клавиш Esc, Enter, и т.д. Кроме того, диалоги не нужно создавать вручную: проще, ведь, набросать кнопок, списков, в редакторе ресурсов, вызвать в WinMain CreateDialog/DialogBox и все готово.

Обойти такие мелкие неприятности просто. Есть, как минимум, два вполне легальных способа:

  1. Создать свой собственный класс через RegisterClassEx и в процедуре обработки класса схватывать WM_KEYDOWN, перенаправлять в процедуру обработки самого диалога. Да-да! Можно создавать диалоги со своим собственным классом, и встроенный в VS редактор даже позволяет задавать имя класса для диалога. Вот только кто об этом знает и этим пользуется?
    Минус очевиден: Нужно регистрировать еще один класс, иметь на 1 CALLBACK процедуру больше, суть которой будет всего-навсего в трансляции пары сообщений. Кроме того, мы не будем знать куда их транслировать, и придется городить костыли.
  2. Использовать встроенный механизм акселераторов. И нам даже не придется менять код диалоговой процедуры! Ну, разве что, добавить одну строчку в switch/case, но об этом ниже.

Tutorials?

Не побоюсь сказать, что все туториалы по созданию окон через WinAPI начинаются с такого незамысловатого кода, обозначая его, как «цикл обработки сообщений» (опущу детали по подготовке класса окна и прочую обвязку):

Здесь действительно все просто:

  1. GetMessage() выхватывает очередное сообщение из очереди, и ключевой момент: блокирует поток, если в очереди пусто.
  2. TranslateMessage() из WM_KEYDOWN/WM_KEYUP формирует сообщения WM_CHAR/WM_SYSCHAR (они нужны, если кто-то хочет сделать свой редактор текста).
  3. DispatchMessage() отправляет сообщение в оконную процедуру (если таковая существует).

Начнем с того, что этот код использовать опасно, и вот почему. Обратите внимание на сноску:

Because the return value can be nonzero, zero, or -1, avoid code like this:

И ниже приводится пример правильного цикла.

Стоит сказать, что в шаблонах VS для Win32 приложений, написан именно такой неправильный цикл. И это очень печально. Ведь мало кто будет вникать в то, что сделали сами авторы, ведь это априори правильно. И неправильный код множится вместе с багами, которые очень сложно отловить.

После этого фрагмента кода, как правило, следует рассказ про акселераторы, и добавляется пара новых строчек (учитывая замечание в MSDN, предлагаю сразу писать правильный цикл):

Этот вариант я видел чаще всего. И он (та-дам) снова неправильный!

Сперва о том, что изменилось (потом о проблемах этого кода):

Илон Маск рекомендует:  zoom в CSS

В первой строчке из ресурсов загружается таблица клавиш, при нажатии на которые, будет формироваться сообщение WM_COMMAND с соответствующим id команды.

Собственно TranslateAccelerator этим и занимается: если видит WM_KEYDOWN и код клавиши, которые есть в этом списке, то (опять же ключевой момент) будет формировать сообщение WM_COMMAND (MAKEWPARAM(id, 1)) и отправлять в соответствующую для дескриптора окна, указанного в первом аргументе, процедуру обработки.

Из последней фразы, думаю, стало понятно, в чем проблема предыдущего кода.
Поясню: GetMessage выхватывает сообщения для ВСЕХ объектов типа «окно» (в число которых входят и дочерние: кнопки, списки и прочее), а TranslateAccelerator будет отправлять сформированную WM_COMMAND куда? Правильно: обратно в кнопку/список и т.д. Но мы обрабатываем WM_COMMAND в своей процедуре, а значит нам интересно ее получать в ней же.

Ясно, что TranslateAccelerator надо вызывать для нашего созданного окна:


И вроде все хорошо и замечательно теперь: мы разобрали все детально и все должно работать идеально.

И снова нет. :-) Это будет работать правильно, пока у нас ровно одно окно — наше. Как только появится немодальное новое окно (диалог), все клавиши, которые будут в нем нажаты оттранслируются в WM_COMMAND и отправляться куда? И опять же правильно: в наше главное окно.

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

IsDialogMessage

По названию этой функции можно подумать, что она зачем-то определяет: относится данное сообщение диалогу или нет. Но, во-первых, зачем нам это знать? А во-вторых, что с этой информацией нам делать дальше?

На самом деле, делает она чуть больше, чем следует из названия. А именно:

  • Осуществляет навигацию по дочерним контролам кнопками Tab/Shift+Tab/вверх/вниз/вправо/влево. Плюс еще кое-что, но этого нам достаточно
  • По нажатии на ESC формирует WM_COMMAND( IDCANCEL )
  • По нажатии на Enter формирует WM_COMMAND( IDOK ) или нажатие на текущую кнопку по умолчанию
  • Переключает кнопки по умолчанию (рамочка у таких кнопок чуть ярче остальных)
  • Ну и еще разные штуки, которые облегчают пользователю работу с диалогом

Что она нам дает? Во-первых, нам не надо думать о навигации внутри окна. Нам и так все сделают. Кстати, навигацию по Tab можно сделать, добавив стиль WS_EX_CONTROLPARENT нашему основному окну, но это топорно и не так функционально.

Во-вторых, она нам облегчит жизнь по всем остальным пунктам, перечисленным в списке (и даже немного больше).

Вообще, она используется где-то в недрах Windows для обеспечения работы модальных диалоговых окон, а программистам дана, чтобы вызывать ее для немодальных диалогов. Однако мы ее можем использовать где угодно:

Although the IsDialogMessage function is intended for modeless dialog boxes, you can use it with any window that contains controls, enabling the windows to provide the same keyboard selection as is used in a dialog box.

Т.е. теперь, если мы оформим цикл так:

То наше окошко будет иметь навигацию, как в родном диалоге Windows. Но теперь мы получили два недостатка:

  1. Этот код также будет хорошо работать только с одним (немодальным) окном;
  2. Получив все достоинства диалоговой навигации, мы лишаемся прелестей в виде сообщений WM_KEYDOWN/WM_KEYUP (только для самого окна, а не для дочерних контролов);

И вот на этом этапе вообще все туториалы заканчиваются и начинаются вопросы: How to handle keyboard events in a winapi standard dialog?
Это первая ссылка в гугле, но поверьте: тысячи их. Про предлагаемые решений (лучшее из которых — это создать свой класс диалогов, о чем я писал выше, до subclassing и RegisterHotKey. Где-то я даже видел «лучший» из способов: использовать Windows Hooks).

Пора поговорить о том, чего нет в туториалах и ответах.

Как правило (как правило! Если кому-то захочется большего, то можно регистрировать свой класс для диалогов и работать так. И, если же, кому-то это интересно, я могу дополнить этим статью) WM_KEYDOWN хотят тогда, когда хотят обработать нажатие на клавишу, которая выполнит функцию в независимости от выбранного контрола в окне — т.е. некая общая функция для всего данного конкретного диалога. А раз так, то почему бы не воспользоваться богатыми возможностями, которые нам сама WinAPI и предлагает: TranslateAccelerator.

Везде используют ровно одну таблицу акселераторов, и только для главного окна. Ну действительно: цикл GetMessage-loop один, значит и таблица одна. Куда еще их девать?

На самом деле, циклы GetMessage-loop могут быть вложенными. Давайте еще раз посмотрим описание PostQuitMessage:

The PostQuitMessage function posts a WM_QUIT message to the thread’s message queue and returns immediately; the function simply indicates to the system that the thread is requesting to quit at some time in the future.

If the function retrieves the WM_QUIT message, the return value is zero.

Таким образом, выход из GetMessage-loop осуществится, если мы вызовем PostQuitMessage в процедуре окна. Что это значит?

Мы можем для каждого немодального окна в нашей программе создавать свой собственный подобный цикл. В данном случае DialogBoxParam нам не подходит, т.к. оно крутит свой собственный цикл и повлиять мы на него не можем. Однако если создадим диалог через CreateDialogBoxParam или окно через CreateWindow, то можно закрутить еще один цикл. При этом в каждом таком окне и диалоге мы должны вызывать PostQuitMessage:

Обратите внимание: теперь для каждого нового окна в нашей программе мы можем добавить в обработку собственную таблицу акселераторов. WM_QUIT будет выхватывать GetMessage из цикла для диалога, а внешний цикл его даже не увидит. Почему так происходит?

Дело в том, что внешний цикл «встал» на вызове DispatchMessage, который вызвал нашу процедуру, которая крутит свой собственный внутренний цикл GetMessage с таким же DispatchMessage. Классический вложенный вызов (в данном случае DispatchMessage). Посему внешний цикл не получит WM_QUIT и не завершится на этом этапе. Все будет работать стройно.


Но и тут есть свои недостатки:
Каждый такой цикл будет обрабатывать сообщения только для «своего» окна. Про другие-то мы здесь не знаем. А значит, если где-то объявится еще один цикл, то все остальные окна не будут получать нужной обработки своих сообщений парой TranslateAccelerator/IsDialogMessage.

Что ж, пора учесть все эти замечание и написать наконец правильную обработку всех сообщений от всех окон нашей программы. Хочу заметить, что ниже рассматривается случай для одного потока. Т.к. каждый поток имеет свою очередь сообщений, то для каждого потока придется создавать свои структуры. Делается это весьма тривиальными изменениями в коде.

Делаем красиво

Т.к. правильная постановка задачи является половиной решения, то сперва надо эту самую задачу правильно же и поставить.

Во-первых, было бы логично, что только активное окно принимает сообщения. Т.е. для неактивного окна мы не будем транслировать акселераторы и передавать сообщения в IsDialogMessage.

Во-вторых, если для окна не задана таблица акселераторов, то транслировать нечего, будем просто отдавать сообщение в IsDialogMessage.

Создадим простой std::map, который будет мапить дескриптор окна в дескриптор таблицы акселераторов. Вот так:

И по мере создания окон будем в него добавлять новые окна с дескриптором на свою любимую таблицу (или нуль, если такая обработка не требуется).

Ну и после закрытия окна удалять. Вот так:

Теперь, как создаем новый диалог/окно, вызываем AddAccelerators( hNewDialog, IDR_MY_ACCEL_TABLE ). Как закрываем: DelAccel( hNewDialog ).

Список окон с нужными дескрипторами у нас есть. Немного модифицируем наш основной цикл обработки сообщений:

Значительно лучше! Что же там в HandleAccelArray и зачем там GetActiveWindow()?

Есть две функции, возвращающих дескриптор активного окна GetForegroundWindow и GetActiveWindow. Отличие первой от второй вполне доходчиво описано в описании второй:

The return value is the handle to the active window attached to the calling thread’s message queue. Otherwise, the return value is NULL.

Если первая будет возвращать дескриптор любого окна в системе, то последняя только того, которое использует очередь сообщений нашего потока. Т.к. нас интересуют окна только нашего потока (а значит те, которые будут попадать в нашу очередь сообщений), то и возьмем последнюю.

Так вот HandleAccelArray, руководствуясь переданным ей дескриптором на активное окно, ищет это самое окно в нашей мапе, и если оно там есть, отдает это сообщение на трансляцию в TranslateAccelerator, а затем (если первый не увидел нужного) в IsDialogMessage. Если и последняя не обработала сообщение, то возвращаем FALSE, чтобы пройти по стандартной процедуре TranslateMessage/DispatchMessage.

Теперь каждое дочернее окно вправе добавить себе любимую таблицу акселераторов и спокойно ловить и обрабатывать WM_COMMAND с нужным кодом.

А что там еще об одной строчке в коде обработчика WM_COMMAND?

To differentiate the message that this function sends from messages sent by menus or controls, the high-order word of the wParam parameter of the WM_COMMAND or WM_SYSCOMMAND message contains the value 1.

Обычно код обработки WM_COMMAND выглядит так:

Илон Маск рекомендует:  Что такое код pg_put_line

Теперь можно написать так:

И теперь, возвращаясь к тому же fceux, добавив всего одну строчку в код обработки команд от кнопок, мы получим желаемое: управлять дебагером с клавиатуры. Достаточно добавить небольшую обертку вокруг главного цикла сообщений и новую таблицу акселераторов с нужными соответствиями VK_KEY => IDC_DEBUGGER_BUTTON.

P.S.: Мало кто знает, но можно создавать свою собственную таблицу акселераторов, а теперь и применять ее прямо налету.

P.P.S.: Т.к. DialogBox/DialogBoxParam крутит собственный цикл, то от при вызове диалога через них акселераторы работать не будут и наш цикл (или циклы) будет «простаивать».

P.P.P.S.: После вызова HandleAccelWindow мап l_mAccelTable может измениться, т.к. TranslateAccelerator или IsDialogMessage вызывают DispatchMessage, а там может встретиться AddAccelerators или DelAccel в наших обработчиках! Поэтому лучше его после этой функции не трогать.


Пощупать код можно здесь. За основу был взят код, генерируемый из стандартного шаблона MS VS 2020.

Как правильно использовать GetActiveWindow

Я хочу в перехватчике нажатия клавиш узнать, с каким окном работает пользователь.
Есть код, который компилируется в dll (в dll запихана форма, на эту форму выводится некоторое количество информации — просто для визуализации процесса работы):

Если в момент вызова GetForegroundWindow активна форма из моей dll, то все работает. Если активно другое окно, программа падает. Если использовать вместо нее GetActiveWindow, то я опять получаю результат для «своего» окна, а для всех остальных — 0. Что я делаю не так? MSDN читал по этим двум функциям, почему программа жестко падает, не понял.
В принципе, если есть другой способ определить, какому окну юзер шлет перехватываемые мной сообщения, он тоже подойдет.

Спасибо за статью!
Сначал долго не мог понять, в чем прикол, потом вроде дошло. Я перенес вызов функции GetForegroundWindow в метод формы (в моем приложении MyHook вызывает один из методов формы, который записывает информацию о нажатых клавишах в StringGrid). После этого в сетке вместо нулей стали появляться разные числа (адреса хэндлов активных окон, как я понял. )
Я понял это так: когда я в своей программе ставлю ловушку, то при наступлении нужного мне события код функции MyHook копируется в адресное пространство чужого процесса. Оттуда он вызывает метод моей формы, который выполняется уже в моем процессе и поэтому может передать значение в StringGrid. Хотя чего-то здесь явно не хватает. Например, этот код выводит в ячейки StringGrid фразу «нажатие клавиши», значения переменных Code, WParam, LParam, wnd. Причем он выводит все эти переменные, кроме последней — она равна нулю!

А вот если строчку wnd:= GetForegroundWindow; перенести в метод TForm1.AddEvent, то там выводится то, что нужно. Причину так и не понял.

added later:
Хм. А может, потому что тип HWND — это тип-указатель (как string или объект), и при передаче его как параметра в функцию он передает в мой процесс не сами данные, а ссылку на них? А в моем процессе этот адрес не имеет смысла и указывает в никуда?

MQL4: Управление компьютером из советника

Иногда бывает необходимо программно нажать кнопку в стороннем приложении, считать текст с определенного компонента, запустить другой терминал, любую другую программу, открыть текстовый файл, выключить компьютер в определенное время, произвести еще какие-либо операции. Здесь нам поможет функция WinAPI — ShellExecute, которая находится в библиотеке shell32.dll и библиотека WinUser32.mqh. Как можно автоматизировать весь этот процесс — узнаем из нашего нового урока по программированию форекс роботов. Тема необычная, сильно расширит ваши навыки как программиста.

Более подробную информацию о функции ShellExecute вы можете получить в справке MSDN. Там же можно получить подробную информацию обо всех функциях, доступных из библиотеки WinUser32.mqh. Я же приведу краткое описание каждой из них:

  • ShellExecute — выполняет операцию с указанным файлом;
  • SendMessage — Отправляет указанное сообщение окну или окнам, ожидает ответа;
  • SendNotifyMessage – то же самое, но не ждет ответа;
  • PostMessage – помещает сообщение в поток, не дожидаясь ответа;
  • keybd_event – синтезирует нажатие заданной клавиши на клавиатуре;
  • mouse_event — синтезирует движение мыши и нажатия кнопок;
  • FindWindow — извлекает дескриптор окна верхнего уровня;
  • SetWindowText – помещает текст в название окна;
  • GetWindowText – считывает текст из названия окна;
  • GetWindowTextLength – считывает количество символов в названии окна;
  • GetWindow — извлекает дескриптор окна, которое имеет отношение к указанному окну;
  • GetParent — извлекает дескриптор указанного или родительского окна;
  • UpdateWindow – обновляет окно программы;
  • EnableWindow — включает или отключает ввод с клавиатуры и мыши в указанное окно или элемент управления;
  • DestroyWindow — деактивирует окно или убирает с него фокус клавиатуры;
  • ShowWindow — устанавливает состояние показа указанного окна;
  • SetActiveWindow — активирует окно;
  • AnimateWindow — позволяет создавать специальные эффекты при отображении или скрытии окон;
  • FlashWindow – заставляет мигнуть указанное окно один раз;
  • CloseWindow — минимизирует (но не закрывает) указанное окно;
  • MoveWindow — изменяет положение и размеры указанного окна;
  • SetWindowPos — изменяет размер и положение дочернего, всплывающего окна или окна верхнего уровня;
  • IsWindowVisible — определяет состояние видимости указанного окна;
  • IsIconic — определяет, является ли указанное окно свернутым;
  • IsZoomed — определяет, развернуто ли окно;
  • SetFocus — устанавливает фокус клавиатуры на указанное окно;
  • GetFocus — извлекает дескриптор окна, которое имеет фокус клавиатуры;
  • GetActiveWindow — получает дескриптор активного окна;
  • IsWindowEnabled — определяет, включено ли указанное окно для ввода с клавиатуры и мыши;
  • MessageBox — отображает модальное диалоговое окно, которое содержит системный значок, набор кнопок и краткое сообщение для конкретного приложения, такое, как информация о состоянии или об ошибке;
  • MessageBeep — воспроизводит звук с помощью системного динамика;
  • GetSystemMetrics — извлекает указанную метрику системы или параметр конфигурации системы;
  • ExitWindows — выход из системы интерактивного пользователя, выключение системы или выключение и перезагрузка системы;
  • SwapMouseButton — меняет или восстанавливает значение левой и правой кнопок мыши.

Что мы будем сегодня делать?

Мы не будем рассматривать каждую функцию из списка, — на это ушло бы очень много времени и, к тому же, мне не хочется отнимать у вас возможность самостоятельного изучения. Поэтому мы просто решим несколько простейших задач, таких, как:

  • выключение или перезагрузка компьютера;
  • запуск другой программы из терминала (например, google chrome);
  • замена названия окна программы.

Да, это очень простые задачи, но их решение вполне может служить хорошим примером для демонстрации возможностей библиотек и построении на основе этих примеров более сложных алгоритмов.

Запуск приложения

Первое, что нужно сделать – объявить функцию ShellExecuteW:

Затем в методе onStart() запустим нужную программу:

Бросим скрипт на любой график и у нас откроется указанная программа.
Теперь включим в наш скрипт библиотеку терминала WinUser32.mqh:

Теперь нам нужно найти хэндл окна запущенной программы. Это можно осуществить с помощью функции WinApi — FindWindowW.
В библиотеке терминала функция описана следующим образом:

Это означает, что в параметр string lpClassName необходимо ввести имя класса нашего приложения, а вместо параметра string lpWindowName имя окна программы — «Новая вкладка». Имя класса приложения можно узнать с помощью таких утилит как: Spy++, WinSight, WinInspector и другие. Скачаем и установим программу Spy++.

Утилита очень проста в использовании. Достаточно запустить программу, нажать кнопку с изображением бинокля и перетащить прицел на нужное нам окно, и мы сразу увидим его имя, класс и прочую информацию. В функции FindWindowW можно указывать и имя класса, и имя окна (или по отдельности). Нам достаточно будет указать только имя окна:

На экран выведена информация с хендлом найденного окна. Если хендл равен 0, значит, окно не найдено. Получив хендл главного окна, можно делать с приложением все, что нам заблагорассудится: искать нужное нам дочернее окно, считывать и передавать текст, программно нажимать кнопки и так далее.


Добавим в наш код еще одну простую функцию SetWindowTextW. Она изменит текст окна на любой другой:

Для выключения компьютера найдем на диске программу shutdown.exe. И так же, как и в предыдущем случае, пропишем в функции адрес программы с необходимыми нам параметрами:

Чтобы выключить компьютер, введите следующую строку:

Чтобы перезагрузить компьютер, введите следующую строку:

Чтобы посмотреть параметры для различных версий Windows — пройдите по этой ссылке.

Заключение

В библиотеке WinUser32.mqh вы сможете также найти и много других интересных функций, которые позволят вам управлять сторонней программой прямо из советника, написанного на MQL4. Полный список функций WinApi вы можете найти на сайте MSDN.

Илон Маск рекомендует:  Как увеличить расстояние от маркера до текста

Таким образом, вы можете полноценно управлять вашим компьютером из mql скрипта, автоматизировать все ваши действия по подготовке к торговле: открывать журналы сделок, новостные сайты при открытии терминала и так далее.

Также вы можете написать советник, который торговал бы в другом торговом терминале, не поддерживающем автоматизированную торговлю, например, в браузерном приложении для бинарных опционов или в платформе для торговли акциями. Это открывает действительно широкие возможности для работы и множество различных интересных способов применения великого множества программ для получения, обработки данных и манипуляции другим ПО.

Что такое код getactivewindow

Вывести список компонент чужого окна — это можно сделать?

что такое «компонент чужого окна» ?

у окна нет компонентов. Есть дочерние окна, но если приложение написано на дельфи, то некоторые компоненты (Label, к примеру) окнами не являются.
EnumChildWindows()

Я вот кое-что нашел, буду пробовать:
1. Раз в компонент на форме осуществлялся ввод, то форма полюбому активна, тада:
Код:
var
H: HWND;
Zagolovok:array[0..255] of Char;
.
begin
H:= GetActiveWindow // — узнаем текущее активное окно
GetWindowText(H, Zagolovok, SizeOf(Zagolovok)); //- считываем заголовок
2. Получили заголовок окна. требуется получить все хендлы компонентов и их классы, сделаем цикл:
Код:

var
Wnd: HWND;
Buff:array[0..255] of Char;
begin
H:=GetActiveWindow;
Wnd:= GetWindow(H, gw_child);
While Wnd <> 0 then begin
If (GetParent(Wnd) = H) then begin
GetClassName(Wnd,Buff,SizeOf(Buff));
ListBox1.Items.Add(StrPas(buff)); // добавляем в список классов
end;
Wnd:= GetWindow(H, gw_HWNDNext);
end;
В ListBox1 будут выведены классы всех child окон


> В ListBox1 будут выведены классы всех child окон

А вопрос твой звучал совсем иначе

«child окно» <> «компонент»

Но если мы знаем имя класса окна — можно же узнать дочерние классы этого окна?


> можно же узнать дочерние классы этого окна?
>

Нельзя.
Можно узнать лишь классы дочерних окон этого окна, если таковые вообще имеются.
Но какое отношение это имеет к «компонент чужого окна» ?

> имя класса окна — можно же узнать дочерние классы этого
> окна?

там нет понятия «дочерние классы»
класс окна — это не то, что класс в ООП
есть дочерние окна, я уже писал — EnumChildWindows()

worldmen (20.10.08 12:12) [3]
1. Раз в компонент на форме осуществлялся ввод, то форма полюбому активна, тада:

GetActiveWindow возвращает окно от данного потока.

> GrayFace ©
> GetActiveWindow возвращает окно от данного потока.
Создал тестовую форму с несколькими полями — Прога-1
Создал программу (Прога-2) с GetActiveWindow — а она почемуто эта функция возвращает имя окна только самой программы (Прога-2),когда она активна, а не активной Проги-1(даже когда она активна) — почему?

Ты читать умеешь ?
Читай внимательно справку:

The GetActiveWindow function retrieves the window handle to the active window associated with the thread that calls the function.


Т.е. возвращает то, чем было вызвана функция?
Так мне перевел промт:
«Функция GetActiveWindow восстанавливает маркер окна к активному окну, связанному с потоком, который вызывает функцию.»

> восстанавливает маркер окна к активному окну

возвращает дескриптор (описатель) активного окна
Промпту двойка

> Промпту двойка

он никогда не отличался хорошим переводом

Каждое существующее в системе окно принадлежит конкретному создавшему его потоку.

Если в потоке T1 были созданы окна W1 и W2, а в потоке T2 — W3 и W4, и в дан.момент времени активно, например, окно W3, то ф-ция GetActiveWindow, будучи вызыванная в потоке T1 вернет 0 (потому что текущее активное окно НЕ принадлежит потоку T1), в то время как та же ф-ция, вызыванная в потоке T2, вернет хэндл окна W3.

Спасибо, даже не знал такого. А можно переходить в другие потоки?
———————
Я нашел то что искал здесь http://forum.codeby.net/topic3765.html


> можно переходить в другие потоки?

Что значит «переходить» ?


> нашел то что искал здесь

Там нет ни слова про «список компонент чужого окна».

Удалено модератором
Примечание: Ненужно так делать.

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

> Сергей М. © (23.10.08 11:53) [17]
> Там нет ни слова про «список компонент чужого окна».

Я просто не правильно вопрос задал.

Использование GetActiveWindow()

У меня есть таймер в моем приложении (timer1). Когда этот таймер отключается, он вызывает подпрограмму, которая обновляет мое представление данных. Перед вызовом подпрограммы обновления я использую GetActiveWindow() из библиотеки user32, чтобы проверить, является ли форма активным окном. Это работает как ожидалось. Вот код, который я использую для проверки активного окна.

Я включил окно сообщения только для того, чтобы показать мне, что оно действительно работает, когда активное окно не является моим приложением.

Чего мне не хватает, так это того, что я хотел бы вызвать sub gridRefresh(), как только мое Приложение снова станет активным окном.

Моей первой мыслью было бы использовать цикл «До» и заставить его ничего не делать, пока он снова не станет активным окном, вот так:

Но когда я пробую это решение, оно никогда не выходит из цикла.

Изменить: интервал таймера составляет 1 минуту. Причина, по которой я хочу обновить его, как только он снова станет активным, заключается в том, что пользователю не нужно ждать целую минуту, чтобы увидеть, было ли что-либо добавлено в сетку.

2 ответа

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

vladgolubev / getActiveWindow.java

import static enumeration.EnumerateWindows.Kernel32.* ;
import static enumeration.EnumerateWindows.Psapi.* ;
import static enumeration.EnumerateWindows.User32DLL.* ;
import com.sun.jna.Native ;
import com.sun.jna.Pointer ;
import com.sun.jna.platform.win32.WinDef.HWND ;
import com.sun.jna.ptr.PointerByReference ;
public class EnumerateWindows <
private static final int MAX_TITLE_LENGTH = 1024 ;
public static void main ( String [] args ) throws Exception <
char [] buffer = new char [ MAX_TITLE_LENGTH * 2 ];
GetWindowTextW(GetForegroundWindow(), buffer, MAX_TITLE_LENGTH );
System . out . println( » Active window title: » + Native . toString(buffer));
PointerByReference pointer = new PointerByReference ();
GetWindowThreadProcessId(GetForegroundWindow(), pointer);
Pointer process = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ , false , pointer . getValue());
GetModuleBaseNameW(process, null , buffer, MAX_TITLE_LENGTH );
System . out . println( » Active window process: » + Native . toString(buffer));
>
static class Psapi <
static
public static native int GetModuleBaseNameW ( Pointer hProcess , Pointer hmodule , char [] lpBaseName , int size );
>
static class Kernel32 <
static
public static int PROCESS_QUERY_INFORMATION = 0x0400 ;
public static int PROCESS_VM_READ = 0x0010 ;
public static native int GetLastError ();
public static native Pointer OpenProcess ( int dwDesiredAccess , boolean bInheritHandle , Pointer pointer );
>
static class User32DLL <
static
public static native int GetWindowThreadProcessId ( HWND hWnd , PointerByReference pref );
public static native HWND GetForegroundWindow ();
public static native int GetWindowTextW ( HWND hWnd , char [] lpString , int nMaxCount );
>
>

This comment has been minimized.


Copy link Quote reply

amitrathi1982 commented Apr 30, 2020

can anybody please guide how do we use this to get active windows as confusion is the file name is «getActiveWindow.java» but in code class name is different.

This comment has been minimized.

Copy link Quote reply

NecroMancer05 commented May 28, 2020

instal jna than cpoy all codes to your class than use it .

This comment has been minimized.

Copy link Quote reply

debabratahazra commented Apr 1, 2020

This java class is incomplete. Lots of methods are not yet defined in this class. How to solve all these undefined methods here?

This comment has been minimized.

Copy link Quote reply

goias5 commented Apr 26, 2020

I had a problem, there is exceptions, erros, it show the active window but then crashes. How to show all opne windows, not only the main one?
Anyway it worked to show only 1 window, so it deserved a star.

  • © 2020 GitHub , Inc.
  • Terms
  • Privacy
  • Security
  • Status
  • Help

You can’t perform that action at this time.

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.

Win32 API. Функции и сообщения ввода информации с клавиатуры
Страница 4. Функция GetActiveWindow

Функция GetActiveWindow

Функция GetActiveWindow извлекает оконный дескриптор активного окна, связанного с потоком, который вызывает функцию.

Параметры
У этой функции нет параметров.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения — дескриптор активного окна, связанного с потоком, который вызывает функцию. Если вызывающий поток не имеет активного окна, величина возвращаемого значения — ПУСТО (NULL).

Смотри также
SetActiveWindow

Размещение и совместимость GetActiveWindow

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL