home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / inole2 / chap21 / patron / patron.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  17.2 KB  |  750 lines

  1. /*
  2.  * PATRON.CPP
  3.  * Patron Chapter 21
  4.  *
  5.  * WinMain which is all we need for the basic application.
  6.  *
  7.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  8.  *
  9.  * Kraig Brockschmidt, Microsoft
  10.  * Internet  :  kraigb@microsoft.com
  11.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  12.  */
  13.  
  14.  
  15. #define INITGUIDS
  16. #include "patron.h"
  17.  
  18. //CHAPTER21MOD
  19. ULONG       g_cObj=0;
  20. ULONG       g_cLock=0;
  21. HWND        g_hWnd=NULL;
  22. BOOL        g_fUser=TRUE;
  23. //End CHAPTER21MOD
  24.  
  25.  
  26. /*
  27.  * WinMain
  28.  *
  29.  * Purpose:
  30.  *  Main entry point of application.  Should register the app class
  31.  *  if a previous instance has not done so and do any other one-time
  32.  *  initializations.
  33.  */
  34.  
  35. int PASCAL WinMain (HINSTANCE hInst, HINSTANCE hPrev
  36.     , LPSTR pszCmdLine, int nCmdShow)
  37.     {
  38.     PCPatronFrame   pFR;
  39.     FRAMEINIT       fi;
  40.     WPARAM          wRet=0;
  41.  
  42.     SETMESSAGEQUEUE;
  43.  
  44.     //Attempt to allocate and initialize the application
  45.     pFR=new CPatronFrame(hInst, hPrev, pszCmdLine, nCmdShow);
  46.  
  47.     if (NULL==pFR)
  48.         return -1;
  49.  
  50.     fi.idsMin=IDS_FRAMEMIN;
  51.     fi.idsMax=IDS_FRAMEMAX;
  52.     fi.idsStatMin=IDS_STATMESSAGEMIN;
  53.     fi.idsStatMax=IDS_STATMESSAGEMAX;
  54.     fi.idStatMenuMin=ID_MENUFILE;
  55.     fi.idStatMenuMax=ID_MENUHELP;
  56.     fi.iPosWindowMenu=WINDOW_MENU;
  57.     fi.cMenus=CMENUS;
  58.  
  59.     fi.x=CW_USEDEFAULT;
  60.     fi.y=CW_USEDEFAULT;
  61.     fi.cx=CW_USEDEFAULT;
  62.     fi.cy=CW_USEDEFAULT;
  63.  
  64.     //If we can initialize pFR, start chugging messages
  65.     if (pFR->Init(&fi))
  66.         wRet=pFR->MessageLoop();
  67.  
  68.     delete pFR;
  69.     return wRet;
  70.     }
  71.  
  72.  
  73.  
  74. //CHAPTER21MOD
  75. /*
  76.  * ObjectDestroyed
  77.  *
  78.  * Purpose:
  79.  *  Function for the Patron Document object to call when it gets
  80.  *  destroyed.  We destroy the main window if the proper conditions
  81.  *  are met for shutdown.
  82.  */
  83.  
  84. void ObjectDestroyed(void)
  85.     {
  86.     g_cObj--;
  87.  
  88.     //No more objects, no locks, no user control, shut the app down.
  89.     if (0==g_cObj && 0==g_cLock && IsWindow(g_hWnd) && !g_fUser)
  90.         PostMessage(g_hWnd, WM_CLOSE, 0, 0L);
  91.  
  92.     return;
  93.     }
  94.  
  95. //End CHAPTER21MOD
  96.  
  97.  
  98.  
  99.  
  100. /*
  101.  * CPatronFrame::CPatronFrame
  102.  * CPatronFrame::~CPatronFrame
  103.  *
  104.  * Constructor Parameters:
  105.  *  hInst           HINSTANCE from WinMain
  106.  *  hInstPrev       HINSTANCE from WinMain
  107.  *  pszCmdLine      LPSTR from WinMain
  108.  *  nCmdShow        int from WInMain
  109.  */
  110.  
  111. CPatronFrame::CPatronFrame(HINSTANCE hInst, HINSTANCE hInstPrev
  112.     , LPSTR pszCmdLine, int nCmdShow)
  113.     : CFrame(hInst, hInstPrev, pszCmdLine, nCmdShow)
  114.     {
  115.     m_fInitialized=FALSE;
  116.     m_pIClassDataTran=NULL;
  117.  
  118.     //CHAPTER21MOD
  119.     m_pDocCreated=NULL;
  120.     m_fEmbedding=FALSE;
  121.  
  122.     m_dwRegCO=0;
  123.     m_pIClassFactory=NULL;
  124.     //End CHAPTER21MOD
  125.  
  126.     return;
  127.     }
  128.  
  129.  
  130. CPatronFrame::~CPatronFrame(void)
  131.     {
  132.     //CHAPTER21MOD
  133.     //Opposite of CoRegisterClassObject, takes class factory ref to 1
  134.     if (0L!=m_dwRegCO)
  135.         CoRevokeClassObject(m_dwRegCO);
  136.  
  137.     //This should be the last Release, which frees the class factory.
  138.     ReleaseInterface(m_pIClassFactory);
  139.     //End CHAPTER21MOD
  140.  
  141.     if (NULL!=m_pIClassDataTran)
  142.         {
  143.         m_pIClassDataTran->LockServer(FALSE);
  144.         m_pIClassDataTran->Release();
  145.         }
  146.  
  147.     OleFlushClipboard();
  148.  
  149.     if (m_fInitialized)
  150.         OleUninitialize();
  151.  
  152.     return;
  153.     }
  154.  
  155.  
  156.  
  157.  
  158. /*
  159.  * CPatronFrame::Init
  160.  *
  161.  * Purpose:
  162.  *  Call OleInitialize then calling down into the base class
  163.  *  initialization.
  164.  *
  165.  * Parameters:
  166.  *  pFI             PFRAMEINIT containing initialization
  167.  *                  parameters.
  168.  *
  169.  * Return Value:
  170.  *  BOOL            TRUE if initialization succeeded,
  171.  *                  FALSE otherwise.
  172.  */
  173.  
  174. BOOL CPatronFrame::Init(PFRAMEINIT pFI)
  175.     {
  176.     HRESULT     hr;
  177.  
  178.     CHECKVER_OLE;
  179.  
  180.     if (FAILED(OleInitialize(NULL)))
  181.         return FALSE;
  182.  
  183.     m_fInitialized=TRUE;
  184.  
  185.     //Lock the data transfer object factory as an optimization.
  186.     hr=CoGetClassObject(CLSID_DataTransferObject
  187.         , CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory
  188.         , (PPVOID)&m_pIClassDataTran);
  189.  
  190.     if (SUCCEEDED(hr))
  191.         m_pIClassDataTran->LockServer(TRUE);
  192.  
  193.     //CHAPTER21MOD
  194.     //Check for command line flags
  195.     ParseCommandLine();
  196.  
  197.     if (NULL!=m_ppszCmdArgs)
  198.         {
  199.         if(0==lstrcmpi(m_ppszCmdArgs[0], TEXT("-Embedding"))
  200.            || 0==lstrcmpi(m_ppszCmdArgs[0], TEXT("/Embedding")))
  201.             m_fEmbedding=TRUE;
  202.         }
  203.  
  204.     g_fUser=!m_fEmbedding;
  205.  
  206.     if (m_fEmbedding)
  207.         {
  208.         HRESULT     hr;
  209.  
  210.         m_pIClassFactory=new CLinkClassFactory(this);
  211.  
  212.         if (NULL==m_pIClassFactory)
  213.             return FALSE;
  214.  
  215.         //Since we hold on to this, we should AddRef it.
  216.         m_pIClassFactory->AddRef();
  217.  
  218.         hr=CoRegisterClassObject(CLSID_PatronPages, m_pIClassFactory
  219.             , CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &m_dwRegCO);
  220.  
  221.         if (FAILED(hr))
  222.             return FALSE;
  223.         }
  224.     //End CHAPTER21MOD
  225.  
  226.     return CFrame::Init(pFI);
  227.     }
  228.  
  229.  
  230.  
  231.  
  232.  
  233. /*
  234.  * CPatronFrame::CreateCClient
  235.  *
  236.  * Purpose:
  237.  *  Constructs a new client specific to the application.
  238.  *
  239.  * Parameters:
  240.  *  None
  241.  *
  242.  * Return Value:
  243.  *  PCClient        Pointer to the new client object.
  244.  */
  245.  
  246. PCClient CPatronFrame::CreateCClient(void)
  247.     {
  248.     return (PCClient)(new CPatronClient(m_hInst, this));
  249.     }
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256. /*
  257.  * CPatronFrame::RegisterAllClasses
  258.  *
  259.  * Purpose:
  260.  *  Registers all classes used in this application.
  261.  *
  262.  * Parameters:
  263.  *  None
  264.  *
  265.  * Return Value:
  266.  *  BOOL            TRUE if registration succeeded, FALSE otherwise.
  267.  */
  268.  
  269. BOOL CPatronFrame::RegisterAllClasses(void)
  270.     {
  271.     WNDCLASS        wc;
  272.  
  273.     //First let the standard frame do its thing
  274.     if (!CFrame::RegisterAllClasses())
  275.         return FALSE;
  276.  
  277.     //We need double-clicks now and for object activation.
  278.     wc.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  279.     wc.hInstance     = m_hInst;
  280.     wc.cbClsExtra    = 0;
  281.     wc.lpfnWndProc   = PagesWndProc;
  282.     wc.cbWndExtra    = CBPAGESWNDEXTRA;
  283.     wc.hIcon         = NULL;
  284.     wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  285.     wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE+1);
  286.     wc.lpszMenuName  = NULL;
  287.     wc.lpszClassName = SZCLASSPAGES;
  288.  
  289.     if (!RegisterClass(&wc))
  290.         return FALSE;
  291.  
  292.     return TRUE;
  293.     }
  294.  
  295.  
  296.  
  297.  
  298. //CHAPTER21MOD
  299. /*
  300.  * CPatronFrame::PreShowInit
  301.  *
  302.  * Purpose:
  303.  *  Called from Init before intially showing the window.  We do
  304.  *  whatever else we want here, modifying m_nCmdShow as necessary
  305.  *  which affects ShowWindow in Init.
  306.  *
  307.  * Parameters:
  308.  *  None
  309.  *
  310.  * Return Value:
  311.  *  BOOL            TRUE if this successful, FALSE otherwise.
  312.  */
  313.  
  314. BOOL CPatronFrame::PreShowInit(void)
  315.     {
  316.     //Base class does nothing
  317.     CFrame::PreShowInit();
  318.  
  319.     //Save the window handle for shutdown if necessary.
  320.     g_hWnd=m_hWnd;
  321.  
  322.     //If we're -Embedding, don't show the window initially.
  323.     if (m_fEmbedding)
  324.         m_nCmdShow=SW_HIDE;
  325.  
  326.     return TRUE;
  327.     }
  328. //End CHAPTER21MOD
  329.  
  330.  
  331.  
  332.  
  333.  
  334. /*
  335.  * CPatronFrame::OnCommand
  336.  *
  337.  * Purpose:
  338.  *  WM_COMMAND handler for the Patron frame window that processes
  339.  *  extra File menu items as well as the Page menu.
  340.  *
  341.  * Parameters:
  342.  *  hWnd            HWND of the frame window.
  343.  *  wParam          WPARAM of the message.
  344.  *  lParam          LPARAM of the message.
  345.  *
  346.  * Return Value:
  347.  *  LRESULT         Return value for the message.
  348.  */
  349.  
  350. LRESULT CPatronFrame::OnCommand(HWND hWnd, WPARAM wParam
  351.     , LPARAM lParam)
  352.     {
  353.     PCPatronDoc     pDoc;
  354.  
  355.     COMMANDPARAMS(wID, wCode, hWndMsg);
  356.  
  357.     /*
  358.      * Don't bother with anything during first initialization,
  359.      * skipping many toolbar notifications.
  360.      */
  361.     if (m_fInit)
  362.         return 0L;
  363.  
  364.     pDoc=(PCPatronDoc)m_pCL->ActiveDocument();
  365.  
  366.     if (NULL!=pDoc && (IDM_VERBMIN <= wID) && (IDM_VERBMAX >= wID))
  367.         {
  368.         pDoc->ActivateObject(wID-IDM_VERBMIN);
  369.         return 0L;
  370.         }
  371.  
  372.     switch (wID)
  373.         {
  374.         case IDM_FILEPRINT:
  375.             pDoc->Print(m_hWnd);
  376.             return 0L;
  377.  
  378.         case IDM_FILEPRINTERSETUP:
  379.             pDoc->PrinterSetup(m_hWnd, FALSE);
  380.             return 0L;
  381.  
  382.         case IDM_EDITPASTESPECIAL:
  383.             pDoc->PasteSpecial(m_hWnd);
  384.             return 0L;
  385.  
  386.         case IDM_EDITDELETEOBJECT:
  387.             pDoc->Delete();
  388.             return 0L;
  389.  
  390.         case IDM_EDITINSERTOBJECT:
  391.             pDoc->InsertObject(m_hWnd);
  392.             return 0L;
  393.  
  394.         case IDM_EDITCONVERT:
  395.             pDoc->ConvertObject(m_hWnd);
  396.             return 0L;
  397.  
  398.         case IDM_EDITLINKS:
  399.             pDoc->EditLinks(m_hWnd);
  400.             return 0L;
  401.  
  402.         case IDM_PAGENEWPAGE:
  403.             pDoc->NewPage();
  404.             break;
  405.  
  406.         case IDM_PAGEDELETEPAGE:
  407.             pDoc->DeletePage();
  408.             break;
  409.  
  410.         case IDM_PAGENEXTPAGE:
  411.             pDoc->NextPage();
  412.             break;
  413.  
  414.         case IDM_PAGEPREVIOUSPAGE:
  415.             pDoc->PreviousPage();
  416.             break;
  417.  
  418.         case IDM_PAGEFIRSTPAGE:
  419.             pDoc->FirstPage();
  420.             break;
  421.  
  422.         case IDM_PAGELASTPAGE:
  423.             pDoc->LastPage();
  424.             break;
  425.  
  426.         case IDM_PAGESHOWOBJECTS:
  427.             {
  428.             BOOL    fTemp;
  429.  
  430.             //First get the current state, then toggle it.
  431.             fTemp=pDoc->ShowOrQueryObjectTypes(TRUE, FALSE);
  432.             pDoc->ShowOrQueryObjectTypes(FALSE, !fTemp);
  433.             }
  434.             break;
  435.  
  436.         default:
  437.            return CFrame::OnCommand(hWnd, wParam, lParam);
  438.         }
  439.  
  440.     return 0L;
  441.     }
  442.  
  443.  
  444.  
  445.  
  446.  
  447.  
  448.  
  449.  
  450. /*
  451.  * CPatronFrame::CreateToolbar
  452.  *
  453.  * Purpose:
  454.  *  Procedure to create all the necessary toolbar buttons.
  455.  *
  456.  * Parameters:
  457.  *  None
  458.  *
  459.  * Return Value:
  460.  *  UINT            Number of tools added to the bar.
  461.  */
  462.  
  463. UINT CPatronFrame::CreateToolbar(void)
  464.     {
  465.     UINT            iLast;
  466.     UINT            uState=GIZMO_NORMAL;
  467.     UINT            utCmd =GIZMOTYPE_BUTTONCOMMAND;
  468.  
  469.     //Insert the standard ones.
  470.     iLast=CFrame::CreateToolbar();
  471.  
  472.     //Remove Undo:  we don't use it.
  473.     m_pTB->Remove(IDM_EDITUNDO);
  474.  
  475.     /*
  476.      * Insert Print File Import in the 5th position and account
  477.      * for it in iLast.
  478.      */
  479.     m_pTB->Add(utCmd, 4, IDM_FILEPRINT, m_dxB, m_dyB
  480.         , NULL, NULL, 6, uState);
  481.  
  482.     iLast++;
  483.  
  484.     m_pTB->Add(GIZMOTYPE_SEPARATOR, iLast++, 0, 6, m_dyB
  485.         , NULL, NULL, 0, uState);
  486.  
  487.     //Add New Page, and Delete Page
  488.     m_pTB->Add(utCmd, iLast++, IDM_PAGENEWPAGE, m_dxB, m_dyB
  489.         , NULL, m_hBmp, 2, uState);
  490.     m_pTB->Add(utCmd, iLast++, IDM_PAGEDELETEPAGE, m_dxB, m_dyB
  491.         , NULL, m_hBmp, 3, uState);
  492.  
  493.     m_pTB->Add(GIZMOTYPE_SEPARATOR, iLast++, 0, 6, m_dyB
  494.         , NULL, NULL, 0, uState);
  495.  
  496.     //First, Prev, Next, Last pages.
  497.     m_pTB->Add(utCmd, iLast++, IDM_PAGEFIRSTPAGE, m_dxB, m_dyB
  498.         , NULL, m_hBmp, 4, uState);
  499.     m_pTB->Add(utCmd, iLast++, IDM_PAGEPREVIOUSPAGE, m_dxB, m_dyB
  500.         , NULL, m_hBmp, 5, uState);
  501.     m_pTB->Add(utCmd, iLast++, IDM_PAGENEXTPAGE, m_dxB, m_dyB
  502.         , NULL, m_hBmp, 6, uState);
  503.     m_pTB->Add(utCmd, iLast++, IDM_PAGELASTPAGE, m_dxB, m_dyB
  504.         , NULL, m_hBmp, 7, uState);
  505.  
  506.     return iLast;
  507.     }
  508.  
  509.  
  510.  
  511.  
  512.  
  513.  
  514.  
  515. /*
  516.  * CPatronFrame::UpdateMenus
  517.  *
  518.  * Purpose:
  519.  *  Handles the WM_INITMENU message for the frame window.  Depending
  520.  *  on the existence of an active window, menu items are selectively
  521.  *  enabled and disabled.
  522.  *
  523.  * Parameters:
  524.  *  hMenu           HMENU of the menu to intialize
  525.  *  iMenu           UINT position of the menu.
  526.  *
  527.  * Return Value:
  528.  *  None
  529.  */
  530.  
  531. void CPatronFrame::UpdateMenus(HMENU hMenu, UINT iMenu)
  532.     {
  533.     PCPatronDoc     pDoc;
  534.     BOOL            fOK=FALSE;
  535.     BOOL            fCallDefault=TRUE;
  536.     UINT            uTemp;
  537.     UINT            uTempE;
  538.     UINT            uTempD;
  539.  
  540.     pDoc=(PCPatronDoc)m_pCL->ActiveDocument();
  541.  
  542.     uTempE=MF_ENABLED | MF_BYCOMMAND;
  543.     uTempD=MF_DISABLED | MF_GRAYED | MF_BYCOMMAND;
  544.     uTemp=((NULL!=pDoc) ? uTempE : uTempD);
  545.  
  546.     if (m_phMenu[0]==hMenu)
  547.         {
  548.         EnableMenuItem(hMenu, IDM_FILEPRINT, uTemp);
  549.  
  550.         if (NULL!=pDoc)
  551.             fOK=pDoc->FQueryPrinterSetup();
  552.  
  553.         EnableMenuItem(hMenu, IDM_FILEPRINTERSETUP
  554.             , (fOK) ? uTempE : uTempD);
  555.         }
  556.  
  557.     if (m_phMenu[1]==hMenu)
  558.         {
  559.         if (NULL!=pDoc)
  560.             fOK=pDoc->FQueryPaste();
  561.  
  562.         EnableMenuItem(hMenu, IDM_EDITPASTE
  563.             , (fOK) ? uTempE : uTempD);
  564.         EnableMenuItem(hMenu, IDM_EDITPASTESPECIAL
  565.             , (fOK) ? uTempE : uTempD);
  566.  
  567.         //Cut, Copy, Delete depends on there being a selection.
  568.         if (NULL!=pDoc)
  569.             fOK=pDoc->FQueryObjectSelected(hMenu);
  570.         else
  571.             fOK=FALSE;
  572.  
  573.         EnableMenuItem(hMenu, IDM_EDITCUT, (fOK) ? uTempE : uTempD);
  574.         EnableMenuItem(hMenu, IDM_EDITCOPY
  575.             , (fOK) ? uTempE : uTempD);
  576.         EnableMenuItem(hMenu, IDM_EDITDELETEOBJECT
  577.             , (fOK) ? uTempE : uTempD);
  578.  
  579.         EnableMenuItem(hMenu, IDM_EDITINSERTOBJECT, uTemp);
  580.  
  581.         if (NULL!=pDoc)
  582.             fOK=pDoc->FQueryEnableEditLinks();
  583.         else
  584.             fOK=FALSE;
  585.  
  586.         EnableMenuItem(hMenu, IDM_EDITLINKS
  587.             , (fOK) ? uTempE : uTempD);
  588.  
  589.         //We did the whole menu...
  590.         fCallDefault=FALSE;
  591.         }
  592.  
  593.     //Page menu
  594.     if (m_phMenu[2]==hMenu)
  595.         {
  596.         EnableMenuItem(hMenu, IDM_PAGENEWPAGE,      uTemp);
  597.         EnableMenuItem(hMenu, IDM_PAGEDELETEPAGE,   uTemp);
  598.         EnableMenuItem(hMenu, IDM_PAGENEXTPAGE,     uTemp);
  599.         EnableMenuItem(hMenu, IDM_PAGEPREVIOUSPAGE, uTemp);
  600.         EnableMenuItem(hMenu, IDM_PAGEFIRSTPAGE,    uTemp);
  601.         EnableMenuItem(hMenu, IDM_PAGELASTPAGE,     uTemp);
  602.  
  603.         //Check the Show Objects command or not.
  604.         if (NULL!=pDoc)
  605.             fOK=pDoc->ShowOrQueryObjectTypes(TRUE, FALSE);
  606.         else
  607.             fOK=FALSE;
  608.  
  609.         CheckMenuItem(hMenu, IDM_PAGESHOWOBJECTS, MF_BYCOMMAND
  610.             | ((fOK) ? MF_CHECKED : MF_UNCHECKED));
  611.         EnableMenuItem(hMenu, IDM_PAGESHOWOBJECTS, uTemp);
  612.         }
  613.  
  614.     if (fCallDefault)
  615.         CFrame::UpdateMenus(hMenu, iMenu);
  616.  
  617.     return;
  618.     }
  619.  
  620.  
  621.  
  622.  
  623.  
  624.  
  625. /*
  626.  * CPatronFrame::UpdateToolbar
  627.  *
  628.  * Purpose:
  629.  *  Enables and disables tools depending on whether we have
  630.  *  a document or not.
  631.  *
  632.  * Parameters:
  633.  *  None
  634.  *
  635.  * Return Value:
  636.  *  None
  637.  */
  638.  
  639. void CPatronFrame::UpdateToolbar(void)
  640.     {
  641.     PCDocument  pDoc;
  642.     BOOL        fEnable;
  643.  
  644.     //Let the default hack on its tools.
  645.     CFrame::UpdateToolbar();
  646.  
  647.     pDoc=m_pCL->ActiveDocument();
  648.     fEnable=(NULL!=pDoc);
  649.  
  650.     //No document, disable just about everything
  651.     m_pTB->Enable(IDM_FILEPRINT,        fEnable);
  652.     m_pTB->Enable(IDM_FILEPRINTERSETUP, fEnable);
  653.  
  654.     m_pTB->Enable(IDM_PAGENEWPAGE,      fEnable);
  655.     m_pTB->Enable(IDM_PAGEDELETEPAGE,   fEnable);
  656.     m_pTB->Enable(IDM_PAGEFIRSTPAGE,    fEnable);
  657.     m_pTB->Enable(IDM_PAGEPREVIOUSPAGE, fEnable);
  658.     m_pTB->Enable(IDM_PAGENEXTPAGE,     fEnable);
  659.     m_pTB->Enable(IDM_PAGELASTPAGE,     fEnable);
  660.  
  661.     return;
  662.     }
  663.  
  664.  
  665.  
  666. /*
  667.  * CPatronFrame::FMessageHook
  668.  *
  669.  * Purpose:
  670.  *  Override of CFrame::FMessageHook so we can specifically trap
  671.  *  WM_MENUSELECT messages for the Object verb menu to provide some
  672.  *  meaningful information on the status strip.
  673.  *
  674.  * Parameters:
  675.  *  <WndProc Parameters>
  676.  *  pLRes           LRESULT * in which to store the return value
  677.  *                  for the message.
  678.  *
  679.  * Return Value:
  680.  *  BOOL            TRUE to prevent further processing,
  681.  *                  FALSE otherwise.
  682.  */
  683.  
  684. BOOL CPatronFrame::FMessageHook(HWND hWnd, UINT iMsg, WPARAM wParam
  685.     , LPARAM lParam, LRESULT *pLRes)
  686.     {
  687.     BOOL        fRet=FALSE;
  688.  
  689.     *pLRes=0;
  690.  
  691.     MENUSELECTPARAMS(wItem, wMenuFlags, hMenu);
  692.  
  693.     //CHAPTER21MOD
  694.     /*
  695.      * When closing, make sure any document create from the
  696.      * class factory is saved since the object in it might
  697.      * have been changed.  We want to save without showing
  698.      * the user any message or asking if the user wants to save.
  699.      */
  700.     if (WM_CLOSE==iMsg)
  701.         {
  702.         if (NULL!=m_pDocCreated)
  703.             {
  704.             if (m_pDocCreated->FDirtyGet())
  705.                 {
  706.                 CHourglass  wait;
  707.                 m_pDocCreated->Save(0, NULL);
  708.                 }
  709.             }
  710.  
  711.         return FALSE;
  712.         }
  713.     //End CHAPTER21MOD
  714.  
  715.     //If this is the wrong message, nothing to do.
  716.     if (WM_MENUSELECT!=iMsg)
  717.         return FALSE;
  718.  
  719.     //This happens when there's no menu selection.
  720.     if (-1==wMenuFlags)
  721.         return FALSE;
  722.  
  723.     if (MF_POPUP & wMenuFlags)
  724.         {
  725.         /*
  726.          * If this is the cascade verb menu itself, display the same
  727.          * message.  m_phMenu[1] contains the current edit menu
  728.          * handle.
  729.          */
  730.         if (0!=wItem)
  731.             {
  732.             fRet=((HMENU)wItem==GetSubMenu(m_phMenu[1]
  733.                 , MENUPOS_OBJECT));
  734.             }
  735.         }
  736.     else
  737.         {
  738.         /*
  739.          * If the ID is in the verb range, use
  740.          * IDS_ITEMMESSAGEEDITOBJECT message
  741.          */
  742.         fRet=(IDM_VERBMIN <= wItem && IDM_VERBMAX >= wItem);
  743.         }
  744.  
  745.     if (fRet)
  746.         m_pSL->MessageDisplay(IDM_EDITOBJECT);
  747.  
  748.     return fRet;
  749.     }
  750.