msgband.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 11k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. #include "priv.h"
  2. #pragma hdrstop
  3. #ifdef UNIX
  4. #include "sccls.h"
  5. #include "bands.h"
  6. #include "util.h"
  7. #include "resource.h"
  8. #include "inpobj.h"
  9. #include "dhuihand.h"
  10. #include "droptgt.h"
  11. #include "iface.h"
  12. #include "stream.h"
  13. #include "isfband.h"
  14. #include "itbdrop.h"
  15. #include "browband.h"
  16. #include "mluisupp.h"
  17. extern "C"  const GUID  CLSID_MsgBand;
  18. STDAPI_(void) unixGetWininetCacheLockStatus (BOOL *pBoolReadOnly, char **ppszLockingHost);
  19. STDAPI_(void) unixCleanupWininetCacheLockFile();
  20. ////////////////
  21. ///  Msg (BrowserOC) band
  22. #undef SUPERCLASS 
  23. #define SUPERCLASS CBrowserBand
  24. class CMsgBand : public CBrowserBand
  25. {
  26. public:
  27.     // *** IDeskBand methods ***
  28.     virtual STDMETHODIMP GetBandInfo(DWORD dwBandID, DWORD fViewMode, 
  29.                                    DESKBANDINFO* pdbi) ;
  30.     
  31.     // *** IPersistStream methods ***
  32.     // (others use base class implementation) 
  33.     virtual STDMETHODIMP GetClassID(CLSID *pClassID);
  34.     virtual STDMETHODIMP Load(IStream *pStm);
  35.     virtual STDMETHODIMP Save(IStream *pStm, BOOL fClearDirty);
  36.     // *** IOleCommandTarget methods ***
  37.     virtual STDMETHODIMP Exec(const GUID *pguidCmdGroup,
  38.         DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut);
  39.     // *** IDockingWindow methods ***
  40.     virtual STDMETHODIMP ShowDW(BOOL fShow);
  41.     CMsgBand();
  42.     virtual ~CMsgBand();
  43.     virtual void _InitBrowser(void);
  44.     virtual STDMETHODIMP Invoke(DISPID dispidMember,REFIID riid,LCID lcid,WORD wFlags, DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo,UINT * puArgErr);
  45. protected:
  46.     void _OnSearchBtnSelect(int x, int y);
  47.     void _CloseBand();
  48.     BOOL _fStrsAdded;
  49.     long _lStrOffset;
  50. };
  51. CMsgBand::CMsgBand() :
  52.     SUPERCLASS()
  53. {
  54.     // _fBlockSIDProxy = FALSE;
  55.     _fBlockDrop = TRUE;
  56.     return;
  57. }
  58. CMsgBand::~CMsgBand()
  59. {
  60. }
  61. void CMsgBand::_OnSearchBtnSelect(int x, int y)
  62. {
  63.     HMENU        hmenu = CreatePopupMenu();
  64.     
  65.     if (hmenu)
  66.     {
  67.         IContextMenu* pcm;
  68.         if (SUCCEEDED(IUnknown_QueryService(_punkSite, SID_SExplorerToolbar, IID_IContextMenu2, (void**)&pcm)))
  69.         {
  70.             HWND  hwnd;
  71.             
  72.             if (SUCCEEDED(IUnknown_GetWindow(pcm, &hwnd)))
  73.             {
  74.                 int   idCmd;
  75.                 
  76.                 pcm->QueryContextMenu(hmenu, 0, FCIDM_SEARCHFIRST, FCIDM_SEARCHLAST, 0);
  77.             
  78.                 idCmd = TrackPopupMenu(hmenu, TPM_RETURNCMD, x, y, 0, hwnd, NULL);
  79.                 
  80.                 if (idCmd != 0)
  81.                 {
  82.                     CMINVOKECOMMANDINFO ici = {0};
  83.     
  84.                     ici.cbSize = SIZEOF(ici);
  85.                     ici.hwnd = _hwnd;
  86.                     ici.lpVerb = (LPSTR)MAKEINTRESOURCE(idCmd - FCIDM_SEARCHFIRST);
  87.                     ici.nShow  = SW_NORMAL;
  88.                     pcm->InvokeCommand(&ici);
  89.                 }
  90.             }
  91.             pcm->Release();
  92.         }
  93.         DestroyMenu(hmenu);
  94.     }
  95. }
  96. HRESULT CMsgBand::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut)
  97. {
  98.     switch (nCmdID)
  99.     {
  100.     case TBIDM_SEARCH:
  101.          if (EVAL(pvarargIn && (pvarargIn->vt == VT_I4)))
  102.              _OnSearchBtnSelect(LOWORD(pvarargIn->lVal), HIWORD(pvarargIn->lVal));
  103.          return S_OK;
  104.     }
  105.     return CBrowserBand::Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvarargIn, pvarargOut);
  106. }
  107. void CMsgBand::_CloseBand()
  108. {
  109.     // Excute SBCMDID_MSGBAND command on the site.
  110.     IUnknown_Exec(_punkSite, &CGID_Explorer, SBCMDID_MSGBAND, FALSE, NULL, NULL);
  111. }
  112. HRESULT CMsgBand::ShowDW(BOOL fShow)
  113. {
  114.     HRESULT hres = CBrowserBand::ShowDW(fShow);
  115.     return hres;
  116. }
  117. /////////////////////////////////////////////////////////////////////////////
  118. // IDispatch::Invoke
  119. /////////////////////////////////////////////////////////////////////////////
  120. HRESULT CMsgBand::Invoke
  121. (
  122.     DISPID          dispidMember,
  123.     REFIID          riid,
  124.     LCID            lcid,
  125.     WORD            wFlags,
  126.     DISPPARAMS *    pdispparams,
  127.     VARIANT *       pvarResult,
  128.     EXCEPINFO *     pexcepinfo,
  129.     UINT *          puArgErr
  130. )
  131. {
  132.     HRESULT hr = S_OK;
  133.     ASSERT(pdispparams);
  134.     if(!pdispparams)
  135.         return E_INVALIDARG;
  136.     //
  137.     // Big HACK!  Do this right after RTW.  Basically, I didn't have time to
  138.     // implement new DISPIDs and connect them up to the MsgBand class correctly.
  139.     // Instead, I overload the title name to be a function call.  The problem
  140.     // with this scheme is that the title is updated all the time so you can
  141.     // only call each function once realiably (of course, for us that's fine :)
  142.     // davidd
  143.     //
  144.     switch (dispidMember)
  145.     {
  146.     case DISPID_TITLECHANGE:
  147.     {
  148.         int iArg = pdispparams->cArgs -1;
  149.         if (iArg == 0 && (pdispparams->rgvarg[iArg].vt == VT_BSTR)) 
  150.         {
  151.             static BOOL s_fLockDeleted = FALSE;
  152.             BSTR pArg = pdispparams->rgvarg[iArg].bstrVal;
  153.             if ( !s_fLockDeleted &&
  154.                  StrCmpW( pArg, L"close" ) == 0 )
  155.             {
  156.                 s_fLockDeleted = TRUE;
  157.                 _CloseBand();
  158.             }
  159.             if ( !s_fLockDeleted &&
  160.                  StrCmpW( pArg, L"deleteLock" ) == 0 )
  161.             {
  162.                 s_fLockDeleted = TRUE;
  163.                 unixCleanupWininetCacheLockFile();
  164.                 _CloseBand();
  165.             }
  166.             if ( !s_fLockDeleted &&
  167.                  StrCmpW( pArg, L"deleteLockAndShutdown" ) == 0 )
  168.             {
  169.                 IOleCommandTarget *poct;
  170.                 s_fLockDeleted = TRUE;
  171.                 unixCleanupWininetCacheLockFile();
  172.                 // Initiate shutdown
  173.                 PostMessage( GetActiveWindow(), WM_QUIT, 10, 0 );
  174.             }
  175.             if ( StrCmpW( pArg, L"Loaded" ) == 0) {
  176.                 //
  177.                 // Change all elements of ID "lockedMachine" to the actual
  178.                 // machine name.
  179.                 //
  180.                 static IHTMLElementCollection *s_pIElementCollection = NULL;
  181.                 IDispatch *pIDispatch;
  182.                 IHTMLDocument2 *pIDocument;
  183.                 IHTMLElement *pIElement;
  184.                 CHAR *pszLockingHostAnsi;
  185.                 HRESULT hr;
  186.                 BSTR bstr;
  187.                 SA_BSTR strLockingHost;
  188.                 unixGetWininetCacheLockStatus( NULL, &pszLockingHostAnsi );
  189.                 if ( NULL == pszLockingHostAnsi ) 
  190.                     break;
  191.                 SHAnsiToUnicode( pszLockingHostAnsi, strLockingHost.wsz, ARRAYSIZE(strLockingHost.wsz));
  192.                 strLockingHost.cb = lstrlenW(strLockingHost.wsz) * SIZEOF(WCHAR);
  193.                 if ( !s_pIElementCollection ) {
  194.                     if ( !_pauto )
  195.                         break;
  196.                     hr = _pauto->get_Document( &pIDispatch );
  197.                     // IEUNIX
  198.                     // WebOC returns hr = S_OK and also sets pIDispatch to NULL
  199.                     if ( !SUCCEEDED( hr ) || !pIDispatch) 
  200.                         break;
  201.                     hr = pIDispatch->QueryInterface( IID_IHTMLDocument2, (void**)&pIDocument );
  202.                     pIDispatch->Release();
  203.                     if ( !SUCCEEDED( hr ))
  204.                         break;
  205.                     hr = pIDocument->get_all( &s_pIElementCollection );
  206.                     pIDocument->Release();
  207.                     if ( !SUCCEEDED( hr )) {
  208.                         s_pIElementCollection = NULL;
  209.                         break;
  210.                     }
  211.                 }
  212.                 bstr = SysAllocString(L"lockedMachine");
  213.                 if (bstr)
  214.                 {
  215.                     VARIANT va;
  216.                     VARIANT vaIndex;
  217.                     va.vt = VT_BSTR;
  218.                     va.bstrVal = bstr;
  219.                     vaIndex.vt = VT_I4;
  220.                     vaIndex.intVal = 0;
  221.                     do {
  222.                         hr = s_pIElementCollection->item( va, vaIndex, &pIDispatch );
  223.                         if ( !SUCCEEDED( hr ) || !pIDispatch)
  224.                             break;
  225.                         hr = pIDispatch->QueryInterface( IID_IHTMLElement, (void**) &pIElement );
  226.                         pIDispatch->Release();
  227.                         if ( !SUCCEEDED( hr ))
  228.                             break;
  229.                         pIElement->put_innerText( strLockingHost.wsz );
  230.                         pIElement->Release();
  231.                         vaIndex.intVal++;
  232.                     } while ( TRUE );
  233.                     SysFreeString( bstr );
  234.                 }
  235.                 break;
  236.             }
  237.         }
  238.         break;
  239.     }
  240.     default:
  241.         SUPERCLASS::Invoke( dispidMember, riid, lcid, wFlags, pdispparams,
  242.                             pvarResult, pexcepinfo, puArgErr );
  243.     }
  244.     return hr;
  245. }
  246. STDAPI CMsgBand_CreateInstance(IUnknown *punkOuter, IUnknown **ppunk, LPCOBJECTINFO poi)
  247. {
  248.     // aggregation checking is handled in class factory
  249.     TCHAR szResURL[MAX_URL_STRING];
  250.     LPITEMIDLIST pidlNew;
  251.     HRESULT hr;
  252.     *ppunk = NULL;
  253.     hr = MLBuildResURLWrap(TEXT("shdoclc.dll"),
  254.                            HINST_THISDLL,
  255.                            ML_CROSSCODEPAGE,
  256.                            TEXT("cachewrn.htm"),
  257.                            szResURL,
  258.                            ARRAYSIZE(szResURL),
  259.                            TEXT("shdocvw.dll"));
  260.     if (SUCCEEDED(hr))
  261.     {
  262.         hr = IECreateFromPath(szResURL, &pidlNew);
  263.         if (SUCCEEDED(hr))
  264.         {
  265.             CMsgBand *p = new CMsgBand();
  266.             if (p)
  267.             {
  268.                 p->_pidl = pidlNew;
  269.                 *ppunk = SAFECAST(p, IDeskBand*);
  270.                 hr = NOERROR;
  271.             }
  272.             else
  273.             {
  274.                 ILFree(pidlNew);
  275.                 hr = E_OUTOFMEMORY;
  276.             }
  277.         }
  278.     }
  279.     return hr;
  280. }
  281. void CMsgBand::_InitBrowser(void)
  282. {
  283.     SUPERCLASS::_InitBrowser();
  284.     _pauto->put_Silent(VARIANT_FALSE);
  285. }
  286. HRESULT CMsgBand::GetBandInfo(DWORD dwBandID, DWORD fViewMode, 
  287.                                 DESKBANDINFO* pdbi) 
  288. {
  289.     _dwBandID = dwBandID;
  290.     pdbi->dwModeFlags = DBIMF_FIXEDBMP;
  291.     
  292.     pdbi->ptMinSize.x = 16;
  293.     pdbi->ptMinSize.y = 0;
  294.     pdbi->ptMaxSize.x = 32000; // random
  295.     pdbi->ptMaxSize.y = 32000; // random
  296.     pdbi->ptActual.y = -1;
  297.     pdbi->ptActual.x = -1;
  298.     pdbi->ptIntegral.y = 1;
  299.     pdbi->dwModeFlags |= DBIMF_VARIABLEHEIGHT;
  300.     MLLoadStringW(IDS_BAND_MESSAGE, pdbi->wszTitle, ARRAYSIZE(pdbi->wszTitle));
  301.     
  302.     return S_OK;
  303. //***   CMsgBand::IPersistStream::* {
  304.         extern "C"  const GUID     CLSID_MsgBand  ;
  305. HRESULT CMsgBand::GetClassID(CLSID *pClassID)
  306. {
  307.     *pClassID = CLSID_MsgBand;
  308.     return S_OK;
  309. }
  310. HRESULT CMsgBand::Load(IStream *pstm)
  311. {
  312.     _NavigateOC();
  313.     
  314.     return S_OK;
  315. }
  316. HRESULT CMsgBand::Save(IStream *pstm, BOOL fClearDirty)
  317. {
  318.     return S_OK;
  319. }
  320. // }
  321. IDeskBand* CMsgBand_Create()
  322. {
  323.     HRESULT hr;
  324.     IUnknown *punk;
  325.     IDeskBand* pistb = NULL;
  326.     hr = CMsgBand_CreateInstance(NULL, &punk, NULL);
  327.     if (SUCCEEDED(hr))
  328.     {
  329.         EVAL(punk->QueryInterface(IID_IDeskBand,(LPVOID *)&pistb));
  330.         // if we succeeded, release the 2nd refcnt and return non-NULL;
  331.         // if we failed   , release the 1st refcnt and return NULL
  332.         punk->Release();
  333.     }
  334.     return pistb;
  335. }
  336. // }
  337. // 
  338. #endif // UNIX