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

VC++ 開發實戰技巧匯總:20 個高頻問題的標準解法與程式碼範本

     編輯:關於VC++

前言

整理自實戰開發中高頻遇到的 20 個典型問題,涵蓋視窗樣式控制、訊息傳遞、Shell 整合、檔案操作、程式庫知識等,附標準 API 呼叫與 MFC 封裝寫法,可直接複製套用。

技巧清單

1. 動態顯示/隱藏標題列

方法一:Win32 API

// 隱藏
LONG style = ::GetWindowLong(m_hWnd, GWL_STYLE);
::SetWindowLong(m_hWnd, GWL_STYLE, style & ~WS_CAPTION);
::SetWindowPos(m_hWnd, NULL, 0,0,0,0,
    SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_FRAMECHANGED);

// 顯示
::SetWindowLong(m_hWnd, GWL_STYLE, style | WS_CAPTION);
::SetWindowPos(m_hWnd, NULL, 0,0,0,0,
    SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_FRAMECHANGED);

方法二:MFC 封裝 (推薦)

// 隱藏
ModifyStyle(WS_CAPTION, 0, SWP_FRAMECHANGED);
// 顯示
ModifyStyle(0, WS_CAPTION, SWP_FRAMECHANGED);

2. 用 SendMessage 清空編輯控制項

HWND hEdit = GetDlgItem(IDC_EDIT1)->GetSafeHwnd();
::SendMessage(hEdit, WM_SETTEXT, 0, (LPARAM)_T(""));

3. 彈出檔案/資料夾屬性視窗

SHELLEXECUTEINFO sei = {0};
sei.cbSize = sizeof(sei);
sei.fMask = SEE_MASK_INVOKEIDLIST;
sei.lpVerb = _T("properties");
sei.lpFile = _T("C:\\"); // 或檔案路徑
sei.nShow = SW_SHOW;
ShellExecuteEx(&sei);

4. 遞迴刪除目錄及所有內容

BOOL DeleteDirectory(LPCTSTR path) {
    CFileFind finder;
    CString pattern; pattern.Format(_T("%s\\*.*"), path);
    BOOL found = finder.FindFile(pattern);
    while (found) {
        found = finder.FindNextFile();
        if (finder.IsDots()) continue;
        CString full = path + _T("\\") + finder.GetFileName();
        if (finder.IsDirectory())
            DeleteDirectory(full); // 遞迴
        else
            DeleteFile(full);
    }
    finder.Close();
    return RemoveDirectory(path) ? TRUE : FALSE;
}

5. .lib vs .dll 差異與關聯

特性.lib (靜態庫).dll (動態庫)
連結時機編譯連結期執行期載入
檔案大小較大 (含代碼)較小 (僅匯出表)
部署無需額外檔案需隨程式部署 DLL
升級需重新編譯僅替換 DLL (介面不變)
跨語言困難容易 (C 介面)

關聯:DLL 專案產出 .dll + .lib (匯入庫),應用程式連結 .lib,執行期載入 .dll。若無 .lib,可用 LoadLibrary/GetProcAddress 顯式載入。

6. C 語言庫在 C++ 專案中連結

extern "C" {
    #include "my_c_header.h"
}

防止 C++ 名稱修飾導致連結錯誤。

7. 取得應用程式目錄

CString GetAppPath() {
    TCHAR path[MAX_PATH];
    GetModuleFileName(NULL, path, MAX_PATH);
    PathRemoveFileSpec(path);
    return CString(path);
}

8. 判斷檔案/資料夾是否存在

BOOL PathExists(LPCTSTR path) {
    return GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES;
}

9. 啟動外部程式並等待結束

BOOL RunAndWait(LPCTSTR cmd, LPCTSTR params = NULL) {
    SHELLEXECUTEINFO sei = {sizeof(sei)};
    sei.fMask = SEE_MASK_NOCLOSEPROCESS;
    sei.lpFile = cmd; sei.lpParameters = params;
    sei.nShow = SW_SHOW;
    if (!ShellExecuteEx(&sei)) return FALSE;
    WaitForSingleObject(sei.hProcess, INFINITE);
    CloseHandle(sei.hProcess);
    return TRUE;
}

10. 取得系統特殊資料夾路徑

CString GetSpecialFolder(int csidl) { // CSIDL_DESKTOP, CSIDL_PROGRAM_FILES 等
    TCHAR path[MAX_PATH];
    SHGetSpecialFolderPath(NULL, path, csidl, FALSE);
    return CString(path);
}

11. 系統版本判斷

BOOL IsWinNT() {
    OSVERSIONINFO osvi = {sizeof(osvi)};
    GetVersionEx(&osvi);
    return osvi.dwPlatformId == VER_PLATFORM_WIN32_NT;
}

12. 關閉/最小化到系統托盤

// 需配合 NOTIFYICONDATA、Shell_NotifyIcon、WM_SYSCOMMAND SC_MINIMIZE 處理

13. 設定視窗置頂/取消置頂

SetWindowPos(&wndTopMost, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE); // 置頂
SetWindowPos(&wndNoTopMost, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE); // 取消

14. 取得控制項項目矩形 (螢幕/用戶區座標)

CRect rect; GetDlgItem(IDC_xxx)->GetWindowRect(&rect); ScreenToClient(&rect);

15. 防止多開:互斥體單一實例

HANDLE hMutex = CreateMutex(NULL, TRUE, _T("Global\\MyAppUniqueName"));
if (GetLastError() == ERROR_ALREADY_EXISTS) { /* 已執行,激活舊視窗並退出 */ }

16. 註冊表讀寫封裝 (參考文章 9156)

17. 記憶體洩漏偵測 (參考文章 9164)

18. 字串格式化安全版

CString str; str.Format(_T("Value: %d, Name: %s"), 123, _T("Test")); // MFC 安全
// 或 C++11: std::to_string, std::ostringstream

19. 位元組陣列與 CString 互轉

CByteArray arr; arr.Append(data, len);
CString str((LPCSTR)arr.GetData(), len); // ANSI
// Unicode 需留意編碼

20. 除錯輸出格式化

TRACE(_T("File: %s, Line: %d, Value: %d\n"), _T(__FILE__), __LINE__, val);
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved