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

Windows Kernel

Development Platform:

Visual C++

  1. #include "precomp.h"
  2. #include "shellp.h"
  3. #include "dllload.h"
  4. UINT GetPidlLength( LPCITEMIDLIST pidl )
  5. {
  6.     UINT cbSize = 0;
  7.     while ( pidl->mkid.cb != 0 )
  8.     {
  9.         cbSize += pidl->mkid.cb;
  10.         pidl = (LPCITEMIDLIST) ( (BYTE *) pidl + pidl->mkid.cb);
  11.     }
  12.     return cbSize;
  13. }
  14. ////////////////////////////////////////////////////////////////////////////////
  15. // used the the ListView for sorting items.
  16. int CALLBACK ListViewCompare( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort )
  17. {
  18.     ListViewCompareStruct * pStruct = (ListViewCompareStruct * ) lParamSort;
  19.     Assert( pStruct->m_pFolder != NULL );
  20.     HRESULT hr = pStruct->m_pFolder->CompareIDs( pStruct->m_iCompareFlag,
  21.                                                  (LPCITEMIDLIST) lParam1,
  22.                                                  (LPCITEMIDLIST) lParam2 );
  23.     int iRes = (int) (short) SCODE_CODE( GetScode( hr ));
  24.     return iRes * pStruct->m_iAscend;
  25. }
  26. /////////////////////////////////////////////////////////////////////////////////
  27. HRESULT GetSelectionPidlList( HWND hwnd,
  28.                               int cItems,
  29.                               LPCITEMIDLIST * apidl,
  30.                               int iItemHit )
  31. {
  32.     if ( apidl == NULL )
  33.     {
  34.         return E_INVALIDARG;
  35.     }
  36.     
  37.     int iItem = -1;
  38.     // assume that the get function doesn't mangle this structure too bad ...
  39.     LV_ITEMW rgItem;
  40.     ZeroMemory( &rgItem, sizeof( LV_ITEM ) );
  41.     rgItem.mask = LVIF_PARAM;
  42.     int iCtr = 0;
  43.     
  44.     for ( int iIndex = 0; iIndex < (int) cItems; iIndex ++ )
  45.     {
  46.         iItem = ListView_GetNextItem( hwnd, iItem, LVNI_SELECTED );
  47.         // Assert that we were not passed a bogus view selection count...
  48.         Assert( iItem != -1 );
  49.         rgItem.iItem = iItem;
  50.         ListView_GetItemWrapW( hwnd, &rgItem);
  51.         Assert( rgItem.mask & LVIF_PARAM );
  52.     // NOTE: we must put the item that was FOCUSED as the
  53.     // NOTE: top item in the list. there are context menu extensions that depend on
  54. // NOTE: this behaviour ....etc
  55.         // Check if the item is the focused one or not.
  56.         if ( iItem == ( int )iItemHit )
  57.         {
  58.             // Yes, put it at the top.
  59.             apidl[iCtr] = apidl[0];
  60.             apidl[0] = (LPCITEMIDLIST) rgItem.lParam;
  61.         }
  62.         else
  63.             // No, put it at the end of the list.
  64.             apidl[iCtr] = (LPCITEMIDLIST) rgItem.lParam;
  65.         iCtr++;
  66.     }
  67.     return NOERROR;
  68. }
  69. ///////////////////////////////////////////////////////////////////////////////////
  70. int FindInView( HWND hWnd, LPSHELLFOLDER pFolder, LPCITEMIDLIST pidl )
  71. {
  72.     if ( pFolder == NULL || pidl == NULL )
  73.     {
  74.         return -1;
  75.     }
  76.     
  77.     LV_ITEMW rgItem;
  78.     int     iItem = -1;
  79.     memset( &rgItem, 0, sizeof( rgItem ) );
  80.     // search through the list view looking for a matching lParam       
  81.     do
  82.     {
  83.         iItem = ListView_GetNextItem( hWnd, iItem, LVNI_ALL );
  84.         if ( iItem != -1 )
  85.         {
  86.             rgItem.mask = LVIF_PARAM;
  87.             rgItem.iItem = iItem;
  88.             BOOL bRes = (BOOL) SendMessageA( hWnd, LVM_GETITEMW, 0, (LPARAM)(LV_ITEMW *)(&rgItem));
  89.             Assert( bRes );
  90.             // ask the folder to kindly compare the Id's for us
  91.             if ( pFolder->CompareIDs( 0, pidl, (LPCITEMIDLIST) rgItem.lParam ) == 0 )
  92.             {
  93.                 break;
  94.             }
  95.         }
  96.     }
  97.     while ( iItem != -1 );
  98.     
  99.     return iItem;
  100. }
  101. /////////////////////////////////////////////////////////////////////////////////////////
  102. void Clear( HWND hWnd )
  103. {
  104.     // because we cache an instance of the pidl as the LPARAM, 
  105.     // it must be freed, so we must enum the vew first..
  106.     int iItem = -1;
  107.     LV_ITEMW rgItem;
  108.     ZeroMemory ( &rgItem, sizeof( rgItem ));
  109.     
  110.     rgItem.mask = LVIF_PARAM;
  111.     
  112.     do
  113.     {
  114.         iItem = ListView_GetNextItem( hWnd, iItem, LVNI_ALL );
  115.         if ( iItem == -1 )
  116.             break;
  117.         rgItem.iItem = iItem;
  118.         rgItem.lParam = 0;
  119.         
  120.         if ( ListView_GetItemWrapW( hWnd, &rgItem))
  121.         {
  122.             Assert( rgItem.lParam != NULL );
  123.             SHFree( (LPVOID ) rgItem.lParam );
  124.         }
  125.     }
  126.     while ( iItem != -1 );
  127.     ListView_DeleteAllItems( hWnd );
  128. }
  129. //////////////////////////////////////////////////////////////////////////////////////
  130. UINT MergeMenus( HMENU hOriginal, HMENU hNew, UINT idStart, UINT idPos )
  131. {
  132.     UINT idMax = idStart;
  133.     MENUITEMINFOW rgMenuItem;
  134.     WCHAR szMenuItem[MAX_PATH];
  135.     
  136.     int iMenuSize = GetMenuItemCount( hOriginal );
  137.     for (int iItem = GetMenuItemCount(hNew)-1; iItem >= 0; -- iItem)
  138.     {
  139.         rgMenuItem.cbSize = sizeof(rgMenuItem);
  140.         rgMenuItem.fMask = MIIM_ID | MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE | MIIM_DATA;
  141.         rgMenuItem.dwTypeData = szMenuItem;
  142.         rgMenuItem.cch = MAX_PATH; 
  143.         rgMenuItem.dwItemData = 0;
  144.         BOOL bRes = GetMenuItemInfoWrapW(hNew, iItem, TRUE, &rgMenuItem);
  145.         if ( bRes == FALSE )
  146.         {
  147.             continue;
  148.         }
  149.         // only adjust the ID if it is not a submenu and is not a separator ...
  150.         if (( rgMenuItem.fMask & MIIM_ID ) && 
  151.             ( rgMenuItem.hSubMenu == NULL ) &&
  152.             ( rgMenuItem.fType != MFT_SEPARATOR ))
  153.         {
  154.             rgMenuItem.wID += idStart;
  155.             if ( idMax < rgMenuItem.wID )
  156.             {
  157.                 idMax = rgMenuItem.wID;
  158.             }
  159.         }
  160.         if ( rgMenuItem.hSubMenu != NULL )
  161.         {
  162.             // must fix up the ID's of the cascading items ...
  163.             MENUITEMINFOW miiSub;
  164.             // assume that there is only one level of cascading menu.....
  165.             for ( int iSubItem = GetMenuItemCount(rgMenuItem.hSubMenu) -1; iSubItem >= 0; -- iSubItem )
  166.             {
  167.                 miiSub.cbSize = sizeof( miiSub );
  168.                 miiSub.fMask = MIIM_ID | MIIM_TYPE;
  169.                 miiSub.cch = 0;
  170.                 miiSub.hSubMenu = NULL;
  171.                 miiSub.fType = 0;
  172.                 BOOL bRes = GetMenuItemInfoWrapW( rgMenuItem.hSubMenu, iSubItem, TRUE, &miiSub );
  173.                 if ( bRes == TRUE )
  174.                 {
  175.                     // only adjust the menu id if it really is a menu item not a submenu or
  176.                     // separator...
  177.                     if (( miiSub.fMask & MIIM_ID ) &&
  178.                         ( miiSub.hSubMenu == NULL ) &&
  179.                         ( miiSub.fType != MFT_SEPARATOR ))
  180.                     {
  181.                         miiSub.wID += idStart;
  182.                         if ( idMax < miiSub.wID )
  183.                         {
  184.                             idMax = miiSub.wID;
  185.                         }
  186.                         // we only want to change the ID
  187.                         miiSub.fMask = MIIM_ID;
  188.                         SetMenuItemInfoWrapW( rgMenuItem.hSubMenu, iSubItem, TRUE, & miiSub );
  189.                     }
  190.                 }
  191.             }
  192.             // remove the menu from the original so that it is not destroyed later.....
  193.             // otherwise there seems to be a menu ref count lying around and the opertunity
  194.             // that when the original menu is destroyed it will destroy all the sub-menus
  195.             // with it.
  196.             RemoveMenu( hNew, iItem, MF_BYPOSITION );
  197.         }
  198.         
  199.         InsertMenuItemWrapW( hOriginal, idPos, TRUE, &rgMenuItem );
  200.     }
  201.     return(idMax);
  202. }
  203. ///////////////////////////////////////////////////////////////////////////////////////////////
  204. // add a separator to the menu in the position specified
  205. void AddMenuSeparator( HMENU hMenu, int iIndex )
  206. {
  207.     AddMenuSeparatorWithID( hMenu, iIndex, 0 );
  208. }
  209. void AddMenuSeparatorWithID( HMENU hMenu, int iIndex, UINT iID )
  210. {
  211.     MENUITEMINFOW mii;
  212.     mii.cbSize = sizeof( mii );
  213.     mii.fMask = MIIM_TYPE | MIIM_ID;
  214.     mii.wID = iID;
  215.     mii.fType = MFT_SEPARATOR;
  216.     mii.cch = 0;
  217.     InsertMenuItemWrapW( hMenu, iIndex, TRUE, &mii ); 
  218. }
  219. //////////////////////////////////////////////////////////////////////////////////////
  220. HMENU LoadPopupMenu( HINSTANCE hDllInst, int iResID )
  221. {
  222.     HMENU hParent = LoadMenuA(hDllInst, (LPCSTR) MAKEINTRESOURCE(iResID));
  223.     if (hParent) 
  224.     {
  225.         HMENU hpopup = GetSubMenu(hParent, 0);
  226.         RemoveMenu(hParent, 0, MF_BYPOSITION);
  227.         
  228.         DestroyMenu(hParent);
  229.         return hpopup;
  230.     }
  231.     return NULL;
  232. }
  233. //////////////////////////////////////////////////////////////////////////////////////
  234. // get color resolution of the current display.
  235. UINT GetCurColorRes( void )
  236. {
  237.     HDC hdc;
  238.     UINT uColorRes;
  239.     hdc = GetDC( NULL );
  240.     uColorRes = GetDeviceCaps( hdc, PLANES ) * GetDeviceCaps( hdc, BITSPIXEL );
  241.     ReleaseDC( NULL , hdc );
  242.     return uColorRes;
  243. }
  244. //////////////////////////////////////////////////////////////////////////////////////
  245. LPCITEMIDLIST * DuplicateIDArray( LPCITEMIDLIST * apidl, UINT cidl )
  246. {
  247.     LPCITEMIDLIST * apidlNew = (LPCITEMIDLIST *) LocalAlloc( LPTR, cidl * sizeof( LPCITEMIDLIST ));
  248.     if ( apidlNew )
  249.     {
  250.         CopyMemory( apidlNew, apidl, cidl * sizeof( LPCITEMIDLIST ));
  251.     }
  252.     return apidlNew;
  253. }
  254. //////////////////////////////////////////////////////////////////////////////////////////
  255. HRESULT SHCLSIDFromStringA( LPCSTR szCLSID, CLSID * pCLSID )
  256. {
  257.     WCHAR szWCLSID[50];
  258.     MultiByteToWideChar( CP_ACP, 0, szCLSID, -1, szWCLSID, 50);
  259.     return CLSIDFromString( szWCLSID, pCLSID );
  260. }
  261. //////////////////////////////////////////////////////////////////////////////////////////
  262. HRESULT SHStringFromCLSIDA( LPSTR szCLSID, DWORD cSize, REFCLSID rCLSID )
  263. {
  264.     if ( cSize < 39 )
  265.     {
  266.         return E_INVALIDARG;
  267.     }
  268.     
  269.     WCHAR szWCLSID[40];
  270.     HRESULT hr = StringFromGUID2( rCLSID, szWCLSID, 40 );
  271.     if ( FAILED( hr ))
  272.     {
  273.         return hr;
  274.     }
  275.     
  276.     WideCharToMultiByte( CP_ACP, 0, szWCLSID, -1, szCLSID, cSize, 0, 0);
  277.     return hr;
  278. }
  279. ///////////////////////////////////////////////////////////////////
  280. LPCITEMIDLIST FindLastPidl(LPCITEMIDLIST pidl)
  281. {
  282.     LPCITEMIDLIST pidlLast = pidl;
  283.     LPCITEMIDLIST pidlNext = pidl;
  284.     if (pidl == NULL)
  285.         return NULL;
  286.     // Find the last one
  287.     while (pidlNext->mkid.cb)
  288.     {
  289.         pidlLast = pidlNext;
  290.         pidlNext = NextPIDL(pidlLast);
  291.     }
  292.     return (LPCITEMIDLIST)pidlLast;
  293. }
  294. ///////////////////////////////////////////////////////////////////////////////////////////////////
  295. HRESULT SimpleIDLISTToRealIDLIST( IShellFolder * psf, LPCITEMIDLIST pidlSimple, LPITEMIDLIST * ppidlReal )
  296. {
  297.     Assert( psf && pidlSimple && ppidlReal );
  298.     STRRET rgStr;
  299.     // check to make sure that we have a single level pidl
  300.     LPCITEMIDLIST pidlNext = NextPIDL( pidlSimple );
  301.     if ( pidlNext && pidlNext->mkid.cb != 0 )
  302.     {
  303.         return E_INVALIDARG;
  304.     }
  305.     
  306.     HRESULT hres = psf->GetDisplayNameOf( pidlSimple, SHGDN_FORPARSING | SHGDN_INFOLDER, &rgStr );
  307.     if ( SUCCEEDED( hres ))
  308.     {
  309.         WCHAR szPath[MAX_PATH];
  310.         StrRetToBufW( &rgStr, pidlSimple, szPath, ARRAYSIZE(szPath) );
  311.         hres = psf->ParseDisplayName( NULL, NULL, szPath, NULL, ppidlReal, NULL );
  312.     }
  313.     return hres;    
  314. }
  315. HRESULT Invoke_OnConnectionPointerContainer(IUnknown * punk, REFIID riidCP, DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo, UINT * puArgErr)
  316. {
  317.     HRESULT hr = S_OK;     // Assume no errors.
  318.     IConnectionPointContainer * pcpc; 
  319.     hr = punk->QueryInterface(IID_IConnectionPointContainer, (LPVOID*)&pcpc);
  320.     if (SUCCEEDED(hr))
  321.     {
  322.         IConnectionPoint * pcp;
  323.         hr = pcpc->FindConnectionPoint(riidCP, &pcp);
  324.         if (SUCCEEDED(hr))
  325.         {
  326.             IEnumConnections * pec;
  327.             hr = pcp->EnumConnections(&pec);
  328.             if (SUCCEEDED(hr))
  329.             {
  330.                 CONNECTDATA cd;
  331.                 ULONG cFetched;
  332.                 while (S_OK == (hr = pec->Next(1, &cd, &cFetched)))
  333.                 {
  334.                     LPDISPATCH pdisp;
  335.                     Assert(1 == cFetched);
  336.                     hr = cd.pUnk->QueryInterface(IID_IDispatch, (LPVOID *) &pdisp);
  337.                     if (SUCCEEDED(hr))
  338.                     {
  339.                         DISPPARAMS dispparams = {0};
  340.                         
  341.                         if (!pdispparams)
  342.                             pdispparams = &dispparams;
  343.                         hr = pdisp->Invoke(dispidMember, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr);
  344.                         pdisp->Release();
  345.                     }
  346.                     else
  347.                         Assert(FALSE);              
  348.                 }
  349.                 pec->Release();
  350.             }
  351.             else
  352.                 Assert(FALSE);              
  353.             pcp->Release();
  354.         }
  355.         else
  356.             Assert(FALSE);              
  357.         pcpc->Release();
  358.     }
  359.     else    
  360.         Assert(FALSE);
  361.     return hr;
  362. }
  363. // Review chrisny:  this can be moved into an object easily to handle generic droptarget, dropcursor
  364. // , autoscrool, etc. . .
  365. void _DragEnter(HWND hwndTarget, const POINTL ptStart, IDataObject *pdtObject)
  366. {
  367.     RECT    rc;
  368.     POINT   pt;
  369.     GetWindowRect(hwndTarget, &rc);
  370.     if (IS_WINDOW_RTL_MIRRORED(hwndTarget))
  371.         pt.x = rc.right - ptStart.x;
  372.     else
  373.         pt.x = ptStart.x - rc.left;
  374.     pt.y = ptStart.y - rc.top;
  375.     DAD_DragEnterEx2(hwndTarget, pt, pdtObject);
  376.     return;
  377. }
  378. void _DragMove(HWND hwndTarget, const POINTL ptStart)
  379. {
  380.     RECT rc;
  381.     POINT pt;
  382.     GetWindowRect(hwndTarget, &rc);
  383.     if (IS_WINDOW_RTL_MIRRORED(hwndTarget))
  384.         pt.x = rc.right - ptStart.x;
  385.     else
  386.         pt.x = ptStart.x - rc.left;
  387.     pt.y = ptStart.y - rc.top;
  388.     DAD_DragMove(pt);
  389.     return; 
  390. }