// IClassFactory IFACEMETHODIMP CreateInstance(IUnknown *punkOuter, REFIID riid, void **ppv) { *ppv = NULL; if (punkOuter) return CLASS_E_NOAGGREGATION; ScopedComPtr<IInitializeWithStream> pObject; CLSID clsid; if (SUCCEEDED(CLSIDFromString(SZ_PDF_PREVIEW_CLSID, &clsid)) && IsEqualCLSID(m_clsid, clsid)) pObject = new CPdfPreview(&g_lRefCount); #ifdef BUILD_XPS_PREVIEW else if (SUCCEEDED(CLSIDFromString(SZ_XPS_PREVIEW_CLSID, &clsid)) && IsEqualCLSID(m_clsid, clsid)) pObject = new CXpsPreview(&g_lRefCount); #endif #ifdef BUILD_CBZ_PREVIEW else if (SUCCEEDED(CLSIDFromString(SZ_CBZ_PREVIEW_CLSID, &clsid)) && IsEqualCLSID(m_clsid, clsid)) pObject = new CCbzPreview(&g_lRefCount); #endif #ifdef BUILD_TGA_PREVIEW else if (SUCCEEDED(CLSIDFromString(SZ_TGA_PREVIEW_CLSID, &clsid)) && IsEqualCLSID(m_clsid, clsid)) pObject = new CTgaPreview(&g_lRefCount); #endif else return E_NOINTERFACE; if (!pObject) return E_OUTOFMEMORY; return pObject->QueryInterface(riid, ppv); }
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); }
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; }
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); }
IStream *CreateStreamFromData(const void *data, size_t len) { if (!data) return NULL; ScopedComPtr<IStream> stream; if (FAILED(CreateStreamOnHGlobal(NULL, TRUE, &stream))) return NULL; ULONG written; if (FAILED(stream->Write(data, (ULONG)len, &written)) || written != len) return NULL; LARGE_INTEGER zero = { 0 }; stream->Seek(zero, STREAM_SEEK_SET, NULL); stream->AddRef(); return stream; }
/* adapted from http://blogs.msdn.com/oldnewthing/archive/2004/09/20/231739.aspx */ IDataObject* GetDataObjectForFile(WCHAR* filePath, HWND hwnd) { ScopedComPtr<IShellFolder> pDesktopFolder; HRESULT hr = SHGetDesktopFolder(&pDesktopFolder); if (FAILED(hr)) return NULL; IDataObject* pDataObject = NULL; ScopedMem<WCHAR> lpWPath(str::Dup(filePath)); LPITEMIDLIST pidl; hr = pDesktopFolder->ParseDisplayName(NULL, NULL, lpWPath, NULL, &pidl, NULL); if (SUCCEEDED(hr)) { ScopedComPtr<IShellFolder> pShellFolder; LPCITEMIDLIST pidlChild; hr = SHBindToParent(pidl, IID_IShellFolder, (void**)&pShellFolder, &pidlChild); if (SUCCEEDED(hr)) pShellFolder->GetUIObjectOf(hwnd, 1, &pidlChild, IID_IDataObject, NULL, (void **)&pDataObject); CoTaskMemFree(pidl); } return pDataObject; }
// IClassFactory IFACEMETHODIMP CreateInstance(IUnknown *punkOuter, REFIID riid, void **ppv) { *ppv = NULL; if (punkOuter) return CLASS_E_NOAGGREGATION; ScopedComPtr<IFilter> pFilter; CLSID clsid; if (SUCCEEDED(CLSIDFromString(SZ_PDF_FILTER_CLSID, &clsid)) && IsEqualCLSID(m_clsid, clsid)) pFilter = new CPdfFilter(&g_lRefCount); #ifdef BUILD_TEX_IFILTER else if (SUCCEEDED(CLSIDFromString(SZ_TEX_FILTER_CLSID, &clsid)) && IsEqualCLSID(m_clsid, clsid)) pFilter = new CTeXFilter(&g_lRefCount); #endif else return E_NOINTERFACE; if (!pFilter) return E_OUTOFMEMORY; return pFilter->QueryInterface(riid, ppv); }
// TODO: using this for XPS files results in documents that Microsoft XPS Viewer can't read IStream *OpenDirAsZipStream(const WCHAR *dirPath, bool recursive) { ScopedComPtr<IStream> stream; if (FAILED(CreateStreamOnHGlobal(NULL, TRUE, &stream))) return NULL; zlib_filefunc64_def ffunc; fill_win32s_filefunc64(&ffunc); zipFile zf = zipOpen2_64(stream, 0, NULL, &ffunc); if (!zf) return NULL; DirIter iter; if (!iter.Start(dirPath, recursive)) return NULL; size_t dirLen = str::Len(dirPath); if (!path::IsSep(dirPath[dirLen - 1])) dirLen++; bool ok = true; const WCHAR *filePath; while (ok && (filePath = iter.Next()) != NULL) { CrashIf(!str::StartsWith(filePath, dirPath)); const WCHAR *nameInZip = filePath + dirLen; size_t fileSize; ScopedMem<char> fileData(file::ReadAll(filePath, &fileSize)); ok = fileData && AppendFileToZip(zf, nameInZip, fileData, fileSize); } int err = zipClose(zf, NULL); if (!ok || err != ZIP_OK) return NULL; stream->AddRef(); return stream; }
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); }