diff --git a/PrimaryFormParts/SongSearch/PrimaryForm.SongSearch.BopomofoSearch.cs b/PrimaryFormParts/SongSearch/PrimaryForm.SongSearch.BopomofoSearch.cs index dcae270..12d459c 100644 --- a/PrimaryFormParts/SongSearch/PrimaryForm.SongSearch.BopomofoSearch.cs +++ b/PrimaryFormParts/SongSearch/PrimaryForm.SongSearch.BopomofoSearch.cs @@ -13,16 +13,22 @@ namespace DualScreenDemo { public partial class PrimaryForm { + // 注音歌曲的 PictureBox private PictureBox pictureBoxZhuYinSongs; - + //存放注音按鈕的陣列 private Button[] phoneticButtonsForSongs; + //特殊功能按鈕(修改、清除、關閉) private Button modifyButtonZhuYinSongs; private Button clearButtonZhuYinSongs; private Button closeButtonZhuYinSongs; + //用於顯示輸入文字的輸入框 private RichTextBox inputBoxZhuYinSongs; - + /// + /// 注音歌曲搜尋按鈕點擊事件 + /// private void ZhuyinSearchSongsButton_Click(object sender, EventArgs e) { + //更新搜尋模式按鈕的背景圖 zhuyinSearchSongButton.BackgroundImage = zhuyinSearchSongActiveBackground; englishSearchSongButton.BackgroundImage = englishSearchSongNormalBackground; pinyinSearchSongButton.BackgroundImage = pinyinSearchSongNormalBackground; @@ -30,199 +36,318 @@ namespace DualScreenDemo handWritingSearchSongButton.BackgroundImage = handWritingSearchSongNormalBackground; numberSearchSongButton.BackgroundImage = numberSearchSongNormalBackground; - + // 讀取 config.ini 並獲取注音圖片的路徑 var configData = LoadConfigData(); - /* 抓注音圖檔(ZhuYinSongs) 來自configData的資料 */ - /* 要確認路經需確認configData內容值 */ string imagePath = Path.Combine(Application.StartupPath, configData["ImagePaths"]["ZhuYinSongs"]); - + //顯示注音歌曲圖片 ShowImageOnPictureBoxZhuYinSongs(Path.Combine(Application.StartupPath, imagePath)); - - SetZhuYinSingersAndButtonsVisibility(false); + //設定不同模式的UI顯示 + //SetZhuYinSingersAndButtonsVisibility(false); SetEnglishSingersAndButtonsVisibility(false); SetPinYinSingersAndButtonsVisibility(false); SetHandWritingForSingersAndButtonsVisibility(false); SetZhuYinSongsAndButtonsVisibility(true); pictureBoxZhuYinSongs.Visible = true; } - /* 初始化拼音按鈕 */ + /// + /// 初始化注音按鈕 (Phonetic Buttons) 並載入其對應的圖片與座標 + /// 1. 讀取 config.ini 設定檔,獲取按鈕的相關數據 (符號、座標、圖片) + /// 2. 解析注音符號並儲存至 phoneticSymbols 陣列 + /// 3. 解析按鈕的座標資訊,存入 phoneticButtonCoords + /// 4. 解析按鈕的圖片 (正常狀態、按下狀態、懸停狀態),存入 phoneticButtonImages。 + /// 5. 依序建立 35 個注音按鈕,並套用對應的圖片與事件處理函數。 + /// private void InitializePhoneticButtonsForSongs() { + // 1. 從設定檔 (config.ini) 讀取配置數據,包含按鈕座標、圖片等 var data = LoadConfigData(); + // 2. 讀取注音符號列表,這些符號將用於顯示在按鈕上 phoneticSymbols = LoadPhoneticSymbols(data); + + // 3. 從設定檔載入 **注音按鈕的座標**,每個按鈕都有對應的 (X, Y, Width, Height) phoneticButtonCoords = LoadButtonCoordinates(data, "PhoneticButtonCoordinates", 35); + + // 4. 從設定檔載入 **注音按鈕的圖片**,每個按鈕都有正常、按下、懸停三種狀態 phoneticButtonImages = LoadButtonImages(data, "PhoneticButtonImages", 35); + // 5. 建立 35 個注音按鈕的陣列 (每個按鈕對應一個注音符號) phoneticButtonsForSongs = new Button[35]; + + // 6. 迴圈建立所有的注音按鈕 for (int i = 0; i < 35; i++) { + // 取得當前按鈕的圖片 (從已載入的 phoneticButtonImages 字典中獲取) var buttonImages = phoneticButtonImages[$"button{i}"]; - CreatePhoneticButtonForSongs(i, buttonImages.normal, buttonImages.mouseDown, buttonImages.mouseOver); + + // 建立單個注音按鈕,並設定其圖片與點擊事件 + CreatePhoneticButtonForSongs( + i, // 按鈕索引 (對應於 phoneticSymbols) + buttonImages.normal, // 按鈕的普通狀態圖片 + buttonImages.mouseDown, // 按下時的圖片 + buttonImages.mouseOver // 滑鼠懸停時的圖片 + ); } } - /* 按鈕設置顯示方式 可參考按鈕事件寫法 */ + + + /// + /// 建立單個注音按鈕,並設定其圖片、大小、位置,以及滑鼠事件。 + /// + /// 按鈕索引 (對應於 phoneticSymbols) + /// 按鈕的普通狀態圖片路徑 + /// 按鈕被按下時的圖片路徑 + /// 滑鼠懸停時的圖片路徑 private void CreatePhoneticButtonForSongs(int index, string normalImagePath, string mouseDownImagePath, string mouseOverImagePath) { try { - - + // 1. 創建按鈕並初始化屬性 phoneticButtonsForSongs[index] = new Button { - Name = $"phoneticButton_{phoneticSymbols[index]}", - BackgroundImage = Image.FromFile(Path.Combine(Application.StartupPath, normalImagePath)), - BackgroundImageLayout = ImageLayout.Stretch, - FlatStyle = FlatStyle.Flat, - FlatAppearance = { BorderSize = 0 } + Name = $"phoneticButton_{phoneticSymbols[index]}", // 設定按鈕名稱,方便識別 + BackgroundImage = Image.FromFile(Path.Combine(Application.StartupPath, normalImagePath)), // 設定預設背景圖 + BackgroundImageLayout = ImageLayout.Stretch, // 背景圖自動填滿按鈕 + FlatStyle = FlatStyle.Flat, // 設定按鈕為扁平樣式 + FlatAppearance = { BorderSize = 0 } // 移除按鈕的邊框 }; - ResizeAndPositionButton(phoneticButtonsForSongs[index], phoneticButtonCoords[index].X, phoneticButtonCoords[index].Y, - phoneticButtonCoords[index].Width, phoneticButtonCoords[index].Height); + // 2. 設定按鈕的大小與位置 + ResizeAndPositionButton( + phoneticButtonsForSongs[index], + phoneticButtonCoords[index].X, + phoneticButtonCoords[index].Y, + phoneticButtonCoords[index].Width, + phoneticButtonCoords[index].Height + ); + // 3. 載入三種狀態的圖片 Image normalImage = Image.FromFile(Path.Combine(Application.StartupPath, normalImagePath)); Image mouseDownImage = Image.FromFile(Path.Combine(Application.StartupPath, mouseDownImagePath)); Image mouseOverImage = Image.FromFile(Path.Combine(Application.StartupPath, mouseOverImagePath)); + // 4. 設定滑鼠事件,改變背景圖 phoneticButtonsForSongs[index].MouseDown += (s, e) => phoneticButtonsForSongs[index].BackgroundImage = mouseDownImage; phoneticButtonsForSongs[index].MouseUp += (s, e) => phoneticButtonsForSongs[index].BackgroundImage = normalImage; phoneticButtonsForSongs[index].MouseEnter += (s, e) => phoneticButtonsForSongs[index].BackgroundImage = mouseOverImage; phoneticButtonsForSongs[index].MouseLeave += (s, e) => phoneticButtonsForSongs[index].BackgroundImage = normalImage; + + // 5. 設定按鈕的點擊事件 (當按下按鈕時,觸發 PhoneticButton_Click) phoneticButtonsForSongs[index].Click += PhoneticButton_Click; + + // 6. 存入對應的注音符號,方便之後的處理 phoneticButtonsForSongs[index].Tag = phoneticSymbols[index]; + // 7. 將按鈕加入視窗 this.Controls.Add(phoneticButtonsForSongs[index]); - - } catch (Exception ex) { + // 例外處理,確保按鈕建立失敗時不影響其他部分 Console.WriteLine($"Error creating button at index {index}: {ex.Message}"); } } + + /// + /// 初始化注音輸入界面的所有按鈕和輸入框。 + /// private void InitializeButtonsForZhuYinSongs() { + // 1. 從設定檔 (config.ini) 載入注音符號 LoadPhoneticSymbolsFromConfig(); + + // 2. 初始化 35 個注音按鈕 InitializePhoneticButtonsForSongs(); + + // 3. 初始化特殊按鈕 (例如:刪除、確定、返回按鈕) InitializeSpecialButtonsForZhuYinSongs(); + + // 4. 初始化輸入框 (用於顯示使用者輸入的注音符號) InitializeInputBoxZhuYinSongs(); } + + /// + /// 初始化注音輸入界面的特殊按鈕,包括「修改」、「清除」和「關閉」。 + /// private void InitializeSpecialButtonsForZhuYinSongs() { - + // 1. 初始化「修改」按鈕 (刪除上一個輸入的注音符號) InitializeModifyButtonZhuYinSongs(); - + // 2. 初始化「清除」按鈕 (清空所有輸入內容) InitializeClearButtonZhuYinSongs(); - + // 3. 初始化「關閉」按鈕 (關閉注音輸入介面) InitializeCloseButtonZhuYinSongs(); } + + /// + /// 初始化「修改」按鈕,讓使用者可以刪除上一個輸入的注音符號。 + /// private void InitializeModifyButtonZhuYinSongs() { + // 1. 讀取設定檔 (config.ini) 來獲取特殊按鈕的座標與圖像資訊 var data = LoadConfigData(); + + // 2. 從設定檔讀取「修改」按鈕的座標數據 modifyButtonZhuYinCoords = LoadSpecialButtonCoordinates(data, "SpecialButtonCoordinates", "modifyButtonZhuYinSongs"); + + // 3. 從設定檔讀取「修改」按鈕的圖像 (Normal、MouseOver、MouseDown) var buttonImages = LoadButtonImages(data, "ModifyButtonImagesZhuYin"); + // 4. 使用座標與圖像來建立「修改」按鈕,並綁定點擊事件 modifyButtonZhuYinSongs = CreateSpecialButton( - "btnModifyZhuYinSongs", - modifyButtonZhuYinCoords, - buttonImages.normal, - buttonImages.mouseOver, - buttonImages.mouseDown, - ModifyButtonZhuYinSongs_Click + "btnModifyZhuYinSongs", // 按鈕名稱 + modifyButtonZhuYinCoords, // 按鈕座標 + buttonImages.normal, // 預設 (normal) 圖像 + buttonImages.mouseOver, // 滑鼠移過 (hover) 圖像 + buttonImages.mouseDown, // 按下 (pressed) 圖像 + ModifyButtonZhuYinSongs_Click // 綁定按鈕點擊事件 ); } + + /// + /// 「修改」按鈕的點擊事件,刪除輸入框內的最後一個注音符號。 + /// private void ModifyButtonZhuYinSongs_Click(object sender, EventArgs e) { - + // 1. 確保輸入框 (inputBoxZhuYinSongs) 存在於目前的視窗控制項中 if (this.Controls.Contains(inputBoxZhuYinSongs) && inputBoxZhuYinSongs.Text.Length > 0) { + // 2. 刪除輸入框中的最後一個字元 (即移除最後一個注音符號) inputBoxZhuYinSongs.Text = inputBoxZhuYinSongs.Text.Substring(0, inputBoxZhuYinSongs.Text.Length - 1); } } + /// + /// 初始化「清除」按鈕,並從設定檔載入其位置與圖片資源。 + /// private void InitializeClearButtonZhuYinSongs() { + // 1. 從設定檔 (config.ini) 讀取配置數據 var data = LoadConfigData(); + + // 2. 讀取「清除」按鈕的座標設定 (從 "SpecialButtonCoordinates" 內的 "clearButtonZhuYinSongs" 取得) clearButtonZhuYinCoords = LoadSpecialButtonCoordinates(data, "SpecialButtonCoordinates", "clearButtonZhuYinSongs"); + + // 3. 讀取「清除」按鈕的圖片 (正常、滑鼠懸停、按下狀態) var buttonImages = LoadButtonImages(data, "ClearButtonImagesZhuYin"); + // 4. 建立「清除」按鈕,並設定對應的事件處理函式 (ClearButtonZhuYinSongs_Click) clearButtonZhuYinSongs = CreateSpecialButton( - "btnClearZhuYinSongs", - clearButtonZhuYinCoords, - buttonImages.normal, - buttonImages.mouseOver, - buttonImages.mouseDown, - ClearButtonZhuYinSongs_Click + "btnClearZhuYinSongs", // 按鈕名稱 + clearButtonZhuYinCoords, // 按鈕座標與大小 + buttonImages.normal, // 正常狀態圖片 + buttonImages.mouseOver, // 滑鼠懸停圖片 + buttonImages.mouseDown, // 按下時圖片 + ClearButtonZhuYinSongs_Click // 點擊事件處理函式 ); } + /// + /// 當使用者點擊「清除」按鈕時,將輸入框 (inputBoxZhuYinSongs) 的內容清空。 + /// + /// 觸發事件的按鈕。 + /// 事件參數。 private void ClearButtonZhuYinSongs_Click(object sender, EventArgs e) - { + { + // 1. 確保視窗內包含「注音輸入框」(inputBoxZhuYinSongs),且輸入框內有文字 if (this.Controls.Contains(inputBoxZhuYinSongs) && inputBoxZhuYinSongs.Text.Length > 0) { + // 2. 清空輸入框內容 inputBoxZhuYinSongs.Text = ""; } } + + /// + /// 初始化注音輸入的關閉按鈕,從設定檔讀取按鈕座標與圖片,並設置點擊事件 + /// private void InitializeCloseButtonZhuYinSongs() { + // 讀取設定檔數據 var data = LoadConfigData(); + + // 從設定檔讀取關閉按鈕的座標 closeButtonZhuYinCoords = LoadSpecialButtonCoordinates(data, "SpecialButtonCoordinates", "closeButtonZhuYinSongs"); + + // 從設定檔讀取關閉按鈕的圖片 var buttonImages = LoadButtonImages(data, "CloseButtonImagesZhuYin"); + // 創建關閉按鈕並綁定點擊事件 closeButtonZhuYinSongs = CreateSpecialButton( - "btnCloseZhuYinSongs", - closeButtonZhuYinCoords, - buttonImages.normal, - buttonImages.mouseOver, - buttonImages.mouseDown, - CloseButtonZhuYinSongs_Click + "btnCloseZhuYinSongs", // 按鈕名稱 + closeButtonZhuYinCoords, // 按鈕座標 + buttonImages.normal, // 正常狀態圖片 + buttonImages.mouseOver, // 滑鼠懸停圖片 + buttonImages.mouseDown, // 按下圖片 + CloseButtonZhuYinSongs_Click // 綁定點擊事件 ); } + + /// + /// 關閉注音輸入介面,隱藏相關 UI 元件 + /// + /// 觸發事件的按鈕 (關閉按鈕) + /// 事件參數 private void CloseButtonZhuYinSongs_Click(object sender, EventArgs e) { + // 隱藏注音輸入的圖片 pictureBoxZhuYinSongs.Visible = false; + + // 隱藏注音輸入的所有按鈕與介面元素 SetZhuYinSongsAndButtonsVisibility(false); } + /// + /// 初始化注音輸入框 (RichTextBox),設定外觀、事件處理及位置大小 + /// private void InitializeInputBoxZhuYinSongs() { try { + // 讀取輸入框的配置,例如字體、顏色、大小等 LoadInputBoxConfig(); + // 建立注音輸入框並套用讀取到的設定 inputBoxZhuYinSongs = new RichTextBox { Name = "inputBoxZhuYinSongs", - ForeColor = inputBoxForeColor, - Font = new Font(inputBoxFontName, inputBoxFontSize, inputBoxFontStyle), - ScrollBars = RichTextBoxScrollBars.None + ForeColor = inputBoxForeColor, // 設定文字顏色 + Font = new Font(inputBoxFontName, inputBoxFontSize, inputBoxFontStyle), // 設定字體 + ScrollBars = RichTextBoxScrollBars.None // 禁用滾動條 }; - ResizeAndPositionControl(inputBoxZhuYinSongs, inputBoxZhuYinCoords.X, inputBoxZhuYinCoords.Y, inputBoxZhuYinCoords.Width, inputBoxZhuYinCoords.Height); + // 調整輸入框大小與位置 + ResizeAndPositionControl(inputBoxZhuYinSongs, inputBoxZhuYinCoords.X, inputBoxZhuYinCoords.Y, + inputBoxZhuYinCoords.Width, inputBoxZhuYinCoords.Height); + // 設定文字變更事件,用來即時篩選歌曲 inputBoxZhuYinSongs.TextChanged += (sender, e) => { - /* 搜尋結果顯示到前歌單點選 */ - string searchText = inputBoxZhuYinSongs.Text; + string searchText = inputBoxZhuYinSongs.Text; // 取得輸入內容 + + // 根據輸入的注音篩選歌曲清單 var searchResults = allSongs.Where(song => song.PhoneticNotation.StartsWith(searchText)).ToList(); + + // 重置分頁 currentPage = 0; currentSongList = searchResults; totalPages = (int)Math.Ceiling((double)searchResults.Count / itemsPerPage); + // 更新多頁面面板的內容 multiPagePanel.currentPageIndex = 0; multiPagePanel.LoadSongs(currentSongList); }; + // 將輸入框加入到 UI 控制項 this.Controls.Add(inputBoxZhuYinSongs); } catch (Exception ex) @@ -230,51 +355,95 @@ namespace DualScreenDemo Console.WriteLine("Error initializing inputBoxZhuYinSongs: " + ex.Message); } } - + + /// + /// 存儲 PictureBoxZhuYinSongs 的座標與尺寸信息。 + /// + /// + /// 此元組包含以下四個值: + /// X:X 座標 + /// , Y:Y 座標 + /// , Width:寬度 + /// , Height:高度 + /// private (int X, int Y, int Width, int Height) pictureBoxZhuYinSongCoords; + /// + /// 從設定檔 (config.ini) 讀取 PictureBoxZhuYinSongs 的座標與尺寸 + /// private void LoadPictureBoxZhuYinSongCoordsFromConfig() { + // 建立 INI 檔案解析器 var parser = new FileIniDataParser(); + + // 讀取 config.ini 設定檔的內容 IniData data = parser.ReadFile("config.ini"); + // 取得 "PictureBoxZhuYinSongs" 段落的設定數據 var coords = data["PictureBoxZhuYinSongs"]; + + // 解析座標與尺寸,並存入 pictureBoxZhuYinSongCoords pictureBoxZhuYinSongCoords = ( - int.Parse(coords["X"]), - int.Parse(coords["Y"]), - int.Parse(coords["Width"]), - int.Parse(coords["Height"]) + int.Parse(coords["X"]), // 讀取 X 座標 + int.Parse(coords["Y"]), // 讀取 Y 座標 + int.Parse(coords["Width"]), // 讀取寬度 + int.Parse(coords["Height"]) // 讀取高度 ); } + + /// + /// 在 pictureBoxZhuYinSongs 上顯示指定路徑的圖片,並根據設定調整其大小與位置。 + /// + /// 要顯示的圖片檔案路徑 private void ShowImageOnPictureBoxZhuYinSongs(string imagePath) { - + // 從 config.ini 讀取 PictureBox 的座標與尺寸 LoadPictureBoxZhuYinSongCoordsFromConfig(); - + // 讀取圖片檔案並載入 Bitmap 物件 Bitmap originalImage = new Bitmap(imagePath); - - Rectangle displayArea = new Rectangle(pictureBoxZhuYinSongCoords.X, pictureBoxZhuYinSongCoords.Y, pictureBoxZhuYinSongCoords.Width, pictureBoxZhuYinSongCoords.Height); + // 設定圖片顯示區域,使用從設定檔讀取的座標與尺寸 + Rectangle displayArea = new Rectangle( + pictureBoxZhuYinSongCoords.X, + pictureBoxZhuYinSongCoords.Y, + pictureBoxZhuYinSongCoords.Width, + pictureBoxZhuYinSongCoords.Height + ); - + // 設定 PictureBox 的圖片 pictureBoxZhuYinSongs.Image = originalImage; - - ResizeAndPositionPictureBox(pictureBoxZhuYinSongs, displayArea.X, displayArea.Y, displayArea.Width, displayArea.Height); + // 調整 PictureBox 的大小與位置,使其符合設定 + ResizeAndPositionPictureBox( + pictureBoxZhuYinSongs, + displayArea.X, + displayArea.Y, + displayArea.Width, + displayArea.Height + ); + // 顯示 PictureBox pictureBoxZhuYinSongs.Visible = true; } + + /// + /// 設定注音歌曲相關的 PictureBox、按鈕和輸入框的可見性。 + /// + /// 若為 true,則顯示這些控件;否則隱藏。 private void SetZhuYinSongsAndButtonsVisibility(bool isVisible) { + // 定義要執行的操作,設定各控件的可見性 System.Action action = () => { try { + // 暫停佈局邏輯,防止在調整控件可見性時觸發不必要的佈局計算,提升性能 SuspendLayout(); + // 檢查並設定 pictureBoxZhuYinSongs 的可見性 if (pictureBoxZhuYinSongs == null) { Console.WriteLine("pictureBoxZhuYinSongs is null"); @@ -285,6 +454,7 @@ namespace DualScreenDemo if (isVisible) pictureBoxZhuYinSongs.BringToFront(); } + // 檢查並設定 phoneticButtonsForSongs 陣列中每個按鈕的可見性 if (phoneticButtonsForSongs == null) { Console.WriteLine("phoneticButtonsForSongs is null"); @@ -305,6 +475,7 @@ namespace DualScreenDemo } } + // 檢查並設定 modifyButtonZhuYinSongs 的可見性 if (modifyButtonZhuYinSongs == null) { Console.WriteLine("modifyButtonZhuYinSongs is null"); @@ -315,6 +486,7 @@ namespace DualScreenDemo if (isVisible) modifyButtonZhuYinSongs.BringToFront(); } + // 檢查並設定 clearButtonZhuYinSongs 的可見性 if (clearButtonZhuYinSongs == null) { Console.WriteLine("clearButtonZhuYinSongs is null"); @@ -325,6 +497,7 @@ namespace DualScreenDemo if (isVisible) clearButtonZhuYinSongs.BringToFront(); } + // 檢查並設定 closeButtonZhuYinSongs 的可見性 if (closeButtonZhuYinSongs == null) { Console.WriteLine("closeButtonZhuYinSongs is null"); @@ -335,6 +508,7 @@ namespace DualScreenDemo if (isVisible) closeButtonZhuYinSongs.BringToFront(); } + // 檢查並設定 inputBoxZhuYinSongs 的可見性 if (inputBoxZhuYinSongs == null) { Console.WriteLine("inputBoxZhuYinSongs is null"); @@ -345,10 +519,12 @@ namespace DualScreenDemo if (isVisible) inputBoxZhuYinSongs.BringToFront(); } + // 恢復佈局邏輯,允許佈局計算 ResumeLayout(); - PerformLayout(); + // 強制控件立即執行佈局邏輯,確保佈局更新立即生效 + PerformLayout(); - + // 刷新各控件,確保其狀態立即更新 pictureBoxZhuYinSongs?.Refresh(); if (phoneticButtonsForSongs != null) { @@ -364,10 +540,12 @@ namespace DualScreenDemo } catch (Exception ex) { + // 捕捉並輸出異常資訊,方便除錯 Console.WriteLine("Error in SetZhuYinSongsAndButtonsVisibility: " + ex.Message); } }; + // 如果當前執行緒需要呼叫 Invoke 方法才能修改控件,則使用 Invoke if (this.InvokeRequired) { this.Invoke(action); @@ -377,5 +555,6 @@ namespace DualScreenDemo action(); } } + } } \ No newline at end of file diff --git a/PrimaryFormParts/SongSearch/PrimaryForm.SongSearch.PinyinSearch.cs b/PrimaryFormParts/SongSearch/PrimaryForm.SongSearch.PinyinSearch.cs index 5a0d7f5..d406e69 100644 --- a/PrimaryFormParts/SongSearch/PrimaryForm.SongSearch.PinyinSearch.cs +++ b/PrimaryFormParts/SongSearch/PrimaryForm.SongSearch.PinyinSearch.cs @@ -20,7 +20,9 @@ namespace DualScreenDemo private Button closeButtonPinYinSongs; // 用於顯示輸入文字的輸入框 private RichTextBox inputBoxPinYinSongs; - // 拼音歌曲搜尋按鈕點擊事件 + /// + /// 拼音歌曲搜尋按鈕點擊事件 + /// private void PinyinSearchSongsButton_Click(object sender, EventArgs e) { // 更新搜尋模式按鈕的背景圖 @@ -124,9 +126,9 @@ namespace DualScreenDemo /// /// 初始化拼音輸入的特殊功能按鈕,包括: - /// 1. 修改按鈕 - 刪除輸入框中的最後一個字母 - /// 2. 清除按鈕 - 清空輸入框的內容 - /// 3. 關閉按鈕 - 隱藏拼音輸入的 UI 元件 + /// 1. 修改按鈕 - 刪除輸入框中的最後一個字母 + /// 2. 清除按鈕 - 清空輸入框的內容 + /// 3. 關閉按鈕 - 隱藏拼音輸入的 UI 元件 /// private void InitializeSpecialButtonsForPinYinSongs() { @@ -167,11 +169,11 @@ namespace DualScreenDemo } /// - /// 「修改」按鈕點擊事件:刪除拼音輸入框 (`inputBoxPinYinSongs`) 中的最後一個字母。 + /// 「修改」按鈕點擊事件:刪除拼音輸入框 (inputBoxPinYinSongs) 中的最後一個字母。 /// private void ModifyButtonPinYinSongs_Click(object sender, EventArgs e) { - // 確保 `inputBoxPinYinSongs` 存在於視窗控制項集合內,且輸入框內有文字 + // 確保 inputBoxPinYinSongs 存在於視窗控制項集合內,且輸入框內有文字 if (this.Controls.Contains(inputBoxPinYinSongs) && inputBoxPinYinSongs.Text.Length > 0) { // 刪除輸入框內的最後一個字母 @@ -181,7 +183,7 @@ namespace DualScreenDemo /// - /// 初始化「清除」按鈕 (`clearButtonPinYinSongs`),用於清空拼音輸入框 (`inputBoxPinYinSongs`)。 + /// 初始化「清除」按鈕 (clearButtonPinYinSongs),用於清空拼音輸入框 (inputBoxPinYinSongs)。 /// private void InitializeClearButtonPinYinSongs() { @@ -220,7 +222,7 @@ namespace DualScreenDemo } /// - /// 初始化「關閉」按鈕 (`closeButtonPinYinSongs`),用於隱藏拼音輸入介面。 + /// 初始化「關閉」按鈕 (closeButtonPinYinSongs),用於隱藏拼音輸入介面。 /// private void InitializeCloseButtonPinYinSongs() { @@ -258,7 +260,7 @@ namespace DualScreenDemo } /// - /// 初始化拼音輸入框 (`RichTextBox`),並從 `config.ini` 讀取相關設定。 + /// 初始化拼音輸入框 (RichTextBox),並從 config.ini 讀取相關設定。 /// private void InitializeInputBoxPinYinSongs() { @@ -268,13 +270,13 @@ namespace DualScreenDemo var parser = new FileIniDataParser(); // 配置解析器的參數 - parser.Parser.Configuration.AssigmentSpacer = ""; // 設定 `=` 兩側沒有空格 - parser.Parser.Configuration.CommentString = "#"; // 使用 `#` 作為註解符號 + parser.Parser.Configuration.AssigmentSpacer = ""; // 設定 = 兩側沒有空格 + parser.Parser.Configuration.CommentString = "#"; // 使用 # 作為註解符號 parser.Parser.Configuration.CaseInsensitive = true; // 參數名稱不區分大小寫 IniData data; // 儲存解析後的 INI 數據 - // 讀取 `config.ini` 文件,使用 UTF-8 編碼 + // 讀取 config.ini 文件,使用 UTF-8 編碼 using (var reader = new StreamReader("config.ini", System.Text.Encoding.UTF8)) { data = parser.ReadData(reader); @@ -292,7 +294,7 @@ namespace DualScreenDemo FontStyle fontStyle = (FontStyle)Enum.Parse(typeof(FontStyle), data["InputBoxPinYinSongs"]["FontStyle"]); // 字體樣式 Color foreColor = Color.FromName(data["InputBoxPinYinSongs"]["ForeColor"]); // 文字顏色 - // 創建拼音輸入框 (`RichTextBox`) + // 創建拼音輸入框 (RichTextBox) inputBoxPinYinSongs = new RichTextBox { Visible = false, // 預設為隱藏 @@ -308,7 +310,7 @@ namespace DualScreenDemo // 設定輸入框的位置與大小 ResizeAndPositionControl(inputBoxPinYinSongs, x, y, width, height); - // **綁定 `TextChanged` 事件 (當輸入內容改變時觸發搜尋)** + // **綁定 TextChanged 事件 (當輸入內容改變時觸發搜尋)** inputBoxPinYinSongs.TextChanged += (sender, e) => { string searchText = inputBoxPinYinSongs.Text; @@ -335,7 +337,7 @@ namespace DualScreenDemo } } /// - /// 存儲 `PictureBoxPinYinSongs` 的座標與尺寸信息。 + /// 存儲 PictureBoxPinYinSongs 的座標與尺寸信息。 /// /// /// 此元組包含以下四個值: @@ -347,20 +349,20 @@ namespace DualScreenDemo private (int X, int Y, int Width, int Height) pictureBoxPinYinSongCoords; /// - /// 從 `config.ini` 配置檔案中載入 `PictureBoxPinYinSongs` 的座標與尺寸設定。 + /// 從 config.ini 配置檔案中載入 PictureBoxPinYinSongs 的座標與尺寸設定。 /// private void LoadPictureBoxPinYinSongCoordsFromConfig() { // 創建一個 INI 檔案解析器 var parser = new FileIniDataParser(); - // 讀取 `config.ini` 文件並解析成 `IniData` 對象 + // 讀取 config.ini 文件並解析成 IniData 對象 IniData data = parser.ReadFile("config.ini"); - // 取得 `PictureBoxPinYinSongs` 區段的設定值 + // 取得 PictureBoxPinYinSongs 區段的設定值 var coords = data["PictureBoxPinYinSongs"]; - // 解析 `X`, `Y`, `Width`, `Height`,並存入 `pictureBoxPinYinSongCoords` + // 解析 X, Y, Width, Height,並存入 pictureBoxPinYinSongCoords pictureBoxPinYinSongCoords = ( int.Parse(coords["X"]), // 解析 X 座標 int.Parse(coords["Y"]), // 解析 Y 座標 @@ -388,10 +390,10 @@ namespace DualScreenDemo pictureBoxPinYinSongCoords.Height // 設定 高度 ); - // 將載入的圖片設定為 `pictureBoxPinYinSongs` 的影像 + // 將載入的圖片設定為 pictureBoxPinYinSongs 的影像 pictureBoxPinYinSongs.Image = originalImage; - // 調整 `PictureBox` 的大小與位置,使其符合 `displayArea` 的設定 + // 調整 PictureBox 的大小與位置,使其符合 displayArea 的設定 ResizeAndPositionPictureBox( pictureBoxPinYinSongs, displayArea.X, @@ -400,7 +402,7 @@ namespace DualScreenDemo displayArea.Height ); - // 顯示 `PictureBox` + // 顯示 PictureBox pictureBoxPinYinSongs.Visible = true; } @@ -416,7 +418,7 @@ namespace DualScreenDemo // 暫停佈局更新,以防止 UI 閃爍或重繪時出現異常 SuspendLayout(); - // 設定 `pictureBoxPinYinSongs` 的可見性 + // 設定 pictureBoxPinYinSongs 的可見性 pictureBoxPinYinSongs.Visible = isVisible; if (isVisible) pictureBoxPinYinSongs.BringToFront(); // 確保顯示時位於最前方 @@ -427,25 +429,25 @@ namespace DualScreenDemo if (isVisible) button.BringToFront(); } - // 設定 `modifyButtonPinYinSongs` (修改按鈕) 的可見性 + // 設定 modifyButtonPinYinSongs (修改按鈕) 的可見性 if (modifyButtonPinYinSongs != null) { modifyButtonPinYinSongs.Visible = isVisible; if (isVisible) modifyButtonPinYinSongs.BringToFront(); } - // 設定 `clearButtonPinYinSongs` (清除按鈕) 的可見性 + // 設定 clearButtonPinYinSongs (清除按鈕) 的可見性 if (clearButtonPinYinSongs != null) { clearButtonPinYinSongs.Visible = isVisible; if (isVisible) clearButtonPinYinSongs.BringToFront(); } - // 設定 `closeButtonPinYinSongs` (關閉按鈕) 的可見性 + // 設定 closeButtonPinYinSongs (關閉按鈕) 的可見性 closeButtonPinYinSongs.Visible = isVisible; if (isVisible) closeButtonPinYinSongs.BringToFront(); - // 設定 `inputBoxPinYinSongs` (輸入框) 的可見性 + // 設定 inputBoxPinYinSongs (輸入框) 的可見性 inputBoxPinYinSongs.Visible = isVisible; if (isVisible) inputBoxPinYinSongs.BringToFront(); @@ -453,7 +455,7 @@ namespace DualScreenDemo ResumeLayout(); PerformLayout(); - // 刷新 `pictureBoxPinYinSongs`,確保畫面更新 + // 刷新 pictureBoxPinYinSongs,確保畫面更新 pictureBoxPinYinSongs.Refresh(); // 刷新拼音字母按鈕