Пользовательский фильтр сообщений для приложения SmartDevice
-
23-09-2019 - |
Вопрос
С тех пор как Компактный Каркас звонки Show()
в форме, переданной Application.Run()
, я решил создать свой собственный насос сообщений.
Я понятия не имею, как я могу это сделать.
Любая помощь (например, простой пример) будет оценена по достоинству.
Решение
- Вы пытались поймать
VisibleChanged
событие?
this.Shown += new EventHandler(Form1_Shown);
void Form1_Shown(object sender, EventArgs e)
{
this.Hide();
}
- Вы также можете попытаться перехватить сообщение, переопределив
WndProc
.
protected override void WndProc(ref Message m) { const int SW_SHOW = 5; if (m.Msg == SW_SHOW) { //DoSomething(); } base.WndProc(ref m); }
- Типичная перекачка сообщений выглядит следующим образом:
MSG msg; while(GetMessage(&msg, hwnd, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); // DoSomething. }
- Возможно, вам также захочется прочитать о
Application.DoEvents()
способ.
Другие советы
Я обнаружил, что это более серьезная проблема, чем вы могли бы ожидать для приложения Windows form.Для своего решения я извлек предложения с трех разных веб-сайтов и обнаружил, что это решение работает очень хорошо.Для моих нужд у меня есть служба Windows, которая имеет компонент контроллера пользовательского интерфейса в системном трее.Пользовательский интерфейс должен запускаться в свернутом виде с помощью только значка в трее и контекстного меню для значка.Пользовательский интерфейс работает как модальный диалог при активации, позволяя пользователю запускать длительный процесс в фоновом потоке, после запуска пользовательский интерфейс должен возобновить прием ответов от пользователя.
В конструкторе для класса Windows Form я устанавливаю ControlBox
включение и отключение кнопок сворачивания и разворачивания:
public SystemTrayApp()
{
InitializeComponent();
this.Visible = false;
// Hide Maximize and Minimize buttons on form
this.StartPosition = FormStartPosition.CenterScreen;
this.MaximizeBox = false;
this.MinimizeBox = false;
}
В ControlBox
должен быть включен, чтобы разрешить пользователю перемещать диалоговое окно по экрану, но не изменять его размер, чтобы отключить кнопку закрытия формы, красный крест в правом верхнем углу формы, я использовал:
// Force form close button to be disabled
private const int CP_NOCLOSE_BUTTON = 0x200;
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ClassStyle = cp.ClassStyle | CP_NOCLOSE_BUTTON;
return cp;
}
}
В основной программе, где статический основной метод выполняется при запуске приложения, я изменил значение по умолчанию Application.Run
Для:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
SystemTrayApp systemTrayApp = new SystemTrayApp();
systemTrayApp.Text = "File Copy Service Controller";
// Show the instance of the form modally.
systemTrayApp.ShowInTaskbar = true;
systemTrayApp.ShowDialog();
Application.Run();
}
}
Теперь покажите страницу дизайна для формы Windows, щелкните правой кнопкой мыши форму и выберите свойства, затем нажмите кнопку события, чтобы отобразить все события для формы.Прокрутите вниз до Показанного события и дважды щелкните, новый обработчик события будет добавлен в ваш исходный код.Перейдите к методу и добавьте this.Hide()
к обработчику:
// Runs the first time the application starts
private void SystemTrayApp_Shown(object sender, EventArgs e)
{
this.Hide();
}
Наконец, откройте страницу свойств проекта Windows Form и выберите вкладку Application.В разделе Startup object выберите класс Program в качестве startup object.
Вам нужно будет добавить кнопку или элемент управления меню в свой диалог, чтобы разрешить закрытие формы без завершения работы приложения, установите кнопку или элемент управления меню так, чтобы скрыть приложение, оставив его запущенным в системном трее.
Замена цикла сообщений в классе Application непрактична.Происходит гораздо больше, чем шаблонный цикл сообщений Windows.В любом случае, это не настоящая проблема, класс Application заставляет форму становиться видимой с помощью вызова ShowWindow().Это необходимо, потому что формы инициализируются лениво, без вызова ShowWindow() он никогда не создает собственный дескриптор окна.
Эту проблему легко исправить в обычной версии .NET framework, переопределив SetVisibleCore():
protected override void SetVisibleCore(bool value) {
if (!this.IsHandleCreated) {
this.CreateHandle();
value = false; // Prevent becoming visible the first time
}
base.SetVisibleCore(value);
}
Но я не думаю, что это доступно в CF.Чтобы найти решение, вам нужно будет точно объяснить почему вы хотите запретить отображение пользовательского интерфейса.Без какого-либо созданного дескриптора окна приложение обычно мертво, как дверной гвоздь.Это может быть так же просто, как отложить вызов Application.Run().