📄 utilities.cpp
字号:
}
if (pfnURLDownloadToFileW == NULL)
return E_UNEXPECTED;
return pfnURLDownloadToFileW(punk, pwszURL, pwszLocalFile, 0, NULL);
*/
USES_CONVERSION;
try{
CInternetSession session("DSO");
CStdioFile * pFile = NULL;
pFile = session.OpenURL(W2A(pwszURL),0,
INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_RELOAD|
INTERNET_FLAG_DONT_CACHE);
if(!pFile){
return -1;
}
FILE *fp = NULL;
if((fp = fopen( W2A(pwszLocalFile),"wb")) == NULL){
pFile->Close();
delete pFile;
return -1;
}
DWORD iLen = 0;
char temp[1024];
while(iLen = pFile->Read(temp, 1024)){
fwrite(temp, 1, iLen, fp);
fflush(fp);
}
fclose(fp);
if(pFile){
pFile->Close();
delete pFile;
}
}catch(...){
return -1;
}
return S_OK;
}
////////////////////////////////////////////////////////////////////////
// OLE Conversion Functions
//
#define HIMETRIC_PER_INCH 2540 // number HIMETRIC units per inch
#define PTS_PER_INCH 72 // number points (font size) per inch
#define MAP_PIX_TO_LOGHIM(x,ppli) MulDiv(HIMETRIC_PER_INCH, (x), (ppli))
#define MAP_LOGHIM_TO_PIX(x,ppli) MulDiv((ppli), (x), HIMETRIC_PER_INCH)
////////////////////////////////////////////////////////////////////////
// DsoHimetricToPixels
//
STDAPI_(void) DsoHimetricToPixels(LONG* px, LONG* py)
{
HDC hdc = GetDC(NULL);
if (px) *px = MAP_LOGHIM_TO_PIX(*px, GetDeviceCaps(hdc, LOGPIXELSX));
if (py) *py = MAP_LOGHIM_TO_PIX(*py, GetDeviceCaps(hdc, LOGPIXELSY));
ReleaseDC(NULL, hdc);
}
////////////////////////////////////////////////////////////////////////
// DsoPixelsToHimetric
//
STDAPI_(void) DsoPixelsToHimetric(LONG* px, LONG* py)
{
HDC hdc = GetDC(NULL);
if (px) *px = MAP_PIX_TO_LOGHIM(*px, GetDeviceCaps(hdc, LOGPIXELSX));
if (py) *py = MAP_PIX_TO_LOGHIM(*py, GetDeviceCaps(hdc, LOGPIXELSY));
ReleaseDC(NULL, hdc);
}
////////////////////////////////////////////////////////////////////////
// GDI Helper Functions
//
STDAPI_(HBITMAP) DsoGetBitmapFromWindow(HWND hwnd)
{
HBITMAP hbmpold, hbmp = NULL;
HDC hdcWin, hdcMem;
RECT rc;
INT x, y;
if (!GetWindowRect(hwnd, &rc))
return NULL;
x = (rc.right - rc.left); if (x < 0) x = 1;
y = (rc.bottom - rc.top); if (y < 0) y = 1;
hdcWin = GetDC(hwnd);
hdcMem = CreateCompatibleDC(hdcWin);
hbmp = CreateCompatibleBitmap(hdcWin, x, y);
hbmpold = (HBITMAP)SelectObject(hdcMem, hbmp);
BitBlt(hdcMem, 0,0, x, y, hdcWin, 0,0, SRCCOPY);
SelectObject(hdcMem, hbmpold);
DeleteDC(hdcMem);
ReleaseDC(hwnd, hdcWin);
return hbmp;
}
////////////////////////////////////////////////////////////////////////
// DsoGetTypeInfoEx
//
// Gets an ITypeInfo from the LIBID specified. Optionally can load and
// register the typelib from a module resource (if specified). Used to
// load our typelib on demand.
//
STDAPI DsoGetTypeInfoEx(REFGUID rlibid, LCID lcid, WORD wVerMaj, WORD wVerMin, HMODULE hResource, REFGUID rguid, ITypeInfo** ppti)
{
HRESULT hr;
ITypeLib* ptlib;
CHECK_NULL_RETURN(ppti, E_POINTER);
*ppti = NULL;
// Try to pull information from the registry...
hr = LoadRegTypeLib(rlibid, wVerMaj, wVerMin, lcid, &ptlib);
// If that failed, and we have a resource module to load from,
// try loading it from the module...
if (FAILED(hr) && (hResource))
{
LPWSTR pwszPath;
if (FGetModuleFileName(hResource, &pwszPath))
{
// Now, load the type library from module resource file...
hr = LoadTypeLib(pwszPath, &ptlib);
// Register library to make things easier next time...
if (SUCCEEDED(hr))
RegisterTypeLib(ptlib, pwszPath, NULL);
DsoMemFree(pwszPath);
}
}
// We have the typelib. Now get the requested typeinfo...
if (SUCCEEDED(hr))
hr = ptlib->GetTypeInfoOfGuid(rguid, ppti);
// Release the type library interface.
SAFE_RELEASE_INTERFACE(ptlib);
return hr;
}
////////////////////////////////////////////////////////////////////////
// DsoDispatchInvoke
//
// Wrapper for IDispatch::Invoke calls to event sinks, or late bound call
// to embedded object to get ambient property.
//
STDAPI DsoDispatchInvoke(LPDISPATCH pdisp, LPOLESTR pwszname, DISPID dspid, WORD wflags, DWORD cargs, VARIANT* rgargs, VARIANT* pvtret)
{
/* HRESULT hr = S_FALSE;
DISPID dspidPut = DISPID_PROPERTYPUT;
DISPPARAMS dspparm = {NULL, NULL, 0, 0};
CHECK_NULL_RETURN(pdisp, E_POINTER);
dspparm.rgvarg = rgargs;
dspparm.cArgs = cargs;
if ((wflags & DISPATCH_PROPERTYPUT) || (wflags & DISPATCH_PROPERTYPUTREF))
{
dspparm.rgdispidNamedArgs = &dspidPut;
dspparm.cNamedArgs = 1;
}
SEH_TRY
if (pwszname)
hr = pdisp->GetIDsOfNames(IID_NULL, &pwszname, 1, LOCALE_USER_DEFAULT, &dspid);
if (SUCCEEDED(hr))
hr = pdisp->Invoke(dspid, IID_NULL, LOCALE_USER_DEFAULT, (WORD)(DISPATCH_METHOD | wflags), &dspparm, pvtret, NULL, NULL);
SEH_EXCEPT(hr)
return hr;
*/
///////////New///////////////////////////
HRESULT hr = S_FALSE;
DISPID dspidPut = DISPID_PROPERTYPUT;
DISPPARAMS dspparm = {NULL, NULL, 0, 0};
CHECK_NULL_RETURN(pdisp, E_POINTER);
dspparm.rgvarg = rgargs;
dspparm.cArgs = cargs;
if ((wflags & DISPATCH_PROPERTYPUT) || (wflags &
DISPATCH_PROPERTYPUTREF))
{
dspparm.rgdispidNamedArgs = &dspidPut;
dspparm.cNamedArgs = 1;
}
SEH_TRY
hr = pdisp->Invoke(dspid, IID_NULL, LOCALE_USER_DEFAULT,
(WORD)(DISPATCH_METHOD | wflags), &dspparm, pvtret, NULL, NULL);
if (!SUCCEEDED(hr)) {
if (pwszname)
hr = pdisp->GetIDsOfNames(IID_NULL, &pwszname, 1,
LOCALE_USER_DEFAULT, &dspid);
if (SUCCEEDED(hr))
hr = pdisp->Invoke(dspid, IID_NULL, LOCALE_USER_DEFAULT,
(WORD)(DISPATCH_METHOD | wflags), &dspparm, pvtret, NULL, NULL);
}
SEH_EXCEPT(hr)
return hr;
}
////////////////////////////////////////////////////////////////////////
// DsoReportError -- Report Error for both ComThreadError and DispError.
//
STDAPI DsoReportError(HRESULT hr, LPWSTR pwszCustomMessage, EXCEPINFO* peiDispEx)
{
BSTR bstrSource, bstrDescription;
ICreateErrorInfo* pcerrinfo;
IErrorInfo* perrinfo;
CHAR szError[MAX_PATH];
UINT nID = 0;
// Don't need to do anything unless this is an error.
if ((hr == S_OK) || SUCCEEDED(hr)) return hr;
// Is this one of our custom errors (if so we will pull description from resource)...
if ((hr > DSO_E_ERR_BASE) && (hr < DSO_E_ERR_MAX))
nID = (hr & 0xFF);
// Set the source name...
bstrSource = SysAllocString(L"DsoFramerControl");
// Set the error description...
if (pwszCustomMessage)
{
bstrDescription = SysAllocString(pwszCustomMessage);
}
else if (((nID) && LoadString(v_hModule, nID, szError, sizeof(szError))) ||
(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr, 0, szError, sizeof(szError), NULL)))
{
bstrDescription = DsoConvertToBSTR(szError);
}
else bstrDescription = NULL;
// Set ErrorInfo so that vtable clients can get rich error information...
if (SUCCEEDED(CreateErrorInfo(&pcerrinfo)))
{
pcerrinfo->SetSource(bstrSource);
pcerrinfo->SetDescription(bstrDescription);
if (SUCCEEDED(pcerrinfo->QueryInterface(IID_IErrorInfo, (void**) &perrinfo)))
{
SetErrorInfo(0, perrinfo);
perrinfo->Release();
}
pcerrinfo->Release();
}
// Fill-in DispException Structure for late-boud clients...
if (peiDispEx)
{
peiDispEx->scode = hr;
peiDispEx->bstrSource = SysAllocString(bstrSource);
peiDispEx->bstrDescription = SysAllocString(bstrDescription);
}
// Free temp strings...
SAFE_FREEBSTR(bstrDescription);
SAFE_FREEBSTR(bstrSource);
// We always return error passed (so caller can chain this in return call).
return hr;
}
////////////////////////////////////////////////////////////////////////
// Variant Type Helpers (Fast Access to Variant Data)
//
VARIANT* __fastcall DsoPVarFromPVarRef(VARIANT* px)
{return ((px->vt == (VT_VARIANT|VT_BYREF)) ? (px->pvarVal) : px);}
BOOL __fastcall DsoIsVarParamMissing(VARIANT* px)
{return ((px->vt == VT_EMPTY) || ((px->vt & VT_ERROR) == VT_ERROR));}
LPWSTR __fastcall DsoPVarWStrFromPVar(VARIANT* px)
{return ((px->vt == VT_BSTR) ? px->bstrVal : ((px->vt == (VT_BSTR|VT_BYREF)) ? *(px->pbstrVal) : NULL));}
SAFEARRAY* __fastcall DsoPVarArrayFromPVar(VARIANT* px)
{return (((px->vt & (VT_BYREF|VT_ARRAY)) == (VT_BYREF|VT_ARRAY)) ? *(px->pparray) : (((px->vt & VT_ARRAY) == VT_ARRAY) ? px->parray : NULL));}
IUnknown* __fastcall DsoPVarUnkFromPVar(VARIANT* px)
{return (((px->vt == VT_DISPATCH) || (px->vt == VT_UNKNOWN)) ? px->punkVal : (((px->vt == (VT_DISPATCH|VT_BYREF)) || (px->vt == (VT_UNKNOWN|VT_BYREF))) ? *(px->ppunkVal) : NULL));}
SHORT __fastcall DsoPVarShortFromPVar(VARIANT* px, SHORT fdef)
{return (((px->vt & 0xFF) != VT_I2) ? fdef : ((px->vt & VT_BYREF) == VT_BYREF) ? *(px->piVal) : px->iVal);}
LONG __fastcall DsoPVarLongFromPVar(VARIANT* px, LONG fdef)
{return (((px->vt & 0xFF) != VT_I4) ? (LONG)DsoPVarShortFromPVar(px, (SHORT)fdef) : ((px->vt & VT_BYREF) == VT_BYREF) ? *(px->plVal) : px->lVal);}
BOOL __fastcall DsoPVarBoolFromPVar(VARIANT* px, BOOL fdef)
{return (((px->vt & 0xFF) != VT_BOOL) ? (BOOL)DsoPVarLongFromPVar(px, (LONG)fdef) : ((px->vt & VT_BYREF) == VT_BYREF) ? (BOOL)(*(px->pboolVal)) : (BOOL)(px->boolVal));}
////////////////////////////////////////////////////////////////////////
// Win32 Unicode API wrappers
//
// This project is not compiled to Unicode in order for it to run on Win9x
// machines. However, in order to try to keep the code language/locale neutral
// we use these wrappers to call the Unicode API functions when supported,
// and thunk down strings to local code page if must run MBCS API.
//
////////////////////////////////////////////////////////////////////////
// FFileExists
//
// Returns TRUE if the given file exists. Does not handle URLs.
//
STDAPI_(BOOL) FFileExists(WCHAR* wzPath)
{
DWORD dw = 0xFFFFFFFF;
if (v_fUnicodeAPI)
{
dw = GetFileAttributesW(wzPath);
}
else
{
LPSTR psz = DsoConvertToMBCS(wzPath);
if (psz) dw = GetFileAttributesA(psz);
DsoMemFree(psz);
}
return (dw != 0xFFFFFFFF);
}
////////////////////////////////////////////////////////////////////////
// FOpenLocalFile
//
// Returns TRUE if the file can be opened with the access required.
// Use the handle for ReadFile/WriteFile operations as normal.
//
STDAPI_(BOOL) FOpenLocalFile(WCHAR* wzFilePath, DWORD dwAccess, DWORD dwShareMode, DWORD dwCreate, HANDLE* phFile)
{
CHECK_NULL_RETURN(phFile, FALSE);
*phFile = INVALID_HANDLE_VALUE;
if (v_fUnicodeAPI)
{
*phFile = CreateFileW(wzFilePath, dwAccess, dwShareMode, NULL, dwCreate, FILE_ATTRIBUTE_NORMAL, NULL);
}
else
{
LPSTR psz = DsoConvertToMBCS(wzFilePath);
if (psz) *phFile = CreateFileA(psz, dwAccess, dwShareMode, NULL, dwCreate, FILE_ATTRIBUTE_NORMAL, NULL);
DsoMemFree(psz);
}
return (*phFile != INVALID_HANDLE_VALUE);
}
////////////////////////////////////////////////////////////////////////
// FPerformShellOp
//
// This function started as a wrapper for SHFileOperation, but that
// shell function had an enormous performance hit, especially on Win9x
// and NT4. To speed things up we removed the shell32 call and are
// using the kernel32 APIs instead. The only drawback is we can't
// handle multiple files, but that is not critical for this project.
//
STDAPI_(BOOL) FPerformShellOp(DWORD dwOp, WCHAR* wzFrom, WCHAR* wzTo)
{
BOOL f = FALSE;
if (v_fUnicodeAPI)
{
if (dwOp == FO_RENAME)
{
f = MoveFileW(wzFrom, wzTo);
}
else if (dwOp == FO_DELETE)
{
f = DeleteFileW(wzFrom);
}
}
else
{
LPSTR pszFrom = DsoConvertToMBCS(wzFrom);
LPSTR pszTo = DsoConvertToMBCS(wzTo);
if (dwOp == FO_RENAME)
{
f = MoveFileA(pszFrom, pszTo);
}
else if (dwOp == FO_DELETE)
{
f = DeleteFileA(pszFrom);
}
if (pszFrom) DsoMemFree(pszFrom);
if (pszTo) DsoMemFree(pszTo);
}
return f;
}
////////////////////////////////////////////////////////////////////////
// FGetModuleFileName
//
// Handles Unicode/ANSI paths from a module handle.
//
STDAPI_(BOOL) FGetModuleFileName(HMODULE hModule, WCHAR** wzFileName)
{
LPWSTR pwsz;
DWORD dw;
CHECK_NULL_RETURN(wzFileName, FALSE);
*wzFileName = NULL;
pwsz = (LPWSTR)DsoMemAlloc((MAX_PATH * sizeof(WCHAR)));
CHECK_NULL_RETURN(pwsz, FALSE);
if (v_fUnicodeAPI)
{
dw = GetModuleFileNameW(hModule, pwsz, MAX_PATH);
if (dw == 0)
{
DsoMemFree(pwsz);
return FALSE;
}
}
else
{
dw = GetModuleFileNameA(hModule, (LPSTR)pwsz, MAX_PATH);
if (dw == 0)
{
DsoMemFree(pwsz);
return FALSE;
}
LPWSTR pwsz2 = DsoConvertToLPWSTR((LPSTR)pwsz);
if (pwsz2 == NULL)
{
DsoMemFree(pwsz);
return FALSE;
}
DsoMemFree(pwsz);
pwsz = pwsz2;
}
*wzFileName = pwsz;
return TRUE;
}
////////////////////////////////////////////////////////////////////////
// FIsIECacheFile
//
// Determines if file came from IE Cache (treat as read-only).
//
STDAPI_(BOOL) FIsIECacheFile(LPWSTR pwszFile)
{
BOOL fIsCacheFile = FALSE;
LPWSTR pwszTmpCache = NULL;
BYTE rgbuffer[MAX_PATH * sizeof(WCHAR)];
HKEY hk;
if (RegOpenKey(HKEY_CURRENT_USER,
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", &hk) == ERROR_SUCCESS)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -