home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / addins / wins / windowslist.cpp < prev    next >
C/C++ Source or Header  |  1998-04-08  |  21KB  |  774 lines

  1. // WindowsList.cpp : Implementation of CWindowsList
  2. #include "stdafx.h"
  3. #include "Wins.h"
  4. #include "WindowsList.h"
  5. #include "dlgwinmgr.h"
  6.  
  7.  
  8. #pragma warning( disable : 4310 )  // Disable warning message: warning C4310: cast truncates constant value
  9. // get this warning for lines containing VARIANT_BOOL, VARIANT_TRUE, or VARIANT_FALSE
  10.  
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CWindowsList
  13.  
  14. HRESULT CWindowsList::OnConnection(IApplication* pApp, VARIANT_BOOL bFirstTime, long dwAddInID, VARIANT_BOOL* bOnConnection)
  15. {
  16.     HRESULT hr = S_OK;
  17.     CString strCmdString;
  18.     CString strCmdName;
  19.  
  20.     AFX_MANAGE_STATE(AfxGetStaticModuleState()); // do this, or you will not be able to load resources
  21.  
  22.     m_spApplication = pApp;
  23.     m_dwAddInID = dwAddInID;
  24.  
  25.     // Connect up to application event sink
  26.     AtlAdvise(pApp, GetUnknown(), IID_IApplicationEvents, &m_dwAppEvents);
  27.  
  28.     // Connect up to debugger event sink
  29.     CComPtr<IDispatch> pDebugger;
  30.     hr = m_spApplication->get_Debugger(&pDebugger);
  31.     if (SUCCEEDED(hr))
  32.         AtlAdvise(pDebugger, GetUnknown(), IID_IDebuggerEvents, &m_dwDbgEvents);
  33.  
  34.     hr = pApp->SetAddInInfo((long)_Module.GetModuleInstance(), 
  35.         static_cast<IWindowsList*>(this), IDB_TOOLBAR_MEDIUM_CWINMGR, IDB_TOOLBAR_LARGE_CWINMGR, dwAddInID);
  36.     VARIANT_BOOL bRet;
  37.     if (SUCCEEDED(hr))
  38.     {
  39.         strCmdString.LoadString(IDS_CMD_WINMGR);
  40.         strCmdName.LoadString(IDS_CMDNAME_WINMGR);//             ,---- This is the name of the method in the IWindowsList interface
  41.         strCmdName += _T('\n');
  42.         strCmdName += strCmdString; //                           V
  43.         hr = pApp->AddCommand(CComBSTR(strCmdName),CComBSTR(_T("WindowsManager")), 0, dwAddInID, &bRet);
  44.         _ASSERTE(SUCCEEDED(hr));
  45.         strCmdString.LoadString(IDS_CMD_MINWIN);
  46.         strCmdName.LoadString(IDS_CMDNAME_MINWIN);
  47.         strCmdName += _T('\n');
  48.         strCmdName += strCmdString;
  49.         hr = pApp->AddCommand(CComBSTR(strCmdName),CComBSTR(_T("MinWin")), 1, dwAddInID, &bRet);
  50.         _ASSERTE(SUCCEEDED(hr));
  51.         strCmdString.LoadString(IDS_CMD_AUTOSIZE);
  52.         strCmdName.LoadString(IDS_CMDNAME_AUTOSIZE);
  53.         strCmdName += _T('\n');
  54.         strCmdName += strCmdString;
  55.         hr = pApp->AddCommand(CComBSTR(strCmdName),CComBSTR(_T("SetLimit")), 2, dwAddInID, &bRet);
  56.         _ASSERTE(SUCCEEDED(hr));
  57.         strCmdString.LoadString(IDS_CMD_ALLVISIBLE);
  58.         strCmdName.LoadString(IDS_CMDNAME_ALLVISIBLE);
  59.         strCmdName += _T('\n');
  60.         strCmdName += strCmdString;
  61.         hr = pApp->AddCommand(CComBSTR(strCmdName),CComBSTR(_T("SetVisible")), 3, dwAddInID, &bRet);
  62.         _ASSERTE(SUCCEEDED(hr));
  63.         strCmdString.LoadString(IDS_CMD_CLOSEDEBUGWNDS);
  64.         strCmdName.LoadString(IDS_CMDNAME_CLOSEDEBUGWNDS);
  65.         strCmdName += _T('\n');
  66.         strCmdName += strCmdString;
  67.         hr = pApp->AddCommand(CComBSTR(strCmdName),CComBSTR(_T("CloseDebugWnds")), 4, dwAddInID, &bRet);
  68.         _ASSERTE(SUCCEEDED(hr));
  69.     }
  70.  
  71.     // Add toolbar buttons only if this is the first time the add-in
  72.     // is being loaded.  Toolbar buttons are automatically remembered
  73.     // by Developer Studio from session to session, so we should only
  74.     // add the toolbar buttons once.
  75.     if (bFirstTime == VARIANT_TRUE)
  76.     {
  77.         if (SUCCEEDED(hr))
  78.         {
  79.             strCmdName.LoadString(IDS_CMDNAME_WINMGR);
  80.             hr = pApp->AddCommandBarButton(dsGlyph, CComBSTR(strCmdName), dwAddInID);
  81.             _ASSERTE(SUCCEEDED(hr));
  82.             strCmdName.LoadString(IDS_CMDNAME_MINWIN);
  83.             hr = pApp->AddCommandBarButton(dsGlyph, CComBSTR(strCmdName), dwAddInID);
  84.             _ASSERTE(SUCCEEDED(hr));
  85.             strCmdName.LoadString(IDS_CMDNAME_AUTOSIZE);
  86.             hr = pApp->AddCommandBarButton(dsGlyph, CComBSTR(strCmdName), dwAddInID);
  87.             _ASSERTE(SUCCEEDED(hr));
  88.             strCmdName.LoadString(IDS_CMDNAME_ALLVISIBLE);
  89.             hr = pApp->AddCommandBarButton(dsGlyph, CComBSTR(strCmdName), dwAddInID);
  90.             _ASSERTE(SUCCEEDED(hr));
  91.             strCmdName.LoadString(IDS_CMDNAME_CLOSEDEBUGWNDS);
  92.             hr = pApp->AddCommandBarButton(dsGlyph, CComBSTR(strCmdName), dwAddInID);
  93.             _ASSERTE(SUCCEEDED(hr));
  94.         }
  95.     }
  96.  
  97.     *bOnConnection = (VARIANT_BOOL)(SUCCEEDED(hr) ? VARIANT_TRUE :VARIANT_FALSE);
  98.     return hr;
  99. }
  100.  
  101. HRESULT CWindowsList::OnDisconnection(VARIANT_BOOL bLastTime)
  102. {
  103.     bLastTime; // UNREFERENCED (don't care why we are disconnectino
  104.  
  105.     AtlUnadvise(m_spApplication, IID_IApplicationEvents, m_dwAppEvents);
  106.     AtlUnadvise(m_spApplication, IID_IDebuggerEvents, m_dwDbgEvents);
  107.     return S_OK;
  108. }
  109.  
  110. /////////////////////////////////////////////////////////////////////////////
  111. // Application events
  112. HRESULT CWindowsList::BeforeBuildStart()
  113. {
  114.     return S_OK;
  115. }
  116. HRESULT CWindowsList::BuildFinish(long nNumErrors, long nNumWarnings)
  117. {
  118.     nNumWarnings;  // UNREFERENCED
  119.     nNumErrors;  // UNREFERENCED
  120.  
  121.     return S_OK;
  122. }
  123. HRESULT CWindowsList::BeforeApplicationShutDown()
  124. {
  125.     return S_OK;
  126. }
  127. HRESULT CWindowsList::DocumentOpen(IDispatch* theDocument)
  128. {
  129.     HRESULT hr = E_FAIL;
  130.     CComPtr<IDispatch> pDispWindow;
  131.     CComQIPtr<IGenericDocument, &IID_IGenericDocument> pDoc;
  132.     CComQIPtr<IGenericDocument, &IID_IGenericDocument> pGenericDocument;
  133.  
  134.     pDoc = theDocument;
  135.     if (pDoc)
  136.     {
  137.         pGenericDocument = theDocument;
  138.         if (pGenericDocument)
  139.         {
  140.             SetInfo(pGenericDocument);
  141.         }
  142.         hr = pDoc->get_ActiveWindow(&pDispWindow);
  143.         if (SUCCEEDED(hr) && pDispWindow)
  144.         {
  145.             MakeLimit(pDispWindow);
  146.         }
  147.     }
  148.     return hr;
  149. }
  150.  
  151. HRESULT CWindowsList::BeforeDocumentClose(IDispatch* theDocument)
  152. {
  153.     theDocument;  // UNREFERENCED
  154.     return S_OK;
  155. }
  156.  
  157. HRESULT CWindowsList::DocumentSave(IDispatch* theDocument)
  158. {
  159.     CComQIPtr<IGenericDocument, &IID_IGenericDocument> pGenericDocument;
  160.     pGenericDocument = theDocument;
  161.     if (pGenericDocument)
  162.     {
  163.         SetInfo(pGenericDocument);
  164.     }
  165.     return S_OK;
  166. }
  167.  
  168. HRESULT CWindowsList::NewDocument(IDispatch* theDocument)
  169. {
  170.     theDocument;  // UNREFERENCED
  171.     return S_OK;
  172. }
  173.  
  174. HRESULT CWindowsList::WindowActivate(IDispatch* theWindow)
  175. {
  176.     theWindow;  // UNREFERENCED
  177.     SetInfo();
  178.     MakeLimit();
  179.     return S_OK;
  180. }
  181.  
  182. HRESULT CWindowsList::WindowDeactivate(IDispatch* theWindow)
  183. {
  184.     theWindow;  // UNREFERENCED
  185.     return S_OK;
  186. }
  187.  
  188. HRESULT CWindowsList::WorkspaceOpen()
  189. {
  190.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  191.  
  192.     m_spApplication->EnableModeless(VARIANT_FALSE);
  193.     
  194.     CComPtr<IDispatch> pDispDocuments;
  195.     CComPtr<IDispatch> pDispDoc;
  196.     CComQIPtr<IDocuments, &IID_IDocuments> pDocuments;
  197.     CComQIPtr<IGenericDocument, &IID_IGenericDocument> pDocActive;
  198.     m_spApplication->get_ActiveDocument(&pDispDoc);
  199.     pDocActive = pDispDoc;
  200.     pDispDoc = NULL;
  201.  
  202.     m_spApplication->get_Documents(&pDispDocuments);
  203.     pDocuments = pDispDocuments;
  204.     pDispDocuments = NULL;
  205.  
  206.     CComPtr<IUnknown> pUnk;
  207.     CComQIPtr<IEnumVARIANT, &IID_IEnumVARIANT> pNewEnum;
  208.     if (SUCCEEDED(pDocuments->get__NewEnum(&pUnk)) && pUnk != NULL)
  209.     {
  210.         pNewEnum = pUnk;
  211.         VARIANT varTextDocument;
  212.         CComQIPtr<IGenericDocument, &IID_IGenericDocument> pGenDoc;
  213.         while (pNewEnum->Next(1, &varTextDocument, NULL) == S_OK)
  214.         {
  215.             _ASSERTE(varTextDocument.vt == VT_DISPATCH);
  216.             pGenDoc = varTextDocument.pdispVal;
  217.             if (pGenDoc)
  218.             {
  219.                 SetInfo(pGenDoc, FALSE);
  220.             }
  221.             VariantClear(&varTextDocument);
  222.         }
  223.     }
  224.     if (pDocActive)
  225.     {
  226.         pDocActive->put_Active(VARIANT_TRUE); // make this active again.
  227.         SetInfo(pDocActive);
  228.     }
  229.  
  230.     m_spApplication->EnableModeless((VARIANT_BOOL)VARIANT_TRUE);
  231.     return S_OK;
  232. }
  233.  
  234. HRESULT CWindowsList::WorkspaceClose()
  235. {
  236.     return S_OK;
  237. }
  238. HRESULT CWindowsList::NewWorkspace()
  239. {
  240.     return S_OK;
  241. }
  242.  
  243. /////////////////////////////////////////////////////////////////////////////
  244. // Debugger event
  245. HRESULT CWindowsList::BreakpointHit(IDispatch* pBreakpoint)
  246. {
  247.     pBreakpoint;  // UNREFERENCED
  248.     return S_OK;
  249. }
  250.  
  251. /// IWindowsList
  252. HRESULT CWindowsList::WindowsManager()
  253. {
  254.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  255.     CDlgWinMgr dlgWinMgr;
  256.     int iRes;
  257.  
  258.     m_fAutoVis = theApp.GetAutoVis();
  259.     m_fAutoDir = theApp.GetAutoDir();
  260.     m_fAutoSize = theApp.GetAutoSize();
  261.     m_iSortedCol = theApp.GetSortedCol();
  262.     m_lSize = theApp.GetSize();
  263.  
  264.     dlgWinMgr.SetVars(m_fAutoVis,m_fAutoDir, m_fAutoSize, m_iSortedCol, m_lSize);
  265.  
  266.     if (m_dirList.Count() == 0)
  267.     {
  268.         WorkspaceOpen(); // pretend we just did this...
  269.     }
  270.     dlgWinMgr.SetDirList(&m_dirList, this);
  271.     iRes = dlgWinMgr.DoModal();
  272.  
  273.     dlgWinMgr.GetVars(m_fAutoVis,m_fAutoDir, m_fAutoSize, m_iSortedCol, m_lSize);
  274.     theApp.SetAutoVis(m_fAutoVis);
  275.     theApp.SetAutoDir(m_fAutoDir);
  276.     theApp.SetAutoSize(m_fAutoSize);
  277.     theApp.SetSize(m_lSize);
  278.  
  279.     return S_OK;
  280. }
  281.  
  282.  
  283. HRESULT CWindowsList::SetInfo(IGenericDocument *pTextDoc /* = NULL */, BOOL fDoExtras /* = TRUE*/)
  284. {
  285.     HRESULT hr = S_OK;
  286.     int i;
  287.  
  288.     if (m_cIgnoreSetDir > 0)
  289.     {
  290.         m_cIgnoreSetDir--;
  291.         return(S_OK);
  292.     }
  293.  
  294.     CString strDir, strFile;
  295.     CComQIPtr<IGenericDocument, &IID_IGenericDocument> pDocument;
  296.  
  297.     if (pTextDoc)
  298.     {
  299.         pDocument = pTextDoc;
  300.     }
  301.     else
  302.     {
  303.         CComPtr<IDispatch> pDispDocument;
  304.         m_spApplication->get_ActiveDocument(&pDispDocument);
  305.         pDocument = pDispDocument;
  306.         pDispDocument = NULL;
  307.     }
  308.     if (pDocument)
  309.     {
  310.         CComBSTR bstrName;
  311.         CString strFullPath;
  312.         pDocument->get_FullName(&bstrName);
  313.         strDir = bstrName;
  314.         strFullPath = strDir;
  315.         i = strDir.ReverseFind(_T('\\'));
  316.         if (i >= 0)
  317.         {
  318.             strFile = strDir.Mid(i+1);
  319.             strDir = strDir.Left(i);
  320.             AddToList(strDir, strFile, strFullPath, fDoExtras);
  321.             if (m_fAutoDir && fDoExtras)
  322.             {
  323.                 SetCurrDir(strDir);
  324.             }
  325.         }
  326.     }
  327.  
  328.  
  329.     return(hr);
  330. }
  331.  
  332. void CWindowsList::IgnoreNextSetDir()
  333. {
  334.     m_cIgnoreSetDir = 1; // don't bother going higher at moment.
  335. }
  336.  
  337. void CWindowsList::SetCurrDir(LPCTSTR szDir)
  338. {
  339.     CComBSTR bstrName;
  340.  
  341.     bstrName = szDir;
  342.     m_spApplication->put_CurrentDirectory(bstrName);
  343. }
  344.  
  345.  
  346.  
  347. BOOL CWindowsList::AddToList(LPCTSTR szDir, LPCTSTR szFile, LPCTSTR szFullPath, BOOL fTouch /* = TRUE*/)
  348. {
  349.     BOOL fOK = TRUE;
  350.     BOOL fInDebugger;
  351.     CRect rectWnd;
  352.  
  353.     fInDebugger = IsInDebugMode();
  354.     GetSize(szFullPath, rectWnd);
  355.     m_dirList.FAddDir(szDir, szFile, rectWnd, fInDebugger, fTouch);
  356.     return(fOK);
  357. }
  358.  
  359. HRESULT CWindowsList::OpenDoc(LPCTSTR szFile, IGenericDocument **ppDocRet /* = NULL*/)
  360. {
  361.     HRESULT hr = E_FAIL;
  362.     CComPtr<IGenericDocument> pDoc;
  363.     if (ppDocRet)
  364.         *ppDocRet = NULL;
  365.     hr = FindDoc(szFile, pDoc);
  366.     if (pDoc)
  367.     {
  368.         hr = pDoc->put_Active((VARIANT_BOOL)VARIANT_TRUE);
  369.         if (ppDocRet)
  370.         {
  371.             *ppDocRet = pDoc.p;
  372.             (*ppDocRet)->AddRef();
  373.         }
  374.     }
  375.     return(hr);
  376. }
  377.  
  378. HRESULT CWindowsList::CloseDoc(LPCTSTR szFile)
  379. {
  380.     HRESULT hr = E_FAIL;
  381.     CComPtr<IGenericDocument> pDoc;
  382.     DsSaveStatus iSaved;
  383.     CComVariant varSaveChanges = dsSaveChangesPrompt;
  384.  
  385.     hr = FindDoc(szFile, pDoc, FALSE);
  386.     if (pDoc)
  387.     {
  388.         hr = pDoc->Close(varSaveChanges, &iSaved);
  389.     }
  390.  
  391.     return(hr);
  392. }
  393.  
  394.  
  395.  
  396. HRESULT CWindowsList::FindDoc(LPCTSTR szFile, CComPtr<IGenericDocument>& pDoc, BOOL fOkToOpen /*= TRUE*/)
  397. {
  398.     HRESULT hr = E_FAIL;
  399.     CComPtr<IDispatch> pDispDocuments;
  400.     CComQIPtr<IDocuments, &IID_IDocuments> pDocuments;
  401.     CComBSTR bstrFile;
  402.     m_spApplication->get_Documents(&pDispDocuments);
  403.     pDocuments = pDispDocuments;
  404.     pDispDocuments = NULL;
  405.     BOOL fFound = FALSE;
  406.  
  407.     if (pDocuments)
  408.     {    // ENSURE DOC IS OPEN -- WE KEEP FILES AROUND THAT MAY HAVE BEEN CLOSED
  409.         CComVariant vtDocType = _T("Auto");
  410.         CComVariant vtBoolReadOnly = FALSE;
  411.         CComPtr<IDispatch> pDispDoc;
  412.         bstrFile = szFile;
  413.         CComQIPtr<IGenericDocument, &IID_IGenericDocument> pDocument;
  414.         if (fOkToOpen)
  415.         {
  416.             hr = pDocuments->Open(bstrFile, vtDocType, vtBoolReadOnly, &pDispDoc);
  417.             pDocument = pDispDoc;
  418.             if (SUCCEEDED(hr) && pDocument)
  419.             {
  420.                 fFound = TRUE;
  421.                 pDoc = pDocument;
  422.             }
  423.         }
  424.         if (!fFound)
  425.         {
  426.             CComPtr<IUnknown> pUnk;
  427.             CComQIPtr<IEnumVARIANT, &IID_IEnumVARIANT> pNewEnum;
  428.             if (SUCCEEDED(pDocuments->get__NewEnum(&pUnk)) && pUnk != NULL)
  429.             {
  430.                 pNewEnum = pUnk;
  431.                 VARIANT varGenericDocument;
  432.  
  433.                 while (!fFound && pNewEnum->Next(1, &varGenericDocument, NULL) == S_OK)
  434.                 {
  435.                     CComQIPtr<IGenericDocument, &IID_IGenericDocument> pGenericDocument;
  436.                     ASSERT (varGenericDocument.vt == VT_DISPATCH);
  437.                     pGenericDocument = varGenericDocument.pdispVal;
  438.                     //varGenericDocument.pdispVal->Release();
  439.                     VariantClear(&varGenericDocument);
  440.                     CComBSTR bstrFullName;
  441.                     pGenericDocument->get_FullName(&bstrFullName);
  442.                     if (bstrFullName == szFile)
  443.                     {
  444.                         fFound = TRUE;
  445.                         pDoc = pGenericDocument;
  446.                         hr = S_OK;
  447.                     }
  448.                 }
  449.             }
  450.  
  451.  
  452.         }
  453.     }
  454.  
  455.     return(hr);
  456. }
  457.  
  458. void CWindowsList::Reset()
  459. {
  460.     m_dirList.Reset();
  461. }
  462.  
  463.  
  464.  
  465. HRESULT CWindowsList::MinWin()
  466. {
  467.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  468.     m_spApplication->EnableModeless(VARIANT_FALSE);
  469.     HRESULT hr;
  470.  
  471.     hr = DoMinWin();
  472.     m_spApplication->EnableModeless((VARIANT_BOOL)VARIANT_TRUE);
  473.     return(hr);
  474. }
  475.  
  476. HRESULT CWindowsList::DoMinWin()
  477. {
  478.     // TODO: Replace this with the actual code to execute this command
  479.     //  Use m_spApplication to access the Developer Studio Application object,
  480.     //  and VERIFY_OK to see error strings in DEBUG builds of your add-in
  481.     //  (see stdafx.h)
  482.  
  483.     
  484.  
  485.     CComPtr<IDispatch> pDispWindows;
  486.     CComQIPtr<IWindows, &IID_IWindows> pWindows;
  487.     m_spApplication->get_Windows(&pDispWindows);
  488.     pWindows = pDispWindows;
  489.     pDispWindows = NULL;
  490.  
  491.     CComPtr<IUnknown> pUnk;
  492.     CComQIPtr<IEnumVARIANT, &IID_IEnumVARIANT> pNewEnum;
  493.     if (SUCCEEDED(pWindows->get__NewEnum(&pUnk)) && pUnk != NULL)
  494.     {
  495.         pNewEnum = pUnk;
  496.         VARIANT varWindow;
  497.         CComQIPtr<IGenericWindow, &IID_IGenericWindow> pWindow;
  498.         while (pNewEnum->Next(1, &varWindow, NULL) == S_OK)
  499.         {
  500.             ASSERT (varWindow.vt == VT_DISPATCH);
  501.             pWindow = varWindow.pdispVal;
  502.             //varWindow.pdispVal->Release();
  503.             VariantClear(&varWindow);
  504.             CComBSTR bstrCaption;
  505.             pWindow->get_Caption(&bstrCaption);
  506.             pWindow->put_WindowState(dsWindowStateMinimized);
  507.         }
  508.     }
  509.  
  510.  
  511.     return S_OK;
  512. }
  513.  
  514. HRESULT CWindowsList::DoMinWin(LPCTSTR szDoc)
  515. {
  516.     HRESULT hr = E_FAIL;
  517.     CComPtr<IGenericDocument> pDoc;
  518.     CComPtr<IDispatch> pDispWindow;
  519.     CComQIPtr<IGenericWindow, &IID_IGenericWindow> pWindow;
  520.  
  521.     hr = FindDoc(szDoc, pDoc, FALSE);
  522.     if (pDoc)
  523.     {
  524.         hr = pDoc->get_ActiveWindow(&pDispWindow);
  525.         if (SUCCEEDED(hr) && pDispWindow)
  526.         {
  527.             pWindow = pDispWindow;
  528.             pWindow->put_WindowState(dsWindowStateMinimized);
  529.         }
  530.     }
  531.  
  532.     return(hr);
  533. }
  534.  
  535.  
  536. HRESULT CWindowsList::MakeLimit(IDispatch* pDispWindow)
  537. {
  538.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  539.     m_spApplication->EnableModeless(VARIANT_FALSE);
  540.  
  541.     if (m_fAutoSize)
  542.     {
  543.         m_spApplication->EnableModeless((VARIANT_BOOL)VARIANT_FALSE);
  544.  
  545.         CComPtr<IDispatch> pDispWindowT = pDispWindow;
  546.         CComQIPtr<IGenericWindow, &IID_IGenericWindow> pWindow;
  547.         if (pDispWindowT == NULL)
  548.         {
  549.             m_spApplication->get_ActiveWindow(&pDispWindowT);
  550.         }
  551.         if (pDispWindowT)
  552.         {
  553.             pWindow = pDispWindowT;
  554.             pDispWindowT = NULL;
  555.             CComBSTR bstrCaption;
  556.             pWindow->get_Caption(&bstrCaption);
  557.             pWindow->put_Width(m_lSize);
  558.         }
  559.         m_spApplication->EnableModeless((VARIANT_BOOL)VARIANT_TRUE);
  560.     }
  561.     m_spApplication->EnableModeless((VARIANT_BOOL)VARIANT_TRUE);
  562.     return S_OK;
  563.  
  564. }
  565.  
  566. HRESULT CWindowsList::SetLimit()
  567. {
  568.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  569.     m_spApplication->EnableModeless((VARIANT_BOOL)VARIANT_FALSE);
  570.     CComPtr<IDispatch> pDispWindow;
  571.     CComQIPtr<IGenericWindow, &IID_IGenericWindow> pWindow;
  572.     m_spApplication->get_ActiveWindow(&pDispWindow);
  573.     if (pDispWindow)
  574.     {
  575.         pWindow = pDispWindow;
  576.         pDispWindow = NULL;
  577.         CComBSTR bstrCaption;
  578.         pWindow->get_Caption(&bstrCaption);
  579.         pWindow->get_Width(&m_lSize);
  580.     }
  581.     m_spApplication->EnableModeless((VARIANT_BOOL)VARIANT_TRUE);
  582.     return S_OK;
  583. }
  584.  
  585. STDMETHODIMP CWindowsList::SetVisible()
  586. {
  587.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  588.  
  589.     m_spApplication->EnableModeless(VARIANT_FALSE);
  590.     
  591.     DsWindowState dsState;
  592.     long t, l, w, h;
  593.     CRect rectClient, rectWnd, rectNew, rectT;
  594.     HRESULT hr;
  595.     
  596.     CComPtr<IDispatch> pDispWindow;
  597.     CComQIPtr<IGenericWindow, &IID_IGenericWindow> pWindow;
  598.     m_spApplication->get_ActiveWindow(&pDispWindow);
  599.     if (pDispWindow) // is there an active window?
  600.     {
  601.         pWindow = pDispWindow;
  602.         pDispWindow = NULL;
  603.  
  604.  
  605.         hr = pWindow->get_WindowState(&dsState);
  606.         if (dsState != dsWindowStateMaximized) // if maximized, nothing to do anyway
  607.         {
  608.             // maximize, temporarily the active window
  609.             pWindow->put_WindowState(dsWindowStateMaximized);
  610.             // get size and position  of maximize window
  611.             pWindow->get_Width(&w);
  612.             pWindow->get_Height(&h);
  613.             pWindow->get_Left(&l);
  614.             pWindow->get_Top(&t);
  615.             rectClient.SetRect(l < 0 ? 0 : l,
  616.                 t < 0 ? 0 : t,
  617.                 w - abs(l) - 16, 
  618.                 h - abs(t) - 16);
  619.  
  620.             // reset window to previus state.
  621.             pWindow->put_WindowState(dsState);
  622.  
  623.             // iterate through all windows and make sure that they fit...
  624.             CComPtr<IDispatch> pDispWindows;
  625.             m_spApplication->get_Windows(&pDispWindows);
  626.             if (pDispWindows)
  627.             {
  628.                 CComQIPtr<IWindows, &IID_IWindows> pWindows;
  629.                 pWindows = pDispWindows;
  630.                 pDispWindows = NULL;
  631.  
  632.                 CComPtr<IUnknown> pUnk;
  633.                 CComQIPtr<IEnumVARIANT, &IID_IEnumVARIANT> pNewEnum;
  634.                 if (SUCCEEDED(pWindows->get__NewEnum(&pUnk)) && pUnk != NULL)
  635.                 {
  636.                     pNewEnum = pUnk;
  637.                     VARIANT varGenericWindow;
  638.  
  639.                     while (pNewEnum->Next(1, &varGenericWindow, NULL) == S_OK)
  640.                     {
  641.                         CComQIPtr<IGenericWindow, &IID_IGenericWindow> pGenericWindow;
  642.                         ASSERT (varGenericWindow.vt == VT_DISPATCH);
  643.                         pGenericWindow = varGenericWindow.pdispVal;
  644.                         varGenericWindow.pdispVal->Release();
  645.                         pGenericWindow->get_Width(&w);
  646.                         pGenericWindow->get_Height(&h);
  647.                         pGenericWindow->get_Left(&l);
  648.                         pGenericWindow->get_Top(&t);
  649.                         rectWnd.SetRect(l, t, l+w, t+h);
  650.                         rectNew.IntersectRect(rectWnd, rectClient);
  651.                         if (rectWnd != rectNew)
  652.                         { // this code could be done more efficiently by calculating offsets and doing one Offset and one Deflate, but this makes it more clear.
  653.                             rectNew = rectWnd; // the intersection may be zero -- translate rects
  654.                             // see if a simple translation will work
  655.                             if (h < rectClient.Height() || w < rectClient.Width())
  656.                             {
  657.                                 if (l < rectClient.left) // window is to left -- shift positively
  658.                                     rectNew.OffsetRect(rectClient.left - l, 0);
  659.                                 else if (rectNew.right > rectClient.right) // window is to right -- shift negatively
  660.                                     rectNew.OffsetRect(rectClient.right - rectNew.right, 0);
  661.                                 if (t < rectClient.top) // window is to top -- shift positively
  662.                                     rectNew.OffsetRect(0, rectClient.top - t);
  663.                                 else if (rectNew.bottom > rectClient.bottom) // window is to bottom -- shift negatively
  664.                                     rectNew.OffsetRect(0, rectClient.bottom - rectNew.bottom);
  665.                             }
  666.                             rectT.IntersectRect(rectNew, rectClient);
  667.                             if (rectT != rectWnd)
  668.                             {
  669.                                 pGenericWindow->put_Left(rectT.left);
  670.                                 pGenericWindow->put_Top(rectT.top);
  671.                                 pGenericWindow->put_Width(rectT.Width());
  672.                                 pGenericWindow->put_Height(rectT.Height());
  673.                             }
  674.  
  675.                         }
  676.                     }
  677.                 }
  678.             }
  679.         }
  680.         if (IsInDebugMode())
  681.         {
  682.             CComPtr<IDispatch> pDispDebugger;
  683.             CComQIPtr<IDebugger, &IID_IDebugger> pDebugger;
  684.             m_spApplication->get_Debugger(&pDispDebugger);
  685.             if (pDispDebugger)
  686.             {
  687.                 pDebugger = pDispDebugger;
  688.                 pDebugger->ShowNextStatement();
  689.             }
  690.  
  691.         }
  692.     }
  693.  
  694.     WorkspaceOpen(); // refresh
  695.  
  696.     m_spApplication->EnableModeless((VARIANT_BOOL)VARIANT_TRUE);
  697.  
  698.     return S_OK;
  699. }
  700.  
  701. HRESULT CWindowsList::GetSize(LPCTSTR szFilePath, CRect& rect)
  702. {
  703.     HRESULT hr = E_FAIL;
  704.     CComPtr<IGenericDocument> pDoc = NULL;
  705.     CComQIPtr<IGenericWindow, &IID_IGenericWindow> pGenericWindow;
  706.     CComPtr<IDispatch> pDispWindow;
  707.     long t, l, w, h;
  708.     
  709.     rect.SetRectEmpty();
  710.     hr = FindDoc(szFilePath, pDoc, FALSE);
  711.     if (pDoc && SUCCEEDED(hr))
  712.     {
  713.         hr = pDoc->get_ActiveWindow(&pDispWindow);
  714.         pGenericWindow = pDispWindow;
  715.         pDispWindow = NULL;
  716.         if (pGenericWindow)
  717.         {
  718.             pGenericWindow->get_Width(&w);
  719.             pGenericWindow->get_Height(&h);
  720.             pGenericWindow->get_Left(&l);
  721.             pGenericWindow->get_Top(&t);
  722.             rect.SetRect(l, t, l+w, t+h);
  723.         }
  724.     }
  725.  
  726.     return(hr);
  727.  
  728. }
  729.  
  730. BOOL CWindowsList::IsInDebugMode()
  731. {
  732.     HRESULT hr = E_FAIL;
  733.     BOOL fOK = FALSE;
  734.     DsExecutionState debugstate;
  735.     
  736.     CComPtr<IDispatch> pDispDebugger;
  737.     CComQIPtr<IDebugger, &IID_IDebugger> pDebugger;
  738.     m_spApplication->get_Debugger(&pDispDebugger);
  739.     if (pDispDebugger)
  740.     {
  741.         pDebugger = pDispDebugger;
  742.         hr = pDebugger->get_State(&debugstate);
  743.         if (debugstate != dsNoDebugee)
  744.             fOK = TRUE;
  745.     }
  746.     return(fOK);
  747. }
  748.  
  749. STDMETHODIMP CWindowsList::CloseDebugWnds()
  750. {
  751.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  752.     m_spApplication->EnableModeless(VARIANT_FALSE);
  753.     POSITION p;
  754.     CFileItem *pFileItem;
  755.     CRect rectDbg, rect;
  756.  
  757.     p = m_dirList.GetHeadPosition();
  758.     while (p)
  759.     {
  760.         pFileItem = m_dirList.GetNextPos(p);
  761.         if (pFileItem->FOpenedInDebug())
  762.         {
  763.             CString strPath;
  764.  
  765.             strPath = pFileItem->GetDir();
  766.             strPath += _T('\\');
  767.             strPath += pFileItem->GetFile();
  768.             CloseDoc(strPath);
  769.         }
  770.     }
  771.     m_spApplication->EnableModeless((VARIANT_BOOL)VARIANT_TRUE);
  772.     return S_OK;
  773. }
  774.