1using System; 2using System.Drawing; 3using System.Threading; 4using System.Windows.Forms; 5 6namespace WindowCapture.App 7{ 8 /// <summary>Hosts a single panel form (Soundpad / Search) as a standalone app: keeps a tray 9 /// icon so the window can be re-shown after it slides away, surfaces on a re-launch "show" 10 /// signal, and exits when the form is actually closed or the user picks Exit.</summary> 11 public class FormHostApp : ApplicationContext 12 { 13 private readonly Form form; 14 private readonly AppMode mode; 15 private NotifyIcon tray; 16 private EventWaitHandle showEvent; 17 private Thread showListener; 18 private volatile bool stopping; 19 20 public FormHostApp(AppMode mode, Form form) 21 { 22 this.mode = mode; 23 this.form = form; 24 25 form.FormClosed += delegate { ExitThread(); }; 26 27 var menu = new ContextMenuStrip(); 28 menu.Items.Add("Показать", null, delegate { Surface(); }); 29 menu.Items.Add("Настройки", null, delegate { try { using (var d = new WindowCapture.UI.SettingsDialog()) d.ShowDialog(); } catch { } }); 30 menu.Items.Add("-"); 31 menu.Items.Add("Выход", null, delegate { ExitThread(); }); 32 33 tray = new NotifyIcon 34 { 35 Icon = AppModes.CreateDiscIcon(AppModes.Accent(mode)), 36 Text = "WindowCapture — " + AppModes.Title(mode), 37 Visible = true, 38 ContextMenuStrip = menu 39 }; 40 tray.MouseClick += delegate(object s, MouseEventArgs e) { if (e.Button == MouseButtons.Left) Surface(); }; 41 42 form.Show(); 43 44 bool created; 45 showEvent = new EventWaitHandle(false, EventResetMode.AutoReset, AppModes.ShowEventName(mode), out created); 46 showListener = new Thread(delegate () 47 { 48 while (!stopping) 49 { 50 try { if (showEvent.WaitOne(500) && !stopping && !form.IsDisposed) form.BeginInvoke(new Action(Surface)); } 51 catch { } 52 } 53 }) { IsBackground = true }; 54 showListener.Start(); 55 } 56 57 private void Surface() 58 { 59 if (form == null || form.IsDisposed) return; 60 try 61 { 62 if (!form.Visible) form.Show(); 63 if (form.WindowState == FormWindowState.Minimized) form.WindowState = FormWindowState.Normal; 64 form.Activate(); 65 } 66 catch { } 67 } 68 69 protected override void Dispose(bool disposing) 70 { 71 if (disposing) 72 { 73 stopping = true; 74 try { if (showEvent != null) showEvent.Set(); } catch { } 75 if (tray != null) { tray.Visible = false; tray.Dispose(); } 76 } 77 base.Dispose(disposing); 78 } 79 } 80}