From e532e26b5411268d41f7e0129fedb79277644be1 Mon Sep 17 00:00:00 2001 From: jasonchenwork Date: Thu, 17 Jul 2025 18:08:22 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AA=BF=E6=95=B4=20=E9=96=8B=E9=97=9C?= =?UTF-8?q?=E5=8F=B0=E6=B5=81=E7=A8=8B=2020250717?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DBObj/SongData.cs | 7 +-- DBObj/SongList.cs | 21 +++++-- OverlayFormObj/OverlayForm.cs | 14 +---- PrimaryFormParts/PrimaryForm.cs | 19 +------ Program.cs | 98 +++++++++------------------------ Room.cs | 60 ++++++++++++++++++++ TCPServer.cs | 66 +++------------------- VideoPlayerForm.cs | 8 +-- 8 files changed, 121 insertions(+), 172 deletions(-) create mode 100644 Room.cs diff --git a/DBObj/SongData.cs b/DBObj/SongData.cs index 4c0983d..d879f66 100644 --- a/DBObj/SongData.cs +++ b/DBObj/SongData.cs @@ -35,11 +35,10 @@ namespace DBObj public string getArtist_B() { return B.getName();} public int getNameLength() { return basic.getName().Length; } public string getFileName() {return basic.getFileName();} - public string next_artist_text() + public string next_song_text() { - return B!=null - ? String.Format("下一首:{0} {1} {2}", A.getName(false), B.getName(false), basic.getName(false)) - : String.Format("下一首:{0} {1}", A.getName(false), basic.getName(false)); + var str = (state == PlayState.InsertPlayback) ? GetStateTxt(false) : ""; + return String.Format("下一首:{0} {1}", basic.getName(false),str); } public string artist_text() { diff --git a/DBObj/SongList.cs b/DBObj/SongList.cs index 6cdb857..96f6e4a 100644 --- a/DBObj/SongList.cs +++ b/DBObj/SongList.cs @@ -6,7 +6,8 @@ namespace DBObj { public class SongList { - public static SongData welcome ; + private static bool isWelcome = true; + public static SongData welcome; public static SongData close ; private static SongData publicPlaying=null; private static List publicSong = new(); @@ -43,9 +44,17 @@ namespace DBObj } private static SongData NextPublicSong() { - publicPlaying = publicSong[0]; - publicSong.RemoveAt(0); - publicSong.Add(publicPlaying); + if (Room.IsClose()) { + publicPlaying = close; + } else if(Room.IsOpen() && isWelcome){ + isWelcome = false; + publicPlaying = welcome; + } else { + publicPlaying = publicSong[0]; + publicSong.RemoveAt(0); + publicSong.Add(publicPlaying); + } + return publicPlaying; } @@ -85,11 +94,13 @@ namespace DBObj public static void UpdateNextSongLabel() { VideoPlayerForm.overlayForm.UpdateTopLeftLabel( - (not_played.Count > 0) ? not_played[0].getName() : "目前沒有下一首,請踴躍點歌!!!" + (not_played.Count > 0) ? not_played[0].next_song_text() : "目前沒有下一首,請踴躍點歌!!!" ); } public static void clearSong() { + + isWelcome = true; not_played.Clear(); played.Clear(); } diff --git a/OverlayFormObj/OverlayForm.cs b/OverlayFormObj/OverlayForm.cs index 36a2f48..d0e3b52 100644 --- a/OverlayFormObj/OverlayForm.cs +++ b/OverlayFormObj/OverlayForm.cs @@ -527,19 +527,7 @@ namespace OverlayFormObj } } - public void ResetMarqueeTextToWelcomeMessage() - { - try - { - string filePath = Path.Combine(Application.StartupPath,"txt","WelcomeMessage.txt"); - string welcomeMessage = File.ReadAllText(filePath); - this.UpdateMarqueeText(welcomeMessage, MarqueeStartPosition.Right, Color.White); - } - catch (Exception ex) - { - Console.WriteLine("Error reading marquee text from file: " + ex.Message); - } - } + protected override void OnPaint(PaintEventArgs e) { diff --git a/PrimaryFormParts/PrimaryForm.cs b/PrimaryFormParts/PrimaryForm.cs index 06dbea3..1d0c7a9 100644 --- a/PrimaryFormParts/PrimaryForm.cs +++ b/PrimaryFormParts/PrimaryForm.cs @@ -222,23 +222,6 @@ namespace DualScreenDemo this.Load += PrimaryForm_Load; } - public bool IsAppResponsive() - { - try - { - var form = this; - if (form != null) - { - bool dummy = form.InvokeRequired; // 如果 Invoke 卡死,會丟錯 - return true; - } - } - catch - { - return false; - } - return true; - } // 添加 DPI 感知支持 [DllImport("user32.dll")] @@ -2265,7 +2248,7 @@ namespace DualScreenDemo { HotPlayButton_Click(null, EventArgs.Empty); } - if (Program.RoomState.Equals("CLOSE")) + if (Room.IsClose()) { ShowSendOffScreen(); } diff --git a/Program.cs b/Program.cs index d4ace41..41393cf 100644 --- a/Program.cs +++ b/Program.cs @@ -1,30 +1,30 @@ using System.IO; using Microsoft.Win32; using System.Diagnostics; -using DBObj; using HeartbeatSender; namespace DualScreenDemo { public static class Program { // 定义全局变量 - internal static SongListManager songListManager; + internal static DBObj.SongListManager songListManager; //internal static ArtistManager artistManager; internal static SerialPortManager serialPortManager; private static PrimaryForm primaryForm; // 儲存實例的參考 - public static string RoomState = Utils.Env.Get("RoomStates", "CLOSE"); - public static DataCheck.PublicSongChecker cherker; + public static Room room = new Room(); + [STAThread] - static void Main() { - Console.WriteLine("Server V.1.2.1 202507171314"); - if(Utils.Env.GetBool("IsCursor", true))Cursor.Hide(); + static void Main() + { + Console.WriteLine("Server V.1.2.2 202507171805"); + if (Utils.Env.GetBool("IsCursor", true)) Cursor.Hide(); AppDomain.CurrentDomain.ProcessExit += (s, e) => Cursor.Show(); //Console.WriteLine("正在與中控取得聯繫..."); var sender = new heartbeatSender(); - cherker =new DataCheck.PublicSongChecker(DBObj.SongList.PublicSong()); - - try { + var cherker=new DataCheck.PublicSongChecker(DBObj.SongList.PublicSong()); + try + { // COM 初始化 int hr = ComInterop.CoInitializeEx(IntPtr.Zero, ComInterop.COINIT_APARTMENTTHREADED); if (hr < 0) @@ -34,7 +34,7 @@ namespace DualScreenDemo } // 初始化管理器 - songListManager = new SongListManager(); // 使用单例 + songListManager = new DBObj.SongListManager(); // 使用单例 //artistManager = new ArtistManager(); var commandHandler = new CommandHandler(songListManager); @@ -49,7 +49,7 @@ namespace DualScreenDemo } // 啟動服務器 - var TCP = new TCPServer(); + Task.Run(() => HttpServerManager.StartServer()); // 註冊事件 @@ -63,11 +63,14 @@ namespace DualScreenDemo primaryForm.Size = new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); // 在完整初始化後檢查狀態 - if (Screen.AllScreens.Length > 1) { + if (Screen.AllScreens.Length > 1) + { var secondaryScreen = Screen.AllScreens.FirstOrDefault(s => !s.Primary); - if (secondaryScreen != null) { + if (secondaryScreen != null) + { // 确保 primaryForm 和 videoPlayerForm 已经正确初始化 - if (primaryForm.videoPlayerForm == null) { + if (primaryForm.videoPlayerForm == null) + { primaryForm.videoPlayerForm = new VideoPlayerForm(); } @@ -85,45 +88,19 @@ namespace DualScreenDemo } primaryForm.Show(); Application.Run(primaryForm); - - - } catch (Exception ex) { - WriteLog(ex.ToString()); - //} finally { - //SystemEvents.DisplaySettingsChanged -= OnDisplaySettingsChanged; - } - } - -/* - private static bool IsUrlAclExists(string url) - { - try - { - ProcessStartInfo startInfo = new ProcessStartInfo - { - FileName = "netsh", - Arguments = "http show urlacl", - RedirectStandardOutput = true, - UseShellExecute = false, - CreateNoWindow = true - }; - - using (Process process = Process.Start(startInfo)) - { - using (StreamReader reader = process.StandardOutput) - { - string output = reader.ReadToEnd(); - return output.Contains(url); // 检查是否包含指定 URL - } - } + + var TCP = new TCPServer(); } catch (Exception ex) { - Console.WriteLine("检查 URL ACL 时出错: " + ex.Message); - return false; + WriteLog(ex.ToString()); + //} finally { + //SystemEvents.DisplaySettingsChanged -= OnDisplaySettingsChanged; } } -*/ + + + private static void OnDisplaySettingsChanged(object sender, EventArgs e) { // UI操作應該放在try-catch塊中 @@ -182,27 +159,6 @@ namespace DualScreenDemo Console.WriteLine(String.Format("Error writing to log file: {0}", ex.Message)); } } -/* - private static Form CreatePrimaryForm() - { - return new Form - { - WindowState = FormWindowState.Maximized, - FormBorderStyle = FormBorderStyle.None - }; - } - - private static Form CreateSecondaryForm(Screen screen) - { - return new Form - { - Text = "Secondary Screen Form", - StartPosition = FormStartPosition.Manual, - Bounds = screen.Bounds, - WindowState = FormWindowState.Maximized, - FormBorderStyle = FormBorderStyle.None - }; - } -*/ + } } \ No newline at end of file diff --git a/Room.cs b/Room.cs new file mode 100644 index 0000000..550ba2c --- /dev/null +++ b/Room.cs @@ -0,0 +1,60 @@ +using OverlayFormObj; + +namespace DualScreenDemo +{ + public class Room + { + private static string State=Utils.Env.Get("RoomStates", "CLOSE"); + public Room(){} + public static void set(string value) + { + string marqueeMessage = "歡迎使用超級巨星歡唱,與你共度美好時光。"; + Color c = Color.White; + State = value; + if (value.Equals("PAUSE")) + { + PrimaryForm.Instance.ShowSendOffScreen(); + VideoPlayerForm.Instance.Pause(); + marqueeMessage = "發生火災,請跟隨引導至逃生出口!!!"; + c = Color.Red; + } + else if (value.Equals("OPEN")) + { + DBObj.SongList.clearSong(); + PrimaryForm.Instance.HotPlayButton_Click(null, EventArgs.Empty); + PrimaryForm.Instance.HideSendOffScreen(); + } + else + { + DBObj.SongList.clearSong(); + PrimaryForm.Instance.pictureBoxQRCode.Visible = false; + PrimaryForm.Instance.closeQRCodeButton.Visible = false; + PrimaryForm.Instance.ShowSendOffScreen(); + + + OverlayForm.MainForm.topLeftLabel.Visible = false; + + VideoPlayerForm.Instance.PlayNextSong(); + PrimaryForm.Instance.logout(); + + } + + OverlayForm.MainForm.UpdateMarqueeText(marqueeMessage, OverlayForm.MarqueeStartPosition.Middle, c); + + } + public static bool IsClose() + { + return State.Equals("CLOSE"); + } + public static bool IsOpen() + { + return State.Equals("OPEN"); + } + + } + + + + + +} \ No newline at end of file diff --git a/TCPServer.cs b/TCPServer.cs index adf021b..fb24c9d 100644 --- a/TCPServer.cs +++ b/TCPServer.cs @@ -5,7 +5,6 @@ using System.Text.RegularExpressions; using System.IO; // 為 Path 和 File 提供支持 using DBObj; using OverlayFormObj; -using HeartbeatSender; namespace DualScreenDemo { public class TCPServer @@ -123,50 +122,17 @@ namespace DualScreenDemo if (command.Trim().Equals("X", StringComparison.OrdinalIgnoreCase)) { - PrimaryForm.Instance.pictureBoxQRCode.Visible = false; - PrimaryForm.Instance.closeQRCodeButton.Visible = false; _ = SafeInvoke(VideoPlayerForm.Instance, async () => { - if (IsFormReady(PrimaryForm.Instance)) - { - await SafeInvoke(PrimaryForm.Instance, async () => - { - PrimaryForm.Instance.ShowSendOffScreen(); - Console.WriteLine("開始設置新的播放列表"); - - - string closePath = @"D:\video\CLOSE.MPG"; - if (File.Exists(closePath)) - { - SongData closeSong = new SongData("0", "結束播放",closePath, 1,true); - SongList.clearSong(); - SongList.Add(closeSong); - - if (IsFormReady(OverlayForm.MainForm)) - OverlayForm.MainForm.topLeftLabel.Visible = false; - - VideoPlayerForm.Instance.PlayNextSong(); - PrimaryForm.Instance.logout(); - Console.WriteLine("已設置新的播放列表,包含當前歌曲和 CLOSE.MPG"); - try - { - await HttpServer.RestartServer(); - } - catch (Exception ex) - { - Console.WriteLine("RestartServer 發生錯誤: " + ex.Message); - } - } - else - { - Console.WriteLine($"錯誤: 找不到檔案 {closePath}"); - } - OverlayForm.Instance.ResetMarqueeTextToWelcomeMessage(); - }); + Room.set("CLOSE"); + try{ + await HttpServer.RestartServer(); + } catch (Exception ex) { + Console.WriteLine("RestartServer 發生錯誤: " + ex.Message); } }); - - Program.RoomState = "CLOSE"; + + byte[] okResponse = Encoding.UTF8.GetBytes("OK\n"); stream.Write(okResponse, 0, okResponse.Length); @@ -176,14 +142,7 @@ namespace DualScreenDemo if (command.Trim().Equals("O", StringComparison.OrdinalIgnoreCase)) { // 開台時跳至首頁 - - SongList.clearSong(); - PrimaryForm.Instance.HotPlayButton_Click(null, EventArgs.Empty); - Program.RoomState = "OPEN"; - PrimaryForm.Instance.HideSendOffScreen(); - - OverlayForm.Instance.ResetMarqueeTextToWelcomeMessage(); - + Room.set("OPEN"); byte[] okResponse = Encoding.UTF8.GetBytes("OK\n"); stream.Write(okResponse, 0, okResponse.Length); continue; @@ -192,17 +151,10 @@ namespace DualScreenDemo { _ = SafeInvoke(PrimaryForm.Instance, () => { - PrimaryForm.Instance.ShowSendOffScreen(); - VideoPlayerForm.Instance.Pause(); - string marqueeMessage = "發生火災,請跟隨引導至逃生出口!!!"; - OverlayForm.MainForm.UpdateMarqueeText(marqueeMessage, OverlayForm.MarqueeStartPosition.Middle, Color.Red); + Room.set("PAUSE"); }); - - // 更新狀態檔案(可選,若你要記錄狀態) - Program.RoomState = "PAUSE"; byte[] okResponse = Encoding.UTF8.GetBytes("OK\n"); stream.Write(okResponse, 0, okResponse.Length); - continue; } diff --git a/VideoPlayerForm.cs b/VideoPlayerForm.cs index 6f354f3..41cd909 100644 --- a/VideoPlayerForm.cs +++ b/VideoPlayerForm.cs @@ -623,8 +623,8 @@ namespace DualScreenDemo if (videoWindowSecondary != null) videoWindowSecondary.put_Visible(OABool.False); // 清理並初始化 DirectShow 圖表 - RemoveAllFilters(graphBuilderPrimary); - RemoveAllFilters(graphBuilderSecondary); + //RemoveAllFilters(graphBuilderPrimary); + //RemoveAllFilters(graphBuilderSecondary); InitializeGraphBuilderPrimary(); InitializeGraphBuilderSecondary(); @@ -667,8 +667,8 @@ namespace DualScreenDemo if (videoWindowSecondary != null) videoWindowSecondary.put_Visible(OABool.False); // 隐藏副屏幕窗口,避免闪烁 // 清理并初始化 DirectShow 图表 - RemoveAllFilters(graphBuilderPrimary); - RemoveAllFilters(graphBuilderSecondary); + //RemoveAllFilters(graphBuilderPrimary); + //RemoveAllFilters(graphBuilderSecondary); InitializeGraphBuilderPrimary(); InitializeGraphBuilderSecondary();