static Bitmap *WICDecodeImageFromStream(IStream *stream) { ScopedCom com; #define HR(hr) if (FAILED(hr)) return NULL; ScopedComPtr<IWICImagingFactory> pFactory; if (!pFactory.Create(CLSID_WICImagingFactory)) return NULL; ScopedComPtr<IWICBitmapDecoder> pDecoder; HR(pFactory->CreateDecoderFromStream(stream, NULL, WICDecodeMetadataCacheOnDemand, &pDecoder)); ScopedComPtr<IWICBitmapFrameDecode> srcFrame; HR(pDecoder->GetFrame(0, &srcFrame)); ScopedComPtr<IWICFormatConverter> pConverter; HR(pFactory->CreateFormatConverter(&pConverter)); HR(pConverter->Initialize(srcFrame, GUID_WICPixelFormat32bppBGRA, WICBitmapDitherTypeNone, NULL, 0.f, WICBitmapPaletteTypeCustom)); UINT w, h; HR(pConverter->GetSize(&w, &h)); double xres, yres; HR(pConverter->GetResolution(&xres, &yres)); Bitmap bmp(w, h, PixelFormat32bppARGB); Rect bmpRect(0, 0, w, h); BitmapData bmpData; Status ok = bmp.LockBits(&bmpRect, ImageLockModeWrite, PixelFormat32bppARGB, &bmpData); if (ok != Ok) return NULL; HR(pConverter->CopyPixels(NULL, bmpData.Stride, bmpData.Stride * h, (BYTE *)bmpData.Scan0)); bmp.UnlockBits(&bmpData); bmp.SetResolution((REAL)xres, (REAL)yres); #undef HR // hack to avoid the use of ::new (because there won't be a corresponding ::delete) return bmp.Clone(0, 0, w, h, PixelFormat32bppARGB); }
WCHAR *ResolveLnk(const WCHAR * path) { ScopedMem<OLECHAR> olePath(str::Dup(path)); if (!olePath) return NULL; ScopedComPtr<IShellLink> lnk; if (!lnk.Create(CLSID_ShellLink)) return NULL; ScopedComQIPtr<IPersistFile> file(lnk); if (!file) return NULL; HRESULT hRes = file->Load(olePath, STGM_READ); if (FAILED(hRes)) return NULL; hRes = lnk->Resolve(NULL, SLR_UPDATE); if (FAILED(hRes)) return NULL; WCHAR newPath[MAX_PATH]; hRes = lnk->GetPath(newPath, MAX_PATH, NULL, 0); if (FAILED(hRes)) return NULL; return str::Dup(newPath); }
bool CreateShortcut(const WCHAR *shortcutPath, const WCHAR *exePath, const WCHAR *args, const WCHAR *description, int iconIndex) { ScopedCom com; ScopedComPtr<IShellLink> lnk; if (!lnk.Create(CLSID_ShellLink)) return false; ScopedComQIPtr<IPersistFile> file(lnk); if (!file) return false; HRESULT hr = lnk->SetPath(exePath); if (FAILED(hr)) return false; lnk->SetWorkingDirectory(ScopedMem<WCHAR>(path::GetDir(exePath))); // lnk->SetShowCmd(SW_SHOWNORMAL); // lnk->SetHotkey(0); lnk->SetIconLocation(exePath, iconIndex); if (args) lnk->SetArguments(args); if (description) lnk->SetDescription(description); hr = file->Save(shortcutPath, TRUE); return SUCCEEDED(hr); }
UINT GuessTextCodepage(const char *data, size_t len, UINT defVal) { // try to guess the codepage ScopedComPtr<IMultiLanguage2> pMLang; if (!pMLang.Create(CLSID_CMultiLanguage)) return defVal; int ilen = (int)min(len, INT_MAX); int count = 1; DetectEncodingInfo info = { 0 }; HRESULT hr = pMLang->DetectInputCodepage(MLDETECTCP_NONE, CP_ACP, (char *)data, &ilen, &info, &count); if (FAILED(hr) || count != 1) return defVal; return info.nCodePage; }