|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997.
//
// File: Msg.h
//
// Contents: Handles inter-thread communications
//
// Classes: CThreadMsgProxy
//
// Notes:
//
// History: 05-Nov-97 rogerg Created.
//
//--------------------------------------------------------------------------
#ifndef _THREADMSG_
#define _THREADMSG_
// stublist for global stublist structure.
typedef struct tagSTUBLIST { struct tagSTUBLIST *pNextStub; // pointer to next proxy.
ULONG cRefs; // number of proxies using Stub
CLSID clsidStub; // clsid for stub.
HANDLE hThreadStub; // Handle of the Stubs Thread
DWORD ThreadIdStub; // ThreadID to send Message to.
HWND hwndStub; // HWND OF STUB.
BOOL fStubTerminated; // set if this stub was force terminated.
} STUBLIST;
// WMs for Thread communication
#define WM_THREADMESSAGE (WM_USER + 1)
#define WM_CFACTTHREAD_REVOKE (WM_USER + 2)
#define WM_MAINTHREAD_QUIT (WM_USER + 3)
#define WM_THREADSTUBMESSAGE (WM_USER + 4)
#define WM_USER_MAX 0x7FFF // maximum user message that can be defined.
// alll msgs are unique bits so hndlrq and others
// can keep track of out calls.
typedef enum _tagThreadMsg { ThreadMsg_Initialize = 0x0001, ThreadMsg_GetHandlerInfo = 0x0002, ThreadMsg_EnumOfflineItems = 0x0004, ThreadMsg_GetItemObject = 0x0008, ThreadMsg_ShowProperties = 0x0010, ThreadMsg_SetProgressCallback = 0x0020,
ThreadMsg_PrepareForSync = 0x0040, ThreadMsg_Synchronize = 0x0080, ThreadMsg_SetItemStatus = 0x0100, ThreadMsg_ShowError = 0x0200,
ThreadMsg_Release = 0x0400, // Private Messages
ThreadMsg_AddHandlerItems = 0x1000, ThreadMsg_CreateServer = 0X2000, ThreadMsg_SetHndlrQueue = 0x4000, ThreadMsg_SetupCallback = 0x8000,
} ThreadMsg;
// messages sent to toplevel stub object.
typedef enum _tagStubMsg { StubMsg_CreateNewStub = 0x0001, StubMsg_Release = 0x0002, } StubMsg;
class CThreadMsgProxy; class CThreadMsgStub; class CHndlrMsg; class CHndlrQueue;
typedef struct _tagHandlerThreadArgs { HANDLE hEvent; // used to know when the message loop has been created.
HRESULT hr; // inidicates if creation was successfull
HWND hwndStub; // hwnd of stub window. This is the window messages should be posted to.
} HandlerThreadArgs;
// helper functions called by client and Server
HRESULT CreateHandlerThread(CThreadMsgProxy **pThreadProxy,HWND hwndDlg ,REFCLSID refClsid); STDAPI InitMessageService();
// WPARAM is messaging specific data
typedef struct _tagMessagingInfo { HANDLE hMsgEvent; // Handle to Message Event for synchronization.
DWORD dwSenderThreadID; // ThreadID of the Caller.
CHndlrMsg *pCHndlrMsg; //handler message instance for this proxy.
} MessagingInfo;
// LPARAM is information specific to the message being sent.
typedef struct _tagGenericMsg { HRESULT hr; // return value from the message.
UINT ThreadMsg; // message to send.
} GenericMsg;
// request to stubObject to create a new stub for a proxy
typedef struct _tagMSGSTUBCreateStub { GenericMsg MsgGen; CHndlrMsg *pCHndlrMsg; // on success returns a pointer to a new hndlrMsg struct.
} MSGSTUBCreateStub;
// Message specific structures
typedef struct _tagMSGCreateServer { GenericMsg MsgGen; const CLSID *pCLSIDServer; CHndlrQueue *pHndlrQueue; HANDLERINFO *pHandlerId; DWORD dwProxyThreadId; } MSGCreateServer;
// Message specific structures
typedef struct _tagSetHndlrQueue { GenericMsg MsgGen; CHndlrQueue *pHndlrQueue; HANDLERINFO *pHandlerId; DWORD dwProxyThreadId; } MSGSetHndlrQueue;
typedef struct _tagMSGInitialize { GenericMsg MsgGen; DWORD dwReserved; DWORD dwSyncFlags; DWORD cbCookie; const BYTE *lpCookie; } MSGInitialize;
typedef struct _tagMSGGetHandlerInfo { GenericMsg MsgGen; LPSYNCMGRHANDLERINFO *ppSyncMgrHandlerInfo; } MSGGetHandlerInfo;
typedef struct _tagMSGEnumOfflineItems { GenericMsg MsgGen; ISyncMgrEnumItems** ppenumOfflineItems; } MSGEnumOfflineItems;
typedef struct _tagMSGGetItemObject { GenericMsg MsgGen; SYNCMGRITEMID ItemID; GUID riid; void** ppv; } MSGGetItemObject;
typedef struct _tagMSGShowProperties { GenericMsg MsgGen; HWND hWndParent; SYNCMGRITEMID ItemID; } MSGShowProperties;
typedef struct _tagMSGSetProgressCallback { GenericMsg MsgGen; ISyncMgrSynchronizeCallback *lpCallBack; } MSGSetProgressCallback;
typedef struct _tagMSGPrepareForSync { GenericMsg MsgGen;
// SetHndlrQueue Items
CHndlrQueue *pHndlrQueue; HANDLERINFO *pHandlerId;
// PrepareForSyncItems
ULONG cbNumItems; SYNCMGRITEMID *pItemIDs; HWND hWndParent; DWORD dwReserved; } MSGPrepareForSync;
typedef struct _tagMSGSynchronize { GenericMsg MsgGen; HWND hWndParent; } MSGSynchronize;
typedef struct _tagMSGSetItemStatus { GenericMsg MsgGen; SYNCMGRITEMID ItemID; DWORD dwSyncMgrStatus; } MSGSetItemStatus;
typedef struct _tagMSGShowErrors { GenericMsg MsgGen; HWND hWndParent; SYNCMGRERRORID ErrorID; ULONG *pcbNumItems; SYNCMGRITEMID **ppItemIDs; } MSGShowConflicts;
typedef struct _tagMSGLogErrors { DWORD mask; SYNCMGRERRORID ErrorID; BOOL fHasErrorJumps; SYNCMGRITEMID ItemID; DWORD dwErrorLevel; const WCHAR *lpcErrorText; } MSGLogErrors;
typedef struct _tagMSGDeleteLogErrors { HANDLERINFO *pHandlerId; SYNCMGRERRORID ErrorID; } MSGDeleteLogErrors;
typedef struct _tagMSGAddItemHandler { GenericMsg MsgGen; HWND hwndList; // review, unused.
DWORD *pcbNumItems; } MSGAddItemHandler;
typedef struct _tagMSGSetupCallback { GenericMsg MsgGen; BOOL fSet; } MSGSetupCallback;
// inherit from IOfflineSynchronize to catch any interface changes.
class CThreadMsgProxy { public: CThreadMsgProxy(); ~CThreadMsgProxy();
STDMETHODIMP InitProxy(HWND hwndStub, DWORD ThreadId,HANDLE hThread,HWND hwndDlg, REFCLSID refClsid,STUBLIST *pStubId); STDMETHODIMP DispatchMsg(GenericMsg *genMsg,BOOL fAllowIncomingCalls,BOOL fAsync); STDMETHODIMP DispatchsStubMsg(GenericMsg *pgenMsg,BOOL fAllowIncomingCalls);
//IUnknown members
STDMETHODIMP QueryInterface(REFIID, LPVOID FAR *); STDMETHODIMP_(ULONG) AddRef(); STDMETHODIMP_(ULONG) Release();
// IOfflineSynchronize Methods
STDMETHODIMP Initialize(DWORD dwReserved,DWORD dwSyncFlags, DWORD cbCookie,const BYTE *lpCooke);
STDMETHODIMP GetHandlerInfo(LPSYNCMGRHANDLERINFO *ppSyncMgrHandlerInfo); STDMETHODIMP EnumSyncMgrItems(ISyncMgrEnumItems **ppenumOfflineItems); STDMETHODIMP GetItemObject(REFSYNCMGRITEMID ItemID,REFIID riid,void** ppv); STDMETHODIMP ShowProperties(HWND hWndParent,REFSYNCMGRITEMID ItemID); STDMETHODIMP SetProgressCallback(ISyncMgrSynchronizeCallback *lpCallBack); STDMETHODIMP PrepareForSync(ULONG cbNumItems,SYNCMGRITEMID *pItemIDs, HWND hWndParent,DWORD dwReserved); STDMETHODIMP Synchronize(HWND hWndParent); STDMETHODIMP SetItemStatus(REFSYNCMGRITEMID ItemID,DWORD dwSyncMgrStatus); STDMETHODIMP ShowError(HWND hWndParent,REFSYNCMGRERRORID ErrorID,ULONG *pcbNumItems,SYNCMGRITEMID **ppItemIDs);
// Private messages
STDMETHODIMP CreateServer(const CLSID *pCLSIDServer,CHndlrQueue *pHndlrQueue,HANDLERINFO *pHandlerId); STDMETHODIMP SetHndlrQueue(CHndlrQueue *pHndlrQueue, HANDLERINFO *pHandlerId, DWORD dwThreadIdProxy); STDMETHODIMP AddHandlerItems(HWND hwndList,DWORD *pcbNumItems); STDMETHODIMP SetupCallback(BOOL fSet); STDMETHODIMP SetProxyParams(HWND hwndDlg, DWORD ThreadIdProxy, CHndlrQueue *pHndlrQueue,HANDLERINFO *pHandlerId );
inline STDMETHODIMP SetProxyHwndDlg(HWND hwndDlg) { m_hwndDlg = hwndDlg; return NOERROR; }
inline BOOL IsProxyInOutCall() { return m_dwNestCount; } STDMETHODIMP SetProxyCompletion(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);
// messages sent to the toplevel stub object.
STDMETHODIMP CreateNewHndlrMsg(); STDMETHODIMP ReleaseStub(); STDMETHODIMP TerminateHandlerThread(TCHAR *pszHandlerName,BOOL fPromptUser);
private: HANDLE m_hThreadStub; // Handle of the Stubs Thread
DWORD m_ThreadIdStub; // ThreadID to send Message to.
HWND m_hwndStub; // HWND OF STUB.
CHndlrMsg *m_pCHndlrMsg; // HndlrMsg associated with this proxy.
BOOL m_fTerminatedHandler; // set to true if handler has been terminated.
STUBLIST *m_pStubId; // Id of stub this proxy belongs to.
HWND m_hwndDlg; // hwnd of any dialog on this thread.
CLSID m_Clsid; // clsid of this handler.
DWORD m_ThreadIdProxy;
// Proxy Side Information
CHndlrQueue *m_pHndlrQueue; HANDLERINFO * m_pHandlerId; BOOL m_fNewHndlrQueue; // set to indicate if Stub side information is out of date.
DWORD m_dwNestCount; // keeps track of number of nestcount on item so can determine if in out call.
MSG m_msgCompletion; BOOL m_fHaveCompletionCall;
DWORD m_cRef; };
#define MSGSERVICE_HWNDCLASSNAME "SyncMgr_HwndMsgService"
#define DWL_THREADWNDPROCCLASS 0 // window long offset to MsgService Hwnd this ptr.
LRESULT CALLBACK MsgThreadWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
typedef enum _tagMSGHWNDTYPE { MSGHWNDTYPE_UNDEFINED = 0x0, // Message Service has not been initialized
MSGHWNDTYPE_HANDLERTHREAD = 0x1, // Message Service if for a Handler Thread.
MSGHWNDTYPE_MAINTHREAD = 0x2, // Message Service if for the Main Thread
} MSGHWNDTYPE;
typedef struct _tagMSGSERVICEQUEUE { struct _tagMSGSERVICEQUEUE *pNextMsg; DWORD dwNestCount; // nestcount completion should be called.
MSG msg; } MSGSERVICEQUEUE;
class CMsgServiceHwnd { public: HWND m_hwnd; DWORD m_dwThreadID; CHndlrMsg *m_pHndlrMsg; MSGHWNDTYPE m_MsgHwndType; MSGSERVICEQUEUE *m_pMsgServiceQueue; // queue to hold any message to process when current
// cal completes.
BOOL m_fInOutCall;
CMsgServiceHwnd(); ~CMsgServiceHwnd(); inline HWND GetHwnd() { return m_hwnd; }; BOOL Initialize(DWORD dwThreadID,MSGHWNDTYPE MsgHwndType); HRESULT HandleThreadMessage(MessagingInfo *pmsgInfo,GenericMsg *pgenMsg); void Destroy(); };
// internal functions
HRESULT SendThreadMessage(DWORD idThread,UINT uMsg,WPARAM wParam,LPARAM lParam); DWORD WINAPI HandlerThread( LPVOID ); HRESULT DoModalLoop(HANDLE hEvent,HANDLE hThread,HWND hwndDlg,BOOL fAllowIncomingCalls,DWORD dwTimeout);
#endif // _THREADMSG_
|