2010-03-30 49 views

回答

1
  • 您是否尝试捕获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. 
}
1

替换Application类中的消息循环并不实际。那么还有更多的模板Windows消息循环正在进行。无论如何,它并不是真正的问题,Application类通过调用ShowWindow()强制窗体变得可见。这是必要的,因为表单被懒惰地初始化,没有ShowWindow()调用它永远不会创建本地Window句柄。

这个问题很容易通过重写SetVisibleCore()在常规的.NET framework版本来解决:

protected override void SetVisibleCore(bool value) { 
    if (!this.IsHandleCreated) { 
    this.CreateHandle(); 
    value = false; // Prevent becoming visible the first time 
    } 
    base.SetVisibleCore(value); 
} 

但我不认为在CF.这可要找到解决方案,您需要准确解释为什么要阻止显示UI。没有任何创建的窗口句柄,一个应用程序通常是作为一个门槛死亡。这可能就像延迟Application.Run()调用一样简单。

+0

这不是小事,但我会不同意,它是不实际的。自卫队这样做,并做得很好。有很多情况下,它是有用的 - 一样,如果你真的想支持IMessageFilters,或者类似这样的用户,实际控制启动形式的知名度。 – ctacke 2010-03-30 15:43:11

2

我发现这是一个比你预计的Windows窗体应用程序更大的问题。对于我的解决方案,我从三个不同的网站获得了建议,并发现此解决方案运行良好。为了我的需要,我有一个Windows服务在系统托盘中有一个UI控制器组件。只需使用托盘图标和图标的上下文菜单即可启动UI。 UI在激活时作为模态对话框运行,允许用户在后台线程上启动长时间运行的进程,一旦启动UI需要恢复用户的响应。

在构造函数中的Windows窗体类我设置了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需要被启用,以允许用户四处移动对话框在屏幕上但不能改变它的大小,来禁止形式的右上角形式关闭按钮,红色的X,我用:

// 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; 
    } 
} 

在静态Main方法在应用程序运行主程序启动时,我改变了def行凶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窗体项目属性页面并选择应用程序选项卡。在启动对象,选择程序类作为启动对象。

您将需要一个按钮或菜单控件添加到您的对话框,可以关闭窗体而不终止应用程序,设置按钮或菜单控制隐藏应用程序,把它留在系统托盘中运行。

相关问题