391 lines
10 KiB
C++
391 lines
10 KiB
C++
//+-------------------------------------------------------------------------
|
|
//
|
|
// 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_
|