首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

VC++ 實作啟動畫面:基於訊息機制的 Splash Screen 完整教學

     編輯:關於VC++

需求:專業應用程式的標配——啟動畫面

Splash Screen (啟動封面) 不僅美化啟動體驗,還能掩蓋主視窗初始化耗時。本文示範純 MFC + Windows 訊息機制實作,無需額外執行緒,邏輯清晰可控。

步驟 1:建立專案與匯入資源

  1. AppWizard 建立 **SDI 空專案** `Splash`。
  2. 資源檢視 → 右鍵 `Splash resources` → `Insert` → `Bitmap` → `Import` 選取 BMP 圖片。
  3. 修改 Bitmap ID 為 `IDB_SPLASH` (原 `IDB_BITMAP1`),方便識別。

步驟 2:建立啟動畫面對話框資源

  1. 資源檢視 → `Dialog` 右鍵 `Insert Dialog` 新建對話框。
  2. 刪除預設 `OK`/`Cancel` 按鈕,設定樣式為無框/彈出式 (屬性 `Border: None`, `Title Bar: False`)。
  3. 放入 `Picture Control`,屬性:`Type: Bitmap`,`Image: IDB_SPLASH`。
  4. 調整對話框大小貼合 Picture Control。
  5. ClassWizard 為對話框新建類別 `CSplashDlg`。

步驟 3:主框架類別整合

3.1 新增成員變數

ClassView → `CMainFrame` 右鍵 `Add Member Variable...`:

  • 型別:`CSplashDlg*`
  • 名稱:`splash`

`Splash.cpp` 加入 `#include "SplashDlg.h"`。

3.2 處理 WM_TIMER 訊息

ClassWizard → `CMainFrame` → `WM_TIMER` → `Add Function` → `OnTimer`。

3.3 實作 OnTimer:狀態機控制顯示/關閉

void CMainFrame::OnTimer(UINT nIDEvent) {
    if (nIDEvent == 1) {
        if (splash->IsWindowVisible()) {
            // 啟動畫面可見:置頂、刷新、停留 2 秒、發送關閉
            splash->SetActiveWindow();
            splash->UpdateWindow();
            Sleep(2000);                 // 停留時間 (可配置)
            splash->SendMessage(WM_CLOSE);
        }
        else {
            // 啟動畫面已關閉:主視窗置頂、殺死定時器
            SetActiveWindow();
            KillTimer(1);
        }
    }
    // CFrameWnd::OnTimer(nIDEvent); // 視需求決定是否呼叫基類
}

3.4 修改 OnCreate:啟動定時器、建立並顯示 Splash

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {
    // 1. 最早啟動定時器 (ID=1, 間隔 5ms,頻率不宜過高)
    SetTimer(1, 5, NULL);

    // 2. 建立並顯示啟動畫面
    splash = new CSplashDlg();
    // 可選:播放歡迎音效
    // sndPlaySound("welcome.wav", SND_ASYNC);
    // PlaySound("welcome.wav", NULL, SND_ASYNC);

    splash->Create(IDD_DIALOG1);
    splash->ShowWindow(SW_SHOW);
    splash->UpdateWindow();

    // 3. 標準主視窗初始化
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1;

    // 工具列、狀態列建立...
    if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
        | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
        !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) {
        TRACE0("Failed to create toolbar\n"); return -1;
    }
    if (!m_wndStatusBar.Create(this) ||
        !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT))) {
        TRACE0("Failed to create status bar\n"); return -1;
    }

    // 停靠設定...
    m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
    EnableDocking(CBRS_ALIGN_ANY);
    DockControlBar(&m_wndToolBar);

    // 主視窗置中顯示
    CenterWindow();

    return 0;
}

關鍵設計要點

要點說明
定時器優先啟動`SetTimer` 放在 `OnCreate` 最開頭,確保 Splash 顯示後即受控制
無模式對話框`Create` + `ShowWindow` 非阻塞,主視窗初始化並行
訊息驅動狀態機`WM_TIMER` 週期性檢查可見性,單一職責,無執行緒同步煩惱
Sleep 阻塞在 UI 執行緒此處 `Sleep(2000)` 可接受,因主視窗尚未顯示;若需響應改用額外定時器
資源清理主視窗銷毀時記得 `delete splash;` (析構函數中處理)

進階擴展建議

  • **漸顯/漸隱動畫**:結合 `AnimateWindow` 或分層視窗 (`WS_EX_LAYERED`) 實現 Alpha 淡入淡出。
  • **進度指示**:在 Splash 上加靜態文字/進度條,主視窗初始化階段透過 `PostMessage` 更新進度。
  • **版本/授權資訊**:動態繪製或載入圖片顯示。
  • **多螢幕支援**:`CenterWindow` 改為置中於主要螢幕或滑鼠所在螢幕。

編譯連結執行,專屬啟動畫面即呈現眼前。此純訊息機制實作簡單可靠,適合中小型 MFC 專案快速集成。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved