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

控制台應用程式顏色偵測、GUI/控制台雙模式啟動與視窗位置持久化

     編輯:關於VC++

本文彙整三個實用的 Windows 程式設計技巧:偵測螢幕色深支援、單一執行檔同時支援 GUI 與控制台模式啟動、以及 .NET Windows Forms 視窗位置儲存與還原。

偵測 256 色與真彩色支援

透過 GetDeviceCaps 取得裝置內容的色階數(PLANES)與每像素位元數(BITSPIXEL),相乘即得總色深位元數:

CWindowDC dc(NULL);
int nPlanes = dc.GetDeviceCaps(PLANES);
int nBitsPixel = dc.GetDeviceCaps(BITSPIXEL);
int totalBits = nPlanes * nBitsPixel; // 8=256色, 16/24/32=真彩色

附贈 ColorBits 範例程式可即時顯示目前螢幕色深資訊。

單一專案產生 GUI 與控制台雙模式執行檔

Windows 將 EXE 分為 /subsystem:windows 與 /subsystem:console 兩類,無法單一檔案兼具。解決方案:專案產生兩個執行檔——App.exe(GUI)與 App.com(控制台)。

  • 命令列輸入 App 時,Windows 優先執行 .com,進入控制台模式。
  • 雙擊或捷徑啟動 App.exe 進入 GUI 模式。
  • 控制台版本處理參數(如 -c),無參數時呼叫 ShellExecute 啟動 GUI 版本並退出。

關鍵實作

// ListProc-cons.cpp 控制台進入點
int main(int argc, char* argv[]) {
    if (argc > 1 && strcmp(argv[1], "-c") == 0) {
        EnumProcessesConsole(); // 列印至控制台
    } else {
        // 啟動 GUI 版本
        TCHAR exePath[MAX_PATH];
        GetModuleFileName(NULL, exePath, MAX_PATH);
        PathRenameExtension(exePath, _T(".exe"));
        ShellExecute(NULL, _T("open"), exePath, NULL, NULL, SW_SHOWNORMAL);
    }
    return 0;
}

Visual Studio 專案設定:ListProc-cons 專案加入自訂建置步驟,將輸出 .exe 重命名為 .com。

.NET Windows Forms 視窗位置儲存(INI 檔方案)

.NET 設定檔(app.config)適合管理員部署,不適合使用者個人化設定。註冊表難以複製與編輯。建議使用 INI 檔,配合 GetPrivateProfileInt/WritePrivateProfileString API,支援 XCOPY 部署。

IniFile 封裝類別核心方法

public class IniFile {
    string path;
    public IniFile(string fileName, bool useAppDataPath) {
        if (useAppDataPath)
            path = Path.Combine(Application.UserAppDataPath, fileName);
        else
            path = fileName;
    }
    public void SaveWinPos(Form form, string section) {
        SetVal(section, "X", form.Left.ToString());
        SetVal(section, "Y", form.Top.ToString());
        SetVal(section, "Width", form.Width.ToString());
        SetVal(section, "Height", form.Height.ToString());
    }
    public void RestoreWinPos(Form form, string section) {
        form.StartPosition = FormStartPosition.Manual; // 關鍵!
        form.Left = GetIntVal(section, "X", form.Left);
        form.Top = GetIntVal(section, "Y", form.Top);
        form.Width = GetIntVal(section, "Width", form.Width);
        form.Height = GetIntVal(section, "Height", form.Height);
    }
    // 內部 P/Invoke GetPrivateProfileInt / WritePrivateProfileString
}

使用範例

public class Form1 : Form {
    IniFile ini = new IniFile("SavePos.ini", true); // 存放於使用者 AppData
    public Form1() { ini.RestoreWinPos(this, "MainWindow"); }
    protected override void Dispose(bool disposing) {
        if (disposing) ini.SaveWinPos(this, "MainWindow");
        base.Dispose(disposing);
    }
}

產生的 SavePos.ini 內容:

[MainWindow]
X=282
Y=442
Width=417
Height=234
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved