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

Windows Kernel

Development Platform:

Visual C++

  1. #include "shellprv.h"
  2. #include <runtask.h>
  3. #include "sfviewp.h"
  4. #include <runtask.h>
  5. // from defview.cpp
  6. void ChangeRefForIdle(CDefView * pdsv, BOOL bAdd);
  7. int CALLBACK DefView_Compare(LPARAM p1, LPARAM p2, LPARAM lParam);
  8. STDAPI SHGetIconFromPIDL(IShellFolder *psf, IShellIcon *psi, LPCITEMIDLIST pidl, UINT flags, int *piImage);
  9. #define TF_ICON TF_DEFVIEW
  10. /////////////////////////////////////////////////////////////////////////////////////
  11. CDVBkgrndEnumTask::CDVBkgrndEnumTask( HRESULT * pHr, 
  12.                                       CDefView * pdsv, 
  13.                                       IEnumIDList *peunk, 
  14.                                       HDPA hdpaNew, 
  15.                                       BOOL fRefresh )
  16.    : CRunnableTask( RTF_SUPPORTKILLSUSPEND )
  17. {
  18.     ASSERT( pHr );
  19.     *pHr = NOERROR;
  20.     _pdsv = pdsv;
  21.     if ( _pdsv )
  22.         ChangeRefForIdle(_pdsv, TRUE);
  23.     else
  24.         *pHr = E_INVALIDARG;
  25.     _peunk = peunk;
  26.     if ( _peunk )
  27.         _peunk->AddRef();
  28.     else
  29.         *pHr = E_INVALIDARG;
  30.         
  31.     _hdpaNew = hdpaNew;
  32.     _fRefresh = fRefresh;
  33. }
  34. /////////////////////////////////////////////////////////////////////////////////////
  35. CDVBkgrndEnumTask::~CDVBkgrndEnumTask()
  36. {
  37.     IUnknown_SetSite( _peunk, NULL);      // Break the site back pointer.
  38.     
  39.     ATOMICRELEASE( _peunk );
  40.     if ( _hdpaNew )
  41.     {
  42.         // empty the DPA first of all the pidls...
  43.         for ( int iPtr = 0; iPtr < DPA_GetPtrCount( _hdpaNew ); iPtr ++ )
  44.         {
  45.             LPITEMIDLIST pidl = (LPITEMIDLIST) DPA_GetPtr( _hdpaNew, iPtr );
  46.             ASSERT( pidl );
  47.             ILFree( pidl );
  48.         }
  49.         DPA_DeleteAllPtrs( _hdpaNew );
  50.         DPA_Destroy( _hdpaNew );
  51.     }
  52.     if ( _pdsv )
  53.         ChangeRefForIdle( _pdsv, FALSE );
  54. }
  55. /////////////////////////////////////////////////////////////////////////////////////
  56. STDMETHODIMP CDVBkgrndEnumTask::RunInitRT( )
  57. {
  58.     // nothing needed to init ...
  59.     return NOERROR;
  60. }
  61. /////////////////////////////////////////////////////////////////////////////////////
  62. STDMETHODIMP CDVBkgrndEnumTask::InternalResumeRT( )
  63. {
  64.     LPITEMIDLIST pidl = NULL;   // just in case
  65.     ULONG celt;
  66.     while ( _peunk->Next( 1, &pidl, &celt) == S_OK)
  67.     {
  68.         // do we need to quit, 
  69.         if ( DPA_AppendPtr(_hdpaNew, pidl) == -1 )
  70.         {
  71.             SHFree(pidl);
  72.         }
  73.         // we were told to either suspend or quit...
  74.         if ( WaitForSingleObject( _hDone, 0 ) == WAIT_OBJECT_0 )
  75.         {
  76.             // return a different error code if we are beign killed...
  77.             if ( _lState != IRTIR_TASK_SUSPENDED )
  78.             {
  79.                 _pdsv->_bBkFilling = FALSE;
  80.             }
  81.             return ( _lState == IRTIR_TASK_SUSPENDED ) ? E_PENDING : E_FAIL;
  82.         }
  83.         pidl = NULL;
  84.     }
  85.     _pdsv->_bBkFilling = FALSE;
  86.     HWND hwndView;
  87.     // Sort on this thread so we do not hang the main thread for as long
  88.     DPA_Sort( _hdpaNew, _pdsv->_GetCompareFunction(), (LPARAM)_pdsv );
  89.     // Tell the main thread to merge the items
  90.     hwndView = _pdsv->_hwndView;
  91.     ASSERT( IsWindow( hwndView ));
  92.     if (PostMessage(hwndView, WM_DSV_DESTROYSTATIC,
  93.                                 _fRefresh, (LPARAM)_hdpaNew))
  94.     {
  95.         // If hwndView is destroyed before receiving this message, we could
  96.         // have a memory leak.  Oh well.
  97.         _hdpaNew = NULL;
  98.     }
  99.     // notify DefView that we're done
  100.     // (NOTE: We can not call the callback directly from here. This causes
  101.     // a gp fault in RecalcIdealSize when we restart after setup (if we hit
  102.     // a small timing window when pdvoi becomes NULL from underneath us.
  103.     // So, we post a message here and while processing it, we will do the
  104.     // actual callback.
  105.     PostMessage( _pdsv->_hwndView, WM_DSV_BACKGROUNDENUMDONE, 0, 0);
  106.     return NOERROR;
  107. }
  108. /////////////////////////////////////////////////////////////////////////////////////
  109. HRESULT CDVBkgrndEnumTask_CreateInstance( CDefView * pdsv, IEnumIDList *peunk,
  110.             HDPA hdpaNew, BOOL fRefresh, LPRUNNABLETASK *ppTask )
  111. {
  112.     HRESULT hr = NOERROR;
  113.     *ppTask = NULL;
  114.     
  115.     CDVBkgrndEnumTask * pNewTask = new CDVBkgrndEnumTask( &hr, pdsv, peunk, hdpaNew, fRefresh );
  116.     if ( pNewTask )
  117.     {
  118.         if ( SUCCEEDED( hr ))
  119.         {
  120.             *ppTask = SAFECAST( pNewTask, IRunnableTask *);
  121.         }
  122.         if ( FAILED( hr ))
  123.         {
  124.             delete pNewTask;
  125.         }
  126.     }
  127.     else
  128.         hr = E_OUTOFMEMORY;
  129.     return hr;
  130. }
  131. /////////////////////////////////////////////////////////////////////////////////////
  132. /////////////////////////////////////////////////////////////////////////////////////
  133. CDVGetIconTask::CDVGetIconTask( HRESULT * pHr, 
  134.                                 LPCITEMIDLIST pidl,
  135.                                 CDefView * pdsv )
  136.     : CRunnableTask( RTF_DEFAULT )
  137. {
  138.     // assume zero init
  139.     ASSERT( !_pdsv && !_pidl);
  140.     ASSERT( pHr );
  141.     if ( pdsv && pidl)
  142.     {
  143.         _pidl = ILClone( pidl );
  144.         if ( !_pidl )
  145.         {
  146.             *pHr = E_OUTOFMEMORY;
  147.             return;
  148.         }
  149.         
  150.         _pdsv = pdsv;
  151.         ChangeRefForIdle(_pdsv, TRUE);
  152.     }
  153.     else
  154.     {
  155.         *pHr = E_INVALIDARG;
  156.     }
  157. }
  158. /////////////////////////////////////////////////////////////////////////////////////
  159. CDVGetIconTask::~CDVGetIconTask()
  160. {
  161.     if ( _pdsv )
  162.     {
  163.         ChangeRefForIdle( _pdsv, FALSE );
  164.     }
  165.     if ( _pidl )
  166.     {
  167.         ILFree( _pidl );
  168.     }
  169. }
  170. /////////////////////////////////////////////////////////////////////////////////////
  171. STDMETHODIMP CDVGetIconTask::RunInitRT( )
  172. {
  173.     BOOL fPosted = FALSE;
  174.     ASSERT(_pidl);
  175.     ASSERT( IsWindow( _pdsv->_hwndView ));
  176.     _iIcon = -1;
  177.     //
  178.     // get the icon for this item.
  179.     //
  180.     SHGetIconFromPIDL(_pdsv->_pshf, _pdsv->_psi, _pidl, 0, &_iIcon);
  181.     if (_iIcon != -1)
  182.     {
  183.         //
  184.         //  now post the result back to the main thread
  185.         //
  186.         
  187.         // bump the ref count, it will get released from the reciever...
  188.         this->AddRef();
  189.             
  190.         if (PostMessage(_pdsv->_hwndView, WM_DSV_UPDATEICON, 0, (LPARAM) this))
  191.         {
  192.             if (_pdsv->_AsyncIconEvent)
  193.                 SetEvent(_pdsv->_AsyncIconEvent);
  194.             fPosted = TRUE;
  195.         }
  196.         else
  197.         {
  198.             this->Release();
  199.         }
  200.     }
  201.     //
  202.     // Clean up everything ourselves if we didn't post anything.
  203.     //
  204.     if (!fPosted )
  205.     {
  206.         InterlockedDecrement(&_pdsv->_AsyncIconCount);
  207.         
  208.         DebugMsg(TF_ICON, TEXT("async icon CANCELED: pidl=%08X count=%d"), _pidl, _pdsv->_AsyncIconCount);
  209.     }
  210.     return NOERROR;
  211. }
  212. /////////////////////////////////////////////////////////////////////////////////////
  213. HRESULT CDVGetIconTask_CreateInstance( CDefView * pdsv, LPCITEMIDLIST pidl, LPRUNNABLETASK *ppTask, CDVGetIconTask ** ppObject )
  214. {
  215.     HRESULT hr = NOERROR;
  216.     *ppObject = NULL;
  217.     
  218.     CDVGetIconTask * pNewTask = new CDVGetIconTask( &hr, pidl, pdsv);
  219.     if(pNewTask)
  220.     {
  221.         if(SUCCEEDED(hr))
  222.         {
  223.             *ppTask = SAFECAST( pNewTask, IRunnableTask *);
  224.             if ( ppObject )
  225.                 *ppObject = pNewTask;
  226.         }
  227.         else
  228.             delete pNewTask;
  229.     }
  230.     else
  231.         hr = E_OUTOFMEMORY;
  232.     return hr;
  233. }
  234. CDVExtendedColumnTask::CDVExtendedColumnTask(CDefView * pdsv, LPCITEMIDLIST pidl, int fmt, UINT uiColumn)
  235.     : CRunnableTask(RTF_DEFAULT),
  236.     _pdsv(pdsv),
  237.     _pidl(ILClone(pidl)),
  238.     _fmt(fmt),
  239.     _uiCol(uiColumn)
  240. {
  241.     _pdsv->AddRef();
  242. }
  243. CDVExtendedColumnTask::~CDVExtendedColumnTask()
  244. {
  245.     ILFree(const_cast<LPITEMIDLIST>(_pidl));
  246.     ATOMICRELEASE(_pdsv);
  247. }
  248. STDMETHODIMP CDVExtendedColumnTask::RunInitRT(void)
  249. {
  250.     DETAILSINFO di;
  251.     
  252.     di.pidl = _pidl;
  253.     di.fmt = _fmt;
  254.     HRESULT hr = _pdsv->_GetDetailsHelper(_uiCol, &di);
  255.     if (SUCCEEDED(hr))
  256.     {
  257.         CBackgroundColInfo  *pbgci;
  258.         pbgci = new CBackgroundColInfo(_pidl, _uiCol, di.str);
  259.         if (pbgci == NULL)
  260.             return E_OUTOFMEMORY;
  261.         _pidl = NULL;        // ILFree checks for null
  262.         //TraceMsg(TF_DEFVIEW, "DVECTask::RunInitRT- got text %s for %d", pbgci->szText, _iCol);
  263.         if (!PostMessage(_pdsv->_hwndView, WM_DSV_UPDATECOLDATA, 0, (LPARAM)pbgci))
  264.             delete pbgci;
  265.     }
  266.     return hr;
  267. }
  268. HRESULT CDVExtendedColumnTask_CreateInstance(CDefView * pdsv, LPCITEMIDLIST pidl, int fmt, UINT uiColumn, IRunnableTask **ppTask)
  269. {
  270.     CDVExtendedColumnTask *pDVECTask = new CDVExtendedColumnTask(pdsv, pidl, fmt, uiColumn);
  271.     if (!pDVECTask)
  272.         return E_OUTOFMEMORY;
  273.     if (ppTask)
  274.         *ppTask = SAFECAST(pDVECTask, IRunnableTask*);
  275.     return S_OK;
  276. }
  277. /////////////////////////////////////////////////////////////////////////////////////
  278. /////////////////////////////////////////////////////////////////////////////////////
  279. CDVIconOverlayTask::CDVIconOverlayTask( HRESULT * pHr, 
  280.                                 LPCITEMIDLIST pidl,
  281.                                 int iList, 
  282.                                 CDefView * pdsv )
  283.     : CRunnableTask( RTF_DEFAULT ), _iList(iList)
  284. {
  285.     // assume zero init
  286.     ASSERT( !_pdsv && !_pidl);
  287.     ASSERT( pHr );
  288.     if ( pdsv && pidl)
  289.     {
  290.         _pidl = ILClone( pidl );
  291.         if ( !_pidl )
  292.         {
  293.             *pHr = E_OUTOFMEMORY;
  294.             return;
  295.         }
  296.         
  297.         _pdsv = pdsv;
  298.         ChangeRefForIdle(_pdsv, TRUE);
  299.     }
  300.     else
  301.     {
  302.         *pHr = E_INVALIDARG;
  303.     }
  304. }
  305. /////////////////////////////////////////////////////////////////////////////////////
  306. CDVIconOverlayTask::~CDVIconOverlayTask()
  307. {
  308.     if ( _pdsv )
  309.     {
  310.         ChangeRefForIdle( _pdsv, FALSE );
  311.     }
  312.     if ( _pidl )
  313.     {
  314.         ILFree( _pidl );
  315.     }
  316. }
  317. /////////////////////////////////////////////////////////////////////////////////////
  318. STDMETHODIMP CDVIconOverlayTask::RunInitRT( )
  319. {
  320.     ASSERT(_pidl);
  321.     ASSERT( IsWindow( _pdsv->_hwndView ));
  322.     ASSERT(IS_VALID_CODE_PTR(_pdsv->_psio, IShellIconOverlay));
  323.     
  324.     int iOverlay = 0;
  325.     
  326.     //
  327.     // get the overlay index for this item.
  328.     //
  329.     _pdsv->_psio->GetOverlayIndex(_pidl, &iOverlay);
  330.     if (iOverlay > 0)
  331.     {
  332.         //
  333.         //  now post the result back to the main thread
  334.         //
  335.         PostMessage(_pdsv->_hwndView, WM_DSV_UPDATEOVERLAY, (WPARAM)_iList, (LPARAM)iOverlay);
  336.     }
  337.     return NOERROR;
  338. }
  339. /////////////////////////////////////////////////////////////////////////////////////
  340. HRESULT CDVIconOverlayTask_CreateInstance( CDefView * pdsv, LPCITEMIDLIST pidl, int iList, LPRUNNABLETASK *ppTask)
  341. {
  342.     HRESULT hr = NOERROR;
  343.     *ppTask = NULL;
  344.     
  345.     CDVIconOverlayTask * pNewTask = new CDVIconOverlayTask( &hr, pidl, iList, pdsv);
  346.     if(pNewTask)
  347.     {
  348.         if(SUCCEEDED(hr))
  349.             *ppTask = SAFECAST( pNewTask, IRunnableTask *);
  350.         else
  351.         {
  352.             delete pNewTask;
  353.             hr = E_FAIL;
  354.         }
  355.     }
  356.     else
  357.     {
  358.         hr = E_OUTOFMEMORY;
  359.     }
  360.     return hr;
  361. }