home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winui / shell / regview / shlview.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-27  |  35.3 KB  |  1,402 lines

  1. /**************************************************************************
  2.    THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  3.    ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  4.    THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  5.    PARTICULAR PURPOSE.
  6.  
  7.    Copyright 1997 Microsoft Corporation.  All Rights Reserved.
  8. **************************************************************************/
  9.  
  10. /**************************************************************************
  11.  
  12.    File:          ShlView.cpp
  13.    
  14.    Description:   Implements IShellView.
  15.  
  16. **************************************************************************/
  17.  
  18. /**************************************************************************
  19.    #include statements
  20. **************************************************************************/
  21.  
  22. #include "ShlView.h"
  23. #include "Guid.h"
  24. #include "resource.h"
  25. #include "tools.h"
  26.  
  27. #define TOOLBAR_ID   (L"RegView")
  28.  
  29. MYTOOLINFO g_Tools[] = 
  30.    {
  31.    IDM_VIEW_KEYS, 0, IDS_TB_VIEW_KEYS, IDS_MI_VIEW_KEYS, 0, TBSTATE_ENABLED,  TBSTYLE_BUTTON,
  32.    IDM_VIEW_IDW,  0, IDS_TB_VIEW_IDW,  IDS_MI_VIEW_IDW,  0, TBSTATE_ENABLED,  TBSTYLE_BUTTON,
  33.    -1, 0, 0, 0, 0,
  34.    };
  35.  
  36. /**************************************************************************
  37.  
  38.    CShellView::CShellView()
  39.  
  40. **************************************************************************/
  41.  
  42. CShellView::CShellView(CShellFolder *pFolder, LPCITEMIDLIST pidl)
  43. {
  44. #ifdef INITCOMMONCONTROLSEX
  45.  
  46. INITCOMMONCONTROLSEX iccex;
  47. iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
  48. iccex.dwICC = ICC_LISTVIEW_CLASSES;
  49. InitCommonControlsEx(&iccex);
  50.  
  51. #else
  52.  
  53. InitCommonControls();
  54.  
  55. #endif   //INITCOMMONCONTROLSEX
  56.  
  57. m_hMenu = NULL;
  58. m_pDockingWindow = NULL;
  59.  
  60. m_pPidlMgr = new CPidlMgr();
  61. if(!m_pPidlMgr)
  62.    {
  63.    delete this;
  64.    return;
  65.    }
  66.  
  67. m_pSFParent = pFolder;
  68. if(m_pSFParent)
  69.    m_pSFParent->AddRef();
  70.  
  71. //get the shell's IMalloc pointer
  72. //we'll keep this until we get destroyed
  73. if(FAILED(SHGetMalloc(&m_pMalloc)))
  74.    {
  75.    delete this;
  76.    return;
  77.    }
  78.  
  79. m_pidl = m_pPidlMgr->Copy(pidl);
  80.  
  81. m_uState = SVUIA_DEACTIVATE;
  82.  
  83. m_ObjRefCount = 1;
  84. g_DllRefCount++;
  85. }
  86.  
  87. /**************************************************************************
  88.  
  89.    CShellView::~CShellView()
  90.  
  91. **************************************************************************/
  92.  
  93. CShellView::~CShellView()
  94. {
  95. if(m_pidl)
  96.    {
  97.    m_pPidlMgr->Delete(m_pidl);
  98.    m_pidl = NULL;
  99.    }
  100.  
  101. if(m_pSFParent)
  102.    m_pSFParent->Release();
  103.  
  104. if(m_pMalloc)
  105.    {
  106.    m_pMalloc->Release();
  107.    }
  108.  
  109. if(m_pPidlMgr)
  110.    {
  111.    delete m_pPidlMgr;
  112.    }
  113.  
  114. g_DllRefCount--;
  115. }
  116.  
  117. ///////////////////////////////////////////////////////////////////////////
  118. //
  119. // IUnknown Implementation
  120. //
  121.  
  122. /**************************************************************************
  123.  
  124.    CShellView::QueryInterface
  125.  
  126. **************************************************************************/
  127.  
  128. STDMETHODIMP CShellView::QueryInterface(REFIID riid, LPVOID *ppReturn)
  129. {
  130. *ppReturn = NULL;
  131.  
  132. //IUnknown
  133. if(IsEqualIID(riid, IID_IUnknown))
  134.    {
  135.    *ppReturn = this;
  136.    }
  137.  
  138. //IOleWindow
  139. else if(IsEqualIID(riid, IID_IOleWindow))
  140.    {
  141.    *ppReturn = (IOleWindow*)this;
  142.    }
  143.  
  144. //IShellView
  145. else if(IsEqualIID(riid, IID_IShellView))
  146.    {
  147.    *ppReturn = (IShellView*)this;
  148.    }   
  149.  
  150. //IOleCommandTarget
  151. else if(IsEqualIID(riid, IID_IOleCommandTarget))
  152.    {
  153.    *ppReturn = (IOleCommandTarget*)this;
  154.    }   
  155.  
  156. if(*ppReturn)
  157.    {
  158.    (*(LPUNKNOWN*)ppReturn)->AddRef();
  159.    return S_OK;
  160.    }
  161.  
  162. return E_NOINTERFACE;
  163. }                                             
  164.  
  165. /**************************************************************************
  166.  
  167.    CShellView::AddRef
  168.  
  169. **************************************************************************/
  170.  
  171. STDMETHODIMP_(DWORD) CShellView::AddRef()
  172. {
  173. return ++m_ObjRefCount;
  174. }
  175.  
  176.  
  177. /**************************************************************************
  178.  
  179.    CShellView::Release
  180.  
  181. **************************************************************************/
  182.  
  183. STDMETHODIMP_(DWORD) CShellView::Release()
  184. {
  185. if(--m_ObjRefCount == 0)
  186.    {
  187.    delete this;
  188.    return 0;
  189.    }
  190.    
  191. return m_ObjRefCount;
  192. }
  193.  
  194. ///////////////////////////////////////////////////////////////////////////
  195. //
  196. // IOleWindow Implementation
  197. //
  198.  
  199. /**************************************************************************
  200.  
  201.    CShellView::GetWindow()
  202.    
  203. **************************************************************************/
  204.  
  205. STDMETHODIMP CShellView::GetWindow(HWND *phWnd)
  206. {
  207. *phWnd = m_hWnd;
  208.  
  209. return S_OK;
  210. }
  211.  
  212. /**************************************************************************
  213.  
  214.    CShellView::ContextSensitiveHelp()
  215.    
  216. **************************************************************************/
  217.  
  218. STDMETHODIMP CShellView::ContextSensitiveHelp(BOOL fEnterMode)
  219. {
  220. return E_NOTIMPL;
  221. }
  222.  
  223. ///////////////////////////////////////////////////////////////////////////
  224. //
  225. // IOleCommandTarget Implementation
  226. //
  227.  
  228. /**************************************************************************
  229.  
  230.    CShellView::QueryStatus()
  231.    
  232. **************************************************************************/
  233.  
  234. STDMETHODIMP CShellView::QueryStatus(  const GUID *pguidCmdGroup, 
  235.                                        ULONG cCmds, 
  236.                                        OLECMD prgCmds[], 
  237.                                        OLECMDTEXT *pCmdText)
  238. {
  239. ULONG i;
  240.  
  241. //only process the commands for our command group
  242. if(pguidCmdGroup && (*pguidCmdGroup != CLSID_CmdGrp))
  243.    return OLECMDERR_E_UNKNOWNGROUP;
  244.  
  245. //make sure prgCmds is not NULL
  246. if(!prgCmds)
  247.    return E_POINTER;
  248.  
  249. //run through all of the commands and supply the correct information
  250. for(i = 0; i < cCmds;i++)
  251.    {
  252.    switch(prgCmds[i].cmdID)
  253.       {
  254.       case IDM_VIEW_KEYS:
  255.          prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  256.          break;
  257.       }
  258.    }
  259.  
  260. return S_OK;
  261. }
  262.  
  263. /**************************************************************************
  264.  
  265.    CShellView::Exec()
  266.    
  267. **************************************************************************/
  268.  
  269. STDMETHODIMP CShellView::Exec(   const GUID *pguidCmdGroup, 
  270.                                  DWORD nCmdID, 
  271.                                  DWORD nCmdExecOpt, 
  272.                                  VARIANTARG *pvaIn, 
  273.                                  VARIANTARG *pvaOut)
  274. {
  275. //only process the commands for our command group
  276. if(pguidCmdGroup && (*pguidCmdGroup == CLSID_CmdGrp))
  277.    {
  278.    OnCommand(nCmdID, 0, NULL);
  279.    return S_OK;
  280.    }
  281.  
  282. return OLECMDERR_E_UNKNOWNGROUP;
  283. }
  284.  
  285. ///////////////////////////////////////////////////////////////////////////
  286. //
  287. // IShellView Implementation
  288. //
  289.  
  290. /**************************************************************************
  291.  
  292.    CShellView::TranslateAccelerator()
  293.    
  294. **************************************************************************/
  295.  
  296. STDMETHODIMP CShellView::TranslateAccelerator(LPMSG pMsg)
  297. {
  298. return E_NOTIMPL;
  299. }
  300.  
  301. /**************************************************************************
  302.  
  303.    CShellView::EnableModeless()
  304.    
  305. **************************************************************************/
  306.  
  307. STDMETHODIMP CShellView::EnableModeless(BOOL fEnable)
  308. {
  309. return E_NOTIMPL;
  310. }
  311.  
  312. /**************************************************************************
  313.  
  314.    CShellView::OnActivate()
  315.    
  316. **************************************************************************/
  317.  
  318. LRESULT CShellView::OnActivate(UINT uState)
  319. {
  320. //don't do anything if the state isn't really changing
  321. if(m_uState == uState)
  322.    return S_OK;
  323.  
  324. OnDeactivate();
  325.  
  326. //only do this if we are active
  327. if(uState != SVUIA_DEACTIVATE)
  328.    {
  329.    //merge the menus
  330.    m_hMenu = CreateMenu();
  331.    
  332.    if(m_hMenu)
  333.       {
  334.        OLEMENUGROUPWIDTHS   omw = {0, 0, 0, 0, 0, 0};
  335.       MENUITEMINFO         mii;
  336.       TCHAR                szText[MAX_PATH];
  337.  
  338.       m_pShellBrowser->InsertMenusSB(m_hMenu, &omw);
  339.  
  340.       //build the top level menu
  341.       //get the menu item's text
  342.       LoadString(g_hInst, IDS_MI_REGISTRY, szText, sizeof(szText));
  343.       
  344.       ZeroMemory(&mii, sizeof(mii));
  345.       mii.cbSize = sizeof(mii);
  346.       mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
  347.       mii.fType = MFT_STRING;
  348.       mii.fState = MFS_ENABLED;
  349.       mii.dwTypeData = szText;
  350.       mii.hSubMenu = BuildRegistryMenu();
  351.  
  352.       //insert our menu into the menu bar
  353.       if(mii.hSubMenu)
  354.          {
  355.          InsertMenuItem(m_hMenu, FCIDM_MENU_HELP, FALSE, &mii);
  356.          }
  357.  
  358.       //get the view menu so we can merge with it
  359.       ZeroMemory(&mii, sizeof(mii));
  360.       mii.cbSize = sizeof(mii);
  361.       mii.fMask = MIIM_SUBMENU;
  362.       
  363.       if(GetMenuItemInfo(m_hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
  364.          {
  365.          MergeViewMenu(mii.hSubMenu);
  366.          }
  367.  
  368.       //add the items that should only be added if we have the focus
  369.       if(SVUIA_ACTIVATE_FOCUS == uState)
  370.          {
  371.          //get the file menu so we can merge with it
  372.          ZeroMemory(&mii, sizeof(mii));
  373.          mii.cbSize = sizeof(mii);
  374.          mii.fMask = MIIM_SUBMENU;
  375.       
  376.          if(GetMenuItemInfo(m_hMenu, FCIDM_MENU_FILE, FALSE, &mii))
  377.             {
  378.             MergeFileMenu(mii.hSubMenu);
  379.             }
  380.          }
  381.  
  382.       m_pShellBrowser->SetMenuSB(m_hMenu, NULL, m_hWnd);
  383.       }
  384.    }
  385.  
  386. m_uState = uState;
  387.  
  388. return 0;
  389. }
  390.  
  391. /**************************************************************************
  392.  
  393.    CShellView::OnDeactivate()
  394.    
  395. **************************************************************************/
  396.  
  397. void CShellView::OnDeactivate(void)
  398. {
  399. if(m_uState != SVUIA_DEACTIVATE)
  400.    {
  401.    if(m_hMenu)
  402.       {
  403.       m_pShellBrowser->SetMenuSB(NULL, NULL, NULL);
  404.  
  405.       m_pShellBrowser->RemoveMenusSB(m_hMenu);
  406.  
  407.       DestroyMenu(m_hMenu);
  408.  
  409.       m_hMenu = NULL;
  410.       }
  411.  
  412.    m_uState = SVUIA_DEACTIVATE;
  413.    }
  414. }
  415.  
  416. /**************************************************************************
  417.  
  418.    CShellView::UIActivate()
  419.  
  420.    This function activates the view window. Note that activating it 
  421.    will not change the focus, while setting the focus will activate it.
  422.  
  423.    
  424. **************************************************************************/
  425.  
  426. STDMETHODIMP CShellView::UIActivate(UINT uState)
  427. {
  428. //don't do anything if the state isn't really changing
  429. if(m_uState == uState)
  430.    return S_OK;
  431.  
  432. //OnActivate handles the menu merging and internal state
  433. OnActivate(uState);
  434.  
  435. //remove the docking window
  436. if(g_bShowIDW)
  437.    AddRemoveDockingWindow(FALSE);
  438.  
  439. //only do this if we are active
  440. if(uState != SVUIA_DEACTIVATE)
  441.    {
  442.    TCHAR szName[MAX_PATH];
  443.    LRESULT  lResult;
  444.    int      nPartArray[1] = {-1};
  445.    
  446.    //update the status bar
  447.    LoadString(g_hInst, IDS_REGISTRY_TITLE, szName, sizeof(szName));
  448.    
  449.    m_pSFParent->GetFolderPath(szName + lstrlen(szName), sizeof(szName) - lstrlen(szName));
  450.  
  451.    //set the number of parts
  452.    m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETPARTS, 1, (LPARAM)nPartArray, &lResult);
  453.  
  454.    //set the text for the parts
  455.    m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 0, (LPARAM)szName, &lResult);
  456.  
  457.    //add the docking window if necessary
  458.    if(g_bShowIDW)
  459.       AddRemoveDockingWindow(TRUE);
  460.    }
  461.  
  462. return S_OK;
  463. }
  464.  
  465. /**************************************************************************
  466.  
  467.    CShellView::BuildRegistryMenu()
  468.    
  469. **************************************************************************/
  470.  
  471. HMENU CShellView::BuildRegistryMenu(void)
  472. {
  473. HMENU hSubMenu = CreatePopupMenu();
  474.  
  475. if(hSubMenu)
  476.    {
  477.    TCHAR          szText[MAX_PATH];
  478.    MENUITEMINFO   mii;
  479.    int            nTools,
  480.                   i;
  481.    //get the number of items in our global array
  482.    for(nTools = 0; g_Tools[nTools].idCommand != -1; nTools++)
  483.       {
  484.       }
  485.  
  486.    //add the menu items
  487.    for(i = 0; i < nTools; i++)
  488.       {
  489.       LoadString(g_hInst, g_Tools[i].idMenuString, szText, sizeof(szText));
  490.       
  491.       ZeroMemory(&mii, sizeof(mii));
  492.       mii.cbSize = sizeof(mii);
  493.       mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
  494.  
  495.       if(TBSTYLE_SEP != g_Tools[i].bStyle)
  496.          {
  497.          mii.fType = MFT_STRING;
  498.          mii.fState = MFS_ENABLED;
  499.          mii.dwTypeData = szText;
  500.          mii.wID = g_Tools[i].idCommand;
  501.          }
  502.       else
  503.          {
  504.          mii.fType = MFT_SEPARATOR;
  505.          }
  506.       
  507.       //tack this item onto the end of the menu
  508.       InsertMenuItem(hSubMenu, (UINT)-1, TRUE, &mii);
  509.       }
  510.    }
  511.  
  512. return hSubMenu;
  513. }
  514.  
  515. /**************************************************************************
  516.  
  517.    CShellView::MergeFileMenu()
  518.    
  519. **************************************************************************/
  520.  
  521. void CShellView::MergeFileMenu(HMENU hSubMenu)
  522. {
  523. if(hSubMenu)
  524.    {
  525.    MENUITEMINFO   mii;
  526.    TCHAR          szText[MAX_PATH];
  527.  
  528.    ZeroMemory(&mii, sizeof(mii));
  529.  
  530.    //add a separator
  531.    mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
  532.    mii.fType = MFT_SEPARATOR;
  533.    mii.fState = MFS_ENABLED;
  534.  
  535.    //insert this item at the beginning of the menu
  536.    InsertMenuItem(hSubMenu, 0, TRUE, &mii);
  537.  
  538.    //add the file menu items
  539.    LoadString(g_hInst, IDS_MI_FILEITEM, szText, sizeof(szText));
  540.    mii.cbSize = sizeof(mii);
  541.    mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
  542.    mii.fType = MFT_STRING;
  543.    mii.fState = MFS_ENABLED;
  544.    mii.dwTypeData = szText;
  545.    mii.wID = IDM_MYFILEITEM;
  546.  
  547.    //insert this item at the beginning of the menu
  548.    InsertMenuItem(hSubMenu, 0, TRUE, &mii);
  549.    }
  550. }
  551.  
  552. /**************************************************************************
  553.  
  554.    CShellView::MergeViewMenu()
  555.    
  556. **************************************************************************/
  557.  
  558. void CShellView::MergeViewMenu(HMENU hSubMenu)
  559. {
  560. if(hSubMenu)
  561.    {
  562.    MENUITEMINFO   mii;
  563.    TCHAR          szText[MAX_PATH];
  564.  
  565.    ZeroMemory(&mii, sizeof(mii));
  566.  
  567.    //add a separator at the correct position in the menu
  568.    mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
  569.    mii.fType = MFT_SEPARATOR;
  570.    mii.fState = MFS_ENABLED;
  571.    InsertMenuItem(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
  572.  
  573.    //add the view menu items at the correct position in the menu
  574.    LoadString(g_hInst, IDS_MI_VIEW_KEYS, szText, sizeof(szText));
  575.    mii.cbSize = sizeof(mii);
  576.    mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
  577.    mii.fType = MFT_STRING;
  578.    mii.fState = MFS_ENABLED;
  579.    mii.dwTypeData = szText;
  580.    mii.wID = IDM_VIEW_KEYS;
  581.    InsertMenuItem(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
  582.    }
  583. }
  584.  
  585. /**************************************************************************
  586.  
  587.    CShellView::Refresh()
  588.    
  589. **************************************************************************/
  590.  
  591. STDMETHODIMP CShellView::Refresh(void)
  592. {
  593. //empty the list
  594. ListView_DeleteAllItems(m_hwndList);
  595.  
  596. //refill the list
  597. FillList();
  598.  
  599. return S_OK;
  600. }
  601.  
  602. /**************************************************************************
  603.  
  604.    CShellView::CreateViewWindow()
  605.    
  606. **************************************************************************/
  607.  
  608. STDMETHODIMP CShellView::CreateViewWindow(   LPSHELLVIEW pPrevView, 
  609.                                              LPCFOLDERSETTINGS lpfs, 
  610.                                              LPSHELLBROWSER psb, 
  611.                                              LPRECT prcView, 
  612.                                              HWND *phWnd)
  613. {
  614. WNDCLASS wc;
  615.  
  616. *phWnd = NULL;
  617.  
  618. //if our window class has not been registered, then do so
  619. if(!GetClassInfo(g_hInst, NS_CLASS_NAME, &wc))
  620.    {
  621.    ZeroMemory(&wc, sizeof(wc));
  622.    wc.style          = CS_HREDRAW | CS_VREDRAW;
  623.    wc.lpfnWndProc    = (WNDPROC)WndProc;
  624.    wc.cbClsExtra     = 0;
  625.    wc.cbWndExtra     = 0;
  626.    wc.hInstance      = g_hInst;
  627.    wc.hIcon          = NULL;
  628.    wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
  629.    wc.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
  630.    wc.lpszMenuName   = NULL;
  631.    wc.lpszClassName  = NS_CLASS_NAME;
  632.    
  633.    if(!RegisterClass(&wc))
  634.       return E_FAIL;
  635.    }
  636.  
  637. //set up the member variables
  638. m_pShellBrowser = psb;
  639. m_FolderSettings = *lpfs;
  640.  
  641. //get our parent window
  642. m_pShellBrowser->GetWindow(&m_hwndParent);
  643.  
  644. *phWnd = CreateWindowEx(   0,
  645.                            NS_CLASS_NAME,
  646.                            NULL,
  647.                            WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
  648.                            prcView->left,
  649.                            prcView->top,
  650.                            prcView->right - prcView->left,
  651.                            prcView->bottom - prcView->top,
  652.                            m_hwndParent,
  653.                            NULL,
  654.                            g_hInst,
  655.                            (LPVOID)this);
  656.                            
  657. if(!*phWnd)
  658.    return E_FAIL;
  659.  
  660. m_pShellBrowser->AddRef();
  661.  
  662. return S_OK;
  663. }
  664.  
  665. /**************************************************************************
  666.  
  667.    CShellView::DestroyViewWindow()
  668.    
  669. **************************************************************************/
  670.  
  671. STDMETHODIMP CShellView::DestroyViewWindow(void)
  672. {
  673. //Make absolutely sure all our UI is cleaned up.
  674. UIActivate(SVUIA_DEACTIVATE);
  675.  
  676. if(m_hMenu)
  677.    DestroyMenu(m_hMenu);
  678.  
  679. DestroyWindow(m_hWnd);
  680.  
  681. //release the shell browser object
  682. m_pShellBrowser->Release();
  683.  
  684. return S_OK;
  685. }
  686.  
  687. /**************************************************************************
  688.  
  689.    CShellView::GetCurrentInfo()
  690.    
  691. **************************************************************************/
  692.  
  693. STDMETHODIMP CShellView::GetCurrentInfo(LPFOLDERSETTINGS lpfs)
  694. {
  695. *lpfs = m_FolderSettings;
  696.  
  697. return S_OK;
  698. }
  699.  
  700. /**************************************************************************
  701.  
  702.    CShellView::AddPropertySheetPages()
  703.    
  704. **************************************************************************/
  705.  
  706. STDMETHODIMP CShellView::AddPropertySheetPages( DWORD dwReserved, 
  707.                                                 LPFNADDPROPSHEETPAGE lpfn, 
  708.                                                 LPARAM lParam)
  709. {
  710. return E_NOTIMPL;
  711. }
  712.  
  713. /**************************************************************************
  714.  
  715.    CShellView::SaveViewState()
  716.    
  717. **************************************************************************/
  718.  
  719. STDMETHODIMP CShellView::SaveViewState(void)
  720. {
  721. return S_OK;
  722. }
  723.  
  724. /**************************************************************************
  725.  
  726.    CShellView::SelectItem()
  727.    
  728. **************************************************************************/
  729.  
  730. STDMETHODIMP CShellView::SelectItem(LPCITEMIDLIST pidlItem, UINT uFlags)
  731. {
  732. return E_NOTIMPL;
  733. }
  734.  
  735. /**************************************************************************
  736.  
  737.    CShellView::GetItemObject()
  738.    
  739. **************************************************************************/
  740.  
  741. STDMETHODIMP CShellView::GetItemObject(UINT uItem, REFIID riid, LPVOID *ppvOut)
  742. {
  743. *ppvOut = NULL;
  744.  
  745. return E_NOTIMPL;
  746. }
  747.  
  748.  
  749. /**************************************************************************
  750.  
  751.    CShellView::WndProc()
  752.    
  753. **************************************************************************/
  754.  
  755. LRESULT CALLBACK CShellView::WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
  756. {
  757. CShellView  *pThis = (CShellView*)GetWindowLong(hWnd, GWL_USERDATA);
  758.  
  759. switch (uMessage)
  760.    {
  761.    case WM_NCCREATE:
  762.       {
  763.       LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
  764.       pThis = (CShellView*)(lpcs->lpCreateParams);
  765.       SetWindowLong(hWnd, GWL_USERDATA, (LONG)pThis);
  766.  
  767.       //set the window handle
  768.       pThis->m_hWnd = hWnd;
  769.       }
  770.       break;
  771.    
  772.    case WM_SIZE:
  773.       return pThis->OnSize(LOWORD(lParam), HIWORD(lParam));
  774.    
  775.    case WM_CREATE:
  776.       return pThis->OnCreate();
  777.    
  778.    case WM_SETFOCUS:
  779.       return pThis->OnSetFocus();
  780.    
  781.    case WM_KILLFOCUS:
  782.       return pThis->OnKillFocus();
  783.  
  784.    case WM_ACTIVATE:
  785.       return pThis->OnActivate(SVUIA_ACTIVATE_FOCUS);
  786.    
  787.    case WM_COMMAND:
  788.       return pThis->OnCommand(   GET_WM_COMMAND_ID(wParam, lParam), 
  789.                                  GET_WM_COMMAND_CMD(wParam, lParam), 
  790.                                  GET_WM_COMMAND_HWND(wParam, lParam));
  791.    
  792.    case WM_INITMENUPOPUP:
  793.       return pThis->UpdateMenu((HMENU)wParam);
  794.    
  795.    case WM_NOTIFY:
  796.       return pThis->OnNotify((UINT)wParam, (LPNMHDR)lParam);
  797.    
  798.    case WM_SETTINGCHANGE:
  799.       return pThis->OnSettingChange((LPCTSTR)lParam);
  800.    }
  801.  
  802. return DefWindowProc(hWnd, uMessage, wParam, lParam);
  803. }
  804.  
  805. /**************************************************************************
  806.  
  807.    CShellView::OnSetFocus()
  808.    
  809. **************************************************************************/
  810.  
  811. LRESULT CShellView::OnSetFocus(void)
  812. {
  813. /*
  814. Tell the browser one of our windows has received the focus. This should always 
  815. be done before merging menus (OnActivate merges the menus) if one of our 
  816. windows has the focus.
  817. */
  818. m_pShellBrowser->OnViewWindowActive(this);
  819.  
  820. OnActivate(SVUIA_ACTIVATE_FOCUS);
  821.  
  822. return 0;
  823. }
  824.  
  825. /**************************************************************************
  826.  
  827.    CShellView::OnKillFocus()
  828.    
  829. **************************************************************************/
  830.  
  831. LRESULT CShellView::OnKillFocus(void)
  832. {
  833. OnActivate(SVUIA_ACTIVATE_NOFOCUS);
  834.  
  835. return 0;
  836. }
  837.  
  838. /**************************************************************************
  839.  
  840.    CShellView::OnCommand()
  841.    
  842. **************************************************************************/
  843.  
  844. LRESULT CShellView::OnCommand(DWORD dwCmdID, DWORD dwCmd, HWND hwndCmd)
  845. {
  846. switch(dwCmdID)
  847.    {
  848.    case IDM_VIEW_KEYS:
  849.       g_bViewKeys = ! g_bViewKeys;
  850.       Refresh();
  851.       break;
  852.  
  853.    case IDM_VIEW_IDW:
  854.       g_bShowIDW = ! g_bShowIDW;
  855.       AddRemoveDockingWindow(g_bShowIDW);
  856.       break;
  857.    
  858.    case IDM_MYFILEITEM:
  859.       MessageBeep(MB_OK);
  860.       break;
  861.    }
  862.  
  863. return 0;
  864. }
  865.  
  866. /**************************************************************************
  867.  
  868.    CShellView::UpdateMenu()
  869.    
  870. **************************************************************************/
  871.  
  872. LRESULT CShellView::UpdateMenu(HMENU hMenu)
  873. {
  874. CheckMenuItem(hMenu, IDM_VIEW_KEYS, MF_BYCOMMAND | (g_bViewKeys ? MF_CHECKED: MF_UNCHECKED));
  875.  
  876. if(CanDoIDockingWindow())
  877.    {
  878.    EnableMenuItem(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_ENABLED);
  879.    CheckMenuItem(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | (g_bShowIDW ? MF_CHECKED: MF_UNCHECKED));
  880.    }
  881. else
  882.    {
  883.    EnableMenuItem(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
  884.    CheckMenuItem(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_UNCHECKED);
  885.    }
  886.  
  887. return 0;
  888. }
  889.  
  890. /**************************************************************************
  891.  
  892.    CShellView::OnNotify()
  893.    
  894. **************************************************************************/
  895.  
  896. LRESULT CShellView::OnNotify(UINT CtlID, LPNMHDR lpnmh)
  897. {
  898. switch(lpnmh->code)
  899.    {
  900.    case NM_SETFOCUS:
  901.       OnSetFocus();
  902.       break;
  903.  
  904.    case NM_KILLFOCUS:
  905.       OnDeactivate();
  906.       break;
  907.  
  908.    case HDN_ENDTRACK:
  909.       {
  910.       g_nColumn1 = ListView_GetColumnWidth(m_hwndList, 0);
  911.       g_nColumn2 = ListView_GetColumnWidth(m_hwndList, 1);
  912.       }
  913.       return 0;
  914.    
  915.    case LVN_DELETEITEM:
  916.       {
  917.       NM_LISTVIEW *lpnmlv = (NM_LISTVIEW*)lpnmh;
  918.       
  919.       //delete the pidl because we made a copy of it
  920.       m_pPidlMgr->Delete((LPITEMIDLIST)lpnmlv->lParam);
  921.       }
  922.       break;
  923.    
  924. #ifdef LVN_ITEMACTIVATE
  925.    
  926.    case LVN_ITEMACTIVATE:
  927.  
  928. #else    //LVN_ITEMACTIVATE
  929.  
  930.    case NM_DBLCLK:
  931.    case NM_RETURN:
  932.  
  933. #endif   //LVN_ITEMACTIVATE
  934.       {
  935.       LV_ITEM        lvItem;
  936.  
  937.       ZeroMemory(&lvItem, sizeof(lvItem));
  938.       lvItem.mask = LVIF_PARAM;
  939.  
  940. #ifdef LVN_ITEMACTIVATE
  941.  
  942.       LPNMLISTVIEW   lpnmlv = (LPNMLISTVIEW)lpnmh;
  943.       lvItem.iItem = lpnmlv->iItem;
  944.  
  945. #else    //LVN_ITEMACTIVATE
  946.  
  947.       lvItem.iItem = -1;
  948.  
  949.       //need to find the selected item
  950.       {
  951.       int   i;
  952.  
  953.       for(i = 0; i < ListView_GetItemCount(m_hwndList); i++)
  954.          {
  955.          if(ListView_GetItemState(m_hwndList, i, LVIS_SELECTED))
  956.             {
  957.             lvItem.iItem = i;
  958.             break;
  959.             }
  960.          }
  961.       //we didn't find a selected item
  962.       if(-1 == lvItem.iItem)
  963.          return 0;
  964.       }
  965.  
  966. #endif   //LVN_ITEMACTIVATE
  967.  
  968.       if(ListView_GetItem(m_hwndList, &lvItem))
  969.          {
  970.          //only allow keys to be activated
  971.          if(!m_pPidlMgr->IsValue((LPITEMIDLIST)lvItem.lParam))
  972.             m_pShellBrowser->BrowseObject(   (LPITEMIDLIST)lvItem.lParam, 
  973.                                              SBSP_DEFBROWSER | SBSP_RELATIVE);
  974.          }
  975.       }
  976.       return 0;
  977.    
  978.    case LVN_GETDISPINFO:
  979.       {
  980.       LV_DISPINFO    *lpdi = (LV_DISPINFO *)lpnmh;
  981.       LPITEMIDLIST   pidl = (LPITEMIDLIST)lpdi->item.lParam;
  982.  
  983.       //is the sub-item information being requested?
  984.       if(lpdi->item.iSubItem)
  985.          {
  986.          //is the text being requested?
  987.          if(lpdi->item.mask & LVIF_TEXT)
  988.             {
  989.             //is this a value or a key?
  990.             if(m_pPidlMgr->IsValue(pidl))
  991.                {
  992.                //get the item's value text
  993.                m_pPidlMgr->GetDataText(m_pidl, pidl, lpdi->item.pszText, lpdi->item.cchTextMax);
  994.  
  995.                //if the data text is NULL, get the no value string
  996.                if(!*lpdi->item.pszText)
  997.                   LoadString(g_hInst, IDS_NODATA, lpdi->item.pszText, lpdi->item.cchTextMax);
  998.                }
  999.             //its a key
  1000.             else
  1001.                {
  1002.                LoadString(g_hInst, IDS_KEY, lpdi->item.pszText, lpdi->item.cchTextMax);
  1003.                }
  1004.             }
  1005.          }
  1006.       //the item text is being requested
  1007.       else
  1008.          {
  1009.          //is the text being requested?
  1010.          if(lpdi->item.mask & LVIF_TEXT)
  1011.             {
  1012.             STRRET   str;
  1013.  
  1014.             if(SUCCEEDED(m_pSFParent->GetDisplayNameOf(pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &str)))
  1015.                {
  1016.                if(STRRET_WSTR == str.uType)
  1017.                   {
  1018.                   WideCharToLocal(lpdi->item.pszText, str.pOleStr, lpdi->item.cchTextMax);
  1019.  
  1020.                   //delete the string buffer
  1021.                   m_pMalloc->Free(str.pOleStr);
  1022.                   }
  1023.                }
  1024.             }
  1025.  
  1026.          //is the image being requested?
  1027.          if(lpdi->item.mask & LVIF_IMAGE)
  1028.             {
  1029.             IExtractIcon   *pei;
  1030.  
  1031.             if(SUCCEEDED(m_pSFParent->GetUIObjectOf(m_hWnd, 1, (LPCITEMIDLIST*)&pidl, IID_IExtractIcon, NULL, (LPVOID*)&pei)))
  1032.                {
  1033.                UINT  uFlags;
  1034.  
  1035.                //GetIconLoaction will give us the index into our image list
  1036.                pei->GetIconLocation(GIL_FORSHELL, NULL, 0, &lpdi->item.iImage, &uFlags);
  1037.  
  1038.                pei->Release();
  1039.                }
  1040.             }
  1041.          }
  1042.       }
  1043.       return 0;
  1044.    }
  1045.  
  1046. return 0;
  1047. }
  1048.  
  1049. /**************************************************************************
  1050.  
  1051.    CShellView::OnSize()
  1052.    
  1053. **************************************************************************/
  1054.  
  1055. LRESULT CShellView::OnSize(WORD wWidth, WORD wHeight)
  1056. {
  1057. //resize the ListView to fit our window
  1058. if(m_hwndList)
  1059.    {
  1060.    MoveWindow(m_hwndList, 0, 0, wWidth, wHeight, TRUE);
  1061.    }
  1062.  
  1063. return 0;
  1064. }
  1065.  
  1066. /**************************************************************************
  1067.  
  1068.    CShellView::OnCreate()
  1069.    
  1070. **************************************************************************/
  1071.  
  1072. LRESULT CShellView::OnCreate(void)
  1073. {
  1074. //create the ListView
  1075. if(CreateList())
  1076.    {
  1077.    if(InitList())
  1078.       {
  1079.       FillList();
  1080.       }
  1081.    }
  1082.  
  1083. return 0;
  1084. }
  1085.  
  1086.  
  1087. /**************************************************************************
  1088.  
  1089.    CShellView::CreateList()
  1090.    
  1091. **************************************************************************/
  1092.  
  1093. BOOL CShellView::CreateList(void)
  1094. {
  1095. DWORD dwStyle;
  1096.  
  1097. dwStyle =   WS_TABSTOP | 
  1098.             WS_VISIBLE |
  1099.             WS_CHILD | 
  1100.             WS_BORDER | 
  1101.             LVS_SINGLESEL |
  1102.             LVS_REPORT | 
  1103.             LVS_NOSORTHEADER |
  1104.             LVS_SHAREIMAGELISTS;
  1105.  
  1106. m_hwndList = CreateWindowEx(     WS_EX_CLIENTEDGE,
  1107.                                  WC_LISTVIEW,
  1108.                                  NULL,
  1109.                                  dwStyle,
  1110.                                  0,
  1111.                                  0,
  1112.                                  0,
  1113.                                  0,
  1114.                                  m_hWnd,
  1115.                                  (HMENU)ID_LISTVIEW,
  1116.                                  g_hInst,
  1117.                                  NULL);
  1118.  
  1119. if(!m_hwndList)
  1120.    return FALSE;
  1121.  
  1122. UpdateShellSettings();
  1123.  
  1124. return TRUE;
  1125. }
  1126.  
  1127. /**************************************************************************
  1128.  
  1129.    CShellView::InitList()
  1130.    
  1131. **************************************************************************/
  1132.  
  1133. BOOL CShellView::InitList(void)
  1134. {
  1135. LV_COLUMN   lvColumn;
  1136. RECT        rc;
  1137. TCHAR       szString[MAX_PATH];
  1138.  
  1139. //empty the list
  1140. ListView_DeleteAllItems(m_hwndList);
  1141.  
  1142. //initialize the columns
  1143. lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  1144. lvColumn.fmt = LVCFMT_LEFT;
  1145. lvColumn.pszText = szString;
  1146.  
  1147. lvColumn.cx = g_nColumn1;
  1148. LoadString(g_hInst, IDS_COLUMN1, szString, sizeof(szString));
  1149. ListView_InsertColumn(m_hwndList, 0, &lvColumn);
  1150.  
  1151. GetClientRect(m_hWnd, &rc);
  1152.  
  1153. lvColumn.cx = g_nColumn2;
  1154. LoadString(g_hInst, IDS_COLUMN2, szString, sizeof(szString));
  1155. ListView_InsertColumn(m_hwndList, 1, &lvColumn);
  1156.  
  1157. ListView_SetImageList(m_hwndList, g_himlSmall, LVSIL_SMALL);
  1158.  
  1159. return TRUE;
  1160. }
  1161.  
  1162. /**************************************************************************
  1163.  
  1164.    CShellView::FillList()
  1165.    
  1166. **************************************************************************/
  1167.  
  1168. void CShellView::FillList(void)
  1169. {
  1170. LPENUMIDLIST   pEnumIDList;
  1171.  
  1172. if(SUCCEEDED(m_pSFParent->EnumObjects(m_hWnd, SHCONTF_NONFOLDERS | (g_bViewKeys ? SHCONTF_FOLDERS : 0), &pEnumIDList)))
  1173.    {
  1174.    LPITEMIDLIST   pidl;
  1175.    DWORD          dwFetched;
  1176.  
  1177.    //turn the listview's redrawing off
  1178.    SendMessage(m_hwndList, WM_SETREDRAW, FALSE, 0);
  1179.  
  1180.    while((S_OK == pEnumIDList->Next(1, &pidl, &dwFetched)) && dwFetched)
  1181.       {
  1182.       LV_ITEM  lvItem;
  1183.  
  1184.       ZeroMemory(&lvItem, sizeof(lvItem));
  1185.  
  1186.       //set the mask
  1187.       lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
  1188.  
  1189.       //add the item to the end of the list
  1190.       lvItem.iItem = ListView_GetItemCount(m_hwndList);
  1191.  
  1192.       //set the item's data
  1193.       lvItem.lParam = (LPARAM)m_pPidlMgr->Copy(pidl);
  1194.  
  1195.       //get text on a callback basis
  1196.       lvItem.pszText = LPSTR_TEXTCALLBACK;
  1197.  
  1198.       //get the image on a callback basis
  1199.       lvItem.iImage = I_IMAGECALLBACK;
  1200.  
  1201.       //add the item
  1202.       ListView_InsertItem(m_hwndList, &lvItem);
  1203.       }
  1204.  
  1205.    //sort the items
  1206.    ListView_SortItems(m_hwndList, CompareItems, (LPARAM)m_pSFParent);
  1207.    
  1208.    //turn the listview's redrawing back on and force it to draw
  1209.    SendMessage(m_hwndList, WM_SETREDRAW, TRUE, 0);
  1210.    InvalidateRect(m_hwndList, NULL, TRUE);
  1211.    UpdateWindow(m_hwndList);
  1212.  
  1213.    pEnumIDList->Release();
  1214.    }
  1215. }
  1216.  
  1217. /**************************************************************************
  1218.  
  1219.    CShellView::CanDoIDockingWindow()
  1220.    
  1221. **************************************************************************/
  1222.  
  1223. BOOL CShellView::CanDoIDockingWindow(void)
  1224. {
  1225. #if (_WIN32_IE < 0x0400)
  1226.  
  1227. return FALSE;
  1228.  
  1229. #else //(_WIN32_IE >= 0x0400)
  1230.  
  1231. BOOL              bReturn = FALSE;
  1232. HRESULT           hr;
  1233. IServiceProvider  *pSP;
  1234.  
  1235. //get the browser's IServiceProvider
  1236. hr = m_pShellBrowser->QueryInterface((REFIID)IID_IServiceProvider, (LPVOID*)&pSP);
  1237. if(SUCCEEDED(hr))
  1238.    {
  1239.    IDockingWindowFrame *pFrame;
  1240.  
  1241.    //get the IDockingWindowFrame
  1242.    hr = pSP->QueryService(SID_SShellBrowser, IID_IDockingWindowFrame, (LPVOID*)&pFrame);
  1243.    if(SUCCEEDED(hr))
  1244.       {
  1245.       bReturn = TRUE;
  1246.  
  1247.       pFrame->Release();
  1248.       }
  1249.  
  1250.    pSP->Release();
  1251.    }
  1252.  
  1253. return bReturn;
  1254. #endif   //(_WIN32_IE >= 0x0400)
  1255. }
  1256.  
  1257. /**************************************************************************
  1258.  
  1259.    CShellView::AddRemoveDockingWindow()
  1260.    
  1261. **************************************************************************/
  1262.  
  1263. BOOL CShellView::AddRemoveDockingWindow(BOOL bAdd)
  1264. {
  1265. #if (_WIN32_IE < 0x0400)
  1266.  
  1267. return FALSE;
  1268.  
  1269. #else //(_WIN32_IE < 0x0400)
  1270.  
  1271. BOOL              bReturn = FALSE;
  1272. HRESULT           hr;
  1273. IServiceProvider  *pSP;
  1274.  
  1275. //get the browser's IServiceProvider
  1276. hr = m_pShellBrowser->QueryInterface((REFIID)IID_IServiceProvider, (LPVOID*)&pSP);
  1277. if(SUCCEEDED(hr))
  1278.    {
  1279.    IDockingWindowFrame *pFrame;
  1280.  
  1281.    //get the IDockingWindowFrame pointer
  1282.    hr = pSP->QueryService(SID_SShellBrowser, IID_IDockingWindowFrame, (LPVOID*)&pFrame);
  1283.    if(SUCCEEDED(hr))
  1284.       {
  1285.       if(bAdd)
  1286.          {
  1287.          hr = S_OK;
  1288.          if(!m_pDockingWindow)
  1289.             {
  1290.             //create the toolbar object
  1291.             m_pDockingWindow = new CDockingWindow(this, m_hWnd);
  1292.             }
  1293.  
  1294.          if(m_pDockingWindow)
  1295.             {
  1296.             //add the toolbar object
  1297.             hr = pFrame->AddToolbar((IDockingWindow*)m_pDockingWindow, TOOLBAR_ID, 0);
  1298.  
  1299.             if(SUCCEEDED(hr))
  1300.                {
  1301.                bReturn = TRUE;
  1302.                }
  1303.             }
  1304.          }
  1305.       else
  1306.          {
  1307.          if(m_pDockingWindow)
  1308.             {
  1309.             hr = pFrame->RemoveToolbar((IDockingWindow*)m_pDockingWindow, DWFRF_NORMAL);
  1310.  
  1311.             if(SUCCEEDED(hr))
  1312.                {
  1313.                /*
  1314.                RemoveToolbar should release the toolbar object which will cause 
  1315.                it to destroy itself. Our toolbar object is no longer valid at 
  1316.                this point.
  1317.                */
  1318.                m_pDockingWindow = NULL;
  1319.                bReturn = TRUE;
  1320.                }
  1321.             }
  1322.          }
  1323.       pFrame->Release();
  1324.       }
  1325.    pSP->Release();
  1326.    }
  1327.  
  1328. return bReturn;
  1329. #endif   //(_WIN32_IE < 0x0400)
  1330. }
  1331.  
  1332. /**************************************************************************
  1333.  
  1334.    CShellView::UpdateShellSettings()
  1335.    
  1336. **************************************************************************/
  1337.  
  1338. typedef void (WINAPI *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
  1339.  
  1340. void CShellView::UpdateShellSettings(void)
  1341. {
  1342. #if (_WIN32_IE >= 0x0400)
  1343. SHELLFLAGSTATE       sfs;
  1344. HINSTANCE            hinstShell32;
  1345.  
  1346. /*
  1347. Since SHGetSettings is not implemented in all versions of the shell, get the 
  1348. function address manually at run time. This allows the extension to run on all 
  1349. platforms.
  1350. */
  1351.  
  1352. ZeroMemory(&sfs, sizeof(sfs));
  1353.  
  1354. /*
  1355. The default, in case any of the following steps fails, is classic Windows 95 
  1356. style.
  1357. */
  1358. sfs.fWin95Classic = TRUE;
  1359.  
  1360. hinstShell32 = LoadLibrary(TEXT("shell32.dll"));
  1361. if(hinstShell32)
  1362.    {
  1363.    PFNSHGETSETTINGSPROC pfnSHGetSettings;
  1364.  
  1365.    pfnSHGetSettings = (PFNSHGETSETTINGSPROC)GetProcAddress(hinstShell32, TEXT("SHGetSettings"));
  1366.    if(pfnSHGetSettings)
  1367.       {
  1368.       (*pfnSHGetSettings)(&sfs, SSF_DOUBLECLICKINWEBVIEW | SSF_WIN95CLASSIC);
  1369.       }
  1370.    FreeLibrary(hinstShell32);
  1371.    }
  1372.  
  1373. DWORD dwExStyles = 0;
  1374.  
  1375. if(!sfs.fWin95Classic && !sfs.fDoubleClickInWebView)
  1376.    dwExStyles |= LVS_EX_ONECLICKACTIVATE | 
  1377.                   LVS_EX_TRACKSELECT | 
  1378.                   LVS_EX_UNDERLINEHOT;
  1379.  
  1380. ListView_SetExtendedListViewStyle(m_hwndList, dwExStyles);
  1381.  
  1382. #endif   //(_WIN32_IE >= 0x0400)
  1383. }
  1384.  
  1385. /**************************************************************************
  1386.  
  1387.    CShellView::OnSettingChange()
  1388.    
  1389. **************************************************************************/
  1390.  
  1391. LRESULT CShellView::OnSettingChange(LPCTSTR lpszSection)
  1392. {
  1393. //if(0 == lstrcmpi(lpszSection, TEXT("ShellState")))
  1394.    {
  1395.    UpdateShellSettings();
  1396.    return 0;
  1397.    }
  1398.  
  1399. return 0;
  1400. }
  1401.  
  1402.