annotate kdiff3/src-QT4/kreplacements/ShellContextMenu.cpp @ 75:08ea9b86c12c

KDiff3-0.9.91
author joachim99
date Sat, 04 Nov 2006 00:05:00 +0000
parents kdiff3/src/kreplacements/ShellContextMenu.cpp@5bbfe4784324
children 1184fc843210
rev   line source
joachim99@69 1 // ShellContextMenu.cpp: Implementierung der Klasse CShellContextMenu.
joachim99@69 2 //
joachim99@69 3 //////////////////////////////////////////////////////////////////////
joachim99@69 4 #ifdef _WIN32
joachim99@69 5 #include <windows.h>
joachim99@69 6 #include <shlobj.h>
joachim99@69 7 #include <malloc.h>
joachim99@69 8 #include <qstring.h>
joachim99@69 9 #include <qstringlist.h>
joachim99@69 10 #include <qwidget.h>
joachim99@69 11 #include <qdir.h>
joachim99@70 12 #include <QMenu>
joachim99@69 13 #include "ShellContextMenu.h"
joachim99@69 14
joachim99@69 15 #ifdef _DEBUG
joachim99@69 16 #undef THIS_FILE
joachim99@69 17 static char THIS_FILE[]=__FILE__;
joachim99@69 18 #define new DEBUG_NEW
joachim99@69 19 #endif
joachim99@69 20
joachim99@69 21 //////////////////////////////////////////////////////////////////////
joachim99@69 22 // Konstruktion/Destruktion
joachim99@69 23 //////////////////////////////////////////////////////////////////////
joachim99@69 24
joachim99@69 25 #define MIN_ID 100
joachim99@69 26 #define MAX_ID 10000
joachim99@69 27
joachim99@69 28
joachim99@70 29 void showShellContextMenu( const QString& itemPath, QPoint pt, QWidget* pParentWidget, QMenu* pMenu )
joachim99@69 30 {
joachim99@69 31 CShellContextMenu scm;
joachim99@69 32 scm.SetObjects(QDir::convertSeparators(itemPath));
joachim99@69 33 int id = scm.ShowContextMenu (pParentWidget, pt, pMenu);
joachim99@69 34 if (id>=1)
joachim99@75 35 pMenu->actions().value(id-1)->trigger();
joachim99@69 36 }
joachim99@69 37
joachim99@69 38 IContextMenu2 * g_IContext2 = NULL;
joachim99@69 39 IContextMenu3 * g_IContext3 = NULL;
joachim99@69 40
joachim99@69 41 CShellContextMenu::CShellContextMenu()
joachim99@69 42 {
joachim99@69 43 m_psfFolder = NULL;
joachim99@69 44 m_pidlArray = NULL;
joachim99@69 45 m_hMenu = NULL;
joachim99@69 46 }
joachim99@69 47
joachim99@69 48 CShellContextMenu::~CShellContextMenu()
joachim99@69 49 {
joachim99@69 50 // free all allocated datas
joachim99@69 51 if (m_psfFolder && bDelete)
joachim99@69 52 m_psfFolder->Release ();
joachim99@69 53 m_psfFolder = NULL;
joachim99@69 54 FreePIDLArray (m_pidlArray);
joachim99@69 55 m_pidlArray = NULL;
joachim99@69 56
joachim99@69 57 if (m_hMenu)
joachim99@69 58 DestroyMenu( m_hMenu );
joachim99@69 59 }
joachim99@69 60
joachim99@69 61
joachim99@69 62
joachim99@69 63 // this functions determines which version of IContextMenu is avaibale for those objects (always the highest one)
joachim99@69 64 // and returns that interface
joachim99@69 65 BOOL CShellContextMenu::GetContextMenu (void ** ppContextMenu, int & iMenuType)
joachim99@69 66 {
joachim99@69 67 *ppContextMenu = NULL;
joachim99@69 68 LPCONTEXTMENU icm1 = NULL;
joachim99@69 69
joachim99@69 70 // first we retrieve the normal IContextMenu interface (every object should have it)
joachim99@69 71 m_psfFolder->GetUIObjectOf (NULL, nItems, (LPCITEMIDLIST *) m_pidlArray, IID_IContextMenu, NULL, (void**) &icm1);
joachim99@69 72
joachim99@69 73 if (icm1)
joachim99@69 74 { // since we got an IContextMenu interface we can now obtain the higher version interfaces via that
joachim99@69 75 if (icm1->QueryInterface (IID_IContextMenu3, ppContextMenu) == NOERROR)
joachim99@69 76 iMenuType = 3;
joachim99@69 77 else if (icm1->QueryInterface (IID_IContextMenu2, ppContextMenu) == NOERROR)
joachim99@69 78 iMenuType = 2;
joachim99@69 79
joachim99@69 80 if (*ppContextMenu)
joachim99@69 81 icm1->Release(); // we can now release version 1 interface, cause we got a higher one
joachim99@69 82 else
joachim99@69 83 {
joachim99@69 84 iMenuType = 1;
joachim99@69 85 *ppContextMenu = icm1; // since no higher versions were found
joachim99@69 86 } // redirect ppContextMenu to version 1 interface
joachim99@69 87 }
joachim99@69 88 else
joachim99@69 89 return (FALSE); // something went wrong
joachim99@69 90
joachim99@69 91 return (TRUE); // success
joachim99@69 92 }
joachim99@69 93
joachim99@69 94
joachim99@69 95 LRESULT CALLBACK CShellContextMenu::HookWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
joachim99@69 96 {
joachim99@69 97 switch (message)
joachim99@69 98 {
joachim99@69 99 case WM_MENUCHAR: // only supported by IContextMenu3
joachim99@69 100 if (g_IContext3)
joachim99@69 101 {
joachim99@69 102 LRESULT lResult = 0;
joachim99@69 103 g_IContext3->HandleMenuMsg2 (message, wParam, lParam, &lResult);
joachim99@69 104 return (lResult);
joachim99@69 105 }
joachim99@69 106 break;
joachim99@69 107
joachim99@69 108 case WM_DRAWITEM:
joachim99@69 109 case WM_MEASUREITEM:
joachim99@69 110 if (wParam)
joachim99@69 111 break; // if wParam != 0 then the message is not menu-related
joachim99@69 112
joachim99@69 113 case WM_INITMENUPOPUP:
joachim99@69 114 if (g_IContext2)
joachim99@69 115 g_IContext2->HandleMenuMsg (message, wParam, lParam);
joachim99@69 116 else // version 3
joachim99@69 117 g_IContext3->HandleMenuMsg (message, wParam, lParam);
joachim99@69 118 return (message == WM_INITMENUPOPUP ? 0 : TRUE); // inform caller that we handled WM_INITPOPUPMENU by ourself
joachim99@69 119 break;
joachim99@69 120
joachim99@69 121 default:
joachim99@69 122 break;
joachim99@69 123 }
joachim99@69 124
joachim99@69 125 // call original WndProc of window to prevent undefined bevhaviour of window
joachim99@69 126 return ::CallWindowProc ((WNDPROC) GetProp ( hWnd, TEXT ("OldWndProc")), hWnd, message, wParam, lParam);
joachim99@69 127 }
joachim99@69 128
joachim99@69 129
joachim99@70 130 UINT CShellContextMenu::ShowContextMenu(QWidget * pParentWidget, QPoint pt, QMenu* pMenu )
joachim99@69 131 {
joachim99@69 132 HWND hWnd = pParentWidget->winId();
joachim99@69 133 int iMenuType = 0; // to know which version of IContextMenu is supported
joachim99@69 134 LPCONTEXTMENU pContextMenu; // common pointer to IContextMenu and higher version interface
joachim99@69 135
joachim99@69 136 if (!GetContextMenu ((void**) &pContextMenu, iMenuType))
joachim99@69 137 return (0); // something went wrong
joachim99@69 138
joachim99@69 139 if (!m_hMenu)
joachim99@69 140 {
joachim99@69 141 DestroyMenu( m_hMenu );
joachim99@69 142 m_hMenu = CreatePopupMenu ();
joachim99@69 143 }
joachim99@69 144
joachim99@75 145 int i;
joachim99@75 146 QList<QAction*> actionList = pMenu->actions();
joachim99@75 147 for( i=0; i<actionList.count(); ++i )
joachim99@69 148 {
joachim99@75 149 QString s = actionList.at(i)->text();
joachim99@69 150 if (!s.isEmpty())
joachim99@75 151 AppendMenuW( m_hMenu, MF_STRING, i+1, (LPCWSTR)s.utf16() );
joachim99@69 152 }
joachim99@69 153 AppendMenuW( m_hMenu, MF_SEPARATOR, i+1, L"" );
joachim99@69 154
joachim99@69 155 // lets fill the our popupmenu
joachim99@69 156 pContextMenu->QueryContextMenu (m_hMenu, GetMenuItemCount (m_hMenu), MIN_ID, MAX_ID, CMF_NORMAL | CMF_EXPLORE);
joachim99@69 157
joachim99@69 158 // subclass window to handle menurelated messages in CShellContextMenu
joachim99@69 159 WNDPROC OldWndProc;
joachim99@69 160 if (iMenuType > 1) // only subclass if its version 2 or 3
joachim99@69 161 {
joachim99@69 162 OldWndProc = (WNDPROC) SetWindowLong (hWnd, GWL_WNDPROC, (DWORD) HookWndProc);
joachim99@69 163 if (iMenuType == 2)
joachim99@69 164 g_IContext2 = (LPCONTEXTMENU2) pContextMenu;
joachim99@69 165 else // version 3
joachim99@69 166 g_IContext3 = (LPCONTEXTMENU3) pContextMenu;
joachim99@69 167 }
joachim99@69 168 else
joachim99@69 169 OldWndProc = NULL;
joachim99@69 170
joachim99@69 171 UINT idCommand = TrackPopupMenu (m_hMenu,TPM_RETURNCMD | TPM_LEFTALIGN, pt.x(), pt.y(), 0, pParentWidget->winId(), 0);
joachim99@69 172
joachim99@69 173 if (OldWndProc) // unsubclass
joachim99@69 174 SetWindowLong (hWnd, GWL_WNDPROC, (DWORD) OldWndProc);
joachim99@69 175
joachim99@69 176 if (idCommand >= MIN_ID && idCommand <= MAX_ID) // see if returned idCommand belongs to shell menu entries
joachim99@69 177 {
joachim99@69 178 InvokeCommand (pContextMenu, idCommand - MIN_ID); // execute related command
joachim99@69 179 idCommand = 0;
joachim99@69 180 }
joachim99@69 181
joachim99@69 182 pContextMenu->Release();
joachim99@69 183 g_IContext2 = NULL;
joachim99@69 184 g_IContext3 = NULL;
joachim99@69 185
joachim99@69 186 return (idCommand);
joachim99@69 187 }
joachim99@69 188
joachim99@69 189
joachim99@69 190 void CShellContextMenu::InvokeCommand (LPCONTEXTMENU pContextMenu, UINT idCommand)
joachim99@69 191 {
joachim99@69 192 CMINVOKECOMMANDINFO cmi = {0};
joachim99@69 193 cmi.cbSize = sizeof (CMINVOKECOMMANDINFO);
joachim99@69 194 cmi.lpVerb = (LPSTR) MAKEINTRESOURCE (idCommand);
joachim99@69 195 cmi.nShow = SW_SHOWNORMAL;
joachim99@69 196
joachim99@69 197 pContextMenu->InvokeCommand (&cmi);
joachim99@69 198 }
joachim99@69 199
joachim99@69 200
joachim99@69 201 void CShellContextMenu::SetObjects(const QString& strObject)
joachim99@69 202 {
joachim99@69 203 // only one object is passed
joachim99@69 204 QStringList strArray;
joachim99@69 205 strArray << strObject; // create a CStringArray with one element
joachim99@69 206
joachim99@69 207 SetObjects (strArray); // and pass it to SetObjects (CStringArray &strArray)
joachim99@69 208 // for further processing
joachim99@69 209 }
joachim99@69 210
joachim99@69 211
joachim99@69 212 void CShellContextMenu::SetObjects(const QStringList &strList)
joachim99@69 213 {
joachim99@69 214 // free all allocated datas
joachim99@69 215 if (m_psfFolder && bDelete)
joachim99@69 216 m_psfFolder->Release ();
joachim99@69 217 m_psfFolder = NULL;
joachim99@69 218 FreePIDLArray (m_pidlArray);
joachim99@69 219 m_pidlArray = NULL;
joachim99@69 220
joachim99@69 221 // get IShellFolder interface of Desktop (root of shell namespace)
joachim99@69 222 IShellFolder * psfDesktop = NULL;
joachim99@69 223 SHGetDesktopFolder (&psfDesktop); // needed to obtain full qualified pidl
joachim99@69 224
joachim99@69 225 // ParseDisplayName creates a PIDL from a file system path relative to the IShellFolder interface
joachim99@69 226 // but since we use the Desktop as our interface and the Desktop is the namespace root
joachim99@69 227 // that means that it's a fully qualified PIDL, which is what we need
joachim99@69 228 LPITEMIDLIST pidl = NULL;
joachim99@69 229
joachim99@75 230 psfDesktop->ParseDisplayName (NULL, 0, (LPOLESTR)strList[0].utf16(), NULL, &pidl, NULL);
joachim99@69 231
joachim99@69 232 // now we need the parent IShellFolder interface of pidl, and the relative PIDL to that interface
joachim99@69 233 LPITEMIDLIST pidlItem = NULL; // relative pidl
joachim99@69 234 SHBindToParentEx (pidl, IID_IShellFolder, (void **) &m_psfFolder, NULL);
joachim99@69 235 free (pidlItem);
joachim99@69 236 // get interface to IMalloc (need to free the PIDLs allocated by the shell functions)
joachim99@69 237 LPMALLOC lpMalloc = NULL;
joachim99@69 238 SHGetMalloc (&lpMalloc);
joachim99@69 239 lpMalloc->Free (pidl);
joachim99@69 240
joachim99@69 241 // now we have the IShellFolder interface to the parent folder specified in the first element in strArray
joachim99@69 242 // since we assume that all objects are in the same folder (as it's stated in the MSDN)
joachim99@69 243 // we now have the IShellFolder interface to every objects parent folder
joachim99@69 244
joachim99@69 245 IShellFolder * psfFolder = NULL;
joachim99@69 246 nItems = strList.size ();
joachim99@69 247 for (int i = 0; i < nItems; i++)
joachim99@69 248 {
joachim99@69 249 pidl=0;
joachim99@75 250 psfDesktop->ParseDisplayName (NULL, 0, (LPOLESTR)strList[i].utf16(), NULL, &pidl, NULL);
joachim99@69 251 if (pidl)
joachim99@69 252 {
joachim99@69 253 m_pidlArray = (LPITEMIDLIST *) realloc (m_pidlArray, (i + 1) * sizeof (LPITEMIDLIST));
joachim99@69 254 // get relative pidl via SHBindToParent
joachim99@69 255 SHBindToParentEx (pidl, IID_IShellFolder, (void **) &psfFolder, (LPCITEMIDLIST *) &pidlItem);
joachim99@69 256 m_pidlArray[i] = CopyPIDL (pidlItem); // copy relative pidl to pidlArray
joachim99@69 257 free (pidlItem);
joachim99@69 258 lpMalloc->Free (pidl); // free pidl allocated by ParseDisplayName
joachim99@69 259 psfFolder->Release ();
joachim99@69 260 }
joachim99@69 261 }
joachim99@69 262 lpMalloc->Release ();
joachim99@69 263 psfDesktop->Release ();
joachim99@69 264
joachim99@69 265 bDelete = TRUE; // indicates that m_psfFolder should be deleted by CShellContextMenu
joachim99@69 266 }
joachim99@69 267
joachim99@69 268
joachim99@69 269 // only one full qualified PIDL has been passed
joachim99@69 270 void CShellContextMenu::SetObjects(LPITEMIDLIST /*pidl*/)
joachim99@69 271 {
joachim99@69 272 /*
joachim99@69 273 // free all allocated datas
joachim99@69 274 if (m_psfFolder && bDelete)
joachim99@69 275 m_psfFolder->Release ();
joachim99@69 276 m_psfFolder = NULL;
joachim99@69 277 FreePIDLArray (m_pidlArray);
joachim99@69 278 m_pidlArray = NULL;
joachim99@69 279
joachim99@69 280 // full qualified PIDL is passed so we need
joachim99@69 281 // its parent IShellFolder interface and its relative PIDL to that
joachim99@69 282 LPITEMIDLIST pidlItem = NULL;
joachim99@69 283 SHBindToParent ((LPCITEMIDLIST) pidl, IID_IShellFolder, (void **) &m_psfFolder, (LPCITEMIDLIST *) &pidlItem);
joachim99@69 284
joachim99@69 285 m_pidlArray = (LPITEMIDLIST *) malloc (sizeof (LPITEMIDLIST)); // allocate ony for one elemnt
joachim99@69 286 m_pidlArray[0] = CopyPIDL (pidlItem);
joachim99@69 287
joachim99@69 288
joachim99@69 289 // now free pidlItem via IMalloc interface (but not m_psfFolder, that we need later
joachim99@69 290 LPMALLOC lpMalloc = NULL;
joachim99@69 291 SHGetMalloc (&lpMalloc);
joachim99@69 292 lpMalloc->Free (pidlItem);
joachim99@69 293 lpMalloc->Release();
joachim99@69 294
joachim99@69 295 nItems = 1;
joachim99@69 296 bDelete = TRUE; // indicates that m_psfFolder should be deleted by CShellContextMenu
joachim99@69 297 */
joachim99@69 298 }
joachim99@69 299
joachim99@69 300
joachim99@69 301 // IShellFolder interface with a relative pidl has been passed
joachim99@69 302 void CShellContextMenu::SetObjects(IShellFolder *psfFolder, LPITEMIDLIST pidlItem)
joachim99@69 303 {
joachim99@69 304 // free all allocated datas
joachim99@69 305 if (m_psfFolder && bDelete)
joachim99@69 306 m_psfFolder->Release ();
joachim99@69 307 m_psfFolder = NULL;
joachim99@69 308 FreePIDLArray (m_pidlArray);
joachim99@69 309 m_pidlArray = NULL;
joachim99@69 310
joachim99@69 311 m_psfFolder = psfFolder;
joachim99@69 312
joachim99@69 313 m_pidlArray = (LPITEMIDLIST *) malloc (sizeof (LPITEMIDLIST));
joachim99@69 314 m_pidlArray[0] = CopyPIDL (pidlItem);
joachim99@69 315
joachim99@69 316 nItems = 1;
joachim99@69 317 bDelete = FALSE; // indicates wheter m_psfFolder should be deleted by CShellContextMenu
joachim99@69 318 }
joachim99@69 319
joachim99@69 320 void CShellContextMenu::SetObjects(IShellFolder * psfFolder, LPITEMIDLIST *pidlArray, int nItemCount)
joachim99@69 321 {
joachim99@69 322 // free all allocated datas
joachim99@69 323 if (m_psfFolder && bDelete)
joachim99@69 324 m_psfFolder->Release ();
joachim99@69 325 m_psfFolder = NULL;
joachim99@69 326 FreePIDLArray (m_pidlArray);
joachim99@69 327 m_pidlArray = NULL;
joachim99@69 328
joachim99@69 329 m_psfFolder = psfFolder;
joachim99@69 330
joachim99@69 331 m_pidlArray = (LPITEMIDLIST *) malloc (nItemCount * sizeof (LPITEMIDLIST));
joachim99@69 332
joachim99@69 333 for (int i = 0; i < nItemCount; i++)
joachim99@69 334 m_pidlArray[i] = CopyPIDL (pidlArray[i]);
joachim99@69 335
joachim99@69 336 nItems = nItemCount;
joachim99@69 337 bDelete = FALSE; // indicates wheter m_psfFolder should be deleted by CShellContextMenu
joachim99@69 338 }
joachim99@69 339
joachim99@69 340
joachim99@69 341 void CShellContextMenu::FreePIDLArray(LPITEMIDLIST *pidlArray)
joachim99@69 342 {
joachim99@69 343 if (!pidlArray)
joachim99@69 344 return;
joachim99@69 345
joachim99@69 346 int iSize = _msize (pidlArray) / sizeof (LPITEMIDLIST);
joachim99@69 347
joachim99@69 348 for (int i = 0; i < iSize; i++)
joachim99@69 349 free (pidlArray[i]);
joachim99@69 350 free (pidlArray);
joachim99@69 351 }
joachim99@69 352
joachim99@69 353
joachim99@69 354 LPITEMIDLIST CShellContextMenu::CopyPIDL (LPCITEMIDLIST pidl, int cb)
joachim99@69 355 {
joachim99@69 356 if (cb == -1)
joachim99@69 357 cb = GetPIDLSize (pidl); // Calculate size of list.
joachim99@69 358
joachim99@69 359 LPITEMIDLIST pidlRet = (LPITEMIDLIST) calloc (cb + sizeof (USHORT), sizeof (BYTE));
joachim99@69 360 if (pidlRet)
joachim99@69 361 CopyMemory(pidlRet, pidl, cb);
joachim99@69 362
joachim99@69 363 return (pidlRet);
joachim99@69 364 }
joachim99@69 365
joachim99@69 366
joachim99@69 367 UINT CShellContextMenu::GetPIDLSize (LPCITEMIDLIST pidl)
joachim99@69 368 {
joachim99@69 369 if (!pidl)
joachim99@69 370 return 0;
joachim99@69 371 int nSize = 0;
joachim99@69 372 LPITEMIDLIST pidlTemp = (LPITEMIDLIST) pidl;
joachim99@69 373 while (pidlTemp->mkid.cb)
joachim99@69 374 {
joachim99@69 375 nSize += pidlTemp->mkid.cb;
joachim99@69 376 pidlTemp = (LPITEMIDLIST) (((LPBYTE) pidlTemp) + pidlTemp->mkid.cb);
joachim99@69 377 }
joachim99@69 378 return nSize;
joachim99@69 379 }
joachim99@69 380
joachim99@69 381 HMENU CShellContextMenu::GetMenu()
joachim99@69 382 {
joachim99@69 383 if (!m_hMenu)
joachim99@69 384 {
joachim99@69 385 m_hMenu = CreatePopupMenu(); // create the popupmenu (its empty)
joachim99@69 386 }
joachim99@69 387 return (m_hMenu);
joachim99@69 388 }
joachim99@69 389
joachim99@69 390
joachim99@69 391 // this is workaround function for the Shell API Function SHBindToParent
joachim99@69 392 // SHBindToParent is not available under Win95/98
joachim99@69 393 HRESULT CShellContextMenu::SHBindToParentEx (LPCITEMIDLIST pidl, REFIID riid, VOID **ppv, LPCITEMIDLIST *ppidlLast)
joachim99@69 394 {
joachim99@69 395 HRESULT hr = 0;
joachim99@69 396 if (!pidl || !ppv)
joachim99@69 397 return E_POINTER;
joachim99@69 398
joachim99@69 399 int nCount = GetPIDLCount (pidl);
joachim99@69 400 if (nCount == 0) // desktop pidl of invalid pidl
joachim99@69 401 return E_POINTER;
joachim99@69 402
joachim99@69 403 IShellFolder * psfDesktop = NULL;
joachim99@69 404 SHGetDesktopFolder (&psfDesktop);
joachim99@69 405 if (nCount == 1) // desktop pidl
joachim99@69 406 {
joachim99@69 407 if ((hr = psfDesktop->QueryInterface(riid, ppv)) == S_OK)
joachim99@69 408 {
joachim99@69 409 if (ppidlLast)
joachim99@69 410 *ppidlLast = CopyPIDL (pidl);
joachim99@69 411 }
joachim99@69 412 psfDesktop->Release ();
joachim99@69 413 return hr;
joachim99@69 414 }
joachim99@69 415
joachim99@69 416 LPBYTE pRel = GetPIDLPos (pidl, nCount - 1);
joachim99@69 417 LPITEMIDLIST pidlParent = NULL;
joachim99@69 418 pidlParent = CopyPIDL (pidl, pRel - (LPBYTE) pidl);
joachim99@69 419 IShellFolder * psfFolder = NULL;
joachim99@69 420
joachim99@69 421 if ((hr = psfDesktop->BindToObject (pidlParent, NULL, IID_IShellFolder, (void **) &psfFolder)) != S_OK)
joachim99@69 422 {
joachim99@69 423 free (pidlParent);
joachim99@69 424 psfDesktop->Release ();
joachim99@69 425 return hr;
joachim99@69 426 }
joachim99@69 427 if ((hr = psfFolder->QueryInterface (riid, ppv)) == S_OK)
joachim99@69 428 {
joachim99@69 429 if (ppidlLast)
joachim99@69 430 *ppidlLast = CopyPIDL ((LPCITEMIDLIST) pRel);
joachim99@69 431 }
joachim99@69 432 free (pidlParent);
joachim99@69 433 psfFolder->Release ();
joachim99@69 434 psfDesktop->Release ();
joachim99@69 435 return hr;
joachim99@69 436 }
joachim99@69 437
joachim99@69 438
joachim99@69 439 LPBYTE CShellContextMenu::GetPIDLPos (LPCITEMIDLIST pidl, int nPos)
joachim99@69 440 {
joachim99@69 441 if (!pidl)
joachim99@69 442 return 0;
joachim99@69 443 int nCount = 0;
joachim99@69 444
joachim99@69 445 BYTE * pCur = (BYTE *) pidl;
joachim99@69 446 while (((LPCITEMIDLIST) pCur)->mkid.cb)
joachim99@69 447 {
joachim99@69 448 if (nCount == nPos)
joachim99@69 449 return pCur;
joachim99@69 450 nCount++;
joachim99@69 451 pCur += ((LPCITEMIDLIST) pCur)->mkid.cb; // + sizeof(pidl->mkid.cb);
joachim99@69 452 }
joachim99@69 453 if (nCount == nPos)
joachim99@69 454 return pCur;
joachim99@69 455 return NULL;
joachim99@69 456 }
joachim99@69 457
joachim99@69 458
joachim99@69 459 int CShellContextMenu::GetPIDLCount (LPCITEMIDLIST pidl)
joachim99@69 460 {
joachim99@69 461 if (!pidl)
joachim99@69 462 return 0;
joachim99@69 463
joachim99@69 464 int nCount = 0;
joachim99@69 465 BYTE* pCur = (BYTE *) pidl;
joachim99@69 466 while (((LPCITEMIDLIST) pCur)->mkid.cb)
joachim99@69 467 {
joachim99@69 468 nCount++;
joachim99@69 469 pCur += ((LPCITEMIDLIST) pCur)->mkid.cb;
joachim99@69 470 }
joachim99@69 471 return nCount;
joachim99@69 472 }
joachim99@69 473
joachim99@69 474 #endif
joachim99@69 475