- SetFocus function (winuser.h)
- Syntax
- Parameters
- Return value
- Remarks
- Функция SetFocus в Power Apps
- Описание
- Ограничения
- Синтаксис
- Примеры
- Фокусировка на недавно появившемся или включенном элементе управления вводом
- Фокус на проблемах проверки
- Фокус при отображении экрана
- Is there a reliable way to activate / set focus to a window using C#?
- 4 Answers 4
- Привлечение внимания к окну
- Метод window.focus
- Мерцание заголовка
- Событие window.onfocus
- Когда событие onfocus не работает?
- Итого
SetFocus function (winuser.h)
Sets the keyboard focus to the specified window. The window must be attached to the calling thread’s message queue.
Syntax
Parameters
Type: HWND
A handle to the window that will receive the keyboard input. If this parameter is NULL, keystrokes are ignored.
Return value
Type: HWND
If the function succeeds, the return value is the handle to the window that previously had the keyboard focus. If the hWnd parameter is invalid or the window is not attached to the calling thread’s message queue, the return value is NULL. To get extended error information, call GetLastError function.
Extended error ERROR_INVALID_PARAMETER (0x57) means that window is in disabled state.
Remarks
This function sends a WM_KILLFOCUS message to the window that loses the keyboard focus and a WM_SETFOCUS message to the window that receives the keyboard focus. It also activates either the window that receives the focus or the parent of the window that receives the focus.
If a window is active but does not have the focus, any key pressed produces the WM_SYSCHAR, WM_SYSKEYDOWN, or WM_SYSKEYUP message. If the VK_MENU key is also pressed, bit 30 of the lParam parameter of the message is set. Otherwise, the messages produced do not have this bit set.
By using the AttachThreadInput function, a thread can attach its input processing to another thread. This allows a thread to call SetFocus to set the keyboard focus to a window attached to another thread’s message queue.
Функция SetFocus в Power Apps
Устанавливает фокус ввода на конкретный элемент управления.
Описание
Функция SetFocus дает элемент управления, который находится в фокусе ввода. Затем клавиши, нажатые пользователем, передаются этому элементу управления, что позволяет пользователю вводить текст в элемент управления ввода текста или использовать клавишу ВВОД, чтобы выбрать кнопку. Пользователь также может использовать клавишу TAB, касание, мышь или другой жест, чтобы переместить фокус ввода самостоятельно. Поведение клавиши TAB контролируется свойством TabIndex.
Используйте функцию SetFocus для установки фокуса, когда (каждый случай с примером ниже):
- вновь открытый или включенный элемент управления вводом, чтобы направлять пользователя к дальнейшим действиям и быстрее вводить данные.
- форма проверена, чтобы сфокусировать и отобразить неправильный элемент управления ввода для быстрого исправления.
- отображается экран, чтобы сфокусировать первый элемент управления ввода со свойством OnVisibleэкрана.
Элемент управления с фокусом может визуально отличаться в зависимости от свойств FocusedBorderColor и FocusedBorderThickness.
Ограничения
Функция SetFocus может использоваться только со следующими элементами:
Невозможно задать фокус на элементы управления, которые находятся внутри элемента управления Gallery (Коллекция), Edit form (Форма редактирования) или Component (Компонент). Функция SetFocus может использоваться с элементом управления на прокручиваемом экране.
Вы не можете установить фокус на элементы управления, которые находятся в пределах элемента управления Container (Контейнер).
Вы можете установить фокус только для элементов управления на том же экране, что и формула, содержащая вызов функции SetFocus.
Попытка установить фокус на элемент управления, для свойства DisplayMode которого установлено значение Disabled, не имеет никакого эффекта. Фокус останется на прежнем месте.
На Apple iOS программная клавиатура будет отображаться автоматически только в том случае, если функция SetFocus была инициирована прямым действием пользователя. Например, при вызове из свойства OnSelect кнопки будет отображаться программная клавиатура, а при вызове из свойства OnVisible экрана она отображаться не будет.
Функцию SetFocus можно использовать только в формулах поведения.
Синтаксис
SetFocus( Control )
- Control — обязательный аргумент. Элемент управления, которому требуется передать фокус ввода.
Примеры
Фокусировка на недавно появившемся или включенном элементе управления вводом
Многие корзины покупок позволяют клиенту использовать адрес доставки в качестве адреса выставления счета, что устраняет необходимость ввода одной и той же информации дважды. Если требуется другой адрес для выставления счета, поля ввода текста адреса для выставления счета включаются и удобно направить клиента к этим недавно включенным элементам управления для более быстрого ввода данных.
Здесь есть много формул, но та, которая смещает фокус, находится в свойстве OnUncheck элемента управления Check box (Флажок):
Клавиша TAB также может быть использована для быстрого перемещения фокуса с одного поля на другое. Чтобы лучше проиллюстрировать, клавиша TAB не была использована в анимации.
Чтобы создать такой пример, сделайте следующее:
- Создайте новое приложение.
- Добавьте элементы управления Label (Метка) с текстом «Shipping address» (Адрес доставки), «Name:» (Имя:), «Address:» (Адрес:), «Billing Address» (Адрес выставления счетов), «Name:» (Имя:) и «Address:» (Адрес:) и расположите их, как показано на анимации.
- Добавьте элемент управления Text Input (Ввод текста) и переименуйте его в ShippingName (Имя для доставки).
- Добавьте элемент управления Text Input (Ввод текста) и переименуйте его в ShippingAddress (Адрес доставки).
- Добавьте элемент управления Check box (Флажок) и переименуй его в SyncAddresses (Синхронизировать адреса).
- Задайте для свойства Text этого элемента управления формулу «Use Shipping address as Billing address» :
- Добавьте элемент управления Text Input (Ввод текста) и переименуйте его в BillingName (Имя для выставления счетов).
- Задайте для свойства Default этого элемента управления формулу ShippingName :
- Задайте для свойства DisplayMode этого элемента управления формулу If( SyncAddresses.Value, DisplayMode.View, DisplayMode.Edit ) : Это автоматически включит или отключит этот элемент управления в зависимости от состояния элемента управления «Флажок».
- Добавьте элемент управления Text Input (Ввод текста) и переименуйте его в BillingAddress (Адрес для выставления счетов).
- Задайте для свойства Default этого элемента управления формулу ShippingAddress :
- Задайте для свойства DisplayMode этого элемента управления формулу If( SyncAddresses.Value, DisplayMode.View, DisplayMode.Edit ) : Это автоматически включит или отключит этот элемент управления в зависимости от состояния элемента управления «Флажок».
- Задайте для свойства Default этого флажка формулу true : По умолчанию адрес выставления счета будет использовать то же значение, что и адрес доставки.
- Задайте для свойства OnCheck этого флажка формулу Reset( BillingName ); Reset( BillingAddress ) : Если пользователь выберет синхронизацию адресов доставки и выставления счетов, это удалит любой пользовательский ввод в полях адреса выставления счетов, позволяя свойствам Default для каждого получить значения из соответствующих полей адреса доставки.
- Задайте для свойства OnUncheck этого флажка формулу SetFocus( BillingName ) : Если пользователь выбирает другой адрес выставления счета, это переместит фокус на первый элемент управления в адресе выставления счета. Элементы управления будут уже включены из-за их свойства DisplayMode.
Фокус на проблемах проверки
Хотя этот пример выглядит как элемент управления Edit form (Форма редактирования), к сожалению, в функции SetFocus этот элемент управления еще не поддерживается. Вместо этого в этом примере используется прокручиваемый экран для размещения элементов управления вводом.
При проверке формы может быть полезно не только отобразить сообщение, если есть проблема, но также и перенести пользователя в поле, которое содержит ошибку. Это может быть особенно полезно, если рассматриваемое поле прокручивается за пределами экрана и не видно.
В этой анимации кнопка проверки нажимается до тех пор, пока все поля не будут заполнены правильно. Обратите внимание, что указатель мыши не перемещается вниз от верхней части экрана. Вместо этого функция SetFocus сместил фокус ввода в элемент управления, требующий внимания, с помощью этой формулы:
Чтобы создать такой пример, сделайте следующее:
- Создайте новое пустое приложение для телефона.
- Из меню Вставка выберите Создать экран, затем выберите С прокруткой.
- В центральной части экрана добавьте элементы управления Text input (Ввод текста) и назовите их Name (Имя), Street1 (Улица1), Street2 (Улица2), City (Город), County (Округ), StateProvince (Штат/провинция), PostalCode (Почтовый индекс) и Phone (Телефон). Добавьте элементы управления Label (Метка) над каждым, чтобы идентифицировать поля. Возможно, вам придется изменить размер раздела, если он недостаточно длинный, чтобы вместить все элементы управления.
- Добавьте элемент управления Icon (Значок) в виде галочки в верхней части экрана, над прокручиваемым разделом.
- Задайте для свойства OnSelect элемента управления Icon формулу If( IsBlank( . , приведенную выше.
Фокус при отображении экрана
Хотя этот пример выглядит как элемент управления Edit form (Форма редактирования), к сожалению, в функции SetFocus этот элемент управления еще не поддерживается. Вместо этого в этом примере используется прокручиваемый экран для размещения элементов управления вводом.
Подобно отображению элемента управления вводом, при отображении экрана ввода данных полезно сфокусировать первый элемент управления вводом для более быстрого ввода данных.
В этой анимации экран ввода данных слева не использует функцию SetFocus. При отображении ни один элемент управления вводом не имеет фокуса, требуя от пользователя нажатия, касания, мыши или использования другого средства для фокусировки поля Name (Имя) перед тем как значение может быть введено в него.
Справа у нас точно такое же приложение, в котором свойству OnVisible экрана ввода данных задана следующая формула:
Это устанавливает фокус на поле Name (Имя) автоматически. Пользователь может начать печатать и переходить между полями с помощью клавиши TAB немедленно без каких-либо предварительных действий.
Чтобы создать такой пример, сделайте следующее:
- Создайте приложение «Фокус на проблемах проверки» выше.
- На этом экране задайте для свойства OnVisible формулу SetFocus( Name ) .
- Добавьте второй экран.
- Добавьте элемент управления Button (Кнопка).
- Назначьте свойству OnSelect этого элемента управления формулу Navigate( Screen1 ) .
- Предварительно просмотрите приложение с этого экрана. Нажмите кнопку. формула OnVisible будет оценена, и поле Name (Имя) будет автоматически в фокусе.
Каковы ваши предпочтения в отношении языка документации? Пройдите краткий опрос (обратите внимание, что этот опрос представлен на английском языке).
Опрос займет около семи минут. Личные данные не собираются (заявление о конфиденциальности).
Is there a reliable way to activate / set focus to a window using C#?
I’m trying to find a reliable way to activate / set focus to a window of an external application using C#. Currently I’m attempting to achieve this using the following Windows API calls:
Previously I also had ShowWindow(handle, SW_SHOWMAXIMIZED); executing before the other 2, but removed it because it was causing strange behavior.
The problem I’m having with my current implementation is that occasionally the focus will not be set correctly. The window will become visible but the top part of it will still appear grayed out as if it wasn’t in focus.
Is there a way to reliably do this which works 100% of the time, or is the inconsistent behavior a side-effect I can’t escape? Please let me know if you have any suggestions or implementations that always work.
4 Answers 4
Windows created in different threads typically process input independently of each other. That is, they have their own input states (focus, active, capture windows, key state, queue status, and so on), and they are not synchronized with the input processing of other threads. By using the AttachThreadInput function, a thread can attach its input processing to another thread. This also allows threads to share their input states, so they can call the SetFocus function to set the keyboard focus to a window of a different thread. This also allows threads to get key-state information. These capabilities are not generally possible.
I am not sure of the ramifications of using this API from (presumably) Windows Forms. That said, I’ve used it in C++ to get this effect. Code would be something like as follows:
targetHwnd being the HWND of the window you want to set focus to. I assume you can work out the P/Invoke signature(s) since you’re already using native APIs.
Привлечение внимания к окну
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
Проверить, находится ли окно в фокусе, а также перевести внимание посетителя на него – сложно.
В первую очередь, это потому, что JavaScript не интегрирован с оконным менеджером ОС. Кроме того, браузер охраняет права посетителя: если он хочет скрыть окно, то JavaScript не может его остановить.
Но кое-что сделать, конечно, можно. Об этом и поговорим.
Метод window.focus
Метод window.focus позволяет сфокусироваться на окне. Он работает по-разному в разных ОС и браузерах.
Что будет, если запустить этот код, и затем переключиться в другое окно или вкладку?
Можно подумать, что окно будет оказываться в фокусе раз в секунду. Но это не так.
Произойдёт одно из трёх:
- Вообще никакого эффекта. Самый распространённый случай, если в окне много вкладок.
- Окно развернётся (при необходимости) и выйдет на передний план. Обычно это происходит, когда метод window.focus() вызывается для попапа, а активно сейчас – главное окно. То есть, в этом случае вызов сработает.
- Заголовок окна начнёт мигать. Чтобы увидеть это в действии – откройте данную страницу в IE, запустите код и переключитесь на другое окно. Браузер попытается привлечь Ваше внимание миганием/мерцанием заголовка окна.
Мерцание заголовка
В дополнение к window.focus() используют мерцание заголовка окна, как показано в примере ниже:
Запустите код и сверните всплывающее окно. А затем – нажмите кнопку с надписью «getAttention(win)». Браузер будет привлекать ваше внимание, как умеет 😉
Обратите внимание: в коде есть проверка на win.closed . Попытка манипулирования закрытым окном вызовет исключение.
Как только посетитель сфокусировался на окне индикация прекращается. Для определения момента фокусировки в примере выше используется событие document.onmousemove .
Можно было использовать событие window.onfocus , но, оказывается, оно ненадёжно.
Событие window.onfocus
Вот переписанный вариант функции getAttention(win) , с использованием события onfocus :
Далее мы посмотрим случаи, когда он не срабатывает, и почему нам всё же нужно document.onmousemove .
Когда событие onfocus не работает?
Возможно такое, что посетитель переключается на окно, а window.onfocus не происходит.
Это потому, что переключение между окнами и фокусировка – это разные вещи. Например, если курсор находится в поле для ввода URL браузера, то считается, что окно не в фокусе, хотя посетитель переключился на это окно.
Попробуйте проделать следующее:
- Запустите пример с getAttention в Chrome или IE (кстати, в них нельзя отключить адресную панель).
- Поместите курсор в панель адреса всплывающего окна.
- Перейдите обратно к главному окну и нажмите кнопку getAttention(win)
Вы увидите, что несмотря на то, что вы переключились на окно, и оно сейчас на переднем плане, событие onfocus не срабатывает.
Есть и другие случаи, когда переключение между окнами не вызывает window.onfocus . Скажем, если окно сфокусировать щелчком в поле ввода формы, то в IE события window.onfocus (а также window.onfocusin ) – не сработают!
Можно попробовать поймать момент фокусировки и по-другому, повесив дополнительные обработчики событий на document . В главе Фокусировка: focus/blur описана техника делегирования для focus/blur .
Но этот способ получает фокус только если посетитель сфокусируется где-то в документе: щёлкнет или сделает ещё какое-то действие в документе, а не просто посмотрит на него и проведёт над ним мышкой.
Впрочем, никто не мешает использовать сочетание всех описанных методов.
Итого
Фокусировка и привлечение внимания к окну:
Метод focus для window не надёжен. Окнами и вкладками браузера можно уверенно управлять только на уровне ОС.
Поэтому для привлечения внимания посетителя к окну стоит также использовать мерцающий заголовок окна.
Обнаружение переключения на окно:
У window есть событие onfocus , но оно также ненадёжно.