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

VC++ 中調用系統「運行」對話框的實現方法

     編輯:關於VC++

在 Windows 程式開發中,有時需要在程式中直接呼叫系統的「運行」對話框(即 Win+R 呼叫的對話框)。雖然這看似是一個常見需求,但微軟並未在 MSDN 中公開相關的 API 函數。經過研究發現,這項功能其實藏在 shell32.dll 中一個未導出名稱的函數 RunFileDlg 裡,只能透過其導出序號(Ordinal)來取得位址並調用。

核心難點:無法直接用函數名稱取得位址

初期嘗試使用 GetProcAddress(hLib, "RunFileDlg") 總是返回 NULL。經過 W32dsm 等工具檢視 shell32.dll 的導出表,確認該 DLL 確實不存在名為 "RunFileDlg" 的導出函數。進一步分析發現,系統保留的內部函數通常不導出名稱,只保留導出序號。對於 shell32.dll,RunFileDlg 的導出序號為 61。

正確的調用方式

必須透過序號來獲取函數指標:

RunFileDlg = (pRunFileDlg)GetProcAddress(hLib, (char *)61);

其中函數原型定義為:

typedef void (__stdcall *pRunFileDlg)(HWND, HICON, LPCTSTR, LPCTSTR, LPCTSTR, UINT);

完整實作程式碼範例 (MFC/VC++)

////////////////////////////////////////////////
// 呼叫系統「運行」對話框
CString pszDllName = _T("shell32.dll");
HINSTANCE hLib = ::LoadLibrary(pszDllName);
if (hLib == NULL) return;

typedef void (__stdcall *pRunFileDlg)(HWND, HICON, LPCTSTR, LPCTSTR, LPCTSTR, UINT);
pRunFileDlg RunFileDlg = (pRunFileDlg)GetProcAddress(hLib, (char *)61); // 序號 61

if (RunFileDlg != NULL)
{
    // 參數準備:標題與提示文字需轉為寬字元
    CString strTitle = _T("自訂運行標題");
    CString strPrompt = _T("請輸入程式路徑或命令");
    
    LPWSTR wTitle = new WCHAR[100];
    LPWSTR wPrompt = new WCHAR[100];
    memset(wTitle, 0, sizeof(WCHAR)*100);
    memset(wPrompt, 0, sizeof(WCHAR)*100);
    
    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, strTitle, strTitle.GetLength(), wTitle, 100);
    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, strPrompt, strPrompt.GetLength(), wPrompt, 100);
    
    // 調用對話框
    // 參數:父視窗、圖示、目錄、標題、提示、旗標(0x02 等)
    RunFileDlg(this->GetSafeHwnd(), NULL, NULL, (LPCTSTR)wTitle, (LPCTSTR)wPrompt, 0x02);
    
    delete[] wTitle;
    delete[] wPrompt;
}
::FreeLibrary(hLib);

關鍵點總結

  • 使用 LoadLibrary 載入 shell32.dll。
  • 使用 GetProcAddress(hLib, (char*)61) 以序號 61 取得 RunFileDlg 位址。
  • 字串參數必須轉換為 Unicode (寬字元) 格式,否則對話框顯示異常。
  • 調用後釋放庫資源。

此技巧同樣適用於其他系統保留的內部函數,掌握「序號調用」是突破未公開 API 限制的關鍵。

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