📄 gwcommand.cpp
字号:
lpSubClassInfo=(LPSUBCLASSINFO)calloc(sizeof(SUBCLASSINFO), 1);
if(NULL != lpSubClassInfo)
{
//fill up the struct with the new control window and groupwise's
//original window proc of the visible message body control
lpSubClassInfo->hWndOther=hOverlappingWnd;
lpSubClassInfo->wpOrigProc=(WNDPROC)GetWindowLong(hVisibleMsgWindow, GWL_WNDPROC);
pgpAssert(NULL != lpSubClassInfo->wpOrigProc);
//store the info in our property for the msg text control.
_VERIFY(0 != SetProp(hVisibleMsgWindow, MODULENAME, lpSubClassInfo));
lpSubClassInfo=NULL;
//subclass now - since the subclass proc can get the details from subclassinfo
SetWindowLong(hVisibleMsgWindow, GWL_WNDPROC, (LONG)SubClassedMsgBodyWndProc);
}
}
//NOTE:control comes here only if we created (just now or sometime in the past) a
//new window. mark the exit path when we set the text in the original control and
//bail out.
//show and set the text on the new control
SendMessage(hOverlappingWnd, WM_SETTEXT, 0, (LPARAM)pszMailTextToWrite);
ShowWindow(hOverlappingWnd, SW_SHOW);//necessary for all those cases when we might have hidden it
//hide the original control
pgpAssert(NULL != hVisibleMsgWindow);
ShowWindow(hVisibleMsgWindow, SW_HIDE);
hTrackedMsgWnd=hVisibleMsgWindow;
cleanup:
return hrRet;
}
//////////////////////////////////////////////////////////////////
// Name:CGWCommand::GetSelectedMessageId
//
// Description:This is called to determine the message id of the
// selected message if any. This is an attempt to determine
// which message is actually on view in the quick view window.
//
//
// Out:bstrMessageId - message id as a BSTR
//
// Comments: This function fails if more than one message is
// selected.
///////////////////////////////////////////////////////////////////
STDMETHODIMP CGWCommand::GetSelectedMessageId(BSTR &bstrMessageId)
{
HRESULT hrRet=S_OK;
IDispatch *pDispTemp=NULL;
DIGWMessage *pGwDispMsg=NULL;
IGWClientState *pClientState=NULL;
IGWMessageList *pMsgs=NULL;
IGWMessage *pSelMsg=NULL;
LONG lMsgCount=0;
VARIANT vtTmp={0};
//if some message id is lying around
if(NULL != bstrMessageId)
{
SysFreeString(bstrMessageId);//free it
bstrMessageId=NULL;
}
//get the client state
pgpAssert(NULL != m_pIMgr);
hrRet=m_pIMgr->get_ClientState(&pDispTemp);
pgpAssert(SUCCEEDED(hrRet) && (NULL != pDispTemp));
if(FAILED(hrRet) || (NULL == pDispTemp))
{
hrRet=E_FAIL;
goto cleanup;
}
hrRet=pDispTemp->QueryInterface(IID_IClientState, (void **)&pClientState);
pgpAssert(SUCCEEDED(hrRet) && (NULL != pClientState));
if(FAILED(hrRet) || (NULL == pClientState))
{
hrRet=E_FAIL;
goto cleanup;
}
pgpAssert(NULL != pDispTemp);
pDispTemp->Release();
pDispTemp=NULL;
//get the selected message list
hrRet=pClientState->get_SelectedMessages(&pDispTemp);
pgpAssert(SUCCEEDED(hrRet) && (NULL != pDispTemp));
if(FAILED(hrRet) || (NULL == pDispTemp))
{
hrRet=E_FAIL;
goto cleanup;
}
hrRet=pDispTemp->QueryInterface(IID_IGWMessageList, (void **)&pMsgs);
pgpAssert(SUCCEEDED(hrRet) && (NULL != pMsgs));
if(FAILED(hrRet) || (NULL == pMsgs))
{
hrRet=E_FAIL;
goto cleanup;
}
pgpAssert(NULL != pDispTemp);
pDispTemp->Release();
pDispTemp=NULL;
//get the count of selected messages
hrRet=pMsgs->get_Count(&lMsgCount);
pgpAssert(SUCCEEDED(hrRet));
if(FAILED(hrRet) || (1 != lMsgCount))//if failed or multiple selection
{
hrRet=E_FAIL;//we dont know which one is selected for the preview pane :(
goto cleanup;
}
//zero in on the only message selected
vtTmp.vt=VT_I4;
vtTmp.lVal=1;
hrRet=pMsgs->Item(vtTmp, &pGwDispMsg);
pgpAssert(SUCCEEDED(hrRet) && (NULL != pGwDispMsg));
if(FAILED(hrRet) || (NULL == pGwDispMsg))
{
hrRet=E_FAIL;
goto cleanup;
}
hrRet=pGwDispMsg->QueryInterface(IID_IGWMessage, (void **)&pSelMsg);
pgpAssert(SUCCEEDED(hrRet) && (NULL != pSelMsg));
if(FAILED(hrRet) || (NULL == pSelMsg))
{
hrRet=E_FAIL;
goto cleanup;
}
//get the message id of that message
hrRet=pSelMsg->get_MessageID(&bstrMessageId);
if(FAILED(hrRet) || (NULL == bstrMessageId))
{
hrRet=E_FAIL;
goto cleanup;
}
cleanup:
if(NULL != pClientState)
{
pClientState->Release();
pClientState=NULL;
}
if(NULL != pDispTemp)
{
pDispTemp->Release();
pDispTemp=NULL;
}
if(NULL != pGwDispMsg)
{
pGwDispMsg->Release();
pGwDispMsg=NULL;
}
if(NULL != pMsgs)
{
pMsgs->Release();
pMsgs=NULL;
}
if(NULL != pSelMsg)
{
pSelMsg->Release();
pSelMsg=NULL;
}
return hrRet;
}
#if(WINVER < 0x0500)
//copied from winuser.h. quick fix for compilation failures
//Menubar information
typedef struct tagMENUBARINFO
{
DWORD cbSize;
RECT rcBar; // rect of bar, popup, item
HMENU hMenu; // real menu handle of bar, popup
HWND hwndMenu; // hwnd of item submenu if one
BOOL fBarFocused:1; // bar, popup has the focus
BOOL fFocused:1; // item has the focus
} MENUBARINFO, *PMENUBARINFO, *LPMENUBARINFO;
extern "C"
BOOL
WINAPI
GetMenuBarInfo(
IN HWND hwnd,
IN LONG idObject,
IN LONG idItem,
OUT PMENUBARINFO pmbi
);
#define OBJID_MENU 0xFFFFFFFD
#endif // WINVER < 0x0500
//////////////////////////////////////////////////////////////////
// Name:CGWCommand::LearnCommandContext
//
// Description:This is called to determine and learn the context
// of this command object. This is perhaps the most important
// part of the command object and is the source and consumer
// of the command hash maintained by us for getting details
// such as command state when needed.
//
// Comments:
//
///////////////////////////////////////////////////////////////////
STDMETHODIMP CGWCommand::LearnCommandContext()
{
HRESULT hrRet=S_OK;
PMSGINFO lpMsgInfo=NULL;
SUBCLASSINFO *lpSubClassInfo=NULL;
MENUBARINFO mbiInfo={sizeof(MENUBARINFO), 0};
BOOL bFreeMsgInfo=FALSE, bLocked=FALSE, bRet=TRUE;
//if we dont know the context window(which is the key to the hash)
if(NULL == m_hCtxtWindow)
{
if(m_dwCmdUiInfo&CUIO_MAIL_CONTEXT)
m_hCtxtWindow=GetWindow(GWO_CURRENTMAIL_WINDOW);
else if(m_dwCmdUiInfo&CUIO_MAINWND_CONTEXT)
m_hCtxtWindow=GetWindow(GWO_CURRENTTOPLEVEL_WINDOW);
else if(m_dwCmdUiInfo&CUIO_ATTVIEW_CONTEXT)
m_hCtxtWindow=GetWindow(GWO_CURRENTATTVIEWER_WINDOW);
else//if we dont know the window context yet we cannot do much
goto cleanup;
pgpAssert(NULL != m_hCtxtWindow);
#ifdef _DEBUG
//verify the class names just to make sure we got the right window
{
char szClassName[255]={0};
//get the window class name
int iRet=GetClassName(m_hCtxtWindow, szClassName,
sizeof(szClassName)-sizeof(char));
pgpAssert(iRet > 0);
pgpAssert((m_dwCmdUiInfo&CUIO_MAINWND_CONTEXT)?
(0 == strcmp(szClassName, MAINWINDOWCLASSNAMEA)):TRUE);//main window class name
pgpAssert((m_dwCmdUiInfo&CUIO_MAIL_CONTEXT)?
(0 == strcmp(szClassName, MAILVIEWWINDOWCLASSNAMEA)):TRUE);//mail window class name
pgpAssert((m_dwCmdUiInfo&CUIO_ATTVIEW_CONTEXT)?
(0 == strcmp(szClassName, ATTACHMENTVIEWERWINDOWCLASSNAMEA)):TRUE);//attachment window class name
}
#endif
}
//if for some reason we could not get the context window by now
if(NULL == m_hCtxtWindow)
goto cleanup;//bail out
//query the hash for other info
lpMsgInfo=g_pccihCmdHash->Get((ULONG)m_hCtxtWindow);
if(NULL == lpMsgInfo)//if we did not get details from the hash
{
//allocate one chunk of msg info
lpMsgInfo = (PMSGINFO)calloc(sizeof(MSGINFO), 1);
pgpAssert(NULL != lpMsgInfo);
if(NULL == lpMsgInfo)
{
hrRet=E_OUTOFMEMORY;
goto cleanup;
}
//fill the key(=context window handle)
if(0 == lpMsgInfo->ulKey)
lpMsgInfo->ulKey=(ULONG)m_hCtxtWindow;
//remember the menu bar handle
//bRet=GetMenuBarInfo(m_hCtxtWindow, OBJID_MENU, 0, &mbiInfo);
//pgpAssert(TRUE == bRet);
//if(TRUE == bRet)
// lpMsgInfo->hMenuBar=mbiInfo.hMenu;
lpMsgInfo->hMenuBar=GetMenu(m_hCtxtWindow);
pgpAssert(NULL != lpMsgInfo->hMenuBar);
//initialize the state to be unknown since we are yet to learn state
lpMsgInfo->dwState = MIS_OPTION_UNKNOWN;
//insert the newly allocated info structure
bRet=g_pccihCmdHash->Insert(lpMsgInfo);
pgpAssert(TRUE == bRet);
if(FALSE == bRet)
{
hrRet=E_FAIL;
bFreeMsgInfo=TRUE;
goto cleanup;
}
}
g_pccihCmdHash->Lock();
bLocked=TRUE;
//if we are in the main window context
if((m_dwCmdUiInfo&CUIO_MAINWND_CONTEXT) && (NULL == lpMsgInfo->bstrId))
{
//check the current selection of messages
GetSelectedMessageId(lpMsgInfo->bstrId);
}
//if we are in some message window context and we dont know the
//message id of it yet...
if((NULL == lpMsgInfo->bstrId) &&
((m_dwCmdUiInfo&CUIO_MAIL_CONTEXT) || (m_dwCmdUiInfo&CUIO_ATTVIEW_CONTEXT)))
{
//get the message id involved
hrRet=Publish("ItemMessageIDFromView()", &(lpMsgInfo->bstrId));
pgpAssert(SUCCEEDED(hrRet) && (NULL != lpMsgInfo->bstrId));
if(FAILED(hrRet) || (NULL == lpMsgInfo->bstrId))
{
hrRet=E_FAIL;
goto cleanup;
}
}
//if we dunno if we are in old mail context or new
if((0 < (m_dwCmdUiInfo&CUIO_MAIL_CONTEXT)) &&
(0 == (m_dwCmdUiInfo&CUIO_NEWMAIL_CONTEXT)) &&
(0 == (m_dwCmdUiInfo&CUIO_OLDMAIL_CONTEXT)))
{
//this code should never execute
pgpAssert(FALSE);//we failed to learn the new mail/old mail context till now !
if(NULL != lpMsgInfo->bstrId)
{
//check if the
if(0 == wcscmp(lpMsgInfo->bstrId, NEWMESSAGEMSGIDW))
m_dwCmdUiInfo |= CUIO_NEWMAIL_CONTEXT;
else
{
//NOTE:the id is not same as "X00" - this does not necessarily mean
//that this is an old mail - as is the case with draft mails opened
//we do this here nevertheless just as a backup for other smarter
//methods of determining this elsewhere in the plugin.
m_dwCmdUiInfo |= CUIO_OLDMAIL_CONTEXT;
}
}
}
//if the state flags of this command are yet to be learnt
if(((m_dwCmdUiInfo&CUIO_NEWMAIL_CONTEXT) ||
(m_dwCmdUiInfo&CUIO_OLDMAIL_CONTEXT)) &&
(lpMsgInfo->dwState&MIS_OPTION_UNKNOWN))
{
BOOL bRet=TRUE;
PGPBoolean pgpbFlag=FALSE;
//if we are in the new mail context set some of the preferences
//as is chosen currently in pgp options dialog
if(m_dwCmdUiInfo&CUIO_NEWMAIL_CONTEXT)
{
//unset the unknown state bit
lpMsgInfo->dwState &= ~MIS_OPTION_UNKNOWN;
pgpAssert(0 == lpMsgInfo->dwState);//no other mask should be set
//check if the prefs are set to encrypt on send. new mails in that case
//will have that option set by default
bRet=PgpGwGetBoolPref(kPGPPrefMailEncryptDefault, pgpbFlag);
pgpAssert(TRUE == bRet);
if((TRUE == bRet) && (TRUE == pgpbFlag))
lpMsgInfo->dwState |= MIS_AUTO_ENCRYPT_ON_SEND;
//check if the prefs are set to sign automatically on send. new mails
//in that case will have that option set by default
bRet=PgpGwGetBoolPref(kPGPPrefMailSignDefault, pgpbFlag);
pgpAssert(TRUE == bRet);
if((TRUE == bRet) && (TRUE == pgpbFlag))
lpMsgInfo->dwState |= MIS_AUTO_SIGN_ON_SEND;
//check if spell checker is on.
}
else if(m_dwCmdUiInfo&CUIO_OLDMAIL_CONTEXT)
{
//unset the unknown state bit
lpMsgInfo->dwState &= ~MIS_OPTION_UNKNOWN;
pgpAssert(0 == lpMsgInfo->dwState); //no other mask should be set
//check if the prefs are set to decrypt/verify automatically on open
bRet=PgpGwGetBoolPref(kPGPPrefAutoDecrypt, pgpbFlag);
pgpAssert(TRUE == bRet);
if((TRUE == pgpbFlag) && (TRUE == pgpbFlag))
lpMsgInfo->dwState |= MIS_AUTO_DECRYPT_ON_OPEN;
}
//if we are in a discussion context
if(m_dwCmdUiInfo&CUIO_DISCUSSION_CONTEXT)
{
//unset the unknown state bit
lpMsgInfo->dwState &= ~MIS_OPTION_UNKNOWN;
lpMsgInfo->dwState |= MIS_SKIP_OPERATION;//we skip all operations on this item
}
}
cleanup:
if((TRUE == bFreeMsgInfo) && (NULL != lpMsgInfo))
{
//there should be no reference to this in the hash
pgpAssert(NULL == g_pccihCmdHash->Get(lpMsgInfo->ulKey));
if(NULL != lpMsgInfo->bstrId)
{
SysFreeString(lpMsgInfo->bstrId);
lpMsgInfo->bstrId=NULL;
}
free(lpMsgInfo);
lpMsgInfo=NULL;
}
if(TRUE == bLocked)
g_pccihCmdHash->UnLock();
return hrRet;
}
BOOL CGWCommand::EnableCommands(HMENU hMenuBar, BOOL bEnable, DWORD dwFlags)
{
BOOL bMoreItemsExist=TRUE, bRet=TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -