⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 commandfactory.cpp

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 CPP
📖 第 1 页 / 共 3 页
字号:
////////////////////////////////////////////////////////////////////////////////
//  File : CommandFactory.cpp
//
//  Copyright (C) 2002 PGP Corporation
//
//  ABSTRACT
//		Create CommandFactory object.
// 
//  Author: Satya S. Das
//
////////////////////////////////////////////////////////////////////////////////
// include files 
#include <crtdbg.h>
#include "pgpdebug.h"
#include "windows.h"
#include "shlwapi.h"
#include "gwdll.h"
#include "gwoapi.h"
#include "gwc3po.h"
#include "gwc3cmd.h"
#include "CommandFactory.h"
#include "GwCommand.h"
#include "util.h"
#include "ofcmndr.h"
#include "globals.h"
#include "resource.h"
#include "globals.h"
#include "globdefs.h"
#include "pgpclientprefs.h"

// Globals 
int	AcceptFlag=0;

//external functions
extern HRESULT Publish(LPCSTR szTokenBuf, BSTR *pbstrResult);

// external data 
extern	IC3POManager *m_pIMgr;

// internal functions 
IUnknown * BuildIUnkDispatch(REFCLSID libid, REFCLSID iid, IUnknown *pIUnk, void *pIFac);


// private functions 
//////////////////////////////////////////////////////////////////
//  Name:CCommandFactory::CCommandFactory				
//
//  Description:CCommandFactory constructor 
//
//  In:none
//
//  Out:none
//
//  Comments:		
//////////////////////////////////////////////////////////////////
CCommandFactory::CCommandFactory(IUnknown *pUnk)
{
	PgpGwTrace("CCommandFactory::CCommandFactory\n");
	m_pUnkOuter = pUnk;
	m_pIUnkDispFact = NULL;
}

//////////////////////////////////////////////////////////////////
//  Name:CCommandFactory::~CCommandFactory				
//
//  Description:CCommandFactory destructor	
//
//  In:none
//
//  Out:none
//
//  Comments:		
//////////////////////////////////////////////////////////////////
CCommandFactory::~CCommandFactory()
{
	PgpGwTrace("CCommandFactory::~CCommandFactory\n");
	if(m_pIUnkDispFact)
	{
		m_pIUnkDispFact->Release();
		m_pIUnkDispFact=NULL;
	}
}

//////////////////////////////////////////////////////////////////
//  Name:CCommandFactory::QueryInterface				
//
//  Description:QueryInterface for CCommandFactory
//
//  In:REFIID riid -  Reference id
//
//  Out:LPVOID FAR* ppv - 
//
//  Comments:		
////////////////////////////////////////////////////////////////////
STDMETHODIMP CCommandFactory::QueryInterface(REFIID riid, LPVOID FAR* ppv)
{
	PgpGwTrace("CCommandFactory::QueryInterface\n");
	if(NULL == ppv)
		return E_INVALIDARG;

    *ppv=NULL;


	if((IID_ICommandFactory == riid ) || (IID_IUnknown == riid))
	{
		*ppv  = this;
		((LPUNKNOWN)*ppv)->AddRef();
		return S_OK;
	}

	if(IID_IDispatch == riid)
	{
		if (NULL == m_pIUnkDispFact)
		{
			m_pIUnkDispFact = BuildIUnkDispatch(LIBID_PgpGwTypeLibrary,
				IID_ICommandFactory, (IUnknown *)(ICommandFactory *)this,
				(void *)(ICommandFactory *)this);
		}

		if (NULL != m_pIUnkDispFact)
			return m_pIUnkDispFact->QueryInterface(IID_IDispatch, ppv);
	}

	return E_NOINTERFACE;
}

//////////////////////////////////////////////////////////////////
//  Name:			CCommandFactory::BuildCommand				
//
//  Description:This method is invoked to create a Command object. 
//				The C3po cannot assume that Command::WantComand 
//				has been called before this method is invoked.
//	
//
//  In:	BSTR bstrContext - This is the context for the command. The 
//		context string contains either the class of a GW data object
//		(e.g. GW.MESSAGE.MAIL.X) or the class of the specific user 
//		interface(e.g. GW.APPLICATION.BROWSER).
//
//		BSTR bstrPersistentID - This can be either a "pre-defined" ID 
//		or is an ID provided in a previous run of GW.
//
//		IDispatch * pIDispBaseCommand - The command object of the 
//		command being overridden.
//
//		IDispatch * pIDispParameters - The parameter list of the command.
//
//  Out:IDispatch * FAR* ppIDispGWCommand - Command object for persistentID.
//
//  Comments:Each time the BuildCommand is invoked, the C3po should 
//			 return a new instance of a GWCommand object. This is 
//			 neccessary because BuildCommand can be called recursively.
////////////////////////////////////////////////////////////////////
STDMETHODIMP CCommandFactory::BuildCommand(BSTR bstrContext, 
			BSTR bstrPersistentID, IDispatch * pIDispBaseCommand, 
			IDispatch * pIDispParameters, IDispatch * FAR* ppIDispGWCommand)
{
	PgpGwTrace("CCommandFactory::BuildCommand(context=%S, id=%S)\n",
					bstrContext, bstrPersistentID);

	pgpAssert(NULL != pIDispBaseCommand);
	pgpAssert(NULL != ppIDispGWCommand);

	pgpAssert(0 == _wcsicmp(bstrContext, MAILMESSAGECONTEXTW));//should be a mail message
	pgpAssert(0 == _wcsicmp(bstrPersistentID, wceGW_CMDID_OPEN));//should be the open command

	HRESULT hrRet=S_OK;
	IGWCommand *pigwBaseCmd=NULL;
	CGWCommand *pcgwCmdTemp=NULL;
	if((NULL == pIDispBaseCommand) || (NULL == ppIDispGWCommand))
	{
		hrRet=E_FAIL;
		goto cleanup;
	}

	//check if we have expired. if so we do not show any commands
	if(TRUE == g_bPlugInExpired)
	{
		hrRet=E_FAIL;
		goto cleanup;
	}

	try
	{
		//create a new command object. 
		pcgwCmdTemp= new CGWCommand(IDM_MAIL_OPEN, CUIO_IS_AN_OPERATION);
	}
	catch(...)
	{
		hrRet=E_OUTOFMEMORY;
		goto cleanup;
	}
	pgpAssert(NULL != pcgwCmdTemp);
	if(NULL == pcgwCmdTemp)
	{
		hrRet=E_OUTOFMEMORY;
		goto cleanup;
	}

	//request command interface pointer from the dispatch passed
	hrRet=pIDispBaseCommand->QueryInterface(IID_IGWCommand, (void**)&pigwBaseCmd);
	pgpAssert(SUCCEEDED(hrRet) && (NULL != pigwBaseCmd));
	if(FAILED(hrRet) || (NULL == pigwBaseCmd))
		goto cleanup;


	//put the base command dispatch in the object
	pcgwCmdTemp->Set_BaseCommand(pigwBaseCmd);

    //request a dispatch interface. GW frees up this later. evidently it does not
	//do addref and assumes it is already addrefed
	hrRet=pcgwCmdTemp->QueryInterface(IID_IDispatch, (void**)ppIDispGWCommand);
	pgpAssert(SUCCEEDED(hrRet) && (NULL != *ppIDispGWCommand));
	if(FAILED(hrRet) || (NULL == *ppIDispGWCommand))
		goto cleanup;
	
cleanup:
	
	return S_OK;
}

//////////////////////////////////////////////////////////////////
//  Name:CCommandFactory::WantCommand				
//
//  Description:This method is used to query the C3po for it's 
//				intention to support a predefined command.
//
//  In:BSTR bstrContext This is the actual object class associates 
//						with the command. 
//	   BSTR bstrPersistentID This can be either a "pre-defined"
//          ID or is an ID provided in a previous run of GW. 
//
//  Out:VARIANT_BOOL FAR* pbChanged
//			TRUE - I do want to support this predefined command
//			FALSE - I do not want to support this predefined command
//
//  Comments:		Not Implemented		
////////////////////////////////////////////////////////////////////
STDMETHODIMP CCommandFactory::WantCommand(BSTR bstrContext, 
					BSTR bstrPersistentID, VARIANT_BOOL FAR* pbChanged)
{
	PgpGwTrace("CCommandFactory::WantCommand(context=%S, id=%S)\n", 
			bstrContext, bstrPersistentID);

	//if it is a mail or the attachment viewer being opened
	if(((0 != wcsstr(bstrContext, MAILMESSAGECONTEXTW)) ||
		(0 != wcsstr(bstrContext, ATTCHVIEWERCONTEXTW))) && 
		(0 == _wcsicmp(bstrPersistentID, wceGW_CMDID_OPEN)))
	{
		//check if auto-decrypt bit on open is set in pgp options
		PGPBoolean pgpbFlag=FALSE;
		BOOL bRet=PgpGwGetBoolPref(kPGPPrefAutoDecrypt, pgpbFlag);
		pgpAssert(TRUE == bRet);

		//we trap open only if the the bit is set
		*pbChanged=pgpbFlag;
	}
	else
		*pbChanged=FALSE;

	return S_OK;
}
   

//////////////////////////////////////////////////////////////////
//  Name:CCommandFactory::CustomizeContextMenu				
//
//  Description:Method to customize the menu.	
//
//  In:BSTR bstrContext The context string property is the class of the
//          containing window.  For example "GW.APPLICATION.BROWSER"
//     IDispatch * pIDispGWMenu - The main menu object being modified.
//
//  Out:TOleBool - The return value indicates whether the modifications 
//		to the menu were "volatile".  If the return value is TRUE, 
//		CustomizeMenu() will continue to be called each time the menu 
//		may need to be updated e.g. at each popup creation).  Otherwise, 
//		C3PO servers can safely assume that CustomizeMenu is called only 
//		once for any single instance of a menu.  This simplifies the 
//		resulting code because there is no need to check for commands 
//		that might already be on the menu. That is, the C3PO's command 
//		are guaranteed to be absent from the menu at the time of the 
//		first CustomizeMenu call.
//
//  Comments:
////////////////////////////////////////////////////////////////////
STDMETHODIMP CCommandFactory::CustomizeContextMenu(BSTR bstrContext, 
						IDispatch * pIDispGWMenu)
{
	PgpGwTrace("CCommandFactory::CustomizeContextMenu(%S)\n", bstrContext);
	IGWMenu	*pIMenu=NULL;
	IGWMenuItems *pIMenuItems=NULL;
	IDispatch *pIDisp=NULL;
	IGWClientState *pClientState=NULL;
	IGWMessageList *pMsgs=NULL;
	HRESULT	hrRet=S_OK;
	VARIANT	vr={0};
	BSTR bstrCaption=NULL;
	LONG lMsgCount=0;
	int iResult=0;
	BSTR bstrResult=NULL;
	VARIANT_BOOL bResult;
	TCHAR *pstr=NULL;

	if (0 != wcsstr(bstrContext, MAILMESSAGECONTEXTW))          // See if it is the correct context
	{
		//get client state to determine if we're being called 
		//from the main browser, not from inside a view.
		hrRet=m_pIMgr->get_ClientState(&pIDisp);
		hrRet=pIDisp->QueryInterface(IID_IClientState, (void **)&pClientState);
		pIDisp->Release();

		pIDisp = NULL;
		hrRet = pClientState->get_SelectedMessages (&pIDisp);
		hrRet = pIDisp->QueryInterface(IID_IGWMessageList, (void **)&pMsgs);
		pIDisp->Release ();
		pIDisp = NULL;
		
		hrRet = pMsgs->get_Count (&lMsgCount);

		pClientState->Release ();
		pClientState = NULL;

		if (0 == lMsgCount)
		{
			// We're in a view, now see if it's a compose view
			g_pigwcCommander->Execute (g_bstrValidateCmd, &bstrResult, &bResult);

			pstr = FROM_OLE_STRING(bstrResult);

			// Handle OnReady event
			if (strcmp(pstr, NEWMESSAGEMSGIDA) == 0)
			{
				hrRet = pIDispGWMenu->QueryInterface(IID_IGWMenu, (void**)&pIMenu);

				//Add menu item
				// Get Menu Items menu
				hrRet = pIMenu->get_MenuItems(&pIDisp);
				pIMenu->Release();

				// Get Cts Menu Items interfaces
				hrRet = pIDisp->QueryInterface(IID_IGWMenuItems, (void**)&pIMenuItems);
				pIDisp->Release();

				// Create new GWCommand object for menu item
				CGWCommand *Cmd01 = new CGWCommand(IDC_ODMA_ATTACH, 0);
				Cmd01->QueryInterface(IID_IDispatch, (void**)&pIDisp);
				bstrCaption = SysAllocString(L"Attach ODMA Document...");

				VariantInit(&vr);
				vr.lVal = 3;
				vr.vt = VT_I4;

				hrRet = pIMenuItems->Add(bstrCaption, pIDisp, vr, &pIDisp );          //Add menu item to menu
				SysFreeString(bstrCaption);
				Cmd01->m_bstrLongPrompt = SysAllocString(L"Add attachments from an ODMA Document Management System");          // Set Long Prompt for menu item

				Cmd01->Release();
				pIDisp->Release();
				pIMenuItems->Release();
			}
		}
	}

	return S_OK;
}

//////////////////////////////////////////////////////////////////
//  Name:CCommandFactory::CustomizeMenu				
//
//  Description:Method to customise the menu.	
//
//  In:BSTR bstrContext - The context string property is the class 
//			of the containing window.  For example "GW.APPLICATION.BROWSER"
//	   IDispatch * pIDispGWMenu - The main menu object being modified.
//
//  Out:VARIANT_BOOL FAR* pbChanged - The return value indicates 
//		whether the modifications to the menu were "volatile".  If 
//		the return value is TRUE, CustomizeMenu() will continue to 
//		be called each time the menu may need to be updated e.g. at 
//		each popup creation).  Otherwise, C3PO servers can safely
//		assume that CustomizeMenu is called only once for any single 
//		instance of a menu.  This simplifies the resulting code because 
//		there is no need to check for commands that might already be on 
//		the menu. That is, the C3PO's command are guaranteed to be 
//		absent from the menu at the time of the first CustomizeMenu 
//		call.
//
//  Comments:
////////////////////////////////////////////////////////////////////
STDMETHODIMP CCommandFactory::CustomizeMenu(BSTR bstrContext,
						IDispatch * pIDispGWMenu, VARIANT_BOOL FAR* pbChanged)
{
	PgpGwTrace("CCommandFactory::CustomizeMenu(%S)\n", bstrContext);
	IGWMenu *pIMenu=NULL;
	IGWMenuItems *pIMenuItems=NULL;
	IDispatch *pIDispTemp=NULL, *pIDispTempTwo=NULL;
	HRESULT hrRet=S_OK;
	BOOL bRet=TRUE;
	VARIANT vTmpOne={0};
	VARIANT vTmpTwo={0};
	char *pszPrependMenuString=NULL, *pszMainMenuString=NULL;
	BSTR bstrCaption=NULL;
	BSTR bstrMessageId=NULL;
	CGWCommand *pcgwCmdTemp=NULL;
	DWORD dwCmdUiOptions=CUIO_IS_MENUBAR_ITEM;

	//if it is the main browser window
	if(0 != wcsstr(bstrContext, MAINWINDOWCONTEXTW))
		dwCmdUiOptions |= CUIO_MAINWND_CONTEXT;
	//or if it is a mail message
	else if (0 != wcsstr(bstrContext, MAILMESSAGECONTEXTW))
	{
		dwCmdUiOptions |= CUIO_MAIL_CONTEXT;

		//additionally if it is a discussion post
		if(0 != wcsstr(bstrContext, DISCUSSIONCONTEXTW))
			dwCmdUiOptions |= CUIO_DISCUSSION_CONTEXT;

		//discussion post context is unfortunately a subclass of mail context
		//so this check needs to be done so we know later that it is a discussion
		//rather than normal mail. the "post" of discussion will kick our tph
		//which would ignore any operations upon detecting this flag
	}
	//or if it is the attachment window
	else if(0 != wcsstr(bstrContext, ATTCHVIEWERCONTEXTW))
		dwCmdUiOptions |= CUIO_ATTVIEW_CONTEXT;
	else//if it is neither a mail message nor the main window nor
	{	//the attachment viewer window
		pgpAssert(FALSE);//erroneous install/faulty hooking
		goto cleanup;//bail out (we are done)
	}

	//request IGWMenu interface of the menu passed
	pgpAssert((NULL != pIDispGWMenu) && (NULL == pIMenu));
	hrRet = pIDispGWMenu->QueryInterface(IID_IGWMenu, (void**)&pIMenu);
	pgpAssert(SUCCEEDED(hrRet) && (NULL != pIMenu));
	if(FAILED(hrRet) || (NULL == pIMenu))
		goto cleanup;
	TraceRefCount(pIMenu);//***


	//query for the read only property MenuItems (of the menu object)
	pgpAssert(NULL == pIDispTemp);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -