Wolfgang Chien's Homepage | Delphi學習筆記 - 創作篇 |
假如您的應用程式也用到 ChartFX 這個 OCX, 但是不清楚該如何登錄 Windows 的registration database, 或者自行登錄後在客戶那邊執行時就是出現缺少重要檔案的訊息, 那您不妨看一下這份文件.
本文合併 12/20/96 與 1/20/97 在 DelphiChat 發表的兩封信件寫成, (後者與楊維中先生一起署名發表)
有關 OCX 的安裝, 除了 DChat 討論資料庫中既有的討論之外, 下午發現了一個新的安裝方式, 謹提出來與大家討論. 當 OCX 要隨軟體移交給用戶時, 發現的方法是:
![]() |
1. 再次閱讀版權聲明文件, 確定您了解著作權限與可以散播的檔案. |
![]() |
2. 確定有哪些 .OCX .DLL(有些 OCX 是需要額外的 DLL 的), 將這些檔案複製到用戶端的機器中, Window95通常是 C:\WINDOWS\SYSTEM |
![]() |
3. 寫一支程式呼叫本文附的 InstallOcx() 函數進行安裝. |
OCX 也是 DLL(比較特殊的 DLL), 我們可以用 LoadLibrary() 載入之後, 分別查出 DllregisterServer, DllUnregisterServer, 呼叫這兩支 export function 登錄/取消 OCX.
ChartFX 是一個支援 Self-Registration 的 OCX, 換句話說我們可以按下列步驟完成登錄的工作.
![]() |
1. LoadLibrary() 將 CFX32.OCX 載入記憶體. |
![]() |
2. 以 GetProcAddress() 找到 DllRegisterServer 的執行位址 |
![]() |
3. 呼叫 DllRegisterServer 完成登錄.
(當然, 還有OLEInitialize的呼叫等其他事項, 但主要是這三步) |
在微軟的技術文件與 Delphi 2 Developer's Guide 中都曾提過上述的作法, 微軟官方也有 RegSvr32.EXE 與 CtlReg32.exe 兩支工具程式可以應用.
但是如果您真的這麼作了之後, 會發現有些機器在安裝時程式會卡在 LoadLibrary 這列出現錯誤訊息, 以 RegSvr32.exe 來說, 該訊息是:
LoadLibrary("File.OCX") GetLastError returns 0x00000485
發生了什麼事呢? 為什麼有的機器又沒事呢? :(
根據我們的試驗(另一位是楊維中先生), Windows Sys 目錄必須有以下的檔案:
(其他的 OLE 所需檔案都是 Windows 預設安裝會有的檔案)
這樣, ChartFX 的 Self-Registration 即可順利執行.
另外, 我們也發現, 在登錄之後, 將 MFC40.DLL 改名字或刪除, 用到 ChartFX 這個 OCX 的應用程式也同時不正常了.
因此, 我們初步的認為是:
![]() |
以下的三個 DLL 檔是必須出現在客戶端的機器中.
|
![]() |
承上, 如果沒有這三個檔案, 即使手動去登記 Windows 的 registration database, CFX32.OCX 也不會順利執行. |
![]() |
透過 RegSvr32.exe 或自己寫的程式, 讓 OCX 自行完成登錄是一個不錯的作法. 原因是, 如果它可以正常完成登錄, 我們也比較放心整個 OLE 系統環境是我們需要的. |
// ------------------------------------------------------------ // OCX 登錄安裝 // ------------ // 使用說明: // InstallOcx(Ocx 的檔案名稱, True(登錄)/False(取消登錄) // 傳回值: True ==> 成功 False ==> 無法登錄/取消登錄 // // e.g. // if InstallOcx('d:\windows\system\cfx32.ocx', False) then .. // if InstallOcx('d:\windows\system\cfx32.ocx', True) then ... // // 注意事項: // 1. 在 Delphi IDE 執行 InstallOcx('xxx.ocx', False); 解除安 // 裝後, 雖然 Windows Register Database 已清除該 OCX 的登 // 錄資料, Delphi 仍需重新啟動才有反應. // 2. 本函數使用前, uses 述句中不要忘了 uses OleCtl, OleAuto; // ------------------------------------------------------------ function InstallOcx( const sFileName: AnsiString; bSetup: boolean): boolean; var hOcx: THandle; funcRegister: TDllRegisterServer; funcUnRegister: TDllUnRegisterServer; begin Result := False; // 檢查檔案是否存在 if not FileExists(sFileName) then Raise EOleError.CreateFmt('找不到 %s', [sFileName]); // 載入 OCX (也是一個 DLL) hOcx := LoadLibrary(pchar(sFileName)); if hOcx < 32 then Raise EOleError.CreateFmt('無法載入 %s', [sFileName]); try // 查出 DllRegisterServer 的 Call address if bSetup then begin funcRegister := GetProcAddress(hOcx, 'DllRegisterServer'); if @funcRegister = nil then Raise EOleError.CreateFmt('無法載入 %s 中的 DllRegisterServer', [sFileName]); // 執行 DllRegisterServer, 並與正常值比較 Result := funcRegister = S_OK; end else begin funcUnRegister := GetProcAddress(hOcx, 'DllUnregisterServer'); if @funcUnRegister = nil then Raise EOleError.CreateFmt('無法載入 %s 中的 DllUnregisterServer', [sFileName]); // 執行, 並與正常值比較 Result := funcUnRegister = S_OK; end; // 如果執行失敗, 提示訊息. if not Result then begin if bSetup then Raise EOleError.CreateFmt('無法登錄註冊 %s', [sFileName]) else Raise EOleError.CreateFmt('無法取消註冊 %s', [sFileName]); end; finally FreeLibrary(hOcx); end; end;
Delphi 2 Developer's
Guide Second Edition. Xavier Pacheco & Steve Teixeira, Page. 195-197
MSDN '96 October, OLE
Controls: Registration, Dale Rogerson.
首頁 | 學習筆記 | 主題公園 | 軟體下載 | 關於本站 | 討論信群 | 相約下次 |