Große Icons mit IExtractIcon
-
Also ich versuche gerade Icons mit (vistaoiden) 128x128 pixeln zu extrahieren, das einzige, was ich dabei bekomme sind normalgroße icons, obwohl die im explorer auch die größe on 128px haben.
Vielleicht hat irgendwer schon einmal damit gearbeitet oder etwas derartiges also will ich mal den code posten und hoffe auf vorschläge, und bin dankbar für dergleichen produktiver art...
Zum code: Die kommentare sind leider aber gottes in (pseudo-)englisch gehalten,
da das allgemein zu dem im englisch gehaltenen C++ passt// Gets the temp folder WCHAR Path0[MAX_PATH + 1] = {0}; GetTempPath(MAX_PATH, Path0); // Create a temp file with the same extension WCHAR Path[MAX_PATH] = {0}; GetTempFileName(Path0, L"EIT", GetTickCount(), Path); PathRemoveExtension(Path); PathAddExtension(Path, PathFindExtension(lpFileName)); CloseHandle(CreateFile(Path, GENERIC_READ, 0, NULL, CREATE_ALWAYS, 0, NULL)); // Obtain the pidl for the temp file IShellFolder* lpShf; SHGetDesktopFolder(&lpShf); LPITEMIDLIST pIdl; lpShf->ParseDisplayName(NULL, NULL, Path0, NULL, &pIdl, NULL); // Get the temp folder IShellFolder* lpShf2; lpShf->BindToObject(pIdl, NULL, __uuidof(IShellFolder), (void**)&lpShf2); lpShf->Release(); CoTaskMemFree(pIdl); // Parse the file name lpShf2->ParseDisplayName(NULL, NULL, wcsrchr(Path, L'\\') + 1, NULL, &pIdl, NULL); // Get the IExtractIcon interface IExtractIcon* lpExi; lpShf2->GetUIObjectOf(NULL, 1, (LPCITEMIDLIST*)&pIdl, __uuidof(IExtractIcon), NULL, (void**)&lpExi); lpShf2->Release(); CoTaskMemFree(pIdl); // Get the icon location WCHAR Path2[MAX_PATH + 1] = {0}; int ind; UINT uFlags; HRESULT hr = lpExi->GetIconLocation(0, Path2, MAX_PATH, &ind, &uFlags); // Extract the icon from its location HICON hIc; if(hr == S_OK) lpExi->Extract(Path2, ind, &hIc, NULL, MAKELONG(128, 16)); else if(hr == S_FALSE) { // Use the standard icon SHFILEINFO sfi = {0}; SHGetFileInfo(Path, 0, &sfi, sizeof(sfi), SHGFI_ICON | SHGFI_LARGEICON); hIc = sfi.hIcon; } else { WORD w1 = 0; hIc = ExtractAssociatedIcon(NULL, Path, &w1); } // Cleanup lpExi->Release(); // Remove the temp file DeleteFile(Path); // Load the icon into a bitmap(128x128) pBmp = new Gdiplus::Bitmap(hIc); Gdiplus::Image* pImg = pBmp->GetThumbnailImage(128, 128); delete pBmp; pBmp = (Gdiplus::Bitmap*)pImg; DestroyIcon(hIc);
-
Nachtrag:
Die HRESULTS werden gerade noch alle ignoriert, aber beim debugen haben alle immer S_OK zurückgegeben
-
Zudem möchte ich sagfen, dass ich es auch mit IExtractImage versucht habe, wobei mir dann aber eine exception entgegengekommen ist.
-
Zu der exception:
Mir ist dabei etwas frappierendes aufgefallen:
Die ex. ist eine AccessViolation, die immer an der stelle MAX_PATH stattfindet!HRESULT GetLocation( LPWSTR pszPathBuffer, DWORD cchMax, // <----- dieser parameter wird als pointer benutzt! DWORD *pdwPriority, const SIZE *prgSize, DWORD dwRecClrDepth, DWORD *pdwFlags );Wenn man für die länge des string z.B. eine kleinere zahl eingibt, kommt jeweils die entsprechende stelle als av bei raus.
Zum aufruf habe ich jetzt auch noch das passende assembler stück parat(vielleicht macht der compiler was falsch...)
;lpExi->GetLocation(Path2, MAX_PATH, &dw1, &s1, 32, &dw2); 000000014001ECEB mov rax,qword ptr [lpExi] 000000014001ECF3 mov rax,qword ptr [rax] 000000014001ECF6 lea rcx,[dw2] 000000014001ECFE mov qword ptr [rsp+30h],rcx 000000014001ED03 mov dword ptr [rsp+28h],20h 000000014001ED0B lea rcx,[s1] 000000014001ED13 mov qword ptr [rsp+20h],rcx 000000014001ED18 lea r9,[dw1] 000000014001ED20 mov r8d,104h 000000014001ED26 lea rdx,[Path2] 000000014001ED2E mov rcx,qword ptr [lpExi] 000000014001ED36 call qword ptr [rax+18h]
-
Häääääääää?
-
Hää? Wieso hää?
Es ist ganz einfach: Windows macht etwas was es nicht machen sollte,
-
Und ich bin blöd!
Ich hab __uuidof(IExtractIcon) benutzt und das resultat als IExtractImage behandelt.............
Die Erkenntbis kommt spät......