//-------------------------------------------------------------------------- // MsgTable.h //-------------------------------------------------------------------------- #pragma once //-------------------------------------------------------------------------- // Forward Decl. //-------------------------------------------------------------------------- class CFindFolder; class CMessageTable; //-------------------------------------------------------------------------- // SafeReleaseRow //-------------------------------------------------------------------------- #define SafeReleaseRow(_pTable, _pMessage) \ if (_pMessage) { \ _pTable->ReleaseRow(_pMessage); \ _pMessage = NULL; \ } //-------------------------------------------------------------------------- // WALKTHREADFLAGS //-------------------------------------------------------------------------- typedef DWORD WALKTHREADFLAGS; #define WALK_THREAD_CURRENT 0x00000001 #define WALK_THREAD_BOTTOMUP 0x00000020 //-------------------------------------------------------------------------- // SORTCHANGEINFO //-------------------------------------------------------------------------- typedef struct tagSORTCHANGEINFO { BYTE fSort; BYTE fThread; BYTE fFilter; BYTE fExpand; } SORTCHANGEINFO, *LPSORTCHANGEINFO; //-------------------------------------------------------------------------- // ROWINFO //-------------------------------------------------------------------------- typedef struct tagROWINFO *LPROWINFO; typedef struct tagROWINFO { BYTE cRefs; ROWSTATE dwState; LPROWINFO pParent; LPROWINFO pChild; LPROWINFO pSibling; WORD wHighlight; unsigned fExpanded : 1; // A thread parent that is expanded unsigned fVisible : 1; // Is displayed in the m_prgpView index unsigned fFiltered : 1; // Filtered and won't be displayed until filter changes unsigned fHidden : 1; // Hidden, but if row is changed it may become visible. unsigned fDelayed : 1; // Delayed Insert MESSAGEINFO Message; } ROWINFO; //-------------------------------------------------------------------------- // NOTIFYQUEUE //-------------------------------------------------------------------------- typedef struct tagNOTIFYQUEUE { BOOL fClean; TRANSACTIONTYPE tyCurrent; ROWINDEX iRowMin; ROWINDEX iRowMax; DWORD cUpdate; DWORD cAllocated; DWORD cRows; BYTE fIsExpandCollapse; LPROWINDEX prgiRow; } NOTIFYQUEUE, *LPNOTIFYQUEUE; //-------------------------------------------------------------------------- // PFWALKTHREADCALLBACK //-------------------------------------------------------------------------- typedef HRESULT (APIENTRY *PFWALKTHREADCALLBACK)(CMessageTable *pThis, LPROWINFO pRow, DWORD_PTR dwCookie); //-------------------------------------------------------------------------- // PFNENUMREFS //-------------------------------------------------------------------------- typedef HRESULT (APIENTRY *PFNENUMREFS)(LPCSTR pszMessageId, DWORD_PTR dwCookie, BOOL *pfDone); //-------------------------------------------------------------------------- // CMessageTable //-------------------------------------------------------------------------- class CMessageTable : public IMessageTable, public IDatabaseNotify, public IServiceProvider, public IOperationCancel { public: //---------------------------------------------------------------------- // Construction //---------------------------------------------------------------------- CMessageTable(void); ~CMessageTable(void); //---------------------------------------------------------------------- // IUnknown Members //---------------------------------------------------------------------- STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv); STDMETHODIMP_(ULONG) AddRef(void); STDMETHODIMP_(ULONG) Release(void); //---------------------------------------------------------------------- // IMessageTable Members //---------------------------------------------------------------------- STDMETHODIMP Initialize(FOLDERID idFolder, IMessageServer *pServer, BOOL fFindTable, IStoreCallback *pCallback); STDMETHODIMP StartFind(LPFINDINFO pCriteria, IStoreCallback *pCallback); STDMETHODIMP SetOwner(IStoreCallback *pDefaultCallback); STDMETHODIMP Close(void); STDMETHODIMP Synchronize(SYNCFOLDERFLAGS dwFlags, DWORD cHeaders, IStoreCallback *pCallback); STDMETHODIMP OnSynchronizeComplete(void); STDMETHODIMP GetCount(GETCOUNTTYPE tyCount, DWORD *pdwCount); STDMETHODIMP GetRow(ROWINDEX iRow, LPMESSAGEINFO *ppData); STDMETHODIMP ReleaseRow(LPMESSAGEINFO pInfo); STDMETHODIMP GetRelativeRow(ROWINDEX iRow, RELATIVEROWTYPE tyRelative, LPROWINDEX piRelative); STDMETHODIMP GetIndentLevel(ROWINDEX iRow, LPDWORD pcIndent); STDMETHODIMP Mark(LPROWINDEX prgiView, DWORD cRows, APPLYCHILDRENTYPE tyApply, MARK_TYPE mark, IStoreCallback *pCallback); STDMETHODIMP GetSortInfo(LPFOLDERSORTINFO pSortInfo); STDMETHODIMP SetSortInfo(LPFOLDERSORTINFO pSortInfo, IStoreCallback *pCallback); STDMETHODIMP GetLanguage(ROWINDEX iRow, LPDWORD pdwCodePage); STDMETHODIMP SetLanguage(DWORD cRows, LPROWINDEX prgiRow, DWORD dwCodePage); STDMETHODIMP GetNextRow(ROWINDEX iCurrentRow, GETNEXTTYPE tyDirection, ROWMESSAGETYPE tyMessage, GETNEXTFLAGS dwFlags, LPROWINDEX piNewRow); STDMETHODIMP GetRowState(ROWINDEX iRow, ROWSTATE dwStateMask, ROWSTATE *pdwState); STDMETHODIMP GetSelectionState(DWORD cRows, LPROWINDEX prgiView, SELECTIONSTATE dwMask, BOOL fIncludeChildren, SELECTIONSTATE *pdwState); STDMETHODIMP Expand(ROWINDEX iRow); STDMETHODIMP Collapse(ROWINDEX iRow); STDMETHODIMP OpenMessage(ROWINDEX iRow, OPENMESSAGEFLAGS dwFlags, IMimeMessage **ppMessage, IStoreCallback *pCallback); STDMETHODIMP GetRowMessageId(ROWINDEX iRow, LPMESSAGEID pidMessage); STDMETHODIMP GetRowIndex(MESSAGEID idMessage, LPROWINDEX piView); STDMETHODIMP DeleteRows(DELETEMESSAGEFLAGS dwFlags, DWORD cRows, LPROWINDEX prgiView, BOOL fIncludeChildren, IStoreCallback *pCallback); STDMETHODIMP CopyRows(FOLDERID idFolder, COPYMESSAGEFLAGS dwOptions, DWORD cRows, LPROWINDEX prgiView, LPADJUSTFLAGS pFlags, IStoreCallback *pCallback); STDMETHODIMP RegisterNotify(REGISTERNOTIFYFLAGS dwFlags, IMessageTableNotify *pNotify); STDMETHODIMP UnregisterNotify(IMessageTableNotify *pNotify); STDMETHODIMP FindNextRow(ROWINDEX iStartRow, LPCTSTR pszFindString, FINDNEXTFLAGS dwFlags, BOOL fIncludeBody, ROWINDEX *piNextRow, BOOL *pfWrapped); STDMETHODIMP GetRowFolderId(ROWINDEX iRow, LPFOLDERID pidFolder); STDMETHODIMP GetMessageIdList(BOOL fRootsOnly, DWORD cRows, LPROWINDEX prgiView, LPMESSAGEIDLIST pIdList); STDMETHODIMP ConnectionAddRef(void); STDMETHODIMP ConnectionRelease(void); STDMETHODIMP IsChild(ROWINDEX iRowParent, ROWINDEX iRowChild); STDMETHODIMP GetAdBarUrl(IStoreCallback *pCallback); //---------------------------------------------------------------------- // IDatabaseNotify //---------------------------------------------------------------------- STDMETHODIMP OnTransaction(HTRANSACTION hTransaction, DWORD_PTR dwCookie, IDatabase *pDB); //---------------------------------------------------------------------- // IServiceProvider //---------------------------------------------------------------------- STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, LPVOID *ppvObject); //---------------------------------------------------------------------- // IOperationCancel //---------------------------------------------------------------------- STDMETHODIMP Cancel(CANCELTYPE tyCancel) { return(S_OK); } private: //---------------------------------------------------------------------- // Private Methods //---------------------------------------------------------------------- HRESULT _CreateRow(LPMESSAGEINFO pMessage, LPROWINFO *ppRow); HRESULT _InsertRowIntoThread(LPROWINFO pRow, BOOL fNotify); HRESULT _DeleteRowFromThread(LPROWINFO pRow, BOOL fNotify); HRESULT _FreeTable(void); HRESULT _FreeTableElements(void); HRESULT _BuildTable(IStoreCallback *pCallback); HRESULT _WalkMessageThread(LPROWINFO pRow, WALKTHREADFLAGS dwFlags, DWORD_PTR dwCookie, PFWALKTHREADCALLBACK pfnCallback); HRESULT _RowTableInsert(ROWORDINAL iOrdinal, LPMESSAGEINFO pMessage); HRESULT _RowTableDelete(ROWORDINAL iOrdinal, LPMESSAGEINFO pMessage); HRESULT _RowTableUpdate(ROWORDINAL iOrdinal, LPMESSAGEINFO pMessage); HRESULT _GetRowFromIndex(ROWINDEX iRow, LPROWINFO *ppRow); HRESULT _LinkRowIntoThread(LPROWINFO pParent, LPROWINFO pRow, BOOL fNotify); HRESULT _GrowIdList(LPMESSAGEIDLIST pList, DWORD cNeeded); HRESULT _ExpandThread(ROWINDEX iRow, BOOL fNotify, BOOL fReExpand); HRESULT _ExpandSingleThread(LPROWINDEX piCurrent, LPROWINFO pParent, BOOL fNotify, BOOL fForceExpand); HRESULT _CollapseThread(ROWINDEX iRow, BOOL fNotify); HRESULT _CollapseSingleThread(LPROWINDEX piCurrent, LPROWINFO pParent, BOOL fNotify); HRESULT _InsertIntoView(ROWINDEX iRow, LPROWINFO pRow); HRESULT _DeleteFromView(ROWINDEX iRow, LPROWINFO pRow); HRESULT _GetRowFromOrdinal(ROWORDINAL iOrdinal, LPMESSAGEINFO pExpected, LPROWINFO *ppRow); HRESULT _AdjustUnreadCount(LPROWINFO pRow, LONG lCount); HRESULT _GetThreadIndexRange(LPROWINFO pRow, BOOL fClearState, LPROWINDEX piMin, LPROWINDEX piMax); HRESULT _IsThreadImportance(LPROWINFO pRow, MESSAGEFLAGS dwFlag, ROWSTATE dwState, ROWSTATE *pdwState); HRESULT _QueueNotification(TRANSACTIONTYPE tyTransaction, ROWINDEX iRowMin, ROWINDEX iRowMax, BOOL fIsExpandCollapse=FALSE); HRESULT _FlushNotificationQueue(BOOL fFinal); HRESULT _GetSortChangeInfo(LPFOLDERSORTINFO pSortInfo, LPFOLDERUSERDATA pUserData, LPSORTCHANGEINFO pChange); HRESULT _SortThreadFilterTable(LPSORTCHANGEINFO pChange, BOOL fApplyFilter); HRESULT _SortAndThreadTable(BOOL fApplyFilter); HRESULT _HideRow(LPROWINFO pRow, BOOL fNotify); HRESULT _ShowRow(LPROWINFO pRow); HRESULT _PruneToReplies(void); HRESULT _FindThreadParentByRef(LPCSTR pszReferences, LPROWINFO *ppParent); HRESULT _RefreshFilter(void); //---------------------------------------------------------------------- // Utilities //---------------------------------------------------------------------- VOID _SortView(LONG left, LONG right); LONG _CompareMessages(LPMESSAGEINFO pMsg1, LPMESSAGEINFO pMsg2); BOOL _FIsFiltered(LPROWINFO pRow); BOOL _FIsHidden(LPROWINFO pRow); LPROWINFO _PGetThreadRoot(LPROWINFO pRow); //---------------------------------------------------------------------- // Friends //---------------------------------------------------------------------- static HRESULT _WalkThreadGetSelectionState(CMessageTable *pThis, LPROWINFO pRow, DWORD_PTR dwCookie); static HRESULT _WalkThreadGetIdList(CMessageTable *pThis, LPROWINFO pRow, DWORD_PTR dwCookie); static HRESULT _WalkThreadGetState(CMessageTable *pThis, LPROWINFO pRow, DWORD_PTR dwCookie); static HRESULT _WalkThreadClearState(CMessageTable *pThis, LPROWINFO pRow, DWORD_PTR dwCookie); static HRESULT _WalkThreadIsFromMe(CMessageTable *pThis, LPROWINFO pRow, DWORD_PTR dwCookie); static HRESULT _WalkThreadHide(CMessageTable *pThis, LPROWINFO pRow, DWORD_PTR dwCookie); private: //---------------------------------------------------------------------- // Private Data //---------------------------------------------------------------------- LONG m_cRef; // Reference Counting BOOL m_fSynching; // Are we synching a folder ? DWORD m_cAllocated; // Allocated elements in m_prgRow and m_prgiView DWORD m_cRows; // Rows... DWORD m_cView; // Number of items in the listview DWORD m_cFiltered; // Number of rows that were filtered DWORD m_cUnread; // Number of unread rows in m_prgpRow LPROWINFO *m_prgpRow; // Array of Pointers to Rows LPROWINFO *m_prgpView; // Current View FOLDERSORTINFO m_SortInfo; // Folder Sort Info IMessageFolder *m_pFolder; // Base Folder IDatabase *m_pDB; // The Database CFindFolder *m_pFindFolder; // Find Folder IMessageTableNotify *m_pNotify; // usually the message list BYTE m_fRelNotify; // Release m_pNotify? IDatabaseQuery *m_pQuery; // Query Object NOTIFYQUEUE m_Notify; // Notify Queue FOLDERINFO m_Folder; // Folder Information DWORD m_cDelayed; // Number of news messages not insert into view BYTE m_fRegistered; // Registered for Notifications BYTE m_fLoaded; // The first load has completed. WORD m_clrWatched; // Watched Color LPSTR m_pszEmail; // Email Address to use for show replies filter IHashTable *m_pThreadMsgId; // Message-ID Hash Table for Threading IHashTable *m_pThreadSubject; // Message-ID Hash Table for Threading }; //-------------------------------------------------------------------------- // Prototypes //-------------------------------------------------------------------------- HRESULT EnumerateRefs(LPCSTR pszReferences, DWORD_PTR dwCookie, PFNENUMREFS pfnEnumRefs);