Мой вопрос: как я могу держать свою форму всегда наверху (я могу сделать это, настроив TopMost = true
), не отвлекая внимание от окна, активного в данный момент, когда моя форма взаимодействует с ней.
Взгляните на изображения, чтобы лучше понять мой вопрос: форма находится сверху, и когда я фокусируюсь на любом другом элементе управления вводом за пределами моей формы, я могу отправить на него выбранный эмодзи.
1: Изображение, которое я хочу видеть в поле ввода в FireFox, когда я нажимаю кнопку Emoji в своей форме.
2: Изображение моей формы: как только я нажимаю кнопку в своей форме, фокус возвращается к этой форме.
FormBorderStyle = none
. Сделайте его TopMost (эта настройка - отдельная тема, я не буду обсуждать ее здесь).ButtonNoSel
, показанный ниже) и установите для их свойства Tag
символ Unicode, соответствующий изображению Emoji, которое показывают эти кнопки.Эти кнопки при нажатии просто используют 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));
}