|
|
/////////////////////////////////////////////////////////////////////////////
// Copyright (C) 1993-1998 Microsoft Corporation. All Rights Reserved.
//
// MODULE: finder.cpp
//
// PURPOSE:
//
#include "pch.hxx"
#include <process.h>
#include "resource.h"
#include "error.h"
#include "finder.h"
#include "goptions.h"
#include "menuutil.h"
#include "statbar.h"
#include "imnact.h"
#include "note.h"
#include "mailutil.h"
#include "statnery.h"
#include "instance.h"
#include "msoeobj.h"
#include "msglist.h"
#include "storutil.h"
#include "menures.h"
#include "findres.h"
#include "multiusr.h"
#include "newsutil.h"
#include "ruleutil.h"
#include "instance.h"
#include "shlwapip.h"
#include "demand.h"
#include "dllmain.h"
#include "order.h"
ASSERTDATA
#define MF_ENABLEFLAGS(b) (MF_BYCOMMAND|(b ? MF_ENABLED : MF_GRAYED | MF_DISABLED))
typedef struct _ThreadList { DWORD dwThreadID; struct _ThreadList * pPrev; struct _ThreadList * pNext; } OETHREADLIST;
OETHREADLIST * g_pOEThrList = NULL;
// Add thread to list
OETHREADLIST * AddThreadToList(DWORD uiThreadId, OETHREADLIST * pThrList) { if(!pThrList) { if(MemAlloc((LPVOID *) &pThrList, sizeof(OETHREADLIST))) {
pThrList->pPrev = NULL; pThrList->pNext = NULL; pThrList->dwThreadID = uiThreadId; } } else pThrList->pNext = AddThreadToList(uiThreadId, pThrList->pNext);
return(pThrList); }
// Remove thread from list
OETHREADLIST * DelThreadToList(DWORD uiThreadId, OETHREADLIST * pThrList) { OETHREADLIST * pLst = NULL;
if(!pThrList) return(NULL); else if(pThrList->dwThreadID == uiThreadId) { if(pThrList->pPrev) { pThrList->pPrev->pNext = pThrList->pNext; pLst = pThrList->pPrev; } if(pThrList->pNext) { pThrList->pNext->pPrev = pThrList->pPrev; if(!pLst) pLst = pThrList->pNext; }
MemFree(pThrList); pThrList = NULL; } else pThrList->pNext = DelThreadToList(uiThreadId, pThrList->pNext);
return pLst; }
// Close all Finder windows
void CloseAllFindWnds(HWND hwnd, OETHREADLIST * pThrList) { while(pThrList) { CloseThreadWindows(hwnd, pThrList->dwThreadID); pThrList = pThrList->pNext; } }
void CloseFinderTreads() { CloseAllFindWnds(NULL, g_pOEThrList); }
/////////////////////////////////////////////////////////////////////////////
// Thread entry point for the finder
//
unsigned int __stdcall FindThreadProc(LPVOID lpvUnused);
HRESULT CPumpRefCount::QueryInterface(REFIID riid, LPVOID *ppvObj) { TraceCall("CPumpRefCount::QueryInterface"); *ppvObj = NULL;
if (IsEqualIID(riid, IID_IUnknown)) *ppvObj = (LPVOID) (IUnknown *)this;
if (*ppvObj) { AddRef(); return (S_OK); }
return (E_NOINTERFACE); }
ULONG CPumpRefCount::AddRef(void) { TraceCall("CPumpRefCount::AddRef"); return ((ULONG) InterlockedIncrement((LONG *) &m_cRef)); }
ULONG CPumpRefCount::Release(void) { TraceCall("CPumpRefCount::Release");
if (0 == InterlockedDecrement((LONG *) &m_cRef)) { delete this; return 0; }
return (m_cRef); }
//
// FUNCTION: FreeFindInfo
//
void FreeFindInfo(FINDINFO *pFindInfo) { SafeMemFree(pFindInfo->pszFrom); SafeMemFree(pFindInfo->pszSubject); SafeMemFree(pFindInfo->pszTo); SafeMemFree(pFindInfo->pszBody); ZeroMemory(pFindInfo, sizeof(FINDINFO)); }
//
// FUNCTION: CopyFindInfo
//
HRESULT CopyFindInfo(FINDINFO *pFindSrc, FINDINFO *pFindDst) { // Locals
HRESULT hr=S_OK;
// Zero
ZeroMemory(pFindDst, sizeof(FINDINFO));
// Duplicate
pFindDst->mask = pFindSrc->mask; pFindDst->ftDateFrom = pFindSrc->ftDateFrom; pFindDst->ftDateTo = pFindSrc->ftDateTo; pFindDst->fSubFolders = pFindSrc->fSubFolders;
// pszFrom
if (pFindSrc->pszFrom) { // Duplicate the String
IF_NULLEXIT(pFindDst->pszFrom = PszDupA(pFindSrc->pszFrom)); }
// pszTo
if (pFindSrc->pszTo) { // Duplicate the String
IF_NULLEXIT(pFindDst->pszTo = PszDupA(pFindSrc->pszTo)); }
// pszSubject
if (pFindSrc->pszSubject) { // Duplicate the String
IF_NULLEXIT(pFindDst->pszSubject = PszDupA(pFindSrc->pszSubject)); }
// pszBody
if (pFindSrc->pszBody) { // Duplicate the String
IF_NULLEXIT(pFindDst->pszBody = PszDupA(pFindSrc->pszBody)); }
exit: // Done
return hr; }
//
// FUNCTION: DoFindMsg()
//
// PURPOSE: Instantiates the finder object on a separate thread.
//
// PARAMETERS:
// [in] pidl - Folder to default the search in
// [in] ftType - Type of folders being searched
//
// RETURN VALUE:
// HRESULT
//
HRESULT DoFindMsg(FOLDERID idFolder, FOLDERTYPE ftType) { HRESULT hr = S_OK; HTHREAD hThread = NULL; DWORD uiThreadId = 0; FINDERPARAMS * pFindParams = NULL; // Allocate a structure to hold the initialization information that we can
// pass to the other thread.
IF_NULLEXIT(pFindParams = new FINDERPARAMS);
// Initialzie the find
pFindParams->idFolder = idFolder; pFindParams->ftType = ftType; // Create another thread to do the search on
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)FindThreadProc, (LPVOID) pFindParams, 0, &uiThreadId); if (NULL == hThread) IF_FAILEXIT(hr = E_FAIL);
// NULL this out so we don't free it later. The other thread owns freeing
// this.
pFindParams = NULL; hr = S_OK; exit: // Close the thread handle
if (NULL != hThread) CloseHandle(hThread);
// Free the find parameters if we still have a pointer to them.
if (NULL != pFindParams) delete pFindParams; return hr; }
unsigned int __stdcall LOADDS_16 FindThreadProc(LPVOID lpv) { CFindDlg *pFindDlg = NULL; MSG msg; FINDERPARAMS *pFindParams = (FINDERPARAMS *) lpv; DWORD uiThreadId = 0;
// Make sure this new thread has all the initialization performed
// correctly.
OleInitialize(0); CoIncrementInit("FindThreadProc", MSOEAPI_START_SHOWERRORS, NULL, NULL);
EnterCriticalSection(&g_csThreadList);
uiThreadId = GetCurrentThreadId(); g_pOEThrList = AddThreadToList(uiThreadId, g_pOEThrList );
LeaveCriticalSection(&g_csThreadList);
// Create the finder
pFindDlg = new CFindDlg(); if (pFindDlg) { // Show the find dialog. This function will return when the user is
// done.
pFindDlg->Show(pFindParams);
// Message Loop
while (GetMessageWrapW(&msg, NULL, 0, 0)) pFindDlg->HandleMessage(&msg);
pFindDlg->Release(); }
// Free this information
if (NULL != pFindParams) delete pFindParams;
// Uninitialize the thread
EnterCriticalSection(&g_csThreadList);
g_pOEThrList = DelThreadToList(uiThreadId, g_pOEThrList);
LeaveCriticalSection(&g_csThreadList);
CoDecrementInit("FindThreadProc", NULL); OleUninitialize(); return 0; }
CFindDlg::CFindDlg() { m_cRef = 1; m_hwnd = NULL; ZeroMemory(&m_rFindInfo, sizeof(m_rFindInfo)); m_hwndList = NULL; m_hTimeout = NULL; m_hAccel = NULL;
m_pStatusBar = NULL; m_pMsgList = NULL; m_pMsgListCT = NULL; m_pCancel = NULL; m_pPumpRefCount = NULL; ZeroMemory(&m_hlDisabled, sizeof(HWNDLIST));
m_fShowResults = FALSE; m_fAbort = FALSE; m_fClose = FALSE; m_fInProgress = FALSE; m_ulPct = 0; m_fFindComplete = FALSE;
m_hIcon = NULL; m_hIconSm = NULL;
m_dwCookie = 0; m_fProgressBar = FALSE; m_fInternal = 0; m_dwIdentCookie = 0;
m_pViewMenu = NULL; }
CFindDlg::~CFindDlg() { SafeRelease(m_pViewMenu); _FreeFindInfo(&m_rFindInfo); SafeRelease(m_pStatusBar); SafeRelease(m_pMsgList); SafeRelease(m_pMsgListCT); SafeRelease(m_pCancel); AssertSz(!m_pPumpRefCount, "This should have been freed");
if (m_hIcon) SideAssert(DestroyIcon(m_hIcon));
if (m_hIconSm) SideAssert(DestroyIcon(m_hIconSm));
CallbackCloseTimeout(&m_hTimeout); }
//
// FUNCTION: CFindDlg::QueryInterface()
//
// PURPOSE: Allows caller to retrieve the various interfaces supported by
// this class.
//
HRESULT CFindDlg::QueryInterface(REFIID riid, LPVOID *ppvObj) { TraceCall("CFindDlg::QueryInterface"); *ppvObj = NULL;
if (IsEqualIID(riid, IID_IUnknown)) *ppvObj = (LPVOID) (IUnknown *) (IDispatch *) this; else if (IsEqualIID(riid, IID_IDispatch)) *ppvObj = (LPVOID) (IDispatch *) this; else if (IsEqualIID(riid, DIID__MessageListEvents)) *ppvObj = (LPVOID) (IDispatch *) this; else if (IsEqualIID(riid, IID_IStoreCallback)) *ppvObj = (LPVOID) (IStoreCallback *) this; else if (IsEqualIID(riid, IID_ITimeoutCallback)) *ppvObj = (LPVOID) (ITimeoutCallback *) this; else if (IsEqualIID(riid, IID_IIdentityChangeNotify)) *ppvObj = (LPVOID) (IIdentityChangeNotify *) this; else if (IsEqualIID(riid, IID_IOleCommandTarget)) *ppvObj = (LPVOID) (IOleCommandTarget *) this;
if (*ppvObj) { AddRef(); return (S_OK); }
return (E_NOINTERFACE); }
//
// FUNCTION: CFindDlg::AddRef()
//
// PURPOSE: Adds a reference count to this object.
//
ULONG CFindDlg::AddRef(void) { TraceCall("CFindDlg::AddRef"); return ((ULONG) InterlockedIncrement((LONG *) &m_cRef)); }
//
// FUNCTION: CFindDlg::Release()
//
// PURPOSE: Releases a reference on this object.
//
ULONG CFindDlg::Release(void) { TraceCall("CFindDlg::Release");
if (0 == InterlockedDecrement((LONG *) &m_cRef)) { delete this; return 0; }
return (m_cRef); }
//
// FUNCTION: CFindDlg::Show()
//
// PURPOSE: Shows the finder dialog and provides a message pump for this
// new thread.
//
void CFindDlg::Show(PFINDERPARAMS pFindParams) { // Validate this
if (NULL == pFindParams) return;
// Load the acclereator table for the finder
if (NULL == m_hAccel) m_hAccel = LoadAcceleratorsWrapW(g_hLocRes, MAKEINTRESOURCEW(IDA_FIND_ACCEL));
// Create the finder dialog
m_hwnd = CreateDialogParamWrapW(g_hLocRes, MAKEINTRESOURCEW(IDD_FIND), NULL, ExtFindMsgDlgProc, (LPARAM) this); if (NULL == m_hwnd) return;
// Create the message list
HRESULT hr = CreateMessageList(NULL, &m_pMsgList); if (FAILED(hr)) return;
// Get some interfaces pointers from the message list that we'll need
// later
m_pMsgList->QueryInterface(IID_IOleCommandTarget, (LPVOID *) &m_pMsgListCT); AtlAdvise(m_pMsgList, (IUnknown *) (IDispatch *) this, DIID__MessageListEvents, &m_dwCookie);
// Display the message list
if (FAILED(m_pMsgList->CreateList(m_hwnd, (IDispatch *) this, &m_hwndList))) return; ShowWindow(m_hwndList, SW_HIDE);
// Have the dialog redraw once or twice
UpdateWindow(m_hwnd);
// Fill in the folder list
if (FAILED(InitFolderPickerEdit(GetDlgItem(m_hwnd, IDC_FOLDER), pFindParams->idFolder))) return;
// Will be released in the WM_NCDESTROY message
m_pPumpRefCount = new CPumpRefCount; if (!m_pPumpRefCount) return; }
void CFindDlg::HandleMessage(LPMSG lpmsg) { HWND hwndTimeout;
CNote *pNote = GetTlsGlobalActiveNote();
// Give it to the active note if a note has focus, call it's XLateAccelerator...
if (pNote && pNote->TranslateAccelerator(lpmsg) == S_OK) return;
if (pNote && (pNote->IsMenuMessage(lpmsg) == S_OK)) return;
// Get Timeout Window for this thread
hwndTimeout = (HWND)TlsGetValue(g_dwTlsTimeout);
// Check for Is modeless timeout dialog window message
if (hwndTimeout && TRUE == IsDialogMessageWrapW(hwndTimeout, lpmsg)) return;
if (m_hwnd) { // We have to do a little voodoo to get some keystrokes down to the
// message list before IsDialogMessage() get's 'em
if (lpmsg->message == WM_KEYDOWN) { if ((lpmsg->wParam == VK_DELETE) && m_pMsgList && (S_OK != m_pMsgList->HasFocus())) { if (!IsDialogMessageWrapW(m_hwnd, lpmsg)) { TranslateMessage(lpmsg); DispatchMessageWrapW(lpmsg); } return; } if ((lpmsg->wParam == VK_RETURN) && m_pMsgList && (S_OK == m_pMsgList->HasFocus())) { if (!TranslateAcceleratorWrapW(m_hwnd, m_hAccel, lpmsg)) { TranslateMessage(lpmsg); DispatchMessageWrapW(lpmsg); } return; } }
if (m_hAccel && TranslateAcceleratorWrapW(m_hwnd, m_hAccel, lpmsg)) return; if (IsDialogMessageWrapW(m_hwnd, lpmsg)) return; }
TranslateMessage(lpmsg); DispatchMessageWrapW(lpmsg); }
//
// FUNCTION: CFindDlg::Invoke()
//
// PURPOSE: Called by the message list to pass us progress and other
// status / error messages.
//
// RETURN VALUE:
// HRESULT
//
HRESULT CFindDlg::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, unsigned int* puArgErr) { switch (dispIdMember) { // Fired whenever the selection in the ListView changes
case DISPID_LISTEVENT_SELECTIONCHANGED: { break; }
// Fired when the number of messages or unread messages changes
case DISPID_LISTEVENT_COUNTCHANGED: { if (!m_fProgressBar && m_pStatusBar) { TCHAR szStatus[CCHMAX_STRINGRES + 20]; TCHAR szFmt[CCHMAX_STRINGRES]; DWORD ids;
if (m_fFindComplete) { AthLoadString(idsXMsgsYUnreadFind, szFmt, ARRAYSIZE(szFmt)); wnsprintf(szStatus, ARRAYSIZE(szStatus), szFmt, pDispParams->rgvarg[0].lVal, pDispParams->rgvarg[1].lVal); } else { AthLoadString(idsXMsgsYUnread, szFmt, ARRAYSIZE(szFmt)); wnsprintf(szStatus, ARRAYSIZE(szStatus), szFmt, pDispParams->rgvarg[0].lVal, pDispParams->rgvarg[1].lVal); }
m_pStatusBar->SetStatusText(szStatus); } break; }
// Fired when the user double clicks an item in the ListView
case DISPID_LISTEVENT_ITEMACTIVATE: { CmdOpen(ID_OPEN, OLECMDEXECOPT_DONTPROMPTUSER, NULL, NULL); break; } }
return (S_OK); }
//
// FUNCTION: CMessageView::QueryStatus()
//
// PURPOSE: Called by the browser to determine if a list of commands should
// should be enabled or disabled.
//
// PARAMETERS:
// [in] pguidCmdGroup - Group the commands are part of (unused)
// [in] cCmds - Number of commands to be evaluated
// [in] prgCmds - List of commands
// [out] pCmdText - Description text for a command
//
// RETURN VALUE:
// HRESULT
//
HRESULT CFindDlg::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText) { DWORD cSel; HRESULT hr; DWORD *rgSelected = 0; DWORD cFocus;
MenuUtil_NewMessageIDsQueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText, TRUE);
// Up front some work
m_pMsgList->GetSelected(&cFocus, &cSel, &rgSelected);
// Now loop through the commands in the prgCmds array looking for ones the
// sub objects didn't handle.
for (UINT i = 0; i < cCmds; i++) { if (prgCmds[i].cmdf == 0) { // If this command is from the language menu
if (prgCmds[i].cmdID >= ID_LANG_FIRST && prgCmds[i].cmdID <= ID_LANG_LAST) { // Enable only the supported languages
if (prgCmds[i].cmdID < (UINT) (ID_LANG_FIRST + GetIntlCharsetLanguageCount())) prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED; else prgCmds[i].cmdf = OLECMDF_SUPPORTED;
continue; }
// if the command id from the View.Current View menu
if ((ID_VIEW_FILTER_FIRST <= prgCmds[i].cmdID) && (ID_VIEW_FILTER_LAST >= prgCmds[i].cmdID)) { if (NULL == m_pViewMenu) { // Create the view menu
HrCreateViewMenu(VMF_FINDER, &m_pViewMenu); } if (NULL != m_pViewMenu) { m_pViewMenu->QueryStatus(m_pMsgList, &(prgCmds[i])); }
continue; } // Look to see if it's a command we provide
switch (prgCmds[i].cmdID) { case ID_OPEN: { // Enabled only if the focus is in the ListView and there
// is at least one item selected.
m_pMsgList->GetSelectedCount(&cSel); if (cSel) prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED; else prgCmds[i].cmdf = OLECMDF_SUPPORTED; break; }
case ID_OPEN_CONTAINING_FOLDER: { if (cSel == 1) prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED; else prgCmds[i].cmdf = OLECMDF_SUPPORTED; break; }
case ID_REPLY: case ID_REPLY_ALL: { // Enabled only if the focus is in the ListView and there
// is only one item selected
prgCmds[i].cmdf = OLECMDF_SUPPORTED;
if (cSel == 1) { // The message's body must also be downloaded
LPMESSAGEINFO pInfo;
if (SUCCEEDED(m_pMsgList->GetMessageInfo(rgSelected[0], &pInfo))) { if (pInfo->dwFlags & ARF_HASBODY) prgCmds[i].cmdf |= OLECMDF_ENABLED;
m_pMsgList->FreeMessageInfo(pInfo); } }
break; }
case ID_FORWARD: case ID_FORWARD_AS_ATTACH: { // Enabled only if the focus is in the ListView and there
// is only one item selected
prgCmds[i].cmdf = OLECMDF_SUPPORTED;
if (cSel > 0) { // The message's body must also be downloaded
LPMESSAGEINFO pInfo;
// Default to success
prgCmds[i].cmdf |= OLECMDF_ENABLED; for (DWORD iItem = 0; iItem < cSel && (prgCmds[i].cmdf & OLECMDF_ENABLED); iItem++) { if (SUCCEEDED(m_pMsgList->GetMessageInfo(rgSelected[iItem], &pInfo))) { if (0 == (pInfo->dwFlags & ARF_HASBODY)) { prgCmds[i].cmdf &= ~OLECMDF_ENABLED; }
m_pMsgList->FreeMessageInfo(pInfo); } } }
break; }
case ID_REPLY_GROUP: { // Enabled only if there is one news message selected
prgCmds[i].cmdf = OLECMDF_SUPPORTED;
if (cSel == 1) { // The message's body must also be downloaded
LPMESSAGEINFO pInfo;
if (SUCCEEDED(m_pMsgList->GetMessageInfo(rgSelected[0], &pInfo))) { if ((pInfo->dwFlags & ARF_HASBODY) && (pInfo->dwFlags & ARF_NEWSMSG)) prgCmds[i].cmdf |= OLECMDF_ENABLED;
m_pMsgList->FreeMessageInfo(pInfo); } } break; }
case ID_POPUP_FILTER: case ID_COLUMNS: case ID_POPUP_NEXT: case ID_POPUP_SORT: { prgCmds[i].cmdf = OLECMDF_SUPPORTED | (m_fShowResults ? OLECMDF_ENABLED : 0); break; }
case ID_POPUP_NEW: case ID_CLOSE: { prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED; break; }
case ID_REFRESH: { if (m_fShowResults && IsWindowEnabled(GetDlgItem(m_hwnd, IDC_FIND_NOW))) prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED; else prgCmds[i].cmdf = OLECMDF_SUPPORTED; break; }
case ID_BLOCK_SENDER: { prgCmds[i].cmdf = OLECMDF_SUPPORTED;
// Enabled only if there is only one item selected and
// we have access to the from address
if (cSel == 1) { // The message's body must also be downloaded
LPMESSAGEINFO pInfo;
if (SUCCEEDED(m_pMsgList->GetMessageInfo(rgSelected[0], &pInfo))) { if (((NULL != pInfo->pszEmailFrom) && ('\0' != pInfo->pszEmailFrom[0])) || (0 != pInfo->faStream)) prgCmds[i].cmdf |= OLECMDF_ENABLED;
m_pMsgList->FreeMessageInfo(pInfo); } } break; } case ID_CREATE_RULE_FROM_MESSAGE: { prgCmds[i].cmdf = OLECMDF_SUPPORTED;
// Enabled only if there is only one item selected
if (cSel == 1) { // Make sure we have a message info
LPMESSAGEINFO pInfo;
if (SUCCEEDED(m_pMsgList->GetMessageInfo(rgSelected[0], &pInfo))) { prgCmds[i].cmdf |= OLECMDF_ENABLED; m_pMsgList->FreeMessageInfo(pInfo); } } break; }
case ID_COMBINE_AND_DECODE: { // Enabled only if the focus is in the ListView and there
// is at least one item selected.
if (cSel > 1) prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED; else prgCmds[i].cmdf = OLECMDF_SUPPORTED; break; }
case ID_CANCEL_MESSAGE: { prgCmds[i].cmdf = OLECMDF_SUPPORTED;
if (DwGetOption(OPT_CANCEL_ALL_NEWS)) prgCmds[i].cmdf |= OLECMDF_ENABLED; else { if (cSel == 1) { FOLDERID idFolder; LPMESSAGEINFO pInfo;
if (SUCCEEDED(m_pMsgList->GetMessageInfo(rgSelected[0], &pInfo))) { if (SUCCEEDED(m_pMsgList->GetRowFolderId(rgSelected[0], &idFolder))) { if (NewsUtil_FCanCancel(idFolder, pInfo)) { prgCmds[i].cmdf |= OLECMDF_ENABLED; } }
m_pMsgList->FreeMessageInfo(pInfo); } } } break; } } } }
MemFree(rgSelected);
// Let the sub objects look last, so we can get ID_REFRESH before them
if (m_pMsgListCT) { hr = m_pMsgListCT->QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText); }
return (S_OK); }
//
// FUNCTION: CMessageView::Exec()
//
// PURPOSE: Called to execute a verb that this view supports
//
// PARAMETERS:
// [in] pguidCmdGroup - unused
// [in] nCmdID - ID of the command to execute
// [in] nCmdExecOpt - Options that define how the command should execute
// [in] pvaIn - Any arguments for the command
// [out] pvaOut - Any return values for the command
//
// RETURN VALUE:
//
//
HRESULT CFindDlg::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut) { // If the sub objects didn't support the command, then we should see if
// it's one of ours
// Language menu first
if (nCmdID >= ID_LANG_FIRST && nCmdID <= ID_LANG_LAST) { // $REVIEW - Not implemented
// SwitchLanguage(nCmdID, TRUE);
return (S_OK); }
// Handle the View.Current View menu
if ((ID_VIEW_FILTER_FIRST <= nCmdID) && (ID_VIEW_FILTER_LAST >= nCmdID)) { if (NULL == m_pViewMenu) { // Create the view menu
HrCreateViewMenu(VMF_FINDER, &m_pViewMenu); } if (NULL != m_pViewMenu) { if (SUCCEEDED(m_pViewMenu->Exec(m_hwnd, nCmdID, m_pMsgList, pvaIn, pvaOut))) { return (S_OK); } } } if (MenuUtil_HandleNewMessageIDs(nCmdID, m_hwnd, FOLDERID_INVALID, TRUE, FALSE, (IUnknown *) (IDispatch *) this)) return S_OK;
// Go through the rest of the commands
switch (nCmdID) { case ID_OPEN: return CmdOpen(nCmdID, nCmdExecOpt, pvaIn, pvaOut);
case ID_OPEN_CONTAINING_FOLDER: return CmdOpenFolder(nCmdID, nCmdExecOpt, pvaIn, pvaOut);
case ID_REPLY: case ID_REPLY_ALL: case ID_FORWARD: case ID_FORWARD_AS_ATTACH: case ID_REPLY_GROUP: return CmdReplyForward(nCmdID, nCmdExecOpt, pvaIn, pvaOut); case ID_REFRESH: case IDC_FIND_NOW: return CmdFindNow(nCmdID, nCmdExecOpt, pvaIn, pvaOut);
case IDC_STOP: return CmdStop(nCmdID, nCmdExecOpt, pvaIn, pvaOut);
case IDC_BROWSE_FOLDER: return CmdBrowseForFolder(nCmdID, nCmdExecOpt, pvaIn, pvaOut);
case IDC_RESET: return CmdReset(nCmdID, nCmdExecOpt, pvaIn, pvaOut);
case ID_BLOCK_SENDER: return CmdBlockSender(nCmdID, nCmdExecOpt, pvaIn, pvaOut);
case ID_CREATE_RULE_FROM_MESSAGE: return CmdCreateRule(nCmdID, nCmdExecOpt, pvaIn, pvaOut);
case ID_COMBINE_AND_DECODE: return CmdCombineAndDecode(nCmdID, nCmdExecOpt, pvaIn, pvaOut);
case ID_CLOSE: case IDCANCEL: { if (m_fInProgress) { CmdStop(ID_STOP, OLECMDEXECOPT_DODEFAULT, NULL, NULL); m_fClose = TRUE; } else { DestroyWindow(m_hwnd); } return (S_OK); }
case ID_CANCEL_MESSAGE: return CmdCancelMessage(nCmdID, nCmdExecOpt, pvaIn, pvaOut); }
// See if our message list wants the command
if (m_pMsgListCT) { if (OLECMDERR_E_NOTSUPPORTED != m_pMsgListCT->Exec(pguidCmdGroup, nCmdID, nCmdExecOpt, pvaIn, pvaOut)) return (S_OK); } return (OLECMDERR_E_NOTSUPPORTED); }
//
// FUNCTION: CFindDlg::OnBegin()
//
// PURPOSE: Called whenever the store is about to start some operation.
//
HRESULT CFindDlg::OnBegin(STOREOPERATIONTYPE tyOperation, STOREOPERATIONINFO *pOpInfo, IOperationCancel *pCancel) { TraceCall("CFindDlg::OnBegin");
Assert(pCancel != NULL); Assert(m_pCancel == NULL); m_pCancel = pCancel; m_pCancel->AddRef();
if (m_fAbort) m_pCancel->Cancel(CT_CANCEL);
return(S_OK); }
//
// FUNCTION: CFindDlg::OnProgress()
//
// PURPOSE: Called during the find, download, etc.
//
HRESULT CFindDlg::OnProgress(STOREOPERATIONTYPE tyOperation, DWORD dwCurrent, DWORD dwMax, LPCSTR pszStatus) { MSG msg;
TraceCall("CFindDlg::OnProgress");
// If we had a timeout dialog up, we can close it since data just became
// available.
CallbackCloseTimeout(&m_hTimeout);
// If it's find, show progress
if (SOT_SEARCHING == tyOperation) { if (m_pStatusBar && pszStatus) { TCHAR szRes[CCHMAX_STRINGRES], szBuf[CCHMAX_STRINGRES]; AthLoadString(idsSearching, szRes, ARRAYSIZE(szRes)); wnsprintf(szBuf, ARRAYSIZE(szBuf), szRes, pszStatus); m_pStatusBar->SetStatusText((LPTSTR) szBuf); }
if (!m_fProgressBar && m_pStatusBar) { m_pStatusBar->ShowProgress(dwMax); m_fProgressBar = TRUE; }
if (m_pStatusBar && dwMax) { m_pStatusBar->SetProgress(dwCurrent); } }
// Pump messages a bit so the UI is responsive.
while (PeekMessageWrapW(&msg, NULL, 0, 0, PM_REMOVE)) HandleMessage(&msg);
return (S_OK); }
//
// FUNCTION: CFindDlg::OnComplete()
//
// PURPOSE: Called when the store operation is complete
//
HRESULT CFindDlg::OnComplete(STOREOPERATIONTYPE tyOperation, HRESULT hrComplete, LPSTOREOPERATIONINFO pOpInfo, LPSTOREERROR pErrorInfo) { TraceCall("CFindDlg::OnComplete");
// Close any timeout dialog, if present
CallbackCloseTimeout(&m_hTimeout);
// Display an Error on Failures
if (FAILED(hrComplete)) { // Call into my swanky utility
CallbackDisplayError(m_hwnd, hrComplete, pErrorInfo); }
if (SOT_SEARCHING == tyOperation) { // Hide the status bar
if (m_fProgressBar && m_pStatusBar) { m_pStatusBar->HideProgress(); m_fProgressBar = FALSE; m_fFindComplete = TRUE; }
Assert(m_pCancel != NULL); m_pCancel->Release(); m_pCancel = NULL; }
// Update the status text
IOEMessageList *pList; if (SUCCEEDED(m_pMsgList->QueryInterface(IID_IOEMessageList, (LPVOID *) &pList))) { long lCount, lUnread; TCHAR szRes[CCHMAX_STRINGRES], szBuf[CCHMAX_STRINGRES];
pList->get_Count(&lCount); pList->get_UnreadCount(&lUnread); AthLoadString(idsXMsgsYUnreadFind, szRes, ARRAYSIZE(szRes)); wnsprintf(szBuf, ARRAYSIZE(szBuf), szRes, lCount, lUnread); m_pStatusBar->SetStatusText(szBuf);
pList->Release(); }
// Select the first row
IListSelector *pSelect; if (SUCCEEDED(m_pMsgList->GetListSelector(&pSelect))) { pSelect->SetActiveRow(0); pSelect->Release(); }
return(S_OK); }
STDMETHODIMP CFindDlg::OnTimeout(LPINETSERVER pServer, LPDWORD pdwTimeout, IXPTYPE ixpServerType) { // Display a timeout dialog
return CallbackOnTimeout(pServer, ixpServerType, *pdwTimeout, (ITimeoutCallback *)this, &m_hTimeout); }
STDMETHODIMP CFindDlg::CanConnect(LPCSTR pszAccountId, DWORD dwFlags) { // Call into general CanConnect Utility
return CallbackCanConnect(pszAccountId, m_hwnd, FALSE); }
STDMETHODIMP CFindDlg::OnLogonPrompt(LPINETSERVER pServer, IXPTYPE ixpServerType) { // Close any timeout dialog, if present
CallbackCloseTimeout(&m_hTimeout);
// Call into general OnLogonPrompt Utility
return CallbackOnLogonPrompt(m_hwnd, pServer, ixpServerType); }
STDMETHODIMP CFindDlg::OnPrompt(HRESULT hrError, LPCTSTR pszText, LPCTSTR pszCaption, UINT uType, INT *piUserResponse) { // Close any timeout dialog, if present
CallbackCloseTimeout(&m_hTimeout);
// Call into my swanky utility
return CallbackOnPrompt(m_hwnd, hrError, pszText, pszCaption, uType, piUserResponse); }
STDMETHODIMP CFindDlg::GetParentWindow(DWORD dwReserved, HWND *phwndParent) { *phwndParent = m_hwnd; return(S_OK); }
STDMETHODIMP CFindDlg::OnTimeoutResponse(TIMEOUTRESPONSE eResponse) { // Call into general timeout response utility
return CallbackOnTimeoutResponse(eResponse, m_pCancel, &m_hTimeout); }
INT_PTR CALLBACK CFindDlg::ExtFindMsgDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { CFindDlg *pThis;
if (msg == WM_INITDIALOG) { SetWindowLongPtr(hwnd, DWLP_USER, lParam); pThis = (CFindDlg*)lParam; } else pThis = (CFindDlg*)GetWindowLongPtr(hwnd, DWLP_USER);
if (pThis) return pThis->DlgProc(hwnd, msg, wParam, lParam); return FALSE; }
//
// FUNCTION: CFindDlg::DlgProc()
//
// PURPOSE: Groovy dialog proc.
//
INT_PTR CFindDlg::DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { HWND hwndActive;
switch (msg) { case WM_INITDIALOG: return (BOOL)HANDLE_WM_INITDIALOG(hwnd, wParam, lParam, OnInitDialog); case WM_PAINT: HANDLE_WM_PAINT(hwnd, wParam, lParam, OnPaint); return TRUE;
case WM_SIZE: HANDLE_WM_SIZE(hwnd, wParam, lParam, OnSize); return TRUE; case WM_GETMINMAXINFO: HANDLE_WM_GETMINMAXINFO(hwnd, wParam, lParam, OnGetMinMaxInfo); return TRUE; case WM_INITMENUPOPUP: HANDLE_WM_INITMENUPOPUP(hwnd, wParam, lParam, OnInitMenuPopup); return TRUE;
case WM_MENUSELECT: // HANDLE_WM_MENUSELECT() has a bug in it, don't use it.
if (LOWORD(wParam) >= ID_STATIONERY_RECENT_0 && LOWORD(wParam) <= ID_STATIONERY_RECENT_9) m_pStatusBar->ShowSimpleText(MAKEINTRESOURCE(idsRSListGeneralHelp)); else HandleMenuSelect(m_pStatusBar, wParam, lParam); return TRUE; case WM_WININICHANGE: HANDLE_WM_WININICHANGE(hwnd, wParam, lParam, OnWinIniChange); return TRUE;
case WM_COMMAND: HANDLE_WM_COMMAND(hwnd, wParam, lParam, OnCommand); return TRUE; case WM_NOTIFY: HANDLE_WM_NOTIFY(hwnd, wParam, lParam, OnNotify); return TRUE;
case WM_DESTROY: // case WM_CLOSE:
HANDLE_WM_DESTROY(hwnd, wParam, lParam, OnDestroy); return TRUE; case WM_NCDESTROY: m_pPumpRefCount->Release(); m_pPumpRefCount = NULL; m_hwnd = 0; break;
case WM_ENABLE: if (!m_fInternal) { Assert (wParam || (m_hlDisabled.cHwnd == NULL && m_hlDisabled.rgHwnd == NULL)); EnableThreadWindows(&m_hlDisabled, (NULL != wParam), ETW_OE_WINDOWS_ONLY, hwnd); g_hwndActiveModal = wParam ? NULL : hwnd; } break;
case WM_ACTIVATEAPP: if (wParam && g_hwndActiveModal && g_hwndActiveModal != hwnd && !IsWindowEnabled(hwnd)) { // $MODAL
// if we are getting activated, and are disabled then
// bring our 'active' window to the top
Assert (IsWindow(g_hwndActiveModal)); PostMessage(g_hwndActiveModal, WM_OE_ACTIVATETHREADWINDOW, 0, 0); } break;
case WM_OE_ACTIVATETHREADWINDOW: hwndActive = GetLastActivePopup(hwnd); if (hwndActive && IsWindowEnabled(hwndActive) && IsWindowVisible(hwndActive)) ActivatePopupWindow(hwndActive); break;
case WM_OE_ENABLETHREADWINDOW: m_fInternal = 1; EnableWindow(hwnd, (BOOL)wParam); m_fInternal = 0; break;
} return FALSE; }
//
// FUNCTION: CFindDlg::OnInitDialog()
//
// PURPOSE: Initializes the UI in the dialog box. Also prep's the sizing
// info so the dialog can be resized.
//
BOOL CFindDlg::OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) { RECT rc, rcClient; RECT rcEdit; WINDOWPLACEMENT wp; HMENU hMenu;
TraceCall("CFindDlg::OnInitDialog");
// We do this so we can enable and disable correctly when modal windows
// are visible
SetProp(hwnd, c_szOETopLevel, (HANDLE)TRUE);
// Get some sizing info
_InitSizingInfo(hwnd);
// Hide the status bar until we've been expanded
ShowWindow(GetDlgItem(hwnd, IDC_STATUS_BAR), SW_HIDE);
// Set the title bar icon
Assert (m_hIconSm == NULL && m_hIcon == NULL); m_hIcon = (HICON)LoadImage(g_hLocRes, MAKEINTRESOURCE(idiFind), IMAGE_ICON, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), 0); SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)m_hIcon); m_hIconSm = (HICON)LoadImage(g_hLocRes, MAKEINTRESOURCE(idiFind), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0); SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)m_hIconSm);
// Set the dialog template fonts correctly
_SetFindIntlFont(hwnd);
// Initialize the find information
_SetFindValues(hwnd, &m_rFindInfo);
// Disable the find and stop buttons
EnableWindow(GetDlgItem(hwnd, IDC_FIND_NOW), _IsFindEnabled(hwnd)); EnableWindow(GetDlgItem(hwnd, IDC_STOP), FALSE); CheckDlgButton(hwnd, IDC_INCLUDE_SUB, BST_CHECKED);
// Create a status bar object for our status bar
m_pStatusBar = new CStatusBar(); if (m_pStatusBar) m_pStatusBar->Initialize(hwnd, SBI_HIDE_SPOOLER | SBI_HIDE_CONNECTED | SBI_HIDE_FILTERED);
// We have menus on this window
hMenu = LoadMenu(g_hLocRes, MAKEINTRESOURCE(IDR_FIND_MENU)); MenuUtil_ReplaceNewMsgMenus(hMenu); SetMenu(hwnd, hMenu);
// Register with identity manager
if (m_dwIdentCookie == 0) SideAssert(SUCCEEDED(MU_RegisterIdentityNotifier((IUnknown *)(IAthenaBrowser *)this, &m_dwIdentCookie)));
SetForegroundWindow(hwnd);
return TRUE; }
//
// FUNCTION: CFindDlg::OnSize()
//
// PURPOSE: When the dialog get's sized, we have to move a whole bunch
// of stuff around. Don't try this at home.
//
void CFindDlg::OnSize(HWND hwnd, UINT state, int cx, int cy) { HDWP hdwp; HWND hwndStatus; HWND hwndTo; int dx;
// If we're minimized, don't do anything
if (state == SIZE_MINIMIZED) return;
// This is the delta for our horizontal size.
dx = cx - m_cxDlgDef;
// Make sure the status bar get's updated
hwndStatus = GetDlgItem(hwnd, IDC_STATUS_BAR); SendMessage(hwndStatus, WM_SIZE, 0, 0L);
if (m_pStatusBar) m_pStatusBar->OnSize(cx, cy);
// Do all the sizing updates at once to make everything smoother
hdwp = BeginDeferWindowPos(15); if (hdwp) { DeferWindowPos(hdwp, GetDlgItem(hwnd, IDC_FOLDER), NULL, 0, 0, (dx + m_cxFolder), m_cyEdit, SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE); DeferWindowPos(hdwp, GetDlgItem(hwnd, IDC_INCLUDE_SUB), NULL, m_xIncSub + dx, m_yIncSub, 0, 0, SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOSIZE); DeferWindowPos(hdwp, GetDlgItem(hwnd, IDC_BROWSE_FOLDER), NULL, m_xBtn + dx, m_yBrowse, 0, 0, SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOSIZE); DeferWindowPos(hdwp, GetDlgItem(hwnd, idcStatic1), NULL, 0, 0, m_cxStatic + dx, 2, SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE); DeferWindowPos(hdwp, GetDlgItem(hwnd, IDC_FIND_NOW), NULL, m_xBtn + dx, m_yBtn, 0, 0, SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOSIZE); DeferWindowPos(hdwp, GetDlgItem(hwnd, IDC_STOP), NULL, m_xBtn + dx, m_yBtn + m_dyBtn, 0, 0, SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOSIZE); DeferWindowPos(hdwp, GetDlgItem(hwnd, IDC_RESET), NULL, m_xBtn + dx, m_yBtn + 2 * m_dyBtn, 0, 0, SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOSIZE); DeferWindowPos(hdwp, GetDlgItem(hwnd, IDC_FROM), NULL, 0, 0, m_cxEdit + dx, m_cyEdit, SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE); DeferWindowPos(hdwp, GetDlgItem(hwnd, IDC_TO), NULL, 0, 0, m_cxEdit + dx, m_cyEdit, SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE); DeferWindowPos(hdwp, GetDlgItem(hwnd, IDC_SUBJECT), NULL, 0, 0, m_cxEdit + dx, m_cyEdit, SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE); DeferWindowPos(hdwp, GetDlgItem(hwnd, IDC_BODY), NULL, 0, 0, m_cxEdit + dx, m_cyEdit, SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE); // ALERT:
// if you add more controls here be sure to UP the value passed
// to BeginDeferWindowPos otherwise user will REALLOC and passback
// a new value to hdwp
EndDeferWindowPos(hdwp); } // If the bottom is exposed (oh my) resize the message list to fit between the
// bottom of the dialog and the top of the status bar.
if (m_fShowResults) { RECT rcStatus; GetClientRect(hwndStatus, &rcStatus); MapWindowRect(hwndStatus, hwnd, &rcStatus);
rcStatus.bottom = rcStatus.top - m_yView; rcStatus.top = m_yView; rcStatus.right -= rcStatus.left; m_pMsgList->SetRect(rcStatus); } }
//
// FUNCTION: CFindDlg::OnPaint()
//
// PURPOSE: All this just to paint a separator line between the menu bar
// and the rest of the menu.
//
void CFindDlg::OnPaint(HWND hwnd) { PAINTSTRUCT ps; RECT rc;
// If we're not minimized
if (!IsIconic(hwnd)) { // Draw that lovely line
BeginPaint(hwnd, &ps); GetClientRect(hwnd, &rc); DrawEdge(ps.hdc, &rc, EDGE_ETCHED, BF_TOP); EndPaint(hwnd, &ps); } }
//
// FUNCTION: CFindDlg::OnGetMinMaxInfo()
//
// PURPOSE: Called by Windows when we're resizing to see what our minimum
// and maximum sizes are.
//
void CFindDlg::OnGetMinMaxInfo(HWND hwnd, LPMINMAXINFO lpmmi) { TraceCall("CFindDlg::OnGetMinMaxInfo");
// Let Window's do most of the work
DefWindowProcWrapW(hwnd, WM_GETMINMAXINFO, 0, (LPARAM)lpmmi);
// Override the minimum track size to be the size or our template
lpmmi->ptMinTrackSize = m_ptDragMin;
// Make sure to adjust for the height of the message list
if (!m_fShowResults) lpmmi->ptMaxTrackSize.y = m_ptDragMin.y; }
//
// FUNCTION: CFindDlg::OnInitMenuPopup()
//
// PURPOSE: Called before the menus are displayed.
//
void CFindDlg::OnInitMenuPopup(HWND hwnd, HMENU hmenuPopup, UINT uPos, BOOL fSystemMenu) { MENUITEMINFO mii; UINT uIDPopup; HMENU hMenu = GetMenu(hwnd);
TraceCall("CFindDlg::OnInitMenuPopup");
ZeroMemory(&mii, sizeof(mii));
mii.cbSize = sizeof(MENUITEMINFO); mii.fMask = MIIM_ID | MIIM_SUBMENU;
// make sure we recognize the popup as one of ours
if (hMenu == NULL || !GetMenuItemInfo(hMenu, uPos, TRUE, &mii) || (hmenuPopup != mii.hSubMenu)) { HMENU hMenuDrop = NULL; int ulIndex = 0; int cMenus = 0;
cMenus = GetMenuItemCount(hMenu); // Try to fix up the top level popups
for (ulIndex = 0; ulIndex < cMenus; ulIndex++) { // Get the drop down menu
hMenuDrop = GetSubMenu(hMenu, ulIndex); if (NULL == hMenuDrop) { continue; } // Initialize the menu info
mii.cbSize = sizeof(MENUITEMINFO); mii.fMask = MIIM_ID | MIIM_SUBMENU;
if (FALSE == GetMenuItemInfo(hMenuDrop, uPos, TRUE, &mii)) { continue; }
if (hmenuPopup == mii.hSubMenu) { break; } }
// Did we find anything?
if (ulIndex >= cMenus) { goto exit; } }
uIDPopup = mii.wID;
// Must have stationery
switch (uIDPopup) { case ID_POPUP_MESSAGE: AddStationeryMenu(hmenuPopup, ID_POPUP_NEW_MSG, ID_STATIONERY_RECENT_0, ID_STATIONERY_MORE); break; case ID_POPUP_FILE: DeleteMenu(hmenuPopup, ID_SEND_INSTANT_MESSAGE, MF_BYCOMMAND); break;
case ID_POPUP_VIEW: if (NULL == m_pViewMenu) { // Create the view menu
HrCreateViewMenu(VMF_FINDER, &m_pViewMenu); } if (NULL != m_pViewMenu) { mii.cbSize = sizeof(MENUITEMINFO); mii.fMask = MIIM_SUBMENU; if (FALSE == GetMenuItemInfo(hmenuPopup, ID_POPUP_FILTER, FALSE, &mii)) { break; } // Remove the old filter submenu
if(IsMenu(mii.hSubMenu)) DestroyMenu(mii.hSubMenu);
// Replace the view menu
if (FAILED(m_pViewMenu->HrReplaceMenu(0, hmenuPopup))) { break; } } break; case ID_POPUP_FILTER: if (NULL != m_pViewMenu) { m_pViewMenu->UpdateViewMenu(0, hmenuPopup, m_pMsgList); } break; } // Let the message list initialize it
if (m_pMsgList) m_pMsgList->OnPopupMenu(hmenuPopup, uIDPopup);
// now enable/disable the items
MenuUtil_EnablePopupMenu(hmenuPopup, this); exit: return; }
//
// FUNCTION: CFindDlg::OnMenuSelect()
//
// PURPOSE: Puts the menu help text on the status bar.
//
void CFindDlg::OnMenuSelect(HWND hwnd, HMENU hmenu, int item, HMENU hmenuPopup, UINT flags) { if (m_pStatusBar) { // If this is the stationery menu, special case it
if (item >= ID_STATIONERY_RECENT_0 && item <= ID_STATIONERY_RECENT_9) m_pStatusBar->ShowSimpleText(MAKEINTRESOURCE(idsRSListGeneralHelp)); else HandleMenuSelect(m_pStatusBar, MAKEWPARAM(item, flags), hmenu ? (LPARAM) hmenu : (LPARAM) hmenuPopup); } }
//
// FUNCTION: CFindDlg::OnWinIniChange()
//
// PURPOSE: Handles updates of fonts, colors, etc.
//
void CFindDlg::OnWinIniChange(HWND hwnd, LPCTSTR lpszSectionName) { // Forward this off to our date picker controls
FORWARD_WM_WININICHANGE(GetDlgItem(hwnd, IDC_DATE_FROM), lpszSectionName, SendMessage); FORWARD_WM_WININICHANGE(GetDlgItem(hwnd, IDC_DATE_TO), lpszSectionName, SendMessage); }
//
// FUNCTION: CFindDlg::OnCommand()
//
// PURPOSE: Handles commands generated by the finder.
//
void CFindDlg::OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) { HRESULT hr = S_OK;
// We need to grab some of the notifications sent to us first
if ((codeNotify == EN_CHANGE) || (codeNotify == BN_CLICKED && (id == IDC_HAS_FLAG || id == IDC_HAS_ATTACH))) { EnableWindow(GetDlgItem(hwnd, IDC_FIND_NOW), _IsFindEnabled(hwnd) && !m_fInProgress); return; }
// If this is from a menu, then first see if the message list wants
// to handle it.
if (NULL == hwndCtl) { // Check to see if the command is even enabled
if (id >= ID_FIRST) { OLECMD cmd; cmd.cmdID = id; cmd.cmdf = 0;
hr = QueryStatus(&CMDSETID_OutlookExpress, 1, &cmd, NULL); if (FAILED(hr) || (0 == (cmd.cmdf & OLECMDF_ENABLED))) return; }
if (m_pMsgListCT) { hr = m_pMsgListCT->Exec(&CMDSETID_OEMessageList, id, OLECMDEXECOPT_DODEFAULT, NULL, NULL); if (S_OK == hr) return; } }
// Otherwise, it goes to the command target
VARIANTARG va;
va.vt = VT_I4; va.lVal = codeNotify;
hr = Exec(NULL, id, OLECMDEXECOPT_DODEFAULT, &va, NULL); return; }
//
// FUNCTION: CFindDlg::OnNotify()
//
// PURPOSE: Handles notifications from the date pickers
//
LRESULT CFindDlg::OnNotify(HWND hwnd, int idFrom, LPNMHDR pnmhdr) { if (DTN_DATETIMECHANGE == pnmhdr->code) EnableWindow(GetDlgItem(hwnd, IDC_FIND_NOW), _IsFindEnabled(hwnd));
return (0); }
//
// FUNCTION: CFindDlg::OnDestroy()
//
// PURPOSE: Clean up the message list now that we're being shut down and
// also save our size etc.
//
void CFindDlg::OnDestroy(HWND hwnd) { WINDOWPLACEMENT wp;
// Save the sizing information
wp.length = sizeof(wp); GetWindowPlacement(hwnd, &wp); SetOption(OPT_FINDER_POS, (LPBYTE)&wp, sizeof(wp), NULL, 0); // Unregister with Identity manager
if (m_dwIdentCookie != 0) { MU_UnregisterIdentityNotifier(m_dwIdentCookie); m_dwIdentCookie = 0; }
// Clean up the property
RemoveProp(hwnd, c_szOETopLevel);
// Stop receieving notifications
AtlUnadvise(m_pMsgList, DIID__MessageListEvents, m_dwCookie);
// Tell the message list to release it's folder
m_pMsgList->SetFolder(FOLDERID_INVALID, NULL, FALSE, NULL, NOSTORECALLBACK);
// Close the message list
m_pMsgList->OnClose(); }
//
// FUNCTION: CFindDlg::CmdOpen()
//
// PURPOSE: Called when the user want's to open a message that they've found.
//
HRESULT CFindDlg::CmdOpen(DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut) { HRESULT hr;
TraceCall("CMessageView::CmdOpen");
// If more than 10 messages are selected, warn the user with a "Don't show
// me again" dialog that this could be bad.
DWORD dwSel = 0; m_pMsgList->GetSelectedCount(&dwSel); if (dwSel > 10) { TCHAR szBuffer[CCHMAX_STRINGRES]; LRESULT lResult;
AthLoadString(idsErrOpenManyMessages, szBuffer, ARRAYSIZE(szBuffer)); lResult = DoDontShowMeAgainDlg(m_hwnd, c_szRegManyMsgWarning, MAKEINTRESOURCE(idsAthena), szBuffer, MB_OKCANCEL); if (IDCANCEL == lResult) return (S_OK); }
// Get the array of selected rows from the message list
DWORD *rgRows = NULL; DWORD cRows = 0;
if (FAILED(hr = m_pMsgList->GetSelected(NULL, &cRows, &rgRows))) return (hr);
// It's possible for the message list to go away while we're doing this.
// To keep us from crashing, make sure you verify it still exists during
// the loop.
LPMESSAGEINFO pInfo; IMessageTable *pTable = NULL;
hr = m_pMsgList->GetMessageTable(&pTable); if (SUCCEEDED(hr)) { for (DWORD i = 0; (i < cRows && m_pMsgList != NULL); i++) { if (SUCCEEDED(hr = m_pMsgList->GetMessageInfo(rgRows[i], &pInfo))) { INIT_MSGSITE_STRUCT initStruct; DWORD dwCreateFlags; initStruct.initTable.pListSelect = NULL; m_pMsgList->GetListSelector(&initStruct.initTable.pListSelect);
// Initialize note struct
initStruct.dwInitType = OEMSIT_MSG_TABLE; initStruct.initTable.pMsgTable = pTable; if (FAILED(GetFolderIdFromMsgTable(pTable, &initStruct.folderID))) initStruct.folderID = FOLDERID_INVALID; initStruct.initTable.rowIndex = rgRows[i];
// Decide whether it is news or mail
if (pInfo->dwFlags & ARF_NEWSMSG) dwCreateFlags = OENCF_NEWSFIRST; else dwCreateFlags = 0;
m_pMsgList->FreeMessageInfo(pInfo);
// Create and Open Note
hr = CreateAndShowNote(OENA_READ, dwCreateFlags, &initStruct, m_hwnd, (IUnknown *)m_pPumpRefCount); ReleaseObj(initStruct.initTable.pListSelect); if (FAILED(hr)) break; } } pTable->Release(); } MemFree(rgRows); return (S_OK); }
//
// FUNCTION: CFindDlg::CmdOpenFolder()
//
// PURPOSE: Called when the user want's to open the folder that contains the
// selected message.
//
HRESULT CFindDlg::CmdOpenFolder(DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut) { HRESULT hr; DWORD dwFocused; DWORD *rgRows = NULL; DWORD cRows = 0;
if (m_pMsgList) { // Figure out which message is focused
if (SUCCEEDED(m_pMsgList->GetSelected(&dwFocused, &cRows, &rgRows))) { FOLDERID idFolder;
// Get some information about the message
if (g_pInstance && SUCCEEDED(hr = m_pMsgList->GetRowFolderId(dwFocused, &idFolder))) { g_pInstance->BrowseToObject(SW_SHOWNORMAL, idFolder); } } }
MemFree(rgRows); return (S_OK); }
//
// FUNCTION: CFindDlg::CmdReply()
//
// PURPOSE: Replies or Reply-All's to the selected message.
//
// RETURN VALUE:
// HRESULT
//
HRESULT CFindDlg::CmdReplyForward(DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut) { HRESULT hr; DWORD dwFocused; DWORD *rgRows = NULL; DWORD cRows = 0; IMessageTable *pTable = NULL;
if (m_pMsgList) { // Figure out which message is focused
if (SUCCEEDED(m_pMsgList->GetSelected(&dwFocused, &cRows, &rgRows))) { INIT_MSGSITE_STRUCT rInitSite; DWORD dwCreateFlags; DWORD dwAction = 0;
// Get the message table from the message list. The note will need
// this to deal with next / prev commands
hr = m_pMsgList->GetMessageTable(&pTable); if (FAILED(hr)) goto exit;
if ((1 < cRows) && ((ID_FORWARD == nCmdID) || (ID_FORWARD_AS_ATTACH == nCmdID))) { IMimeMessage *pMsgFwd = NULL; BOOL fErrorsOccured = FALSE, fCreateNote = TRUE;
hr = HrCreateMessage(&pMsgFwd); if (FAILED(hr)) goto exit; rInitSite.dwInitType = OEMSIT_MSG; rInitSite.pMsg = pMsgFwd; if (FAILED(GetFolderIdFromMsgTable(pTable, &rInitSite.folderID))) rInitSite.folderID = FOLDERID_INVALID;
dwCreateFlags = 0; dwAction = OENA_COMPOSE;
for (DWORD i = 0; i < cRows; i++) { DWORD iRow = rgRows[i]; IMimeMessage *pMsg = NULL;
// Since this command is
hr = pTable->OpenMessage(iRow, OPEN_MESSAGE_SECURE, &pMsg, NOSTORECALLBACK); if (SUCCEEDED(hr)) { if (FAILED(pMsgFwd->AttachObject(IID_IMimeMessage, (LPVOID)pMsg, NULL))) fErrorsOccured = TRUE; pMsg->Release(); } else fErrorsOccured = TRUE; }
if (fErrorsOccured) { if(AthMessageBoxW(m_hwnd, MAKEINTRESOURCEW(idsAthenaMail), MAKEINTRESOURCEW(idsErrorAttachingMsgsToNote), NULL, MB_OKCANCEL) == IDCANCEL) fCreateNote = FALSE; }
if (fCreateNote) hr = CreateAndShowNote(dwAction, dwCreateFlags, &rInitSite, m_hwnd, (IUnknown *)m_pPumpRefCount); pMsgFwd->Release(); } else { LPMESSAGEINFO pInfo;
// Get some information about the message
if (SUCCEEDED(hr = m_pMsgList->GetMessageInfo(dwFocused, &pInfo))) { // Determine if this is a news or mail message.
if (pInfo->dwFlags & ARF_NEWSMSG) dwCreateFlags = OENCF_NEWSFIRST; else dwCreateFlags = 0;
// Reply or forward
if (nCmdID == ID_FORWARD) dwAction = OENA_FORWARD; else if (nCmdID == ID_FORWARD_AS_ATTACH) dwAction = OENA_FORWARDBYATTACH; else if (nCmdID == ID_REPLY) dwAction = OENA_REPLYTOAUTHOR; else if (nCmdID == ID_REPLY_ALL) dwAction = OENA_REPLYALL; else if (nCmdID == ID_REPLY_GROUP) dwAction = OENA_REPLYTONEWSGROUP; else AssertSz(FALSE, "Didn't ask for a valid action");
// Fill out the initialization information
rInitSite.dwInitType = OEMSIT_MSG_TABLE; rInitSite.initTable.pMsgTable = pTable; rInitSite.initTable.pListSelect = NULL; if (FAILED(GetFolderIdFromMsgTable(pTable, &rInitSite.folderID))) rInitSite.folderID = FOLDERID_INVALID; rInitSite.initTable.rowIndex = dwFocused;
m_pMsgList->FreeMessageInfo(pInfo);
// Create the note object
hr = CreateAndShowNote(dwAction, dwCreateFlags, &rInitSite, m_hwnd, (IUnknown *)m_pPumpRefCount); } } } }
exit: ReleaseObj(pTable); MemFree(rgRows); return (S_OK); }
HRESULT CFindDlg::CmdCancelMessage(DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut) { HRESULT hr; FOLDERID idFolder; DWORD dwFocused; DWORD *rgRows = NULL; DWORD cRows = 0;
if (m_pMsgList) { // Figure out which message is focused
if (SUCCEEDED(m_pMsgList->GetSelected(&dwFocused, &cRows, &rgRows))) { IMessageTable *pTable = NULL; LPMESSAGEINFO pInfo; // Get the message table from the message list. The note will need
// this to deal with next / prev commands
hr = m_pMsgList->GetMessageTable(&pTable); if (FAILED(hr)) goto exit;
// Get some information about the message
if (SUCCEEDED(hr = m_pMsgList->GetMessageInfo(dwFocused, &pInfo))) { if (SUCCEEDED(hr = m_pMsgList->GetRowFolderId(dwFocused, &idFolder))) hr = NewsUtil_HrCancelPost(m_hwnd, idFolder, pInfo);
m_pMsgList->FreeMessageInfo(pInfo); } pTable->Release(); } }
exit: MemFree(rgRows); return (S_OK); }
//
// FUNCTION: CFindDlg::CmdFindNow()
//
// PURPOSE: Start's a new find.
//
HRESULT CFindDlg::CmdFindNow(DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut) { // Start by freeing our current find information if we have any
_FreeFindInfo(&m_rFindInfo);
// Retrieve the find values from the dialog and store them in the
// m_rFindInfo struct.
if (_GetFindValues(m_hwnd, &m_rFindInfo)) { // Validate the data. If the user has Date From && Date To set, make
// sure that to is after from.
if ((m_rFindInfo.mask & (FIM_DATEFROM | FIM_DATETO)) == (FIM_DATEFROM | FIM_DATETO) && CompareFileTime(&m_rFindInfo.ftDateTo, &m_rFindInfo.ftDateFrom) < 0) { AthMessageBoxW(m_hwnd, MAKEINTRESOURCEW(idsAthena), MAKEINTRESOURCEW(idsErrBadFindParams), NULL, MB_OK | MB_ICONINFORMATION); return (E_INVALIDARG); } // Case insensitive search
if (m_rFindInfo.pszFrom) CharUpper(m_rFindInfo.pszFrom); if (m_rFindInfo.pszSubject) CharUpper(m_rFindInfo.pszSubject); if (m_rFindInfo.pszTo) CharUpper(m_rFindInfo.pszTo); if (m_rFindInfo.pszBody) CharUpper(m_rFindInfo.pszBody); // Show the bottom portion of the dialog
_ShowResults(m_hwnd);
// Start the find.
_OnFindNow(m_hwnd); } else { // If we couldn't store the information, assume it's becuase
// their isn't enough memory to
AthMessageBoxW(m_hwnd, MAKEINTRESOURCEW(idsAthena), MAKEINTRESOURCEW(idsMemory), NULL, MB_OK | MB_ICONINFORMATION); DestroyWindow(m_hwnd); }
return (S_OK); }
//
// FUNCTION: CFindDlg::CmdBrowseForFolder()
//
// PURPOSE: Bring's up the folder picker dialog
//
HRESULT CFindDlg::CmdBrowseForFolder(DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut) { FOLDERID idFolder; return PickFolderInEdit(m_hwnd, GetDlgItem(m_hwnd, IDC_FOLDER), 0, NULL, NULL, &idFolder); }
//
// FUNCTION: CFindDlg::CmdStop()
//
// PURPOSE: Called when the user want's to stop a find in progress.
//
HRESULT CFindDlg::CmdStop(DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut) { HWND hwndBtn;
m_fAbort = TRUE;
hwndBtn = GetDlgItem(m_hwnd, IDC_STOP); EnableWindow(hwndBtn, FALSE); Button_SetStyle(hwndBtn, BS_PUSHBUTTON, TRUE);
hwndBtn = GetDlgItem(m_hwnd, IDC_FIND_NOW); EnableWindow(hwndBtn, _IsFindEnabled(m_hwnd)); Button_SetStyle(hwndBtn, BS_DEFPUSHBUTTON, TRUE);
EnableWindow(GetDlgItem(m_hwnd, IDC_RESET), TRUE);
UpdateWindow(m_hwnd);
if (m_pCancel != NULL) m_pCancel->Cancel(CT_CANCEL);
return (S_OK); }
//
// FUNCTION: CFindDlg::CmdReset()
//
// PURPOSE: Called when the user want's to reset the find criteria
//
HRESULT CFindDlg::CmdReset(DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut) { _FreeFindInfo(&m_rFindInfo); m_rFindInfo.mask = FIM_FROM | FIM_TO | FIM_SUBJECT | FIM_BODYTEXT; _SetFindValues(m_hwnd, &m_rFindInfo); EnableWindow(GetDlgItem(m_hwnd, IDC_FIND_NOW), _IsFindEnabled(m_hwnd)); ((CMessageList *) m_pMsgList)->SetFolder(FOLDERID_INVALID, NULL, FALSE, NULL, NOSTORECALLBACK); m_fFindComplete = FALSE; m_pStatusBar->SetStatusText((LPTSTR) c_szEmpty);
return (S_OK); }
//
// FUNCTION: CFindDlg::CmdBlockSender()
//
// PURPOSE: Add the sender of the selected messages to the block senders list
//
// RETURN VALUE:
// HRESULT
//
HRESULT CFindDlg::CmdBlockSender(DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut) { HRESULT hr = S_OK; DWORD * rgRows = NULL; DWORD cRows = 0; LPMESSAGEINFO pInfo = NULL; IUnknown * pUnkMessage = NULL; IMimeMessage * pMessage = 0; LPSTR pszEmailFrom = NULL; ADDRESSPROPS rSender = {0}; CHAR szRes[CCHMAX_STRINGRES]; LPSTR pszResult = NULL;
TraceCall("CFindDlg::CmdBlockSender");
IF_FAILEXIT(hr = m_pMsgList->GetSelected(NULL, &cRows, &rgRows));
// It's possible for the message list to go away while we're doing this.
// To keep us from crashing, make sure you verify it still exists during
// the loop.
IF_FAILEXIT(hr = m_pMsgList->GetMessageInfo(rgRows[0], &pInfo)); // Do we already have the address?
if ((NULL != pInfo->pszEmailFrom) && ('\0' != pInfo->pszEmailFrom[0])) { pszEmailFrom = pInfo->pszEmailFrom; } else { // Load that message from the store
IF_FAILEXIT(hr = m_pMsgList->GetMessage(rgRows[0], FALSE, FALSE, &pUnkMessage));
if (NULL == pUnkMessage) IF_FAILEXIT(hr = E_FAIL); // Get the IMimeMessage interface from the message
IF_FAILEXIT(hr = pUnkMessage->QueryInterface(IID_IMimeMessage, (LPVOID *) &pMessage));
rSender.dwProps = IAP_EMAIL; IF_FAILEXIT(hr = pMessage->GetSender(&rSender)); Assert(rSender.pszEmail && ISFLAGSET(rSender.dwProps, IAP_EMAIL)); pszEmailFrom = rSender.pszEmail; } // Bring up the rule editor for this message
IF_FAILEXIT(hr = RuleUtil_HrAddBlockSender((0 != (pInfo->dwFlags & ARF_NEWSMSG)) ? RULE_TYPE_NEWS : RULE_TYPE_MAIL, pszEmailFrom)); // Load the template string
AthLoadString(idsSenderAdded, szRes, sizeof(szRes));
// Allocate the space to hold the final string
DWORD cchSize = (lstrlen(szRes) + lstrlen(pszEmailFrom) + 1); IF_FAILEXIT(hr = HrAlloc((VOID **) &pszResult, sizeof(*pszResult) * cchSize));
// Build up the warning string
wnsprintf(pszResult, cchSize, szRes, pszEmailFrom);
// Show the success dialog
AthMessageBox(m_hwnd, MAKEINTRESOURCE(idsAthena), pszResult, NULL, MB_OK | MB_ICONINFORMATION);
exit: MemFree(pszResult); g_pMoleAlloc->FreeAddressProps(&rSender); ReleaseObj(pMessage); ReleaseObj(pUnkMessage); m_pMsgList->FreeMessageInfo(pInfo); MemFree(rgRows); if (FAILED(hr)) { AthMessageBoxW(m_hwnd, MAKEINTRESOURCEW(idsAthena), MAKEINTRESOURCEW(idsSenderError), NULL, MB_OK | MB_ICONERROR); } return (hr); }
//
// FUNCTION: CFindDlg::CmdCreateRule()
//
// PURPOSE: Add the sender of the selected messages to the block senders list
//
// RETURN VALUE:
// HRESULT
//
HRESULT CFindDlg::CmdCreateRule(DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut) { HRESULT hr; DWORD * rgRows = NULL; DWORD cRows = 0; LPMESSAGEINFO pInfo = NULL; IUnknown * pUnkMessage = NULL; IMimeMessage * pMessage = 0;
TraceCall("CFindDlg::CmdCreateRule");
// Get the array of selected rows from the message list
if (FAILED(hr = m_pMsgList->GetSelected(NULL, &cRows, &rgRows))) return (hr);
// It's possible for the message list to go away while we're doing this.
// To keep us from crashing, make sure you verify it still exists during
// the loop.
if (SUCCEEDED(hr = m_pMsgList->GetMessageInfo(rgRows[0], &pInfo))) { // Load that message from the store
if (S_OK == m_pMsgList->GetMessage(rgRows[0], FALSE, FALSE, &pUnkMessage)) { // Get the IMimeMessage interface from the message
if (NULL != pUnkMessage) { pUnkMessage->QueryInterface(IID_IMimeMessage, (LPVOID *) &pMessage); } } // Bring up the rule editor for this message
hr = HrCreateRuleFromMessage(m_hwnd, (0 != (pInfo->dwFlags & ARF_NEWSMSG)) ? CRFMF_NEWS : CRFMF_MAIL, pInfo, pMessage); }
ReleaseObj(pMessage); ReleaseObj(pUnkMessage); m_pMsgList->FreeMessageInfo(pInfo); MemFree(rgRows);
return (S_OK); }
//
// FUNCTION: CFindDlg::CmdCombineAndDecode()
//
// PURPOSE: Combines the selected messages into a single message.
//
// RETURN VALUE:
// HRESULT
//
HRESULT CFindDlg::CmdCombineAndDecode(DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut) { FOLDERID idFolder; DWORD *rgRows = NULL; DWORD cRows = 0; CCombineAndDecode *pDecode = NULL; HRESULT hr;
// Create the decoder object
pDecode = new CCombineAndDecode(); if (!pDecode) return (S_OK);
// Get the array of selected rows from the message list
if (FAILED(hr = m_pMsgList->GetSelected(NULL, &cRows, &rgRows))) { pDecode->Release(); return (hr); }
// Get a pointer to the message table
IMessageTable *pTable = NULL; if (SUCCEEDED(m_pMsgList->GetMessageTable(&pTable))) { // Initialize the decoder
if (SUCCEEDED(GetFolderIdFromMsgTable(pTable, &idFolder))) pDecode->Start(m_hwnd, pTable, rgRows, cRows, idFolder);
}
MemFree(rgRows); pDecode->Release(); pTable->Release();
return (S_OK); }
void CFindDlg::_ShowResults(HWND hwnd) { if (!m_fShowResults) { RECT rc;
m_fShowResults = TRUE;
GetWindowRect(hwnd, &rc); m_ptDragMin.y = (3 * m_ptDragMin.y) / 2; ShowWindow(GetDlgItem(hwnd, IDC_STATUS_BAR), SW_SHOW); ShowWindow(m_hwndList, SW_SHOW);
SetWindowPos(hwnd, NULL, 0, 0, rc.right - rc.left, m_cyDlgFull, SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE); } }
void CFindDlg::_OnFindNow(HWND hwnd) { HWND hwndBtn;
m_fInProgress = TRUE;
hwndBtn = GetDlgItem(hwnd, IDC_FIND_NOW); EnableWindow(hwndBtn, FALSE); Button_SetStyle(hwndBtn, BS_PUSHBUTTON, TRUE);
EnableWindow(GetDlgItem(hwnd, IDC_RESET), FALSE);
hwndBtn = GetDlgItem(hwnd, IDC_STOP); EnableWindow(hwndBtn, TRUE); Button_SetStyle(hwndBtn, BS_DEFPUSHBUTTON, TRUE);
ShowWindow(m_hwndList, SW_SHOW); SetFocus(m_hwndList);
UpdateWindow(hwnd);
m_fAbort = m_fClose = FALSE;
_StartFind(_GetCurSel(hwnd), IsDlgButtonChecked(hwnd, IDC_INCLUDE_SUB));
CmdStop(ID_STOP, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
if (m_fClose) DestroyWindow(m_hwnd);
m_fInProgress = FALSE; }
FOLDERID CFindDlg::_GetCurSel(HWND hwnd) { return GetFolderIdFromEdit(GetDlgItem(hwnd, IDC_FOLDER)); }
void CFindDlg::_StartFind(FOLDERID idFolder, BOOL fSubFolders) { // If we're searching subfolders, then set that flag too
m_rFindInfo.fSubFolders = fSubFolders;
// Initialize the Message List
((CMessageList *)m_pMsgList)->SetFolder(idFolder, NULL, fSubFolders, &m_rFindInfo, (IStoreCallback *)this); }
void CFindDlg::_FreeFindInfo(FINDINFO *pfi) { FreeFindInfo(pfi); }
void CFindDlg::_SetFindValues(HWND hwnd, FINDINFO *pfi) { SYSTEMTIME st; HWND hwndTo; if (pfi->mask & FIM_FROM) { Assert(GetDlgItem(hwnd, IDC_FROM)); Edit_SetText(GetDlgItem(hwnd, IDC_FROM), pfi->pszFrom); } if (pfi->mask & FIM_TO) { hwndTo = GetDlgItem(hwnd, IDC_TO); if (NULL != hwndTo) { Edit_SetText(hwndTo, pfi->pszTo); } } if (pfi->mask & FIM_SUBJECT) { Assert(GetDlgItem(hwnd, IDC_SUBJECT)); Edit_SetText(GetDlgItem(hwnd, IDC_SUBJECT), pfi->pszSubject); } if (pfi->mask & FIM_BODYTEXT) { Assert(GetDlgItem(hwnd, IDC_BODY)); Edit_SetText(GetDlgItem(hwnd, IDC_BODY), pfi->pszBody); } if (GetDlgItem(hwnd, IDC_HAS_ATTACH)) CheckDlgButton(hwnd, IDC_HAS_ATTACH, (pfi->mask & FIM_ATTACHMENT) ? BST_CHECKED : BST_UNCHECKED);
if (GetDlgItem(hwnd, IDC_HAS_FLAG)) CheckDlgButton(hwnd, IDC_HAS_FLAG, (pfi->mask & FIM_FLAGGED) ? BST_CHECKED : BST_UNCHECKED); FileTimeToSystemTime(&pfi->ftDateFrom, &st); DateTime_SetSystemtime(GetDlgItem(hwnd, IDC_DATE_FROM), (pfi->mask & FIM_DATEFROM) ? GDT_VALID : GDT_NONE, &st); FileTimeToSystemTime(&pfi->ftDateTo, &st); DateTime_SetSystemtime(GetDlgItem(hwnd, IDC_DATE_TO), (pfi->mask & FIM_DATETO) ? GDT_VALID : GDT_NONE, &st); }
BOOL CFindDlg::_GetFindValues(HWND hwnd, FINDINFO *pfi) { SYSTEMTIME st; pfi->mask = 0; if (!AllocStringFromDlg(hwnd, IDC_FROM, &pfi->pszFrom) || !AllocStringFromDlg(hwnd, IDC_SUBJECT, &pfi->pszSubject) || !AllocStringFromDlg(hwnd, IDC_TO, &pfi->pszTo) || !AllocStringFromDlg(hwnd, IDC_BODY, &pfi->pszBody)) { return FALSE; } if (pfi->pszFrom) pfi->mask |= FIM_FROM; if (pfi->pszSubject) pfi->mask |= FIM_SUBJECT; if (pfi->pszTo) pfi->mask |= FIM_TO; if (pfi->pszBody) pfi->mask |= FIM_BODYTEXT; if (IsDlgButtonChecked(hwnd, IDC_HAS_ATTACH)) pfi->mask |= FIM_ATTACHMENT; if (IsDlgButtonChecked(hwnd, IDC_HAS_FLAG)) pfi->mask |= FIM_FLAGGED;
if (DateTime_GetSystemtime(GetDlgItem(hwnd, IDC_DATE_FROM), &st) != GDT_NONE) { pfi->mask |= FIM_DATEFROM; st.wHour = st.wMinute = st.wSecond = st.wMilliseconds = 0; // start of the day
SystemTimeToFileTime(&st, &pfi->ftDateFrom); } if (DateTime_GetSystemtime(GetDlgItem(hwnd, IDC_DATE_TO), &st) != GDT_NONE) { pfi->mask |= FIM_DATETO;
// end of day
st.wHour = 23; st.wMinute = 59; st.wSecond = 59; st.wMilliseconds = 999; SystemTimeToFileTime(&st, &pfi->ftDateTo); } return TRUE; }
//
// FUNCTION: CFindDlg::_IsFindEnabled()
//
// PURPOSE: Checks to see if the "Find Now" button should be enabled.
//
BOOL CFindDlg::_IsFindEnabled(HWND hwnd) { BOOL fEnable; SYSTEMTIME st; HWND hwndBody, hwndAttach, hwndTo;
hwndBody = GetDlgItem(hwnd, IDC_BODY); hwndAttach = GetDlgItem(hwnd, IDC_HAS_ATTACH); hwndTo = GetDlgItem(hwnd, IDC_TO);
// If we have content in any of these fields, we can search.
fEnable = Edit_GetTextLength(GetDlgItem(hwnd, IDC_FROM)) || Edit_GetTextLength(hwndTo) || Edit_GetTextLength(GetDlgItem(hwnd, IDC_SUBJECT)) || Edit_GetTextLength(hwndBody) || IsDlgButtonChecked(hwnd, IDC_HAS_ATTACH) || IsDlgButtonChecked(hwnd, IDC_HAS_FLAG) || (DateTime_GetSystemtime(GetDlgItem(hwnd, IDC_DATE_FROM), &st) != GDT_NONE) || (DateTime_GetSystemtime(GetDlgItem(hwnd, IDC_DATE_TO), &st) != GDT_NONE);
return fEnable; }
//
// FUNCTION: CFindDlg::_SetFindIntlFont()
//
// PURPOSE: Set's the correct international font for all edit boxes.
//
void CFindDlg::_SetFindIntlFont(HWND hwnd) { HWND hwndT;
hwndT = GetDlgItem(hwnd, IDC_FROM); if (hwndT != NULL) SetIntlFont(hwndT); hwndT = GetDlgItem(hwnd, IDC_TO); if (hwndT != NULL) SetIntlFont(hwndT); hwndT = GetDlgItem(hwnd, IDC_SUBJECT); if (hwndT != NULL) SetIntlFont(hwndT); hwndT = GetDlgItem(hwnd, IDC_BODY); if (hwndT != NULL) SetIntlFont(hwndT); }
//
// FUNCTION: CFindDlg::_InitSizingInfo()
//
// PURPOSE: Grabs all the sizing information we'll need later when the
// dialog is resized.
//
void CFindDlg::_InitSizingInfo(HWND hwnd) { RECT rc, rcClient; RECT rcEdit; WINDOWPLACEMENT wp;
TraceCall("CFindDlg::_InitSizingInfo");
// Get the overall size of the default dialog template
GetClientRect(hwnd, &rcClient); m_cxDlgDef = rcClient.right - rcClient.left; m_yView = rcClient.bottom;
// Make room for the menu bar and save that for resizing
AdjustWindowRect(&rcClient, GetWindowStyle(hwnd), TRUE); m_ptDragMin.x = rcClient.right - rcClient.left; m_ptDragMin.y = rcClient.bottom - rcClient.top;
GetWindowRect(GetDlgItem(hwnd, IDC_FOLDER), &rcEdit); MapWindowRect(NULL, hwnd, &rcEdit); m_xEdit = rcEdit.left; m_cxFolder = rcEdit.right - rcEdit.left;
GetWindowRect(GetDlgItem(hwnd, IDC_INCLUDE_SUB), &rc); MapWindowRect(NULL, hwnd, &rc); m_xIncSub = rc.left; m_yIncSub = rc.top;
GetWindowRect(GetDlgItem(hwnd, idcStatic1), &rc); m_cxStatic = rc.right - rc.left;
GetWindowRect(GetDlgItem(hwnd, IDC_BROWSE_FOLDER), &rc); MapWindowRect(NULL, hwnd, &rc); m_yBrowse = rc.top; m_dxBtnGap = rc.left - rcEdit.right;
GetWindowRect(GetDlgItem(hwnd, IDC_FIND_NOW), &rc); MapWindowRect(NULL, hwnd, &rc); m_xBtn = rc.left; m_dxBtn = rc.right - rc.left; m_yBtn = rc.top;
GetWindowRect(GetDlgItem(hwnd, IDC_STOP), &rc); MapWindowRect(NULL, hwnd, &rc); m_dyBtn = rc.top - m_yBtn;
GetWindowRect(GetDlgItem(hwnd, IDC_FROM), &rc); m_cxEdit = rc.right - rc.left; m_cyEdit = rc.bottom - rc.top;
SetWindowPos(hwnd, NULL, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE);
if (sizeof(wp) == GetOption(OPT_FINDER_POS, (LPBYTE)&wp, sizeof(wp))) { if (wp.showCmd != SW_SHOWMAXIMIZED) wp.showCmd = SW_SHOWNORMAL; m_cyDlgFull = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; SetWindowPlacement(hwnd, &wp); } else { m_cyDlgFull = (3 * m_ptDragMin.y) / 2; CenterDialog(hwnd); } }
//
// FUNCTION: CFindDlg::QuerySwitchIdentities()
//
// PURPOSE: Determine if it is OK for the identity manager to
// switch identities now
//
HRESULT CFindDlg::QuerySwitchIdentities() { if (!IsWindowEnabled(m_hwnd)) return E_PROCESS_CANCELLED_SWITCH;
return S_OK; }
//
// FUNCTION: CFindDlg::SwitchIdentities()
//
// PURPOSE: The current identity has switched. Close the window.
//
HRESULT CFindDlg::SwitchIdentities() { if (m_fInProgress) { CmdStop(ID_STOP, OLECMDEXECOPT_DODEFAULT, NULL, NULL); m_fClose = TRUE; } else { DestroyWindow(m_hwnd); } return S_OK; }
//
// FUNCTION: CFindDlg::IdentityInformationChanged()
//
// PURPOSE: Information about the current identity has changed.
// This is ignored.
//
HRESULT CFindDlg::IdentityInformationChanged(DWORD dwType) { return S_OK; }
|