VC实现插件的开发

要实现Add-in Object 有三种方法,一种是利用ATL COM Wizard中的ATL对象 Add-in Object来实现,另一种是利用DevStudio Add-in Wizard来实现,第三种就是手工写所有的代码,如果手工写,一定要记住实现IDSAddIn接口,这样才能才能增加新的命令和工具条到VC的IDE环境中去。

  我主要是讲解ATL COM Wizard,所以我用第一种方法来实现。在这里我实现了IApplicationEvents 和 IDSAddIn接口,实现IapplicationEvents接口是应为我要对Application 对象进行操作,比如NewDocument()、WorkspaceOpen()等等方法。而实现IDSAddIn接口,是应为要增加新的命令和工具条到VC的IDE环境中去。

  示例程序实现的功能:

  1)在VC的IDE环境中增加一个工具条(4个按钮),并且能操纵VC的IDE环境,(工具条如下图) 第一个按钮弹出对话框允许修改用户信息,第二个按钮最小化所有打开的窗口,第三个最大化所有的窗口,第四个按钮弹出一个Messagbox。



  2)对每一个新建的文档,根据文档类型在文件头自动加上版权信息和相关内容注释。

  观看效果:下载源代码,编译后生成Sample_02.dll,然后在VC的环境中,选择菜单tools/customize ,然后选择最后一个Add-ins and Macro Files 标签,选择Browse按钮,选择刚才编译后的Sample_02.dll文件,然后在Add-ins adn Macro列表框中选中Copyright Class ,然后Close Customize对话框,这时VC的IDE环境就会出现一个有四个按钮的工具条(见上图)。大家可以分别点击这几个按钮看看效果,也可分别在VC环境中(新建)New 几种类型的文件(.cpp ,.h .htm 和.txt文件)看看文件头是否加上版权信息.

  下面一步步引导大家来实现此例子程序:

  1) 用ATL COM Wizard建立一个叫Sample_02的DLL项目文件

  2) 在Class Wizard 中鼠标右键,在弹出菜单种选择New ATL Object…

  3) 在ATL COM Wizard对话框中的Categroy选择Object 在Object中选择Add-in Object,选择Next按钮(如图)。


 4) 选择属性对话框的Names标签,在C++组的Short Name编辑框输入Copyright(如图)



  5) 选择DevStudio Add-in标签,在Add-in Features中选择Application Events,选择OK按钮确定



  上面的步骤生成基本Add-in框架代码

  6) 创建IDE工具条

   a) 创建两个Bitmap 文件作为工具条图像资源

    IDB_TOOLBAR_LARGE_COPYRIGHT 32 x 32大小

    IDB_TOOLBAR_MEDIUM_COPYRIGHT 16 x 16 大小

   b) 在Ccopyright 类的OnConnection()函数中加入创建工具条按钮的代码, 详细代码:

HRESULT CCopyright::OnConnection(IApplication* pApp, 
VARIANT_BOOL bFirstTime, long dwAddInID, VARIANT_BOOL* bOnConnection)
{
HRESULT hr = S_OK;
m_spApplication = pApp;
m_dwAddInID = dwAddInID;

// Connect up to application event sink
AtlAdvise(pApp, GetUnknown(), IID_IApplicationEvents, &m_dwAppEvents);

hr = pApp->SetAddInInfo((long)_Module.GetModuleInstance(), 
static_cast<ICopyright*>(this), IDB_TOOLBAR_MEDIUM_COPYRIGHT, 
IDB_TOOLBAR_LARGE_COPYRIGHT, dwAddInID);

// LPCTSTR szCommand = _T("ShowInfoDlg");
VARIANT_BOOL bRet;
if (SUCCEEDED(hr))
{
hr = pApp->AddCommand(CComBSTR(_T("ShowInfoDlgÏÔʾ
ÐÞ¸ÄÓûµÄ
æȨÐÅÏ¢
Ð޸İæÈ
ÐÅÏ¢")),CComBSTR(_T("ShowInfoDlg")), 0, dwAddInID, &bRet);
hr = pApp->AddCommand(CComBSTR(_T("MiniWindownËõС
n×îС»¯ËÓеĴ
¿ÚîС»¯´°¿Ú")),
CComBSTR(_T("MiniWindow")), 1, dwAddInID, &bRet);
hr = pApp->AddCommand(CComBSTR(_T("MaxWindown·Å´
î´»¯ËÓеĴ
¿Úî´»¯´
¿Ú")),CComBSTR(_T("MaxWindow")), 2, dwAddInID, &bRet);
hr = pApp->AddCommand(CComBSTR(_T("TestnTestnTestnTest")),CComBSTR(_T("Test")), 3, dwAddInID, &bRet);
}

// Add toolbar buttons only if this is the first time the add-in
// is being loaded. Toolbar buttons are automatically remembered
// by Developer Studio from session to session, so we should only
// add the toolbar buttons once.
if (bFirstTime)
{
if (SUCCEEDED(hr))
{
hr = pApp->AddCommandBarButton(dsGlyph, CComBSTR(_T("ShowInfoDlg")), dwAddInID);
hr = pApp->AddCommandBarButton(dsGlyph, CComBSTR(_T("MiniWindow")), dwAddInID);
hr = pApp->AddCommandBarButton(dsGlyph, CComBSTR(_T("MaxWindow")), dwAddInID);
hr = pApp->AddCommandBarButton(dsGlyph, CComBSTR(_T("Test")), dwAddInID);

}
}
//
CRegKey reg;
TCHAR strName[256];
DWORD dwSize = 256,dwRet = 0;
reg.Create(HKEY_CURRENT_USER,_T("SoftwareEvesoftAddins"));
dwRet = reg.QueryValue(strName,_T("NAME"),&dwSize);
if(dwRet != ERROR_SUCCESS || lstrlen(strName) == 0)
m_bstrName = _T("Evelan");
else
m_bstrName = strName;

dwSize = 100;
dwRet = reg.QueryValue(strName,_T("EMAIL"),&dwSize);
if(dwRet != ERROR_SUCCESS || lstrlen(strName) == 0)
m_bstrEmail = _T("dbw.evelan@263.net");
else
m_bstrEmail = strName;

//

*bOnConnection = SUCCEEDED(hr) ? VARIANT_TRUE :VARIANT_FALSE;
return hr;
}

HRESULT CCopyright::OnDisconnection(VARIANT_BOOL bLastTime)
{
AtlUnadvise(m_spApplication, IID_IApplicationEvents, m_dwAppEvents);
return S_OK;
} 


  此段代码主要用了Application Object的两个方法AddCommand()和AddCommandBarButton(),AddCommand()方法调用后,在菜单的Tools/Customize 中的Commands标签中的Categroy列表框中就会有对应的Command命令(),
增加命令对应的方法:

  1) 如果要增加一条命令,必须在Icopyright中增加相应的方法。如在示例程序中我增加了MiniWindow这个命令,那么我在Icopyright中也必须增加MiniWindow这样一个方法 (在ClassWizard中鼠标右键Icopyright,在弹出菜单中选择Add Method 即可增加方法)

  示例程序程序中共增加了四个命令:ShowInfoDlg,MiniWindow,MaxWindow和Test,应此必须在Icopyright接口中实现此四个方法

  7)实现工具条后,就是实现具体的方法了,具体的实现请参看Ccopyright中的四个方法

STDMETHODIMP CCopyright::ShowInfoDlg()
STDMETHODIMP CCopyright::MaxWindow()
STDMETHODIMP CCopyright::MiniWindow()
STDMETHODIMP CCopyright::Test()
STDMETHODIMP CCopyright::ShowInfoDlg()
{
// TODO: Add your implementation code here
USES_CONVERSION;
CUserInfoDlg dlg;
dlg.m_bstrName = m_bstrName;
dlg.m_bstrEmail = m_bstrEmail;
if(dlg.DoModal() == IDOK)
{
m_bstrName = dlg.m_bstrName;
m_bstrEmail = dlg.m_bstrEmail;
}
CRegKey reg;
reg.Create(HKEY_CURRENT_USER,_T("SoftwareEvesoftAddIns"));
reg.SetValue(OLE2CT(m_bstrName),_T("NAME"));
reg.SetValue(OLE2CT(m_bstrEmail),_T("EMAIL"));
reg.Close();
return S_OK;
}

STDMETHODIMP CCopyright::MaxWindow()
{
// TODO: Add your implementation code here
CComPtr<IDispatch> pDispWindows;
CComQIPtr<IWindows, &IID_IWindows> pWindows;
m_spApplication->get_Windows(&pDispWindows);
pWindows = pDispWindows;
pDispWindows = NULL;

CComPtr<IUnknown> pUnk;
CComQIPtr<IEnumVARIANT, &IID_IEnumVARIANT> pNewEnum;
if (SUCCEEDED(pWindows->get__NewEnum(&pUnk)) && pUnk != NULL)
{
pNewEnum = pUnk;
VARIANT varWindow;
CComQIPtr<IGenericWindow, &IID_IGenericWindow> pWindow;
while (pNewEnum->Next(1, &varWindow, NULL) == S_OK)
{
pWindow = varWindow.pdispVal;
VariantClear(&varWindow);
CComBSTR bstrCaption;
pWindow->get_Caption(&bstrCaption);
//dsWindowStateMaximized ×î´ó»¯
pWindow->put_WindowState(dsWindowStateMaximized);
}
}

return S_OK;
}

STDMETHODIMP CCopyright::MiniWindow()
{
// TODO: Add your implementation code here
CComPtr<IDispatch> pDispWindows;
CComQIPtr<IWindows, &IID_IWindows> pWindows;
m_spApplication->get_Windows(&pDispWindows);
pWindows = pDispWindows;
pDispWindows = NULL;

CComPtr<IUnknown> pUnk;
CComQIPtr<IEnumVARIANT, &IID_IEnumVARIANT> pNewEnum;
if (SUCCEEDED(pWindows->get__NewEnum(&pUnk)) && pUnk != NULL)
{
pNewEnum = pUnk;
VARIANT varWindow;
CComQIPtr<IGenericWindow, &IID_IGenericWindow> pWindow;
while (pNewEnum->Next(1, &varWindow, NULL) == S_OK)
{
pWindow = varWindow.pdispVal;
VariantClear(&varWindow);
CComBSTR bstrCaption;
pWindow->get_Caption(&bstrCaption);
//dsWindowStateMaximized ×î´ó»¯
pWindow->put_WindowState(dsWindowStateMinimized);
}
}
return S_OK;
}

STDMETHODIMP CCopyright::Test()
{
// TODO: Add your implementation code here
MessageBox(NULL,"ллʹÓ
㬶¡Ó±ÉÏ","ÖÂл",MB_OK | MB_ICONINFORMATION);
return S_OK;

} 



  值的说明的是在ShowInfoDlg()方法中弹出了一个对话框。在ATL中类似于这种对话框很容易实现。在Class Wizard 中鼠标右键,在弹出菜单种选择New ATL Object…在ATL Object wizard中的Category中选择Miscellaneous ,在Object中选择Dialog,Next按钮后,在ATL Object wizard属性对话框中Short name 编辑框中输入UserInfoDlg即完成对话框的实现。另外,对话框中输入的用户信息是记载在注册表中的.ShowInfoDlg()方法弹出的界面如下图:



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值