Пользовательский фильтр сообщений для приложения SmartDevice

StackOverflow https://stackoverflow.com/questions/2543591

Вопрос

С тех пор как Компактный Каркас звонки 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().

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top