Как сохранить форму всегда наверху, не отвлекая внимание от активного окна?

Мой вопрос: как я могу держать свою форму всегда наверху (я могу сделать это, настроив TopMost = true), не отвлекая внимание от окна, активного в данный момент, когда моя форма взаимодействует с ней.

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

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

2: Изображение моей формы: как только я нажимаю кнопку в своей форме, фокус возвращается к этой форме.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
591
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
  1. Сделайте стандартную форму, установите ее FormBorderStyle = none. Сделайте его TopMost (эта настройка - отдельная тема, я не буду обсуждать ее здесь).
  2. Переопределите CreateParams , чтобы установить расширенные стили WS_EX_NOACTIVATE и WS_EX_TOOLWINDOW. Это предотвращает активацию формы, когда события мыши генерируются внутри ее поверхности (см. документы об этих стилях).
  3. Добавьте к нему несколько невыбираемых элементов управления Button (элемент управления ButtonNoSel, показанный ниже) и установите для их свойства Tag символ Unicode, соответствующий изображению Emoji, которое показывают эти кнопки.
  4. Добавьте один и тот же обработчик кликов ко всем кнопкам.

Эти кнопки при нажатии просто используют SendKeys::Send() (он же SendInput()), чтобы отправить выбранный символ Unicode в окно переднего плана, приведя к строке значение свойства Tag.

Вот как это работает (установка эмодзи на веб-страницу, отображаемую FireFox):


using namespace System;
using namespace System::ComponentModel;
using namespace System::Windows::Forms;
using namespace System::Drawing;

public ref class frmKeyBoard : public System::Windows::Forms::Form
{
public:
    frmKeyBoard(void) { InitializeComponent(); }

// [...] Initialization...

protected:
    property System::Windows::Forms::CreateParams^ CreateParams {
        virtual System::Windows::Forms::CreateParams^ get() override {
            auto cp = Form::CreateParams;
            cp->ExStyle |= (WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW);
            return cp;
        }
    }

// Event handler for all the Buttons
private:
    System::Void buttonNoSelAll_Click(System::Object^  sender, System::EventArgs^  e) {
        Control^ ctl = safe_cast<Control^>(sender);
        SendKeys::Send(ctl->Tag->ToString());
    }
};

Добавьте этот простой пользовательский элемент управления в проект.
Этот элемент управления просто использует Control.SetStyle, устанавливая ControlStyles::Selectable = false, чтобы предотвратить превращение дочернего элемента управления в ActiveControl при взаимодействии с ним, поскольку он не получает фокуса.

using namespace System;
using namespace System::Windows::Forms;
using namespace System::ComponentModel;

namespace CustomControls {
    [ToolboxItem(true)]
    public ref class ButtonNoSel : public System::Windows::Forms::Button
    {
    public:
        ButtonNoSel(void) {
            this->InitializeComponent();
            this->SetStyle(ControlStyles::Selectable, false);
        }

    private:
        void InitializeComponent(void) {
            this->UseVisualStyleBackColor = true;
        }

    protected:
        ~ButtonNoSel() { }
    };
}

Обратите внимание, что эта форма должна работать в отдельном потоке.
Если вам нужно показать эту форму из другой, используйте Task.Run(), чтобы отобразить ее как диалоговое окно, вызвав ShowDialog(). Это запустит цикл сообщений.

Например, из обработчика Button.Click другой формы (здесь с именем MainForm).

private: 
    void ShowKeyboard() {
        frmKeyBoard^ fk = gcnew frmKeyBoard();
        fk->ShowDialog();
        delete fk;
    }

private: 
    System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
        Task::Run(gcnew Action(this, &MainForm::ShowKeyboard));
    }

Другие вопросы по теме