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

Windows Kernel

Development Platform:

Visual C++

  1. #include "shellprv.h"
  2. #include <shellp.h>
  3. #include <sfview.h>
  4. #include "sfviewp.h"
  5. //
  6. //  punkFolder is an object that ultimately supports IShellFolder.
  7. //
  8. CBaseShellFolderViewCB::CBaseShellFolderViewCB(IUnknown* punkFolder, LPCITEMIDLIST pidl, LONG lEvents)
  9.     : m_cRef(1), m_hwndMain(NULL), m_lEvents(lEvents)
  10. {
  11.     // Use QueryInterface instead of IUnknown_Set for two reasons.
  12.     //
  13.     // 1. Helps us track leaks with QISTUB.
  14.     // 2. To make sure we really have an IShellFolder.
  15.     //
  16.     EVAL(SUCCEEDED(punkFolder->QueryInterface(IID_IShellFolder, (LPVOID*)&m_pshf)));
  17.     m_pidl = pidl ? ILClone(pidl) : NULL;   // Bitbuck1.cpp passes NULL!
  18. }
  19. CBaseShellFolderViewCB::~CBaseShellFolderViewCB()
  20. {
  21.     if (m_pshf)
  22.         m_pshf->Release();
  23.     if (m_pidl)
  24.         ILFree((LPITEMIDLIST)m_pidl);
  25. }
  26. STDMETHODIMP CBaseShellFolderViewCB::QueryInterface(REFIID riid, void **ppv)
  27. {
  28.     static const QITAB qit[] = {
  29.         QITABENT(CBaseShellFolderViewCB, IShellFolderViewCB),   // IID_IShellFolderViewCB
  30.         QITABENT(CBaseShellFolderViewCB, IObjectWithSite),      // IID_IObjectWithSite
  31.         { 0 },
  32.     };
  33.     return QISearch(this, qit, riid, ppv);
  34. }
  35. STDMETHODIMP_(ULONG) CBaseShellFolderViewCB::AddRef()
  36. {
  37.     return InterlockedIncrement(&m_cRef);
  38. }
  39. STDMETHODIMP_(ULONG) CBaseShellFolderViewCB::Release()
  40. {
  41.     if (InterlockedDecrement(&m_cRef))
  42.         return m_cRef;
  43.     delete this;
  44.     return 0;
  45. }
  46. STDMETHODIMP CBaseShellFolderViewCB::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam)
  47. {
  48.     HRESULT hres = RealMessage(uMsg, wParam, lParam);
  49.     if (SUCCEEDED(hres))
  50.         return hres;
  51.     switch (uMsg)
  52.     {
  53.     case SFVM_HWNDMAIN:
  54.         m_hwndMain = (HWND)lParam;
  55.         break;
  56.     case SFVM_GETNOTIFY:
  57.         *(LPCITEMIDLIST*)wParam = m_pidl;
  58.         *(LONG*)lParam = m_lEvents;
  59.         break;
  60.     default:
  61.         return hres;
  62.     }
  63.     return NOERROR;
  64. }
  65. class CWrapOldCallback : public CBaseShellFolderViewCB
  66. {
  67. public:
  68.     CWrapOldCallback(LPCSFV pcsfv);
  69.     STDMETHODIMP RealMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
  70.     //*** IObjectWithSite overload ***
  71.     virtual STDMETHODIMP SetSite(IUnknown *punkSite);
  72. private:
  73. //#define TEST_MACROS
  74. #ifdef TEST_MACROS
  75.     STDMETHODIMP TestMacros(UINT uMsg, WPARAM wParam, LPARAM lParam);
  76.     HRESULT TestMergeMenu(DWORD pv, QCMINFO*lP) {OutputDebugString(TEXT("TestMergeMenurn"));return(NOERROR);}
  77.     HRESULT TestInvokeCommand(DWORD pv, UINT wP) {OutputDebugString(TEXT("TestInvokeCommandrn"));return(E_NOTIMPL);}
  78.     HRESULT TestGetHelpText(DWORD pv, UINT wPl, UINT wPh, LPTSTR lP) {OutputDebugString(TEXT("TestGetHelpTextrn"));return(E_NOTIMPL);}
  79.     HRESULT TestGetTooltipText(DWORD pv, UINT wPl, UINT wPh, LPTSTR lP) {OutputDebugString(TEXT("TestGetTooltipTextrn"));return(E_NOTIMPL);}
  80.     HRESULT TestGetButtonInfo(DWORD pv, TBINFO*lP) {OutputDebugString(TEXT("TestGetButtonInforn"));return(E_NOTIMPL);}
  81.     HRESULT TestGetButtons(DWORD pv, UINT wPl, UINT wPh, TBBUTTON*lP) {OutputDebugString(TEXT("TestGetButtonsrn"));return(E_NOTIMPL);}
  82.     HRESULT TestInitMenuPopup(DWORD pv, UINT wPl, UINT wPh, HMENU lP) {OutputDebugString(TEXT("TestInitMenuPopuprn"));return(E_NOTIMPL);}
  83.     HRESULT TestSelChange(DWORD pv, UINT wPl, UINT wPh, SFVM_SELCHANGE_DATA*lP) {OutputDebugString(TEXT("TestSelChangern"));return(E_NOTIMPL);}
  84.     HRESULT TestDrawItem(DWORD pv, UINT wP, DRAWITEMSTRUCT*lP) {OutputDebugString(TEXT("TestDrawItemrn"));return(E_NOTIMPL);}
  85.     HRESULT TestMeasureItem(DWORD pv, UINT wP, MEASUREITEMSTRUCT*lP) {OutputDebugString(TEXT("TestMeasureItemrn"));return(E_NOTIMPL);}
  86.     HRESULT TestExitMenuLoop(DWORD pv) {OutputDebugString(TEXT("TestExitMenuLooprn"));return(E_NOTIMPL);}
  87.     HRESULT TestPreRelease(DWORD pv) {OutputDebugString(TEXT("TestPreReleasern"));return(E_NOTIMPL);}
  88.     HRESULT TestGetCCHMax(DWORD pv, LPCITEMIDLIST wP, UINT*lP) {OutputDebugString(TEXT("TestGetCCHMaxrn"));return(E_NOTIMPL);}
  89.     HRESULT TestFSNotify(DWORD pv, LPCITEMIDLIST*wP, LONG lP) {OutputDebugString(TEXT("TestFSNotifyrn"));return(E_NOTIMPL);}
  90.     HRESULT TestWindowCreated(DWORD pv, HWND wP) {OutputDebugString(TEXT("TestWindowCreatedrn"));return(E_NOTIMPL);}
  91.     HRESULT TestWindowDestroy(DWORD pv, HWND wP) {OutputDebugString(TEXT("TestWindowDestroyrn"));return(E_NOTIMPL);}
  92.     HRESULT TestRefresh(DWORD pv, BOOL wP) {OutputDebugString(TEXT("TestRefreshrn"));return(E_NOTIMPL);}
  93.     HRESULT TestSetFocus(DWORD pv) {OutputDebugString(TEXT("TestSetFocusrn"));return(E_NOTIMPL);}
  94.     HRESULT TestQueryCopyHook(DWORD pv) {OutputDebugString(TEXT("TestQueryCopyHookrn"));return(E_NOTIMPL);}
  95.     HRESULT TestNotifyCopyHook(DWORD pv, COPYHOOKINFO*lP) {OutputDebugString(TEXT("TestNotifyCopyHookrn"));return(E_NOTIMPL);}
  96.     HRESULT TestGetDetailsOf(DWORD pv, UINT wP, DETAILSINFO*lP) {OutputDebugString(TEXT("TestGetDetailsOfrn"));return(E_NOTIMPL);}
  97.     HRESULT TestColumnClick(DWORD pv, UINT wP) {OutputDebugString(TEXT("TestColumnClickrn"));return(E_NOTIMPL);}
  98.     HRESULT TestQueryFSNotify(DWORD pv, SHChangeNotifyEntry*lP) {OutputDebugString(TEXT("TestQueryFSNotifyrn"));return(E_NOTIMPL);}
  99.     HRESULT TestDefItemCount(DWORD pv, UINT*lP) {OutputDebugString(TEXT("TestDefItemCountrn"));return(E_NOTIMPL);}
  100.     HRESULT TestDefViewMode(DWORD pv, FOLDERVIEWMODE*lP) {OutputDebugString(TEXT("TestDefViewModern"));return(E_NOTIMPL);}
  101.     HRESULT TestUnMergeMenu(DWORD pv, HMENU lP) {OutputDebugString(TEXT("TestUnMergeMenurn"));return(E_NOTIMPL);}
  102.     HRESULT TestInsertItem(DWORD pv, LPCITEMIDLIST wP) {OutputDebugString(TEXT("TestInsertItemrn"));return(E_NOTIMPL);}
  103.     HRESULT TestDeleteItem(DWORD pv, LPCITEMIDLIST wP) {OutputDebugString(TEXT("TestDeleteItemrn"));return(E_NOTIMPL);}
  104.     HRESULT TestUpdateStatusBar(DWORD pv, BOOL wP) {OutputDebugString(TEXT("TestUpdateStatusBarrn"));return(E_NOTIMPL);}
  105.     HRESULT TestBackgroundEnum(DWORD pv) {OutputDebugString(TEXT("TestBackgroundEnumrn"));return(E_NOTIMPL);}
  106.     HRESULT TestGetWorkingDir(DWORD pv, UINT wP, LPTSTR lP) {OutputDebugString(TEXT("TestGetWorkingDirrn"));return(E_NOTIMPL);}
  107.     HRESULT TestGetColSaveStream(DWORD pv, WPARAM wP, IStream**lP) {OutputDebugString(TEXT("TestGetColSaveStreamrn"));return(E_NOTIMPL);}
  108.     HRESULT TestSelectAll(DWORD pv) {OutputDebugString(TEXT("TestSelectAllrn"));return(E_NOTIMPL);}
  109.     HRESULT TestDidDragDrop(DWORD pv, DWORD wP, IDataObject*lP) {OutputDebugString(TEXT("TestDidDragDroprn"));return(E_NOTIMPL);}
  110.     HRESULT TestHwndMain(DWORD pv, HWND lP) {OutputDebugString(TEXT("TestHwndMainrn"));return(E_NOTIMPL);}
  111.     HRESULT TestGetNotify(DWORD pv, LPITEMIDLIST*wP, LONG*lP) {OutputDebugString(TEXT("TestGetNotifyrn"));return(E_NOTIMPL);}
  112.     HRESULT TestSetISFV(DWORD pv, IShellFolderView*lP) {OutputDebugString(TEXT("TestSetISFVrn"));return(E_NOTIMPL);}
  113.     HRESULT TestGetViews(DWORD pv, SHELLVIEWID *pvid, IEnumSFVViews**lP) {OutputDebugString(TEXT("TestGetViewsrn"));return(E_NOTIMPL);}
  114.     HRESULT TestTHISIDLIST(DWORD pv, LPITEMIDLIST*lP) {OutputDebugString(TEXT("TestTHISIDLISTrn"));return(E_NOTIMPL);}
  115.     HRESULT TestGetItemIDList(DWORD pv, UINT iItem, LPITEMIDLIST *ppidl) {OutputDebugString(TEXT("TestGetItemIDListrn"));return(E_NOTIMPL);}
  116.     HRESULT TestSetItemIDList(DWORD pv, UINT iItem, LPITEMIDLIST pidl) {OutputDebugString(TEXT("TestSetItemIDListrn"));return(E_NOTIMPL);}
  117.     HRESULT TestIndexOfItemIDList(DWORD pv, int * piItem, LPITEMIDLIST pidl) {OutputDebugString(TEXT("TestIndexOfItemIDListrn"));return(E_NOTIMPL);}
  118.     HRESULT TestODFindItem(DWORD pv, int * piItem, NM_FINDITEM* pnmfi) {OutputDebugString(TEXT("TestODFindItemrn"));return(E_NOTIMPL);}
  119.     HRESULT TestAddPropertyPages(DWORD pv, SFVM_PROPPAGE_DATA *ppagedata) {OutputDebugString(TEXT("TestAddPropertyPagesrn"));return(E_NOTIMPL);}
  120.     HRESULT TestArrange(DWORD v, LPARAM lp) {OutputDebugString(TEXT("TestArrangern"));return(E_NOTIMPL);}
  121.     HRESULT TestQueryStandardViews(DWORD pv, BOOL *pfAllowStandardViews) {OutputDebugString(TEXT("TestQueryStandardViewsrn"));return(E_NOTIMPL);}
  122.     HRESULT TestQueryReuseExtView(DWORD pv, BOOL *pfReuseAllowed) {OutputDebugString(TEXT("TestQueryReuseExtViewrn"));return(E_NOTIMPL);}
  123.     HRESULT TestGetEmptyText(DWORD pv, UINT u, LPTSTR psz) {OutputDebugString(TEXT("TestGetEmptyTextrn"));return(E_NOTIMPL);}
  124.     HRESULT TestGetItemIconIndex(DWORD pv, UINT iItem, int *piIcon) {OutputDebugString(TEXT("TestGetItemIconIndexrn"));return(E_NOTIMPL);}
  125.     HRESULT TestSize(DWORD pv, UINT cx, UINT cy) {OutputDebugString(TEXT("TestSizern"));return(E_NOTIMPL);}
  126.     HRESULT TestGetZone(DWORD pv, DWORD *pdwZone) {OutputDebugString(TEXT("TestGetZonern"));return(E_NOTIMPL);}
  127.     HRESULT TestGetPane(DWORD pv, DWORD dwPaneID, DWORD *pdwPane) {OutputDebugString(TEXT("TestGetPanern"));return(E_NOTIMPL);}
  128.     HRESULT TestSupportsIdentity(DWORD pv){OutputDebugString(TEXT("TestSupportsIdentityrn"));return(E_NOTIMPL);}
  129. #endif // TEST_MACROS
  130. private:
  131.     IShellView* m_psvOuter;
  132.     LPFNVIEWCALLBACK m_pfnCB;
  133.     UINT m_fvm;
  134.     LPARAM m_lSelChangeInfo;
  135. } ;
  136. CWrapOldCallback::CWrapOldCallback(LPCSFV pcsfv)
  137.     : CBaseShellFolderViewCB(pcsfv->pshf, pcsfv->pidl, pcsfv->lEvents)
  138. {
  139.     m_psvOuter  = pcsfv->psvOuter;
  140.     m_fvm = pcsfv->fvm;
  141.     m_pfnCB = pcsfv->pfnCallback;
  142. }
  143. // Some older clients may not support IObjectWithSite::SetSite
  144. // For compat send them the old SFVM_SETISFV message
  145. HRESULT CWrapOldCallback::SetSite(IUnknown *punkSite)
  146. {
  147.     HRESULT hr = CBaseShellFolderViewCB::SetSite( punkSite );
  148.     MessageSFVCB( SFVM_SETISFV, 0, (LPARAM)punkSite );
  149.     return hr;
  150. }
  151. #ifdef TEST_MACROS
  152. STDMETHODIMP CWrapOldCallback::TestMacros(UINT uMsg, WPARAM wParam, LPARAM lParam)
  153. {
  154.     switch (uMsg)
  155.     {
  156.     HANDLE_MSG(0, SFVM_MERGEMENU, TestMergeMenu);
  157.     HANDLE_MSG(0, SFVM_INVOKECOMMAND, TestInvokeCommand);
  158.     HANDLE_MSG(0, SFVM_GETHELPTEXT, TestGetHelpText);
  159.     HANDLE_MSG(0, SFVM_GETTOOLTIPTEXT, TestGetTooltipText);
  160.     HANDLE_MSG(0, SFVM_GETBUTTONINFO, TestGetButtonInfo);
  161.     HANDLE_MSG(0, SFVM_GETBUTTONS, TestGetButtons);
  162.     HANDLE_MSG(0, SFVM_INITMENUPOPUP, TestInitMenuPopup);
  163.     HANDLE_MSG(0, SFVM_SELCHANGE, TestSelChange);
  164.     HANDLE_MSG(0, SFVM_DRAWITEM, TestDrawItem);
  165.     HANDLE_MSG(0, SFVM_MEASUREITEM, TestMeasureItem);
  166.     HANDLE_MSG(0, SFVM_EXITMENULOOP, TestExitMenuLoop);
  167.     HANDLE_MSG(0, SFVM_PRERELEASE, TestPreRelease);
  168.     HANDLE_MSG(0, SFVM_GETCCHMAX, TestGetCCHMax);
  169.     HANDLE_MSG(0, SFVM_FSNOTIFY, TestFSNotify);
  170.     HANDLE_MSG(0, SFVM_WINDOWCREATED, TestWindowCreated);
  171.     HANDLE_MSG(0, SFVM_WINDOWDESTROY, TestWindowDestroy);
  172.     HANDLE_MSG(0, SFVM_REFRESH, TestRefresh);
  173.     HANDLE_MSG(0, SFVM_SETFOCUS, TestSetFocus);
  174.     HANDLE_MSG(0, SFVM_QUERYCOPYHOOK, TestQueryCopyHook);
  175.     HANDLE_MSG(0, SFVM_NOTIFYCOPYHOOK, TestNotifyCopyHook);
  176.     HANDLE_MSG(0, SFVM_GETDETAILSOF, TestGetDetailsOf);
  177.     HANDLE_MSG(0, SFVM_COLUMNCLICK, TestColumnClick);
  178.     HANDLE_MSG(0, SFVM_QUERYFSNOTIFY, TestQueryFSNotify);
  179.     HANDLE_MSG(0, SFVM_DEFITEMCOUNT, TestDefItemCount);
  180.     HANDLE_MSG(0, SFVM_DEFVIEWMODE, TestDefViewMode);
  181.     HANDLE_MSG(0, SFVM_UNMERGEMENU, TestUnMergeMenu);
  182.     HANDLE_MSG(0, SFVM_INSERTITEM, TestInsertItem);
  183.     HANDLE_MSG(0, SFVM_DELETEITEM, TestDeleteItem);
  184.     HANDLE_MSG(0, SFVM_UPDATESTATUSBAR, TestUpdateStatusBar);
  185.     HANDLE_MSG(0, SFVM_BACKGROUNDENUM, TestBackgroundEnum);
  186.     HANDLE_MSG(0, SFVM_GETWORKINGDIR, TestGetWorkingDir);
  187.     HANDLE_MSG(0, SFVM_GETCOLSAVESTREAM, TestGetColSaveStream);
  188.     HANDLE_MSG(0, SFVM_SELECTALL, TestSelectAll);
  189.     HANDLE_MSG(0, SFVM_DIDDRAGDROP, TestDidDragDrop);
  190.     HANDLE_MSG(0, SFVM_HWNDMAIN, TestHwndMain);
  191.     HANDLE_MSG(0, SFVM_GETNOTIFY, TestGetNotify);
  192.     HANDLE_MSG(0, SFVM_SETISFV, TestSetISFV);
  193.     HANDLE_MSG(0, SFVM_GETVIEWS, TestGetViews);
  194.     HANDLE_MSG(0, SFVM_THISIDLIST, TestTHISIDLIST);
  195.     HANDLE_MSG(0, SFVM_GETITEMIDLIST, TestGetItemIDList);
  196.     HANDLE_MSG(0, SFVM_SETITEMIDLIST, TestSetItemIDList);
  197.     HANDLE_MSG(0, SFVM_INDEXOFITEMIDLIST, TestIndexOfItemIDList);
  198.     HANDLE_MSG(0, SFVM_SUPPORTSIDENTITY, TestSupportsIdentity);
  199.     HANDLE_MSG(0, SFVM_ODFINDITEM, TestODFindItem);
  200.     HANDLE_MSG(0, SFVM_ADDPROPERTYPAGES, TestAddPropertyPages);
  201.     HANDLE_MSG(0, SFVM_ARRANGE, TestArrange);
  202.     HANDLE_MSG(0, SFVM_QUERYSTANDARDVIEWS, TestQueryStandardViews);
  203.     HANDLE_MSG(0, SFVM_QUERYREUSEEXTVIEW, TestQueryReuseExtView);
  204.     HANDLE_MSG(0, SFVM_GETEMPTYTEXT, TestGetEmptyText);
  205.     HANDLE_MSG(0, SFVM_GETITEMICONINDEX, TestGetItemIconIndex);
  206.     HANDLE_MSG(0, SFVM_SIZE, TestSize);
  207.     HANDLE_MSG(0, SFVM_GETZONE, TestGetZone);
  208.     HANDLE_MSG(0, SFVM_GETPANE, TestGetPane);
  209.     }
  210.     return E_NOTIMPL;
  211. }
  212. #endif // TEST_MACROS
  213. STDMETHODIMP CWrapOldCallback::RealMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
  214. {
  215.     DVSELCHANGEINFO dvsci;
  216. #ifdef TEST_MACROS
  217.     TestMacros(uMsg, wParam, lParam);
  218. #endif // TEST_MACROS
  219.     switch (uMsg)
  220.     {
  221.     case SFVM_DEFVIEWMODE:
  222.         if (m_fvm)
  223.             *(UINT*)lParam = m_fvm;
  224.         break;
  225.     case SFVM_SELCHANGE:
  226.     {
  227.         SFVM_SELCHANGE_DATA* pSelChange = (SFVM_SELCHANGE_DATA*)lParam;
  228.         dvsci.uNewState = pSelChange->uNewState;
  229.         dvsci.uOldState = pSelChange->uOldState;
  230.         dvsci.plParam = &m_lSelChangeInfo;
  231.         dvsci.lParamItem = pSelChange->lParamItem;
  232.         lParam = (LPARAM)&dvsci;
  233.         break;
  234.     }
  235.     case SFVM_INSERTITEM:
  236.     case SFVM_DELETEITEM:
  237.     case SFVM_WINDOWCREATED:
  238.         dvsci.plParam = &m_lSelChangeInfo;
  239.         dvsci.lParamItem = lParam;
  240.         lParam = (LPARAM)&dvsci;
  241.         break;
  242.     case SFVM_REFRESH:
  243.     case SFVM_SELECTALL:
  244.     case SFVM_UPDATESTATUSBAR:
  245.     case SFVM_SETFOCUS:
  246.     case SFVM_PRERELEASE:
  247.         lParam = m_lSelChangeInfo;
  248.         break;
  249.     default:
  250.         break;
  251.     }
  252.     // NOTE: The DVM_ messages are the same as the SFVM_ message
  253.     return m_pfnCB(m_psvOuter, m_pshf, m_hwndMain, uMsg, wParam, lParam);
  254. }
  255. LRESULT _ShellFolderViewMessage(IShellFolderView* psfv, UINT uMsg, LPARAM lParam)
  256. {
  257.     UINT uScratch;
  258.     switch (uMsg)
  259.     {
  260.     case SFVM_REARRANGE:
  261.         psfv->Rearrange(lParam);
  262.         break;
  263.     case SFVM_ARRANGEGRID:
  264.         psfv->ArrangeGrid();
  265.         break;
  266.     case SFVM_AUTOARRANGE:
  267.         psfv->AutoArrange();
  268.         break;
  269.     case SFVM_GETAUTOARRANGE:
  270.         return psfv->GetAutoArrange() == S_OK;
  271.     // BUGBUG: not used?
  272.     case SFVM_GETARRANGEPARAM:
  273.         psfv->GetArrangeParam(&lParam);
  274.         return lParam;
  275.     case SFVM_ADDOBJECT:
  276.         if (SUCCEEDED(psfv->AddObject((LPITEMIDLIST)lParam, &uScratch))
  277.              && (int)uScratch >= 0)
  278.         {
  279.             // New semantics make a copy of the IDList
  280.             ILFree((LPITEMIDLIST)lParam);
  281.             return uScratch;
  282.         }
  283.         return -1;
  284.     case SFVM_GETOBJECTCOUNT:
  285.         return SUCCEEDED(psfv->GetObjectCount(&uScratch)) ? uScratch : -1;
  286.     case SFVM_GETOBJECT:
  287.     {
  288.         LPITEMIDLIST pidl;
  289.         return SUCCEEDED(psfv->GetObject(&pidl, (UINT)lParam)) ? (LPARAM)pidl : NULL;
  290.     }
  291.     case SFVM_REMOVEOBJECT:
  292.         return SUCCEEDED(psfv->RemoveObject((LPITEMIDLIST)lParam, &uScratch)) ? uScratch : -1;
  293.     case SFVM_UPDATEOBJECT:
  294.     {
  295.         LPITEMIDLIST *ppidl = (LPITEMIDLIST*)lParam;
  296.         if (SUCCEEDED(psfv->UpdateObject(ppidl[0], ppidl[1], &uScratch))
  297.             && (int)uScratch >= 0)
  298.         {
  299.             // New semantics make a copy of the IDList
  300.             ILFree(ppidl[1]);
  301.             return uScratch;
  302.         }
  303.         return -1;
  304.     }
  305.     case SFVM_REFRESHOBJECT:
  306.     {
  307.         LPITEMIDLIST *ppidl = (LPITEMIDLIST*)lParam;
  308.         return SUCCEEDED(psfv->RefreshObject(ppidl[0], &uScratch)) ? uScratch : -1;
  309.     }
  310.     case SFVM_SETREDRAW:
  311.         psfv->SetRedraw(BOOLFROMPTR(lParam));
  312.         break;
  313.     case SFVM_GETSELECTEDOBJECTS:
  314.         return SUCCEEDED(psfv->GetSelectedObjects((LPCITEMIDLIST**)lParam, &uScratch)) ? uScratch : -1;
  315.     case SFVM_GETSELECTEDCOUNT:
  316.         return SUCCEEDED(psfv->GetSelectedCount(&uScratch)) ? uScratch : -1;
  317.     case SFVM_ISDROPONSOURCE:
  318.         return psfv->IsDropOnSource((LPDROPTARGET)lParam) == S_OK;
  319.     case SFVM_MOVEICONS:
  320.         psfv->MoveIcons((LPDATAOBJECT)lParam);
  321.         break;
  322.     case SFVM_GETDROPPOINT:
  323.         return psfv->GetDropPoint((LPPOINT)lParam) == S_OK;
  324.     case SFVM_GETDRAGPOINT:
  325.         return psfv->GetDragPoint((LPPOINT)lParam) == S_OK;
  326.     case SFVM_SETITEMPOS:
  327.     {
  328.         SFV_SETITEMPOS* psip = (SFV_SETITEMPOS*)lParam;
  329.         psfv->SetItemPos(psip->pidl, &psip->pt);
  330.         break;
  331.     }
  332.     case SFVM_ISBKDROPTARGET:
  333.         return psfv->IsBkDropTarget((LPDROPTARGET)lParam) == S_OK;
  334.     case SFVM_SETCLIPBOARD:
  335.         psfv->SetClipboard(lParam == DFM_CMD_MOVE);
  336.         break;
  337.     case SFVM_SETPOINTS:
  338.         psfv->SetPoints((LPDATAOBJECT)lParam);
  339.         return 0;
  340.     case SFVM_GETITEMSPACING:
  341.         return psfv->GetItemSpacing((LPITEMSPACING)lParam) == S_OK;
  342.     default:
  343.         // -1L is the default return value
  344.         return 0;
  345.     }
  346.     return 1;
  347. }
  348. IShellFolderView* ShellFolderViewFromWindow(HWND hwnd)
  349. {
  350.     IShellFolderView* psfv = NULL;
  351.     // HPCView sometimes gets confused and passes HWND_BROADCAST as its
  352.     // window.  We can't let this reach FileCabinet_GetIShellBrowser or
  353.     // we end up broadcasting the CWM_GETISHELLBROWSER message and screwing
  354.     // up everybody in the system.  (Not to mention that it will return TRUE,
  355.     // indicating a successful broadcast, and then we fault thinking that
  356.     // it's a vtbl.)
  357.     if (hwnd && hwnd != HWND_BROADCAST)
  358.     {
  359.         IShellBrowser* psb = FileCabinet_GetIShellBrowser(hwnd);
  360.         // Use !IS_INTRESOURCE() to protect against blatanly bogus values
  361.         // that clearly aren't pointers to objects.
  362.         if (!IS_INTRESOURCE(psb))
  363.         {
  364.             IShellView* psv;
  365.             if (SUCCEEDED(psb->QueryActiveShellView(&psv)))
  366.             {
  367.                 psv->QueryInterface(IID_IShellFolderView, (void **)&psfv);
  368.                 psv->Release();
  369.             }
  370.         }
  371.     }
  372.     return psfv;
  373. }
  374. // old msg based way of programming defview (pre dates IShellFolderView)
  375. STDAPI_(LRESULT) SHShellFolderView_Message(HWND hwnd, UINT uMsg, LPARAM lParam)
  376. {
  377.     LRESULT lret = 0;
  378.     IShellFolderView* psfv = ShellFolderViewFromWindow(hwnd);
  379.     if (psfv)
  380.     {
  381.         lret = _ShellFolderViewMessage(psfv, uMsg, lParam);
  382.         psfv->Release();
  383.     }
  384.     return lret;
  385. }
  386. STDAPI SHCreateShellFolderViewEx(LPCSFV pcsfv, IShellView **ppsv)
  387. {
  388.     SFV_CREATE sfvc;
  389.     sfvc.cbSize = SIZEOF(sfvc);
  390.     sfvc.pshf = pcsfv->pshf;
  391.     sfvc.psvOuter = pcsfv->psvOuter;
  392.     sfvc.psfvcb = pcsfv->pfnCallback ? new CWrapOldCallback(pcsfv) : NULL;
  393.     HRESULT hres = SHCreateShellFolderView(&sfvc, ppsv);
  394.     if (sfvc.psfvcb)
  395.         sfvc.psfvcb->Release();
  396.     return hres;
  397. }
  398. STDAPI_(void) InitializeStatus(IUnknown *psite)
  399. {
  400.     IShellBrowser *psb;
  401.     if (SUCCEEDED(IUnknown_QueryService(psite, SID_STopLevelBrowser, IID_IShellBrowser, (void **)&psb)))
  402.     {
  403.         LONG_PTR nParts = 0, n;
  404.         psb->SendControlMsg(FCW_STATUS, SB_GETPARTS, 0, 0, &nParts);
  405.         for (n = 0; n < nParts; n ++)
  406.         {
  407.             psb->SendControlMsg(FCW_STATUS, SB_SETTEXT, n, (LPARAM)TEXT(""), NULL);
  408.             psb->SendControlMsg(FCW_STATUS, SB_SETICON, n, (LPARAM)NULL, NULL);
  409.         }
  410.         psb->SendControlMsg(FCW_STATUS, SB_SETPARTS, 0, 0, NULL);
  411.         psb->Release();
  412.     }
  413. }
  414. //
  415. //  The status bar partitioning has undergone several changes.  Here's
  416. //  what we've got right now:
  417. //
  418. //      Pane 0 = Selection - all remaining space
  419. //      Pane 1 = Size      - just big enough to say 9,999 bytes (11 chars)
  420. //      Pane 2 = Zone      - just big enough to hold longest zone
  421. //
  422. STDAPI_(void) ResizeStatus(IUnknown *psite, UINT cx)
  423. {
  424.     IShellBrowser *psb;
  425.     if (SUCCEEDED(IUnknown_QueryService(psite, SID_STopLevelBrowser, IID_IShellBrowser, (void **)&psb)))
  426.     {
  427.         HWND hwndStatus;
  428.         if (SUCCEEDED(psb->GetControlWindow(FCW_STATUS, &hwndStatus)) && hwndStatus)
  429.         {
  430.             RECT rc;
  431.             int ciParts[3];
  432.             int ciBorders[3];
  433.             int cxPart;
  434.             GetClientRect(hwndStatus, &rc);
  435.             // Must also take status bar borders into account.
  436.             psb->SendControlMsg(FCW_STATUS, SB_GETBORDERS, 0, (LPARAM)ciBorders, NULL);
  437.             // We build the panes from right to left.
  438.             ciParts[2] = -1;
  439.             // The Zones part
  440.             cxPart = ciBorders[0] + ZoneComputePaneSize(hwndStatus) + ciBorders[2];
  441.             ciParts[1] = rc.right - cxPart;
  442.             // The Size part
  443.             HDC hdc = GetDC(hwndStatus);
  444.             HFONT hfPrev = SelectFont(hdc, GetWindowFont(hwndStatus));
  445.             SIZE siz;
  446.             GetTextExtentPoint32(hdc, TEXT("0"), 1, &siz);
  447.             SelectObject(hdc, hfPrev);
  448.             ReleaseDC(hwndStatus, hdc);
  449.             
  450.             cxPart = ciBorders[0] + siz.cx * (11 + 2); // "+2" for slop
  451.             ciParts[0] = ciParts[1] - cxPart;
  452.             //
  453.             //  If we underflowed, then give up and just give everybody
  454.             //  one third.
  455.             //
  456.             if (ciParts[0] < 0)
  457.             {
  458.                 ciParts[0] = rc.right / 3;
  459.                 ciParts[1] = 2 * ciParts[0];
  460.             }
  461.             psb->SendControlMsg(FCW_STATUS, SB_SETPARTS, ARRAYSIZE(ciParts), (LPARAM)ciParts, NULL);
  462.         }
  463.         psb->Release();
  464.     }
  465. }
  466. STDAPI_(void) SetStatusText(IUnknown *psite, LPCTSTR *ppszText, int iStart, int iEnd)
  467. {
  468.     IShellBrowser *psb;
  469.     if (SUCCEEDED(IUnknown_QueryService(psite, SID_STopLevelBrowser, IID_IShellBrowser, (void **)&psb)))
  470.     {
  471.         for (; iStart <= iEnd; iStart++) 
  472.         {
  473.             LPCTSTR psz;
  474.             if (ppszText) 
  475.             {
  476.                 psz = *ppszText;
  477.                 ppszText++;
  478.             } 
  479.             else 
  480.                 psz = c_szNULL;
  481.             // a-msadek; needed only for BiDi Win95 loc
  482.             // Mirroring will take care of that over NT5 & BiDi Win98
  483.             if (g_bBiDiW95Loc)
  484.                 psb->SendControlMsg(FCW_STATUS, SB_SETTEXT, SBT_RTLREADING | (WPARAM)iStart, (LPARAM)psz, NULL);
  485.             else
  486.                 psb->SendControlMsg(FCW_STATUS, SB_SETTEXT, (WPARAM)iStart, (LPARAM)psz, NULL);
  487.         }
  488.         psb->Release();
  489.     }
  490. }