using System.IO; using System.Drawing.Imaging; namespace DualScreenDemo { public partial class PrimaryForm { private PictureBox pictureBoxWordCountSongs; private Button[] numberWordCountButtonsForSongs; private Button modifyButtonWordCountSongs; private Button clearButtonWordCountSongs; private Button closeButtonWordCountSongs; private Button enterButtonWordCountSongs; private RichTextBox inputBoxWordCountSongs; // 初始化所有與注音歌手相關的按鈕,包括語音符號按鈕、特殊按鈕及輸入框。 private void InitializeButtonsForWordCountSongs() { // 初始化所有語音按鈕 InitializeNumberWordCountSongsButtons(pictureBoxWordCountSongs,NumberWordCountSongsButton_Click); // 初始化注音歌手的輸入框 InitializeInputBoxWordCountSongs(); // 初始化下排功能按鈕 InitializeSongWordButton(); } /// 初始化並設置語音按鈕的相關資料,包括符號、座標與圖片等。 private void InitializeNumberWordCountSongsButtons(Control control, EventHandler handler) { // 初始化語音按鈕陣列,總共有 10 個按鈕 numberWordCountButtonsForSongs = new Button[10]; // 設置上排數字按鈕 int x = 10; for (int i = 0; i < 5; i++) { CreateNumBtnWordCountButton(i, x, 120, control, handler); x += 82; } // 設置下排數字按鈕 x = 10; for (int i = 5; i < 10; i++) { CreateNumBtnWordCountButton(i, x, 197, control, handler); x += 82; } } private void CreateNumBtnWordCountButton(int index, int x, int y,Control control,EventHandler handler) { try { // 加載配置數據 var data = LoadBtnConfigData(); // 創建語音按鈕並設置其屬性 numberWordCountButtonsForSongs[index] = new Button { Name = $"numberWordCountButton_{numberWordCountSymbols[index]}", // 按鈕名稱設為語音符號名稱 }; ConfigureButton(numberWordCountButtonsForSongs[index], x, y, 72, 67, new Bitmap(Path.Combine(serverPath, data["NumberWordCountButtonImages"][$"button{index}_normal"])), new Bitmap(Path.Combine(serverPath, data["NumberWordCountButtonImages"][$"button{index}_mouseOver"])), new Bitmap(Path.Combine(serverPath, data["NumberWordCountButtonImages"][$"button{index}_mouseDown"])), handler); // 設置按鈕的 Tag 屬性為對應的語音符號 numberWordCountButtonsForSongs[index].Tag = numberWordCountSymbols[index]; // 將按鈕添加到表單的控制項集合中 control.Controls.Add(numberWordCountButtonsForSongs[index]); } catch (Exception ex) { Console.WriteLine($"Error creating button at index {index}: {ex.Message}"); } } /// 初始化下排按鈕,設定按鈕的坐標、圖片和點擊事件。 private void InitializeSongWordButton() { // 加載配置數據 var data = LoadBtnConfigData(); // 初始化「清除」按鈕 clearButtonWordCountSongs = new Button { Name = "btnClearWordCountSongs" }; ConfigureButton(clearButtonWordCountSongs, 55, 274, 72, 67, new Bitmap(Path.Combine(serverPath, data["ClearButtonImagesWordCount"]["normal"])), new Bitmap(Path.Combine(serverPath, data["ClearButtonImagesWordCount"]["mouseOver"])), new Bitmap(Path.Combine(serverPath, data["ClearButtonImagesWordCount"]["mouseDown"])), ClearButtonWordCountSongs_Click); pictureBoxWordCountSongs.Controls.Add(clearButtonWordCountSongs); // 初始化「重填」按鈕 modifyButtonWordCountSongs = new Button { Name = "btnModifyWordCountSongs" }; ConfigureButton(modifyButtonWordCountSongs, 136, 274, 72, 67, new Bitmap(Path.Combine(serverPath, data["ModifyButtonImagesWordCount"]["normal"])), new Bitmap(Path.Combine(serverPath, data["ModifyButtonImagesWordCount"]["mouseOver"])), new Bitmap(Path.Combine(serverPath, data["ModifyButtonImagesWordCount"]["mouseDown"])), ModifyButtonWordCountSongs_Click); pictureBoxWordCountSongs.Controls.Add(modifyButtonWordCountSongs); // 初始化「確認」按鈕 enterButtonWordCountSongs = new Button { Name = "btnEnterWordCountSongs" }; ConfigureButton(enterButtonWordCountSongs, 217, 274, 72, 67, new Bitmap(Path.Combine(serverPath, data["EnterButtonImagesWordCount"]["normal"])), new Bitmap(Path.Combine(serverPath, data["EnterButtonImagesWordCount"]["mouseOver"])), new Bitmap(Path.Combine(serverPath, data["EnterButtonImagesWordCount"]["mouseDown"])), (sender, e) => FindWordCountSongs()); pictureBoxWordCountSongs.Controls.Add(enterButtonWordCountSongs); // 初始化「關閉」按鈕 closeButtonWordCountSongs = new Button { Name = "btnCloseWordCountSongs" }; ConfigureButton(closeButtonWordCountSongs, 298, 274, 72, 67, new Bitmap(Path.Combine(serverPath, data["CloseButtonImagesWordCount"]["normal"])), new Bitmap(Path.Combine(serverPath, data["CloseButtonImagesWordCount"]["mouseOver"])), new Bitmap(Path.Combine(serverPath, data["CloseButtonImagesWordCount"]["mouseDown"])), CloseButtonWordCountSongs_Click); pictureBoxWordCountSongs.Controls.Add(closeButtonWordCountSongs); } // 初始化 WordCount 歌手輸入框,並設定其屬性與事件處理程序。 private void InitializeInputBoxWordCountSongs() { try { // 創建一個 RichTextBox 控件來作為輸入框 inputBoxWordCountSongs = new RichTextBox { Name = "inputBoxWordCountSongs", ForeColor = Color.Black, // 設定文字顏色 Font = new Font("Times New Roman", 26, FontStyle.Regular), // 設定字體樣式 ScrollBars = RichTextBoxScrollBars.None // 不顯示滾動條 }; // 調整和定位輸入框的位置及大小 ResizeAndPositionControl(inputBoxWordCountSongs, 10, 55, 400, 60); // 將輸入框加入到窗體的控件集合中 pictureBoxWordCountSongs.Controls.Add(inputBoxWordCountSongs); } catch (Exception ex) { Console.WriteLine("Error initializing inputBoxWordCountSongs: " + ex.Message); } } // 顯示圖片並根據配置文件設置顯示區域的大小和位置。 // 圖片的路徑。 private void ShowImageOnPictureBoxWordCountSongs(string imagePath) { // 加載原始圖片 Bitmap originalImage = new Bitmap(imagePath); // 設置圖片到 PictureBox pictureBoxWordCountSongs.Image = originalImage; // 調整 PictureBox 大小和位置 ResizeAndPositionPictureBox(pictureBoxWordCountSongs, 778, 366, 420, 350); // 顯示圖片 pictureBoxWordCountSongs.Visible = true; } // 設置注音歌手相關控制項(包括圖片框、按鈕和輸入框)的顯示或隱藏狀態。 // 指定控件是否可見。True 為顯示,False 為隱藏。 private void SetWordCountSongsAndButtonsVisibility(bool isVisible) { // 定義一個動作來處理控制項的顯示或隱藏 System.Action action = () => { try { // 暫停控制項佈局的重新排版,提高效率 SuspendLayout(); if (isVisible) SetUIVisible(pictureBoxWordCountSongs); else CloseUI(pictureBoxWordCountSongs); } catch (Exception ex) { Console.WriteLine("Error in SetWordCountSongsAndButtonsVisibility: " + ex.Message); } }; // 檢查是否需要在主執行緒外執行 if (this.InvokeRequired) { this.Invoke(action); // 如果需要,透過主執行緒執行 } else { action(); // 否則直接執行 } } #region 按鈕點擊事件 /// /// 點擊「注音歌手搜尋」按鈕時執行的事件處理函式。 /// 此函式負責更新按鈕的背景圖片、載入對應的歌手圖片,並切換相關 UI 控件的可見性。 /// /// 觸發事件的物件(通常是按鈕本身)。 /// 事件參數。 private void WordCountSearchSongsButton_Click(object sender, EventArgs e) { // 設定按鈕背景,將「注音搜尋」設為啟動狀態,其餘按鈕恢復為正常狀態 zhuyinSearchSongButton.BackgroundImage = zhuyinSearchSongNormalBackground; englishSearchSongButton.BackgroundImage = englishSearchSongNormalBackground; pinyinSearchSongButton.BackgroundImage = pinyinSearchSongNormalBackground; wordCountSearchSongButton.BackgroundImage = wordCountSearchSongActiveBackground; handWritingSearchSongButton.BackgroundImage = handWritingSearchSongNormalBackground; numberSearchSongButton.BackgroundImage = numberSearchSongNormalBackground; // 載入設定檔,取得圖片路徑資訊 var configData = LoadBtnConfigData(); // 取得「注音歌手圖片」的完整路徑 string imagePath = Path.Combine(serverPath, configData["ImagePaths"]["WordCountSongs"]); // 在 PictureBox 中顯示對應的「注音歌手」圖片 ShowImageOnPictureBoxWordCountSongs(Path.Combine(serverPath, imagePath)); // 鍵盤UI介面顯示設定 SetWordCountSongsAndButtonsVisibility(true); SetEnglishSongsAndButtonsVisibility(false); SetPinYinSongsAndButtonsVisibility(false); SetHandWritingForSongsAndButtonsVisibility(false); SetSongIDSearchAndButtonsVisibility(false); SetZhuYinSongsAndButtonsVisibility(false); SetHandWritingForSongsAndButtonsVisibility(false); SetWordCountSongsAndButtonsVisibility(true); // 顯示字數搜尋相關控件 // 顯示「注音歌手搜尋」的圖片框 ResetinputBox(); pictureBoxWordCountSongs.Visible = true; } /// /// 處理「修改」按鈕的點擊事件,該事件會刪除輸入框中的最後一個字符。 /// private void ModifyButtonWordCountSongs_Click(object sender, EventArgs e) { // 如果輸入框不為空,且包含輸入內容,則刪除最後一個字符 if (pictureBoxWordCountSongs.Controls.Contains(inputBoxWordCountSongs) && inputBoxWordCountSongs.Text.Length > 0) { inputBoxWordCountSongs.Text = inputBoxWordCountSongs.Text.Substring(0, inputBoxWordCountSongs.Text.Length - 1); } } /// /// 處理「清除」按鈕的點擊事件,該事件會清空輸入框中的所有文本。 /// private void ClearButtonWordCountSongs_Click(object sender, EventArgs e) { // 如果輸入框不為空,則清空該框的文本內容 if (pictureBoxWordCountSongs.Controls.Contains(inputBoxWordCountSongs) && inputBoxWordCountSongs.Text.Length > 0) { inputBoxWordCountSongs.Text = ""; } } /// /// 「關閉」按鈕的點擊事件處理方法。 /// 隱藏 WordCount 歌手圖片框以及與其相關的按鈕。 /// private void CloseButtonWordCountSongs_Click(object sender, EventArgs e) { // 隱藏 WordCount 歌手圖片框 pictureBoxWordCountSongs.Visible = false; // 關閉背景圖式 wordCountSearchSongButton.BackgroundImage = wordCountSearchSongNormalBackground; // 隱藏與 WordCount 歌手相關的所有按鈕 SetWordCountSongsAndButtonsVisibility(false); } private void NumberWordCountSongsButton_Click(object sender, EventArgs e) { var button = sender as Button; if (button != null && button.Tag != null) { if (inputBoxWordCountSongs.Visible) { inputBoxWordCountSongs.Text += button.Tag.ToString(); } } } /// 查詢歌曲(字數查詢) private void FindWordCountSongs() { string searchText = inputBoxWordCountSongs.Text; // 在這裡添加搜尋歌曲的邏輯 // 例如:根據輸入框的內容搜尋歌曲 string query; if (int.TryParse(searchText, out int length)) { query = $"SELECT * FROM song_library_cache WHERE CHAR_LENGTH(song_name) = {length} order by 'song_name' DESC ;"; } else { // 處理輸入錯誤,例如顯示提示訊息 //MessageBox.Show("請輸入正確的數字!"); query = string.Empty; // 清空查詢 return; } var searchResults = SearchSongs_Mysql(query); // 重置分頁 currentPage = 0; totalPages = (int)Math.Ceiling((double)searchResults.Count / itemsPerPage); // 更新多頁面面板的內容 multiPagePanel.currentPageIndex = 0; multiPagePanel.LoadSongs(searchResults); } #endregion #region 移除圖像周圍的白色邊框 /// /// 移除圖像周圍的白色邊框,將邊框的像素透明化。 /// /// 待處理的圖像文件路徑。 /// 處理後的圖像,其中白色邊框已被去除並替換為透明。 private Image RemoveWhiteBorderForWordCountSongs(string imagePath) { // 創建一個 Bitmap 物件來加載圖像 Bitmap bmp = new Bitmap(imagePath); // 定義圖像的矩形區域,這是我們將要操作的區域 Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); // 鎖定圖像的位圖數據,以便進行直接修改 BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat); IntPtr ptr = bmpData.Scan0; // 獲取位圖數據的起始位置 int bytes = Math.Abs(bmpData.Stride) * bmp.Height; // 計算圖像的總字節數 byte[] rgbValues = new byte[bytes]; // 用來存儲圖像的像素數據 System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes); // 從圖像數據中複製像素數據到 rgbValues 陣列 // 遍歷每個像素點,檢查是否為白色邊框 for (int y = 0; y < bmp.Height; y++) { for (int x = 0; x < bmp.Width; x++) { int position = (y * bmpData.Stride) + (x * 4); // 計算當前像素的位址 byte b = rgbValues[position]; // 藍色分量 byte g = rgbValues[position + 1]; // 綠色分量 byte r = rgbValues[position + 2]; // 紅色分量 byte a = rgbValues[position + 3]; // alpha 分量(透明度) // 如果當前像素在圖像邊緣且為白色 (255, 255, 255),則將其設為透明 if ((x < 5 || x > bmp.Width - 5 || y < 5 || y > bmp.Height - 5) && r == 255 && g == 255 && b == 255) { // 將白色像素的 RGB 設置為 255, 255, 255 且 alpha 設為 0 (透明) rgbValues[position] = 255; rgbValues[position + 1] = 255; rgbValues[position + 2] = 255; rgbValues[position + 3] = 0; // 透明 } } } // 將修改後的像素數據重新複製回位圖數據 System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes); // 解鎖圖像數據 bmp.UnlockBits(bmpData); // 返回處理後的圖像 return bmp; } #endregion } }