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

Access 2000 內部 COM 增益集開發實戰:使用 ATL 實現自訂工具列與按鈕

     編輯:關於VC++

前言

在 Office 2000 開發體系中,內部 COM 增益集是擴展應用程式功能的核心技術。本文承接先前關於 Word、Excel、PowerPoint 與 Outlook 內部增益集開發的探討,專注於 Access 2000 的獨特實作細節。完整範例程式碼可至 code.cnblogs.com 下載。下圖展示範例執行後的效果:在 Access 視窗中動態新增一個自訂工具列,並包含帶有圖示與提示文字的按鈕。

Access 2000 增益集執行效果圖

專案建立與 ATL 物件導入

  1. 啟動 Visual C++ 6.0,選擇 ATL COM AppWizard,專案命名為 AccessAddin。
  2. 在 ClassView 中右鍵選擇 Insert → New ATL Object,挑選 Simple Object,Short Name 輸入 AcceAddin 完成物件插入。
  3. 編譯專案後,於 ClassView 的 CAcceAddin 類別右鍵選 Implement Interface,點擊 Add Typelib,選取 Microsoft Add-in Designer (1.0),匯入 _IDTExtensibility2 介面。系統將自動產生五個必要的介面函式骨架。

Access 2000 專屬的三大實作差異

1. 登錄資訊 (.rgs) 撰寫不同

Access 的增益集登錄路徑位於 HKCU\Software\Microsoft\Office\Access\Addins。在 AcceAddin.rgs 檔案末尾加入下列內容:

HKCU
{
    Software
    {
        Microsoft
        {
            Office
            {
                Access
                {
                    Addins
                    {
                        'AccessAddin.AcceAddin'
                        {
                            val FriendlyName = s 'Access2000增益集'
                            val Description = s '使用ATL開發的Access2000內部增益集'
                            val LoadBehavior = d '00000003'
                            val CommandLineSafe = d '00000000'
                        }
                    }
                }
            }
        }
    }
}

2. Stdafx.h 型別程式庫匯入路徑調整

因 Access 物件模型不同,需匯入 ADO、DAO、VBE、Office 及 Access 專屬型別程式庫。請依實際安裝路徑修改:

#pragma warning(disable:4146)

#import "D:\\Program Files\\Common Files\\system\\ado\\msado21.tlb" no_namespace \
rename("EOF", "adoEOF")
#import "D:\\Program Files\\Common Files\\Microsoft Shared\\DAO\\DAO360.DLL" \
rename("EOF","EndOfFile") rename("BOF","BegOfFile")
#import "E:\\Program Files\\Microsoft Office\\Office\\mso9.dll" rename_namespace("Office")
using namespace Office;
#import "D:\\Program Files\\Common Files\\Microsoft Shared\\VBA\\VBA6\\VBE6EXT.olb" rename_namespace("VBE6")
using namespace VBE6;
#import "E:\\Program Files\\Microsoft Office\\Office\\MSACC9.OLB" named_guids,rename_namespace("MSACCESS")
using namespace MSACCESS;

#pragma warning(default:4146)

3. 直接取得 CommandBars,無需 ActiveExplorer

Access 沒有 ActiveExplorer 物件,可直接從 _Application 介面取得 CommandBars。核心程式碼如下:

STDMETHOD(OnConnection)(IDispatch * Application, ext_ConnectMode ConnectMode, 
                        IDispatch * AddInInst, SAFEARRAY * * custom)
{
    CComPtr< Office::_CommandBars> spCmdBars;
    CComQIPtr<MSACCESS::_Application> spApp(Application);
    ATLASSERT(spApp);

    HRESULT hr = spApp->get_CommandBars(&spCmdBars);
    if(FAILED(hr)) return hr;
    ATLASSERT(spCmdBars);

    // 建立工具列
    CComVariant vName(L"Access2000 自訂工具列");
    CComPtr<Office::CommandBar> spNewCmdBar;
    CComVariant vPos(1); // 位置:頂端
    CComVariant vTemp(VARIANT_TRUE);
    CComVariant vEmpty(DISP_E_PARAMNOTFOUND, VT_ERROR);
    spNewCmdBar = spCmdBars->Add(vName, vPos, vEmpty, vTemp);

    // 新增按鈕
    CComPtr< Office::CommandBarControls> spBarControls;
    spBarControls = spNewCmdBar->GetControls();
    ATLASSERT(spBarControls);

    CComVariant vToolBarType(1); // msoControlButton
    CComVariant vShow(VARIANT_TRUE);
    CComPtr< Office::CommandBarControl> spNewBar;
    spNewBar = spBarControls->Add(vToolBarType, vEmpty, vEmpty, vEmpty, vShow);
    ATLASSERT(spNewBar);

    CComQIPtr< Office::_CommandBarButton> spCmdButton(spNewBar);
    ATLASSERT(spCmdButton);

    // 設定按鈕圖示 (32x32 位圖)
    HBITMAP hBmp = (HBITMAP)::LoadImage(_Module.GetResourceInstance(),
        MAKEINTRESOURCE(IDB_BITMAP), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS);
    ::OpenClipboard(NULL);
    ::EmptyClipboard();
    ::SetClipboardData(CF_BITMAP, (HANDLE)hBmp);
    ::CloseClipboard();
    ::DeleteObject(hBmp);

    spCmdButton->PutStyle(Office::msoButtonIconAndCaption);
    hr = spCmdButton->PasteFace();
    if (FAILED(hr)) return hr;

    spCmdButton->PutVisible(VARIANT_TRUE);
    spCmdButton->PutCaption(OLESTR(L"按鈕1"));
    spCmdButton->PutEnabled(VARIANT_TRUE);
    spCmdButton->PutTooltipText(OLESTR(L"按鈕1提示訊息"));
    spCmdButton->PutTag(OLESTR(L"按鈕1標記"));

    spNewCmdBar->PutVisible(VARIANT_TRUE);
    m_spButton = spCmdButton;
    m_spApp = spApp;
    hr = CommandButton1Events::DispEventAdvise((IDispatch*)m_spButton);
    if(FAILED(hr)) return hr;
    ::EmptyClipboard();
    return S_OK;
}

其餘共通部分

工具列按鈕事件回應 (CommandBarButton 發送介面)、連接與斷開連接點的處理等,與 Word/Excel/PowerPoint/Outlook 版本大同小異,詳見先前文章。掌握上述三點差異,即可順利完成 Access 2000 內部 COM 增益集開發。

參考文獻

  • Office2000下內部COM插件的編程實現 — 徐景周
  • Word2000/XP中內部COM插件的編程實現 — 徐景周
  • Excel2000/XP和PowerPoint2000/XP下內部COM插件的實現 — 徐景周
  • ATL開發指南(第二版) — Tom Armstrong & Ron Patton
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved