FORM.CPP
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:48k
源码类别:
Windows编程
开发平台:
Visual C++
- /* --------------------------------------------------------------------------
- Basic Forms example of a custom sendable form. It is an EXE server
- rather than a DLL. It implements the minimum form interface required
- to launch and send a form.
- Copyright (C) 1995 Microsoft Corporation
- -------------------------------------------------------------------------- */
- //#define ALLOW_SUBCLASS_IPM // all other forms to subclass the reply behavior
- // of this form (slower, but more correct)
- #include <windows.h>
- #include <windowsx.h>
- #include <ole2.h>
- #include <initguid.h>
- #include <mapiform.h>
- #define INITGUID
- #include <initguid.h>
- #include <mapix.h>
- #include <mapiutil.h>
- #include <mapinls.h>
- #include "dbugit.h"
- #include "check.h"
- #include "form.h"
- #include "dlg.h"
- /*
- *
- * Checkers form clsid. This must match the configuration file.
- *
- */
- DEFINE_GUID(CLSID_MyFormsClsId, 0x86174010, 0x5030, 0x0076, 0x99, 0x12, 0x00, 0xaa, 0x00, 0x38, 0x90, 0x1b);
- /*
- * HrStartOleAndRegisterClassFactory
- *
- * Purpose:
- * Initialize OLE, MAPI, and the Forms Interface
- * Should be called from WinMain() or InitApplication() in an SDI app
- *
- * This function LoadLibraries the neccessary DLLs rather than
- * linking with them. This permits the form to run as a stand-
- * alone executable even when MAPI and OLE are not installed.
- *
- * Returns:
- * HRESULT
- */
- #ifdef _WIN32
- #define szOleDll "ole32.dll"
- #define szMapiDll "mapi32.dll"
- #else
- #define szOleDll "compobj.dll"
- #define szMapiDll "mapi.dll"
- #endif
- HINSTANCE hinstOle = NULL;
- HINSTANCE hinstMapi = NULL;
- typedef HRESULT (FAR PASCAL *LPFNCOREGISTERCLASSOBJECT)(REFCLSID rclsid,
- IUnknown FAR * pUnk, DWORD dwClsContext, DWORD flags, LPDWORD lpdwRegister);
- #ifdef WIN16
- typedef BOOL (FAR PASCAL *LPFNISEQUALGUID)(REFGUID rguid1, REFGUID rguid2);
- #undef IsEqualIID
- #define IsEqualIID(riid1, riid2) (*lpfnIsEqualGUID)(riid1, riid2)
- #endif
- typedef HRESULT (FAR PASCAL *LPFNHRQUERYALLROWS)(LPMAPITABLE ptable,
- LPSPropTagArray ptaga, LPSRestriction pres,
- LPSSortOrderSet psos, LONG crowsMax,
- LPSRowSet FAR *pprows);
- typedef ULONG (FAR PASCAL *LPFNMAPIFREEBUFFER)(LPVOID pv);
- typedef HRESULT (FAR PASCAL *LPFNMAPIINITIALIZE)(LPVOID lpvReserved);
- typedef void (FAR PASCAL *LPFNMAPIUNINITIALIZE)(VOID);
- typedef void (FAR PASCAL *LPFNMAPIFREEPADRLIST)(LPADRLIST);
- LPFNCOREGISTERCLASSOBJECT lpfnCoRegisterClassObject;
- #ifdef WIN16
- LPFNISEQUALGUID lpfnIsEqualGUID;
- #endif
- LPFNHRQUERYALLROWS lpfnHrQueryAllRows ;
- LPFNMAPIFREEBUFFER lpfnMAPIFreeBuffer ;
- LPFNMAPIINITIALIZE lpfnMAPIInitialize ;
- LPFNMAPIUNINITIALIZE lpfnMAPIUninitialize ;
- LPFNMAPIFREEPADRLIST lpfnFreePadrlist ;
- HRESULT
- HrStartOleAndRegisterClassFactory(void)
- {
- FRMFMR * pfrmfmr = NULL;
- HRESULT hr;
- TraceTag(tagFormFunc,"HrStartOleAndRegisterClassFactory");
- // ----- LoadLibrary the essentials
- hinstOle = LoadLibrary(szOleDll);
- hinstMapi = LoadLibrary(szMapiDll);
- #ifdef WIN16
- if (hinstOle < HINSTANCE_ERROR) hinstOle = 0;
- if (hinstMapi < HINSTANCE_ERROR) hinstMapi = 0;
- #endif
- if (0 == hinstOle || 0 == hinstMapi)
- {
- return ResultFromScode(E_FAIL);
- }
- // ----- Setup a few function pointers
- lpfnCoRegisterClassObject = (LPFNCOREGISTERCLASSOBJECT) GetProcAddress(hinstOle, "CoRegisterClassObject");
- #if defined(_WIN32)
- #if defined(_X86_)
- lpfnHrQueryAllRows = (LPFNHRQUERYALLROWS ) GetProcAddress(hinstMapi,"HrQueryAllRows@24");
- lpfnFreePadrlist = (LPFNMAPIFREEPADRLIST ) GetProcAddress(hinstMapi,"FreePadrlist@4");
- #else
- lpfnHrQueryAllRows = (LPFNHRQUERYALLROWS ) GetProcAddress(hinstMapi,"HrQueryAllRows");
- lpfnFreePadrlist = (LPFNMAPIFREEPADRLIST ) GetProcAddress(hinstMapi,"FreePadrlist");
- #endif //_X86_
- #else
- lpfnIsEqualGUID = (LPFNISEQUALGUID ) GetProcAddress(hinstOle, "IsEqualGUID");
- lpfnHrQueryAllRows = (LPFNHRQUERYALLROWS ) GetProcAddress(hinstMapi,"HrQueryAllRows");
- lpfnFreePadrlist = (LPFNMAPIFREEPADRLIST ) GetProcAddress(hinstMapi,"FreePadrlist");
- #endif //_WIN32
- lpfnMAPIFreeBuffer = (LPFNMAPIFREEBUFFER ) GetProcAddress(hinstMapi,"MAPIFreeBuffer");
- lpfnMAPIInitialize = (LPFNMAPIINITIALIZE ) GetProcAddress(hinstMapi,"MAPIInitialize");
- lpfnMAPIUninitialize = (LPFNMAPIUNINITIALIZE ) GetProcAddress(hinstMapi,"MAPIUninitialize");
- AssertSz(lpfnCoRegisterClassObject ,"missing lpfnCoRegisterClassObject");
- AssertSz(lpfnHrQueryAllRows ,"missing lpfnHrQueryAllRows ");
- AssertSz(lpfnMAPIFreeBuffer ,"missing lpfnMAPIFreeBuffer ");
- AssertSz(lpfnMAPIInitialize ,"missing lpfnMAPIInitialize ");
- AssertSz(lpfnMAPIUninitialize ,"missing lpfnMAPIUninitialize ");
- AssertSz(lpfnFreePadrlist ,"missing lpfnFreePadrlist ");
- if (0 == lpfnCoRegisterClassObject ||
- 0 == lpfnHrQueryAllRows ||
- 0 == lpfnMAPIFreeBuffer ||
- 0 == lpfnMAPIInitialize ||
- 0 == lpfnMAPIUninitialize ||
- 0 == lpfnFreePadrlist)
- {
- AssertSz(0,"get procaddress failed");
- return ResultFromScode(E_FAIL);
- }
- // ----- Initialize MAPI
- hr = (*lpfnMAPIInitialize)(NULL);
- if (S_OK != hr)
- {
- TraceTag(tagForm,"MapiInit failed 0x%08lx",hr);
- return hr;
- }
- // ----- Allocate Memory for our class factory
- pfrmfmr = new FRMFMR;
- if (NULL == pfrmfmr)
- {
- TraceTag(tagForm, "RegisterClassFactory: OOM 0x%08lx",hr);
- hr = ResultFromScode(E_OUTOFMEMORY);
- return hr;
- }
- // ----- Register our class object(s)
- DWORD dwRegMyForm = 0;
- hr = (*lpfnCoRegisterClassObject) (CLSID_MyFormsClsId, (LPUNKNOWN)pfrmfmr,
- CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE,
- &dwRegMyForm); /* switch singleuse to multipleuse if you are an MDI app */
- if (FAILED(hr))
- {
- TraceTag(tagForm,"CoRegisterClassObject() failed 0x%08lx",hr);
- return hr;
- }
- TraceTag(tagForm,"return 0x%08lx",hr);
- return hr;
- }
- /*
- * HrStopForms
- *
- * Purpose:
- * UnInitialize OLE, MAPI, and the Forms Interface
- *
- * Returns:
- * HRESULT == 0
- */
- HRESULT
- HrStopForms(void)
- {
- HRESULT hr = ResultFromScode(S_OK);
- TraceTag(tagFormFunc,"HrStopForms");
- (*lpfnMAPIUninitialize)();
- FreeLibrary(hinstOle);
- FreeLibrary(hinstMapi);
- return hr;
- }
- /*
- * S a m p l e F o r m
- */
- // Checkers form specific methods follow ///////////////////////////
- /*
- * FRM::ScGetRecipientAdrList
- *
- * Purpose:
- * Fill the addrlist with the current recipients in the message
- *
- * Arguments:
- * LPMESSAGE - the message (in)
- * LPADRLIST - the addr list destination (out)
- *
- * Returns:
- * SCODE Error status.
- */
- SCODE
- FRM::ScGetRecipientAdrlist(LPMESSAGE pmsg, LPADRLIST * ppal)
- {
- SCODE sc = S_OK;
- HRESULT hr;
- LPMAPITABLE pmt = NULL;
- LPSPropTagArray ptaga = NULL;
- TraceTag(tagFormFunc,"ScGetRecipientAdrlist");
- AssertSz(!*ppal, "pal should be NULL on entry");
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- // Get the recipient table from the message
- if (hr = pmsg->GetRecipientTable(MAPI_DEFERRED_ERRORS, &pmt))
- {
- TraceTag(tagForm,"2043 0x%08lx",hr);
- goto Cleanup;
- }
- if (hr = pmt->QueryColumns(TBL_ALL_COLUMNS, &ptaga))
- {
- TraceTag(tagForm,"sdlkfj 0x%08lx",hr);
- goto Cleanup;
- }
- #ifdef NEVER
- ConvertToCorrectCharset(ptaga);
- #endif
- // Read in the recipients
- hr = (*lpfnHrQueryAllRows)(pmt, ptaga, NULL, NULL, 0, (LPSRowSet *) ppal);
- if (hr)
- {
- TraceTag(tagForm,"sdfhjsadjfhadkflhxxxx 0x%08lx",hr);
- goto Cleanup;
- }
- Cleanup:
- TraceTag(tagForm,"ScGetRecipientAdrlist 0x%08lx 0x%08lx", hr, sc);
- (*lpfnMAPIFreeBuffer)(ptaga);
- ReleaseObj(pmt);
- TraceTag(tagForm,"return 0x%08lx",ResultFromScode(sc));
- return sc;
- }
- /*
- * FRM::SendForm
- *
- * Purpose:
- * Have the message site send us
- * (also tries to send the message using mapi if message site fails)
- *
- * Arguments:
- * None.
- *
- * Returns:
- * HRESULT Error status.
- */
- HRESULT
- FRM::SendForm(VOID)
- {
- HRESULT hr = S_OK;
- TraceTag(tagFormFunc,"FRM::SendForm (this is not a standard form function)");
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- Assert(pMessageSite);
- Assert(pMessage);
- // ----- Submit message
- if (hr = pMessageSite->SubmitMessage(0) )
- {
- TraceTag(tagForm,"failure pMessageSite->SubmitMessage 0x%08lx",hr);
- #ifndef GOOD_FORM_BEHAVIOR // the following is not standard behavior
- // ----- No harm in trying to send it myself
- if (IDYES == MessageBox(hMainWnd, "The message site failed to send this form.nDo you want this form to attempt sending through the message interface?", "Checkers", MB_YESNO | MB_ICONSTOP))
- {
- // this is often times easier to debug than the remoted
- // message site interface (which does the same thing .. almost)
- if (hr = Save(NULL,TRUE))
- {
- TraceTag(tagForm,"NO: ::Save 0x%08lx",hr);
- }
- HandsOffMessage();
- if (hr = pMessage->SaveChanges(KEEP_OPEN_READWRITE) )
- {
- TraceTag(tagForm,"NO: pMessage->SaveChanges 0x%08lx",hr);
- }
- if (hr = pMessage->SubmitMessage(0) )
- {
- TraceTag(tagForm,"NO: pMessage->SubmitMessage 0x%08lx",hr);
- }
- }
- #endif // good_form_behavior
- }
- // ----- advise everyone of what we just did
- ADVISE(OnSubmitted)();
- TraceTag(tagForm,"return 0x%08lx",hr);
- return hr;
- }
- /*
- * FRM::LaunchReplyMessage
- *
- * Purpose:
- * Construct a reply to PR_SENDER* (note: ignoring sent representing)
- * Display any form user interface on the existing form
- *
- * Arguments:
- * HWND Parent window
- *
- * Returns:
- * HRESULT Error status.
- */
- HRESULT
- FRM::LaunchReplyMessage(ULONG ulhwndParent)
- {
- #ifdef ALLOW_SUBCLASS_IPM
- LPMAPIFORM pNewForm;
- LPPERSISTMESSAGE pNewFormIPersist;
- #endif
- ULONG itaga;
- ADRLIST al = {1,0}; /* our adrlist will have exactly one entry */
- HRESULT hr = S_OK;
- LPMAPIMESSAGESITE pNewMessageSite;
- LPMAPIVIEWCONTEXT pNewMapiViewContext;
- LPMESSAGE pNewMessage;
- SizedSPropTagArray(6,tagaSender) =
- { 6,
- { PR_RECIPIENT_TYPE,
- PR_SENDER_NAME,
- PR_SENDER_ADDRTYPE,
- PR_SENDER_ENTRYID,
- PR_SENDER_EMAIL_ADDRESS,
- PR_SENDER_SEARCH_KEY } };
- SizedSPropTagArray(6,tagaRepliee) =
- { 6,
- { PR_RECIPIENT_TYPE,
- PR_DISPLAY_NAME,
- PR_ADDRTYPE,
- PR_ENTRYID,
- PR_EMAIL_ADDRESS,
- PR_SEARCH_KEY
- } };
- static SizedSPropTagArray(26,tagaRemoveFromNewReply) =
- { 26,
- { // Stuff you would typically want to remove on reply
- PR_MESSAGE_FLAGS, // Want unsent compose note
- PR_MESSAGE_RECIPIENTS, // Will generate new recip list
- PR_SENDER_ENTRYID, // Clear sender/recipient info
- PR_SENDER_NAME, //
- PR_RECEIVED_BY_ENTRYID, //
- PR_RECEIVED_BY_NAME, //
- PR_SENT_REPRESENTING_ENTRYID, // Clear delegate access stuff
- PR_SENT_REPRESENTING_NAME, //
- PR_SENT_REPRESENTING_ADDRTYPE, // 10961
- PR_SENT_REPRESENTING_EMAIL_ADDRESS,
- PR_RCVD_REPRESENTING_ENTRYID, //
- PR_RCVD_REPRESENTING_NAME, //
- PR_READ_RECEIPT_ENTRYID, // Clear destination overrides
- PR_REPORT_ENTRYID, //
- PR_REPLY_RECIPIENT_ENTRIES, //
- PR_REPLY_RECIPIENT_NAMES, //
- PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED, // Clear delivery receipt
- PR_READ_RECEIPT_REQUESTED, // Clear read receipt
- PR_CLIENT_SUBMIT_TIME, // Clear submit time
- PR_MESSAGE_ATTACHMENTS, // Drop attachments on reply
- PR_ORIGINAL_AUTHOR_ENTRYID, // Keep original author information
- PR_ORIGINAL_AUTHOR_NAME, // on forwards
- PR_ORIGINAL_SUBMIT_TIME, // Keep original time on forwards
- PR_IMPORTANCE, // Lose importance on reply
- PR_PRIORITY, // Lose priority on reply
- PR_SENSITIVITY // Lose sensitivity on reply
- } };
- TraceTag(tagFormFunc,"FRM::LaunchReplyMessage");
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- Assert(pMessageSite);
- Assert(pSession);
- Assert(pMessage);
- #ifdef ALLOW_SUBCLASS_IPM
- /*
- Since I am a single instance exe, creating a new form results in
- a new process. For performance reasons, this form does not conform
- to the forms API precisely. This effectively removes the ability to
- subclass the reply note for IPM.Checkers. This is acceptable.
- */
- // ----- open form manager
- AssertSz(NULL == pFormMgr,"two form managers?");
- hr = pMessageSite->GetFormManager(&pFormMgr);
- if (FAILED(hr))
- {
- TraceTag(tagForm,"failure MAPIOpenFormMgr 0x%08lx",hr);
- return hr;
- }
- Assert(pFormMgr);
- // ----- Get form info
- hr = pFormMgr->ResolveMessageClass("IPM.Checkers",0,NULL,&pFormInfo);
- if (FAILED(hr))
- {
- TraceTag(tagForm,"failure to ResolveMessageClass 0x%08lx",hr);
- return hr;
- }
- // ----- Create the new form
- hr = pFormMgr->CreateForm(0,0,pFormInfo,IID_IMAPIForm,(LPVOID FAR*) &pNewForm);
- if (FAILED(hr))
- {
- TraceTag(tagForm,"failure to CreateForm 0x%08lx",hr);
- return hr;
- }
- hr = pNewForm->QueryInterface(IID_IPersistMessage, (LPVOID FAR*) &pNewFormIPersist);
- if (FAILED(hr))
- {
- TraceTag(tagForm,"failure asking form for IPersistMessage 0x%08lx",hr);
- return hr;
- }
- AssertSz(pNewFormIPersist,"have it?");
- #endif // ALLOW_SUBCLASS_IPM
- // ----- Create the reply message
- hr = pMessageSite->NewMessage(0,NULL,
- #ifdef ALLOW_SUBCLASS_IPM
- pNewFormIPersist
- #else
- this
- #endif // ALLOW_SUBCLASS_IPM
- ,&pNewMessage,&pNewMessageSite,&pNewMapiViewContext);
- if (FAILED(hr))
- {
- TraceTag(tagForm,"failure VDOG_*NewMessage* comform...c 0x%08lx",hr);
- return hr;
- }
- AssertSz(pNewMessage,"nothing new with you");
- AssertSz(pNewMessageSite,"no new site?");
- AssertSz(pNewMapiViewContext,"no new view context ... did NewMessage work at all?");
- // ----- Copy current message to new message
- hr = pMessage->CopyTo(0, NULL, (LPSPropTagArray)&tagaRemoveFromNewReply, 0, NULL,
- (LPIID) &IID_IMessage, pNewMessage, 0, NULL);
- if (FAILED(hr))
- {
- TraceTag(tagForm,"failure CopyTo 0x%08lx",hr);
- return hr;
- }
- // ----- who sent this to us?
- hr = pMessage->GetProps((LPSPropTagArray) &tagaSender, 0, &al.aEntries[0].cValues, &al.aEntries[0].rgPropVals);
- AssertSz(ResultFromScode(MAPI_W_ERRORS_RETURNED) == hr,"mapi gave me pr_recipient_type, but should not have");
- // ----- Make the sender the recipient
- if (al.aEntries && al.aEntries[0].rgPropVals)
- {
- al.aEntries[0].rgPropVals[0].ulPropTag = PR_RECIPIENT_TYPE;
- al.aEntries[0].rgPropVals[0].Value.ul = MAPI_TO;
- }
- else
- {
- AssertSz(0,"could not form reply message: al.aEntries && al.aEntries[0].rgPropVals");
- return ResultFromScode(E_FAIL);
- }
- // ----- Set our new recipients properties to their expected property ids
- itaga = 1;
- TraceTag(tagForm,"0x%08lx cEntries",al.cEntries);
- TraceTag(tagForm,"0x%08lx <0x%08lx> %s",al.aEntries[0].rgPropVals[itaga].ulPropTag,al.aEntries[0].rgPropVals[itaga].Value.ul,al.aEntries[0].rgPropVals[itaga].Value.LPSZ);
- for (itaga = 1; itaga < tagaRepliee.cValues; itaga++)
- {
- al.aEntries[0].rgPropVals[itaga].ulPropTag =
- PROP_TAG(PROP_TYPE(al.aEntries[0].rgPropVals[itaga].ulPropTag),
- PROP_ID(tagaRepliee.aulPropTag[itaga]));
- TraceTag(tagForm,"0x%08lx <0x%08lx> %d",al.aEntries[0].rgPropVals[itaga].ulPropTag,al.aEntries[0].rgPropVals[itaga].Value.ul,itaga);
- AssertSz(SUCCEEDED(al.aEntries[0].rgPropVals[itaga].Value.ul),"Failure to get PR_SENDER* 10961 ");
- }
- // ----- Save out addresses
- AssertSz(1 == al.cEntries,"we only reply to one person");
- hr = pNewMessage->ModifyRecipients(0, &al);
- if (FAILED(hr) )
- {
- TraceTag(tagForm,"pMessage->ModifyRecipients 0x%08lx",hr);
- return hr;
- }
- // ----- Release everything the read form was remembering (if we reply inplace)
- #ifndef ALLOW_SUBCLASS_IPM
- Forget();
- #endif
- // ----- Call LoadForm (this makes the current form the new form)
- hr =
- #ifdef ALLOW_SUBCLASS_IPM
- pNewFormIPersist->
- #endif
- Load(pNewMessageSite,pNewMessage,0,MSGFLAG_UNSENT);
- if (FAILED(hr))
- {
- TraceTag(tagForm,"failure LoadForm 0x%08lx",hr);
- return hr;
- }
- // ----- Call SetViewContext
- #ifdef ALLOW_SUBCLASS_IPM
- hr = pNewForm->SetViewContext(pNewMapiViewContext);
- if (FAILED(hr))
- {
- TraceTag(tagForm,"failure SetViewContext 0x%08lx",hr);
- return hr;
- }
- #endif
- // ----- Call DoVerb So we can see the reply form
- hr =
- #ifdef ALLOW_SUBCLASS_IPM
- pNewForm->
- #endif
- DoVerb(OLEIVERB_PRIMARY,NULL,ulhwndParent,NULL);
- if (FAILED(hr))
- {
- TraceTag(tagForm,"failure DoVerb 0x%08lx",hr);
- return hr;
- }
- // ----- release stuff
- pNewMessage->Release();
- pNewMessageSite->Release();
- pNewMapiViewContext->Release();
- (*lpfnMAPIFreeBuffer)(al.aEntries[0].rgPropVals);
- // ----- Close down the read form (that's me)
- #ifdef ALLOW_SUBCLASS_IPM
- hr = ShutdownForm(OLECLOSE_NOSAVE);
- if (FAILED(hr))
- {
- TraceTag(tagForm,"failure ShutdownForm'ing read form 0x%08lx",hr);
- return hr;
- }
- #endif // ALLOW_SUBCLASS_IPM
- // ----- return to caller
- return hr;
- }
- /*
- * FRM::GetCheckersData
- *
- * Purpose:
- * Allows anyone to query the form for it's current data
- *
- * Arguments:
- * data members (out)
- *
- * Returns:
- * void
- */
- VOID
- FRM::GetCheckersData(SQUARE* out_b, int* out_turn, long* out_movenum, long* out_score)
- {
- Assert(out_b);
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- if (turn) /* set elements only if we have data to give out */
- {
- memcpy(out_b,b,sizeof(b));
- if (out_turn) *out_turn = turn;
- if (out_movenum) *out_movenum = movenum;
- if (out_score) *out_score = score;
- }
- }
- /*
- * FRM::SetCheckersData
- *
- * Purpose:
- * Allows anyone to set the forms current data members
- *
- * Arguments:
- * data members (in)
- *
- * Returns:
- * void
- */
- VOID
- FRM::SetCheckersData(SQUARE* in_b, int in_turn, long in_movenumber, long in_score)
- {
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- Assert(in_b && in_turn);
- fDirty = TRUE;
- memcpy(b,in_b,sizeof(b));
- turn = in_turn;
- movenum = in_movenumber;
- score = in_score;
- }
- /*
- * FRM::AddressForm
- *
- * Purpose:
- * Look at the current message addresses, and show user
- * interface to address the message.
- *
- * Arguments:
- * HWND - parent
- * BOOL - true if no user interface should be presented when
- * recipients are already present
- *
- * Returns:
- * HRESULT Error Status.
- */
- HRESULT
- FRM::AddressForm(HWND hwnd, BOOL fDontShowIfRecipsExist)
- {
- LPADRBOOK pAdrBook;
- ULONG ulUIParam = (ULONG) (UINT) hwnd;
- SCODE sc;
- HRESULT hr = S_OK;
- ADRPARM ap = { 0 };
- LPADRLIST pal = NULL;
- BOOL fCloseForm = FALSE;
- TraceTag(tagFormFunc,"FRM::AddressForm");
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- Assert(pMessageSite);
- Assert(pSession);
- Assert(pMessage);
- // ----- Read in addresses from message
- sc = ScGetRecipientAdrlist(pMessage, &pal);
- hr = ResultFromScode(sc);
- if (FAILED(hr))
- {
- TraceTag(tagForm,"failed to read address into pal 0x%08lx",hr);
- return hr;
- }
- // ----- remember address book from the session
- hr = pSession->OpenAddressBook(ulUIParam, NULL, 0, &pAdrBook);
- if (FAILED(hr))
- {
- TraceTag(tagForm,"failed to get pAdrBook object 0x%08lx",hr);
- goto cleanuppal;
- }
- // ----- Show the address book
- ap.ulFlags = AB_RESOLVE | DIALOG_OPTIONS | DIALOG_MODAL | fMapiUnicode;
- ap.lpszCaption = TEXT("Select Checkers Opponent");
- ap.cDestFields = 1;
- if (0 == fDontShowIfRecipsExist || 0 == pal->cEntries)
- hr = pAdrBook->Address(&ulUIParam, &ap, &pal);
- #ifdef DEBUG
- if (hwnd != hMainWnd)
- {
- TraceTag(tagNull,"ADDRESSFORM: pAdrBook->Address changed it's out parameter even though DIALOG_MODAL");
- }
- #endif
- if (FAILED(hr))
- {
- // cancel is a failed scode
- TraceTag(tagForm,"cant pop up addr book 0x%08lx %d",hr,pal?pal->cEntries:0);
- }
- // ----- Save out addresses
- AssertSz(pMessage,"pMessage said goodbye during the Address function");
- hr = pMessage->ModifyRecipients(0, pal);
- if (FAILED(hr) )
- {
- TraceTag(tagForm,"pMessage->ModifyRecipients 0x%08lx",hr);
- goto cleanup;
- }
- // ----- Close the form if there are no recipients for this move
- if (pal->cEntries <= 0) fCloseForm = TRUE;
- // ----- Release the address book, adrlist, and clean up
- cleanup:
- Assert(pAdrBook);
- pAdrBook->Release();
- cleanuppal:
- Assert(pal);
- (*lpfnFreePadrlist)(pal);
- if (fCloseForm) ShutdownForm(OLECLOSE_PROMPTSAVE);
- TraceTag(tagForm,"return 0x%08lx",hr);
- return hr;
- }
- /*
- * FRM::Remember
- *
- * Purpose:
- * Store and addref the message site, the message, and the session
- * for later use
- *
- * Returns:
- * HRESULT Error Status.
- */
- HRESULT
- FRM::Remember(LPMAPIMESSAGESITE pmsite, LPMESSAGE pmsg)
- {
- HRESULT hr;
- TraceTag(tagFormFunc,"FRM::Remember");
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- AssertSz(pmsite,"what am I going to do without it?");
- AssertSz(pmsg,"what am I going to do without it? pmsg that is");
- // ----- remember our message site object
- AssertSz(!pMessageSite,"who me? a message site?");
- pMessageSite = pmsite;
- pMessageSite->AddRef();
- // ----- remember our message
- AssertSz(!pMessage,"a message in my");
- pMessage = pmsg;
- pMessage->AddRef();
- // ----- remember mapi session
- AssertSz(!pSession,"another session?");
- hr = pMessageSite->GetSession(&pSession);
- #ifdef DEBUG
- if (FAILED(hr))
- {
- TraceTag(tagForm,"failed to get session object %08lx",hr);
- }
- #endif
- // ----- return result to caller
- TraceTag(tagForm,"return 0x%08lx",hr);
- return hr;
- }
- /*
- * FRM::Forget
- *
- * Purpose:
- * Release the message site, the message, and the session
- *
- * Returns:
- * HRESULT Error Status.
- */
- HRESULT
- FRM::Forget(VOID)
- {
- TraceTag(tagFormFunc,"FRM::Forget");
- if (pMessage) pMessage->Release();
- if (pMessageSite) pMessageSite->Release();
- if (pSession) pSession->Release();
- pMessage = NULL;
- pMessageSite = NULL;
- pSession = NULL;
- return NOERROR;
- }
- /*
- * FRM::ShowCurrentMessage
- *
- * Purpose:
- * Display any form user interface on a form
- *
- * Arguments:
- * HWND Parent window
- *
- * Returns:
- * HRESULT Error status.
- */
- HRESULT
- FRM::ShowCurrentMessage(ULONG ulhwndParent)
- {
- HRESULT hr = NOERROR;
- TraceTag(tagFormFunc,"FRM::ShowCurrentMessage");
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- Assert(pMessageSite);
- Assert(pSession);
- Assert(pMessage);
- // ----- Give our user access to our form interface
- SendMessage(hMainWnd,EM_GIVEFORMTOHWND,0,(LPARAM) this);
- // ----- Display address book modal to form if this message has not yet been addressed
- FORWARD_WM_COMMAND(hMainWnd, IDM_ADDRESS, 0, 1 /* Don't Show Recips */, PostMessage);
- return hr;
- }
- // IUnknown methods follow ///////////////////////////
- /*
- * FRM::QueryInterface
- *
- * Purpose:
- * Returns a pointer to the specified interface.
- *
- * Arguments:
- * REFIID Interface we want.
- * LPUNKNOWN * Interface we return.
- *
- * Returns:
- * HRESULT Error status.
- */
- STDMETHODIMP
- FRM::QueryInterface(REFIID riid, LPVOID FAR * ppvObj)
- {
- HRESULT hr = NOERROR;
- TraceTag(tagFuncTriv,"FRM::QueryInterface %s",DumpCLSID(riid));
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- if (IsEqualIID(riid, IID_IUnknown))
- {
- AddRef();
- *ppvObj = (IMAPIForm *)this;
- }
- else if (IsEqualIID(riid, IID_IPersistMessage))
- {
- AddRef();
- *ppvObj = (IPersistMessage *)this;
- }
- else if (IsEqualIID(riid, IID_IMAPIForm))
- {
- AddRef();
- *ppvObj = (IMAPIForm *)this;
- }
- else
- {
- hr = ResultFromScode(E_NOINTERFACE);
- *ppvObj = NULL;
- }
- #ifdef DEBUG
- if (hr != ResultFromScode(E_NOINTERFACE)) AssertSz(ppvObj,"no object pointer");
- #endif
- TraceTag(tagForm,"return 0x%08lx",hr);
- return hr;
- }
- /*
- * FRM::AddRef
- *
- * Purpose:
- * Increments reference count on the sample extension.
- *
- * Arguments:
- *
- * Returns:
- * ULONG New value of reference count.
- */
- STDMETHODIMP_(ULONG)
- FRM::AddRef(void)
- {
- TraceTag(tagFuncTriv,"FRM::AddRef ret %d",cRef + 1);
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- return ++cRef;
- }
- /*
- * FRM::Release
- *
- * Purpose:
- * Decrements reference count on the sample extension. If count is
- * decremented to zero, the object is freed.
- *
- * Arguments:
- *
- * Returns:
- * ULONG New value of reference count.
- */
- STDMETHODIMP_(ULONG)
- FRM::Release(void)
- {
- TraceTag(tagFuncTriv,"FRM::Release cRef %d",cRef);
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- if (!(--cRef))
- {
- // ----- be sure our ui is gone when we leave
- #ifdef DEBUG
- if (IsWindow(hMainWnd))
- {
- TraceTag(tagForm,"Last Release called, but IsWindow(hMainWnd). ShutdownForm called?");
- }
- TraceTag(tagForm,"return 0");
- #endif //debug
- delete this;
- return 0;
- }
- return cRef;
- }
- // IPersistMessage methods follow ///////////////////////////
- /*
- * FRM::GetLastError
- *
- * Purpose:
- * Get the last error
- *
- * Arguments:
- *
- * Returns:
- * HRESULT NOERROR always.
- */
- STDMETHODIMP
- FRM::GetLastError(HRESULT hResult, ULONG ulFlags, LPMAPIERROR FAR * lppMAPIError)
- {
- TraceTag(tagFormFunc,"FRM::GetLastError 0x%08x",hResult);
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- if (lppMAPIError) *lppMAPIError = NULL;
- return NOERROR;
- }
- /*
- * FRM::GetClassID
- *
- * Purpose:
- * Get the class ID associated with this message.
- *
- * Arguments:
- * LPCLSID Where to put the class ID.
- *
- * Returns:
- * HRESULT NOERROR always.
- */
- STDMETHODIMP
- FRM::GetClassID(LPCLSID pclsid)
- {
- TraceTag(tagFormFunc,"FRM::GetClassID");
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- // The form only plays with things of its own class ID, so
- // this is easy; it's more complicated if code supports multiple
- // classes, or can do "treat as" operations
- if (pclsid) *pclsid = clsid;
- return NOERROR;
- }
- /*
- * FRM::IsDirty
- *
- * Purpose:
- * Returns whether the object has changed since the last save
- *
- * Arguments:
- *
- * Returns:
- * HRESULT S_OK if dirty, S_FALSE if not dirty.
- */
- STDMETHODIMP
- FRM::IsDirty(void)
- {
- TraceTag(tagFormFunc,"FRM::IsDirty");
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- return fDirty ? NOERROR : ResultFromScode(S_FALSE);
- }
- /*
- * FRM::InitNew
- *
- * Purpose:
- * Create a new message of our message class in the provided pmsg.
- *
- * Arguments:
- * LPMAPISESSION Session in which the message belongs.
- * LPMESSAGE Message to create the new form in.
- *
- * Returns:
- * HRESULT S_OK, or error value.
- */
- STDMETHODIMP
- FRM::InitNew(LPMAPIMESSAGESITE pmsite, LPMESSAGE pmsg)
- {
- HRESULT hr;
- SPropValue prop;
- TraceTag(tagFormFunc,"FRM::InitNew");
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- // ----- Remember our pointers and such
- hr = Remember(pmsite,pmsg);
- if (FAILED(hr))
- {
- TraceTag(tagForm,"loss of memory in initnew 0x%08lx",hr);
- return hr;
- }
- // ----- set our message class
- prop.ulPropTag = PR_MESSAGE_CLASS;
- prop.Value.LPSZ = TEXT("IPM.Checkers");
- hr = pMessage->SetProps(1, &prop, NULL);
- if (FAILED(hr) )
- {
- TraceTag(tagForm,"failed setprops in initnew 0x%08lx",hr);
- return hr;
- }
- // ----- remind ourselves that this new message could not have been sent
- fSentMessage = 0;
- // ----- set our special properties
- prop.ulPropTag = PR_SUBJECT;
- prop.Value.LPSZ = TEXT("--- CHECKERS FORM ---");
- hr = pMessage->SetProps(1, &prop, NULL);
- if (FAILED(hr) )
- {
- TraceTag(tagForm,"failed setprops in on pr_subject here 0x%08lx",hr);
- return hr;
- }
- ADVISE(OnNewMessage)();
- return hr;
- }
- /*
- * FRM::Load
- *
- * Purpose:
- * Attaches our object to the provided pmsg.
- *
- * Arguments:
- * LPMAPISESSION Our session to remember.
- * LPMESSAGE Our message to remember.
- *
- * Returns:
- * HRESULT S_OK, or error value.
- */
- STDMETHODIMP
- FRM::Load(LPMAPIMESSAGESITE pmsite, LPMESSAGE pmsg, ULONG ulMessageStatus, ULONG ulMessageFlags)
- {
- ULONG cProps = 0;
- #define ctagMax 10
- char rgchTaga[sizeof(SPropTagArray) + (ctagMax * sizeof(ULONG))];
- LPSPropTagArray ptaga = (LPSPropTagArray) rgchTaga;
- LPSPropValue rgval = NULL;
- LPSPropValue pval = NULL;
- HRESULT hr=S_OK;
- TraceTag(tagFormFunc,"FRM::Load status=0x%08lx flags=0x%08lx",ulMessageStatus,ulMessageFlags);
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- // ----- Remember our pointers and such
- hr = Remember(pmsite,pmsg);
- if (FAILED(hr))
- {
- TraceTag(tagForm,"loads call to remember failed 0x%08lx",hr);
- return hr;
- }
- // ----- If this message has been sent we would like to remember that
- fSentMessage = !( ulMessageFlags & MSGFLAG_UNSENT);
- TraceTag(tagForm,"fSentMessage = %d",(int) fSentMessage);
- // ----- Load our data out of the message like a nice form
- ptaga->cValues = 0;
- ptaga->aulPropTag[ptaga->cValues++] = PR_SUBJECT;
- ptaga->aulPropTag[ptaga->cValues++] = PR_BODY;
- ptaga->aulPropTag[ptaga->cValues++] = PR_BOARD;
- ptaga->aulPropTag[ptaga->cValues++] = PR_TURN;
- ptaga->aulPropTag[ptaga->cValues++] = PR_MOVENUMBER;
- hr = pmsg->GetProps(ptaga,0, &cProps, &rgval);
- if (FAILED(hr) )
- {
- TraceTag(tagForm,"failed getprops on pr_board there 0x%08lx",hr);
- return hr;
- }
- AssertSz(ptaga->cValues <= ctagMax, "Too many properties to read!");
- AssertSz(cProps == ptaga->cValues,"to mucho values");
- pval = rgval;
- // ----- set properties to variables
- pval; // subject
- pval++; // body
- pval++; // board
- if (pval->Value.bin.cb == sizeof(b)) /* if it's a valid board */
- {
- memcpy(b,pval->Value.bin.lpb,(int) pval->Value.bin.cb);
- pval++; // turn
- AssertSz(pval->Value.l == RED || pval->Value.l == BLACK,"cool: neither red or blacks turn according to mapi");
- turn = (int) pval->Value.l;
- pval++; // movenumber
- }
- Assert(rgval);
- (*lpfnMAPIFreeBuffer)(rgval);
- ADVISE(OnNewMessage)();
- return hr;
- }
- /*
- * FRM::Save
- *
- * Purpose:
- * Writes out our information to the provided pmsg. Does NOT commit
- * changes; this is the responsibility of the caller. Puts the form
- * into no-scribble mode until SaveCompleted is called.
- *
- * Arguments:
- * LPMESSAGE Message to write our changes to.
- * BOOL TRUE if this is our home message, FALSE if
- * this is a different message.
- *
- * Returns:
- * HRESULT S_OK, or error value.
- */
- STDMETHODIMP
- FRM::Save(LPMESSAGE pmsg, ULONG fSameAsLoad)
- {
- SPropValue prop;
- HRESULT hr = NOERROR;
- TraceTag(tagFormFunc,"FRM::Save");
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- AssertSz(pMessage,"no pmesssg in ::Save");
- #ifdef DEBUG
- if (!pmsg)
- {
- TraceTag(tagNull,"NULL == pmsg in ::Save fsameasload==0x%08lx",fSameAsLoad);
- }
- #endif
- // ----- If this is the same pmsg as we got back when we loaded ...
- if (fSameAsLoad)
- {
- TraceTag(tagForm,"fSameAsLoad true");
- pmsg = pMessage;
- }
- // ----- Put ourselves in no-scribble mode
- fNoScribble = TRUE;
- // ----- set our message class
- prop.ulPropTag = PR_MESSAGE_CLASS;
- prop.Value.LPSZ = TEXT("IPM.Checkers");
- hr = pMessage->SetProps(1, &prop, NULL);
- if (FAILED(hr) )
- {
- TraceTag(tagForm,"failed setprops in initnew 0x%08lx",hr);
- return hr;
- }
- // ----- Write out our data
- AssertSz(turn,"nobody's turn? this is not a good sign...");
- prop.ulPropTag = PR_BOARD;
- prop.Value.bin.lpb = (unsigned char *) b;
- prop.Value.bin.cb = sizeof(b);
- hr = pmsg->SetProps(1, &prop, NULL);
- if (FAILED(hr) )
- {
- TraceTag(tagForm,"failed setprops in on pr_board here 0x%08lx",hr);
- return hr;
- }
- prop.ulPropTag = PR_TURN;
- prop.Value.l = (long) turn;
- hr = pmsg->SetProps(1, &prop, NULL);
- if (FAILED(hr) )
- {
- TraceTag(tagForm,"failed setprops in on pr_turn here 0x%08lx",hr);
- return hr;
- }
- prop.ulPropTag = PR_MOVENUMBER;
- prop.Value.l = (long) movenum;
- hr = pmsg->SetProps(1, &prop, NULL);
- if (FAILED(hr) )
- {
- TraceTag(tagForm,"failed setprops in on pr_turn here 0x%08lx",hr);
- return hr;
- }
- prop.ulPropTag = PR_SCORINGFUNC;
- prop.Value.l = (long) score;
- hr = pmsg->SetProps(1, &prop, NULL);
- if (FAILED(hr) )
- {
- TraceTag(tagForm,"failed setprops in on pr_turn here 0x%08lx",hr);
- return hr;
- }
- prop.ulPropTag = PR_BODY;
- prop.Value.lpszA = TextizeBoard(b);
- TraceTag(tagForm,"Here's the board I saved:n%s",prop.Value.lpszA);
- hr = pmsg->SetProps(1, &prop, NULL);
- if (FAILED(hr) )
- {
- TraceTag(tagForm,"failed setprops in on pr_body here 0x%08lx",hr);
- return hr;
- }
- ADVISE(OnSaved)();
- return hr;
- }
- /*
- * FRM::SaveCompleted
- *
- * Purpose:
- * Terminates no-scribble and hands-off modes, returning the object
- * to its normal storage mode.
- *
- * Arguments:
- * LPMESSAGE Our new home message, if we need to change.
- *
- * Returns:
- * HRESULT S_OK, or error value.
- */
- STDMETHODIMP
- FRM::SaveCompleted(LPMESSAGE pmsg)
- {
- TraceTag(tagFormFunc,"FRM::SaveCompleted");
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- // Reset modes
- fDirty = FALSE;
- fNoScribble = FALSE;
- return NOERROR;
- }
- /*
- * FRM::HandsOffMessage
- *
- * Purpose:
- * Releases our reference on the message so that a Save As operation
- * can occur.
- *
- * Arguments:
- *
- * Returns:
- * HRESULT S_OK, or error value.
- */
- STDMETHODIMP
- FRM::HandsOffMessage(void)
- {
- TraceTag(tagFormFunc,"FRM::HandsOffMessage");
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- return NOERROR;
- }
- // IMAPIForm methods follow /////////////////////////////
- /*
- * FRM::DoVerb
- *
- * Purpose:
- * Performs the specified verb on the message.
- *
- * Arguments:
- * LONG What to do.
- * LPMAPIVIEWCONTEXT Our view context.
- * HWND Our parent window.
- * LPCRECT Where we should display ourselves given a choice.
- *
- * Returns:
- * HRESULT S_OK, or error value.
- */
- STDMETHODIMP
- FRM::DoVerb(LONG iVerb, LPMAPIVIEWCONTEXT pmvc, ULONG ulhwndParent,
- LPCRECT prcPosRect)
- {
- TraceTag(tagFormFunc,"FRM::DoVerb iVerb=%d",iVerb);
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- switch (iVerb)
- {
- default:
- case OLEIVERB_HIDE:
- case OLEIVERB_DISCARDUNDOSTATE:
- TraceTag(tagForm,"DoVerb: not implemented iVerb");
- return ResultFromScode(E_NOTIMPL);
- case OLEIVERB_UIACTIVATE:
- case OLEIVERB_INPLACEACTIVATE:
- TraceTag(tagForm,"DoVerb: not implemented iVerb=%d",iVerb);
- if (iVerb < 0)
- return ResultFromScode(E_NOTIMPL);
- return ResultFromScode(OLEOBJ_S_INVALIDVERB);
- case OLEIVERB_SHOW:
- ShowCurrentMessage(ulhwndParent);
- return NOERROR;
- case OLEIVERB_OPEN:
- case OLEIVERB_PRIMARY:
- TraceTag(tagForm,"fSentMessage = %d",(int) fSentMessage);
- if (fSentMessage)
- LaunchReplyMessage(ulhwndParent);
- else
- ShowCurrentMessage(ulhwndParent);
- return NOERROR;
- }
- }
- /*
- * FRM::ShutdownForm
- *
- * Purpose:
- * Closes down any UI associated with the form.
- *
- * Arguments:
- * DWORD One of OLECLOSE_SAVEIFDIRTY, OLECLOSE_NOSAVE,
- * or OLECLOSE_PROMPTSAVE.
- *
- * Returns:
- * HRESULT S_OK, or error value.
- */
- STDMETHODIMP
- FRM::ShutdownForm(DWORD dwSaveOptions)
- {
- HRESULT hr = NOERROR;
- TraceTag(tagFormFunc,"FRM::ShutdownForm dwSaveOptions=%d",dwSaveOptions);
- TraceTag(tagForm,"pMessageSite 0x%08x",(ULONG) pMessageSite);
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- // ----- no way I'm closeing if I'm in a modal dialog
- // especially if the modal dialog occurs in a remoted interface
- if (!IsWindowEnabled(hMainWnd))
- return ResultFromScode(E_ABORT);
- // ----- be kind, and save ourself
- switch (dwSaveOptions)
- {
- case OLECLOSE_NOSAVE:
- break;
- case OLECLOSE_SAVEIFDIRTY:
- if (fDirty)
- hr = pMessageSite->SaveMessage();
- break;
- default:
- case OLECLOSE_PROMPTSAVE:
- if (fDirty)
- if (IDYES == MessageBox(hMainWnd, "Save changes?", "Checkers", MB_YESNO))
- hr = pMessageSite->SaveMessage();
- break;
- }
- Assert(hMainWnd && IsWindow(hMainWnd));
- if (NOERROR == hr)
- {
- // ----- let everyone know we're shutting down
- ADVISE(OnShutdown)();
- // ----- Release everything we have remembered thus far
- Forget();
- // ----- make sure everyone has Unadvised
- AssertSz(0==afAdvisee[0],"0 didn't Unadvise before ShutdownForm");
- AssertSz(0==afAdvisee[1],"1 didn't Unadvise before ShutdownForm");
- AssertSz(0==afAdvisee[2],"2 didn't Unadvise before ShutdownForm");
- AssertSz(0==afAdvisee[3],"3 didn't Unadvise before ShutdownForm");
- // ----- post a quit message to our UI
- SendMessage(hMainWnd,WM_CLOSE,0,0);
- }
- return hr;
- }
- STDMETHODIMP
- FRM::SetViewContext(LPMAPIVIEWCONTEXT pViewContextNew)
- {
- TraceTag(tagFormFunc,"FRM::SetViewContext");
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- AssertSz(pViewContextNew,"no view context to set");
- /* View context is used for next and previous behavior
- The checkers form does not do next and previous because
- there is not a standard read note. It is always in
- reply mode */
- return NOERROR;
- }
- STDMETHODIMP
- FRM::GetViewContext(LPMAPIVIEWCONTEXT FAR * ppViewContext)
- {
- TraceTag(tagFormFunc,"FRM::GetViewContext");
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- AssertSz(ppViewContext,"get view context to where?");
- if (ppViewContext) *ppViewContext = NULL; /* not supported */
- return NOERROR;
- }
- STDMETHODIMP
- FRM::Advise(LPMAPIVIEWADVISESINK pAdvise, ULONG FAR * pdwStatus)
- {
- LONG i;
- TraceTag(tagFormFunc,"FRM::Advise");
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- Assert(pdwStatus);
- Assert(pAdvise);
- // ----- remember who to advise
- for (i=0; i<MAX_ADVISE; i++)
- if (!afAdvisee[i])
- {
- aAdvisePtrs[i] = pAdvise;
- afAdvisee[i] = 1;
- *pdwStatus = i + 1; /* ulConnection of zero is not valid */
- pAdvise->AddRef();
- return NOERROR;
- }
- // ----- bad news
- AssertSz(0,"out of aAdvisPtrs");
- return ResultFromScode(E_FAIL);
- return NOERROR;
- }
- STDMETHODIMP
- FRM::Unadvise(ULONG ulConnection)
- {
- TraceTag(tagFormFunc,"FRM::Unadvise");
- AssertSz(cRef > 0,"excuse me. are you refering to me?");
- AssertSz(ulConnection < MAX_ADVISE && ulConnection >= 0,"testing, 123");
- AssertSz(ulConnection,"a non-zero ulConnection is not valid according to OLE");
- // ----- forget about advising this guy
- --ulConnection; // remember, we added one in advise
- AssertSz(afAdvisee[(int) ulConnection],"never wanted ::Advise in ::Unadvise?");
- afAdvisee[(int) ulConnection] = 0;
- aAdvisePtrs[(int) ulConnection]->Release();
- return NOERROR;
- }
- /*
- * FRM::FRM
- *
- * Purpose:
- * Initialize or new form object
- *
- */
- FRM::FRM(REFCLSID clsid)
- {
- LONG i;
- TraceTag(tagFormFunc,"FRM::FRM .................");
- cRef = 1;
- this->clsid = clsid;
- pMessage = NULL;
- pMessageSite = NULL;
- pSession = NULL;
- pFormMgr = NULL;
- pFormInfo = NULL;
- fDirty = FALSE;
- for (i=0; i<MAX_ADVISE; i++)
- {
- aAdvisePtrs[i] = NULL;
- afAdvisee[i] = 0;
- }
- turn = 0;
- }
- /*
- * FRM::~FRM
- *
- * Purpose:
- * Destroy our form object
- */
- FRM::~FRM(void)
- {
- TraceTag(tagFormFunc,"FRM::~FRM Bye now ...");
- AssertSz(0==cRef,"quit referring to this form please");
- AssertSz(NULL == pMessage,"still refing the message");
- AssertSz(NULL == pMessageSite,"still refing the messagesite");
- AssertSz(NULL == pSession,"still refing the session");
- }
- /*
- * S a m p l e F o r m C l a s s F a c t o r y
- *
- * Because we are an exe server, we must implement a class factory
- * so that other viewers (like Exchange) can learn of our clsid
- *
- */
- /*
- * FRMFAC::CreateInstance
- *
- * Purpose:
- * Creates a new form object of the IPM.Form class.
- *
- * Arguments:
- * LPUNKNOWN Outer object to aggregate with (not supported).
- * REFIID Desired interface on new form object.
- * LPVOID FAR * Where to put new form object.
- *
- * Returns:
- * HRESULT S_OK, or one of the following errors:
- * CLASS_E_NOAGGREGATION, E_OUTOFMEMORY,
- * E_NOINTERFACE, E_INVALIDARG.
- */
- STDMETHODIMP
- FRMFAC::CreateInstance(LPUNKNOWN punkOuter, REFIID riid, LPVOID FAR * ppvObject)
- {
- FRM * pfrm = NULL;
- HRESULT hr;
- TraceTag(tagFormFunc,"FRMFAC::CreateInstance");
- // ----- Initialize out parameter and check validity of parameters
- if (!ppvObject)
- {
- hr = ResultFromScode(E_INVALIDARG);
- goto Cleanup;
- }
- *ppvObject = NULL;
- if (punkOuter)
- {
- hr = ResultFromScode(CLASS_E_NOAGGREGATION);
- goto Cleanup;
- }
- // ----- Instantiate new form
- if (!(pfrm = new FRM(clsid)))
- {
- hr = ResultFromScode(E_OUTOFMEMORY);
- TraceTag(tagForm,"E_OUTOFMEMORY 0x%08lx",hr);
- goto Cleanup;
- }
- // ----- Get the desired interface
- hr = pfrm->QueryInterface(riid, ppvObject);
- AssertSz(0==hr,"QueryInterface failed");
- Cleanup:
- ReleaseObj(pfrm);
- TraceTag(tagForm,"return 0x%08lx initial reference %d",hr,cRef);
- return hr;
- }
- /*
- * FRMFAC::QueryInterface
- *
- * Purpose:
- * Returns a pointer to the specified interface.
- *
- * Arguments:
- * REFIID Interface we want.
- * LPUNKNOWN * Interface we return.
- *
- * Returns:
- * HRESULT Error status.
- */
- STDMETHODIMP
- FRMFAC::QueryInterface(REFIID riid, LPVOID FAR * ppvObj)
- {
- TraceTag(tagFuncTriv,"FRMFAC::QueryInterface %s",DumpCLSID(riid));
- if (IsEqualIID(riid, IID_IUnknown) ||
- IsEqualIID(riid, IID_IClassFactory))
- {
- *ppvObj = this;
- AddRef();
- TraceTag(tagForm,"return ok");
- return NOERROR;
- }
- *ppvObj = NULL;
- TraceTag(tagForm,"return no interface");
- return ResultFromScode(E_NOINTERFACE);
- }
- /*
- * FRMFAC::LockServer
- *
- * Purpose:
- *
- *
- * Arguments:
- * BOOL Whether to increment or decrement DLL reference count.
- *
- * Returns:
- * HRESULT S_OK always.
- */
- STDMETHODIMP
- FRMFAC::LockServer(BOOL fLock)
- {
- TraceTag(tagFormFunc,"LockServer (not implemented)");
- return NOERROR;
- }
- /*
- * FRMFAC::AddRef
- *
- * Purpose:
- * Increments reference count on the form class factory.
- *
- * Arguments:
- *
- * Returns:
- * ULONG New value of reference count.
- */
- STDMETHODIMP_(ULONG)
- FRMFAC::AddRef(void)
- {
- TraceTag(tagFuncTriv,"FRMFAC::AddRef ret %d",cRef+1);
- return ++cRef;
- }
- /*
- * FRMFAC::Release
- *
- * Purpose:
- * Decrements reference count on the form class factory.
- * If count is decremented to zero, the object is freed.
- *
- * Arguments:
- *
- * Returns:
- * ULONG New value of reference count.
- */
- STDMETHODIMP_(ULONG)
- FRMFAC::Release(void)
- {
- TraceTag(tagFuncTriv,"FRMFAC::Release cRef %d",cRef);
- if (!(--cRef))
- {
- TraceTag(tagForm,"return 0");
- delete this;
- return 0;
- }
- return cRef;
- }
- FRMFMR::FRMFMR()
- {
- TraceTag(tagFuncTriv,"FRMFMR::FRMFMR");
- clsid = CLSID_MyFormsClsId;
- }
- FRMFAC::FRMFAC()
- {
- TraceTag(tagFuncTriv,"FRMFAC::FRMFAC");
- cRef = 1;
- }
- FRMFAC::~FRMFAC(void)
- {
- TraceTag(tagFuncTriv,"FRMFAC::~FRMFAC");
- AssertSz(!cRef,"0817236");
- }