📄 utilities.cpp
字号:
{
DWORD dwT, dwS; dwT = MAX_PATH;
memset(rgbuffer, 0, (MAX_PATH * sizeof(WCHAR)));
if (v_fUnicodeAPI)
{
if ((RegQueryValueExA(hk, "Cache", 0, &dwT, rgbuffer, &dwS) == ERROR_SUCCESS) &&
(dwT == REG_SZ) && (dwS > 1))
pwszTmpCache = DsoConvertToLPWSTR((LPSTR)rgbuffer);
}
else
{
if ((RegQueryValueExW(hk, L"Cache", 0, &dwT, rgbuffer, &dwS) == ERROR_SUCCESS) &&
(dwT == REG_SZ) && (dwS > 1))
pwszTmpCache = DsoCopyString((LPWSTR)rgbuffer);
}
RegCloseKey(hk);
if (pwszTmpCache)
{
dwS = lstrlenW(pwszTmpCache);
dwT = lstrlenW(pwszFile);
fIsCacheFile = ((dwS < dwT) &&
(DsoCompareStringsEx(pwszTmpCache, dwS, pwszFile, dwS) == CSTR_EQUAL));
DsoMemFree(pwszTmpCache);
}
}
return fIsCacheFile;
}
////////////////////////////////////////////////////////////////////////
// FDrawText
//
// This is used by the control for drawing the caption in the titlebar.
// Since a custom caption could contain Unicode characters only printable
// on Unicode OS, we should try to use the Unicode version when available.
//
STDAPI_(BOOL) FDrawText(HDC hdc, WCHAR* pwsz, LPRECT prc, UINT fmt)
{
BOOL f;
if (v_fUnicodeAPI)
{
f = (BOOL)DrawTextW(hdc, pwsz, -1, prc, fmt);
}
else
{
LPSTR psz = DsoConvertToMBCS(pwsz);
f = (BOOL)DrawTextA(hdc, psz, -1, prc, fmt);
DsoMemFree(psz);
}
return f;
}
////////////////////////////////////////////////////////////////////////
// FSetRegKeyValue
//
// We use this for registration when dealing with the file path, since
// that path may have Unicode characters on some systems. Win9x boxes
// will have to be converted to ANSI.
//
STDAPI_(BOOL) FSetRegKeyValue(HKEY hk, WCHAR* pwsz)
{
LONG lret;
if (v_fUnicodeAPI)
{
lret = RegSetValueExW(hk, NULL, 0, REG_SZ, (BYTE*)pwsz, (lstrlenW(pwsz) * sizeof(WCHAR)));
}
else
{
LPSTR psz = DsoConvertToMBCS(pwsz);
lret = RegSetValueExA(hk, NULL, 0, REG_SZ, (BYTE*)psz, lstrlen(psz));
DsoMemFree(psz);
}
return (lret == ERROR_SUCCESS);
}
////////////////////////////////////////////////////////////////////////
// FOpenPrinter
//
// Open the specified printer by name.
//
STDAPI_(BOOL) FOpenPrinter(LPCWSTR pwszPrinter, LPHANDLE phandle)
{
BOOL fRet = FALSE;
DWORD dwLastError = 0;
if (v_fUnicodeAPI)
{
PRINTER_DEFAULTSW prtdef;
memset(&prtdef, 0, sizeof(PRINTER_DEFAULTSW));
prtdef.DesiredAccess = PRINTER_ACCESS_USE;
fRet = OpenPrinterW((LPWSTR)pwszPrinter, phandle, &prtdef);
}
else
{
LPSTR psz = DsoConvertToMBCS(pwszPrinter);
fRet = OpenPrinterA(psz, phandle, NULL);
if (!fRet) dwLastError = GetLastError();
DsoMemFree(psz);
}
if (dwLastError) SetLastError(dwLastError);
return fRet;
}
////////////////////////////////////////////////////////////////////////
// FGetPrinterSettings
//
// Returns the default device, port name, and DEVMODE structure for the
// printer passed. Handles Unicode translation of DEVMODE if on Win9x.
//
STDAPI_(BOOL) FGetPrinterSettings(HANDLE hprinter, LPWSTR *ppwszProcessor, LPWSTR *ppwszDevice, LPWSTR *ppwszOutput, LPDEVMODEW *ppdvmode, DWORD *pcbSize)
{
BOOL fRet = FALSE;
DWORD dwLastError = 0;
DWORD cbNeed, cbAlloc = 0;
if ((ppwszProcessor == NULL) || (ppwszDevice == NULL) || (ppwszOutput == NULL) ||
(ppdvmode == NULL) || (pcbSize == NULL))
return FALSE;
*ppwszProcessor = NULL; *ppwszDevice = NULL; *ppwszOutput = NULL;
*ppdvmode = NULL; *pcbSize = 0;
if (v_fUnicodeAPI) // Use Unicode API if possible (much easier)...
{
GetPrinterW(hprinter, 2, NULL, 0, &cbAlloc);
PRINTER_INFO_2W *pinfo = (PRINTER_INFO_2W*)DsoMemAlloc(++cbAlloc);
if (pinfo)
{
fRet = GetPrinterW(hprinter, 2, (BYTE*)pinfo, cbAlloc, &cbNeed);
if (fRet)
{
*ppwszProcessor = DsoConvertToLPWSTR("winspool");
*ppwszDevice = DsoCopyString(pinfo->pDriverName);
*ppwszOutput = DsoCopyString(pinfo->pPortName);
if (pinfo->pDevMode) // If we have the devmode, just need to copy it...
{
DWORD cbData = (pinfo->pDevMode->dmSize) + (pinfo->pDevMode->dmDriverExtra);
*ppdvmode = (DEVMODEW*)DsoMemAlloc(cbData);
if (*ppdvmode)
{
memcpy(*ppdvmode, pinfo->pDevMode, cbData);
*pcbSize = cbData;
}
}
}
else dwLastError = GetLastError();
DsoMemFree(pinfo);
}
else dwLastError = ERROR_NOT_ENOUGH_MEMORY;
}
else
{
GetPrinterA(hprinter, 2, NULL, 0, &cbAlloc);
PRINTER_INFO_2A *pinfo = (PRINTER_INFO_2A*)DsoMemAlloc(++cbAlloc);
if (pinfo)
{
fRet = GetPrinterA(hprinter, 2, (BYTE*)pinfo, cbAlloc, &cbNeed);
if (fRet)
{
*ppwszProcessor = DsoConvertToLPWSTR("winspool");
*ppwszDevice = DsoConvertToLPWSTR(pinfo->pDriverName);
*ppwszOutput = DsoConvertToLPWSTR(pinfo->pPortName);
if (pinfo->pDevMode) // For Win9x API, we have to convert the DEVMODEA
{ // into DEVMODEW so we have Unicode names for TARGETDEVICE...
DWORD cbData = sizeof(DEVMODEW) +
((pinfo->pDevMode->dmSize > sizeof(DEVMODEA)) ? (pinfo->pDevMode->dmSize - sizeof(DEVMODEA)) : 0) +
pinfo->pDevMode->dmDriverExtra;
*ppdvmode = (DEVMODEW*)DsoMemAlloc(cbData);
if (*ppdvmode)
{
DsoConvertToUnicodeEx(
(LPSTR)(pinfo->pDevMode->dmDeviceName), CCHDEVICENAME,
(LPWSTR)((*ppdvmode)->dmDeviceName), CCHDEVICENAME, 0);
// The rest of the copy depends on the default size of the DEVMODE.
// Just check the size and convert the form name if it exists...
if (pinfo->pDevMode->dmSize <= FIELD_OFFSET(DEVMODEA, dmFormName))
{
memcpy(&((*ppdvmode)->dmSpecVersion),
&(pinfo->pDevMode->dmSpecVersion),
pinfo->pDevMode->dmSize - CCHDEVICENAME);
}
else
{
memcpy(&((*ppdvmode)->dmSpecVersion),
&(pinfo->pDevMode->dmSpecVersion),
FIELD_OFFSET(DEVMODEA, dmFormName) -
FIELD_OFFSET(DEVMODEA, dmSpecVersion));
DsoConvertToUnicodeEx(
(LPSTR)(pinfo->pDevMode->dmFormName), CCHFORMNAME,
(LPWSTR)((*ppdvmode)->dmFormName), CCHFORMNAME, 0);
if (pinfo->pDevMode->dmSize > FIELD_OFFSET(DEVMODEA, dmLogPixels))
memcpy(&((*ppdvmode)->dmLogPixels),
&(pinfo->pDevMode->dmLogPixels),
pinfo->pDevMode->dmSize - FIELD_OFFSET(DEVMODEA, dmLogPixels));
}
(*ppdvmode)->dmSize = (WORD)((pinfo->pDevMode->dmSize > sizeof(DEVMODEA)) ?
(sizeof(DEVMODEW) + (pinfo->pDevMode->dmSize - sizeof(DEVMODEA))) :
sizeof(DEVMODEW));
memcpy((((BYTE*)(*ppdvmode)) + ((*ppdvmode)->dmSize)),
(((BYTE*)(pinfo->pDevMode)) + (pinfo->pDevMode->dmSize)),
pinfo->pDevMode->dmDriverExtra);
*pcbSize = cbData;
}
}
}
else dwLastError = GetLastError();
DsoMemFree(pinfo);
}
else dwLastError = ERROR_NOT_ENOUGH_MEMORY;
}
if (dwLastError) SetLastError(dwLastError);
return fRet;
}
///////////////////////////////////////////////////////////////////////////////////
// DsoGetFileFromUser
//
// Displays the Open/Save dialog using Unicode version if available. Returns the
// path as a unicode BSTR regardless of OS.
//
STDAPI DsoGetFileFromUser(HWND hwndOwner, LPCWSTR pwzTitle, DWORD dwFlags,
LPCWSTR pwzFilter, DWORD dwFiltIdx, LPCWSTR pwszCurrentItem, BOOL fShowSave,
BSTR *pbstrFile, BOOL *pfReadOnly)
{
BYTE buffer[MAX_PATH * sizeof(WCHAR)];
BOOL fSuccess;
DWORD dw;
// Make sure they pass a *bstr...
CHECK_NULL_RETURN(pbstrFile, E_POINTER);
*pbstrFile = NULL;
buffer[0] = 0; buffer[1] = 0;
// See if we have Unicode function to call. If so, we use OPENFILENAMEW and
// get the file path in Unicode, returned as BSTR...
if (v_fUnicodeAPI)
{
OPENFILENAMEW ofnw;
memset(&ofnw, 0, sizeof(OPENFILENAMEW));
ofnw.lStructSize = sizeof(OPENFILENAMEW);
ofnw.hwndOwner = hwndOwner;
ofnw.lpstrFilter = pwzFilter;
ofnw.nFilterIndex = dwFiltIdx;
ofnw.lpstrTitle = pwzTitle;
ofnw.lpstrFile = (LPWSTR)&buffer[0];
ofnw.nMaxFile = MAX_PATH;
ofnw.Flags = dwFlags;
if (pwszCurrentItem)
{
dw = lstrlenW(pwszCurrentItem);
if ((dw) && (dw < MAX_PATH))
{
memcpy(ofnw.lpstrFile, pwszCurrentItem, dw * sizeof(WCHAR));
ofnw.lpstrFile[dw] = L'\0';
}
}
if (fShowSave)
fSuccess = GetSaveFileNameW(&ofnw);
else
fSuccess = GetOpenFileNameW(&ofnw);
if (fSuccess)
{
*pbstrFile = SysAllocString((LPWSTR)&buffer[0]);
if (pfReadOnly) *pfReadOnly = (ofnw.Flags & OFN_READONLY);
}
}
else
{ // If not, then we use OPENFILENAMEA and thunk down our params to
// the MBCS of the system, and then thunk back the Unicode for the return...
OPENFILENAMEA ofn;
memset(&ofn, 0, sizeof(OPENFILENAMEA));
ofn.lStructSize = sizeof(OPENFILENAMEA);
ofn.hwndOwner = hwndOwner;
ofn.lpstrFilter = DsoConvertToMBCS(pwzFilter);
ofn.nFilterIndex = dwFiltIdx;
ofn.lpstrTitle = DsoConvertToMBCS(pwzTitle);
ofn.lpstrFile = (LPSTR)&buffer[0];
ofn.nMaxFile = MAX_PATH;
ofn.Flags = dwFlags;
if (pwszCurrentItem)
DsoConvertToMBCSEx(pwszCurrentItem, lstrlenW(pwszCurrentItem), (LPSTR)&buffer[0], MAX_PATH, GetACP());
if (fShowSave)
fSuccess = GetSaveFileNameA(&ofn);
else
fSuccess = GetOpenFileNameA(&ofn);
if (fSuccess)
{
*pbstrFile = DsoConvertToBSTR((LPCSTR)&buffer[0]);
if (pfReadOnly) *pfReadOnly = (ofn.Flags & OFN_READONLY);
}
DsoMemFree((void*)(ofn.lpstrFilter));
DsoMemFree((void*)(ofn.lpstrTitle));
}
// If we got a string, then success. All other errors (even user cancel) should
// be treated as a general failure (feel free to change this for more full function).
return ((*pbstrFile == NULL) ? E_FAIL : S_OK);
}
///////////////////////////////////////////////////////////////////////////////////
// DsoGetOleInsertObjectFromUser
//
// Displays the OLE InsertObject dialog using Unicode version if available.
//
STDAPI DsoGetOleInsertObjectFromUser(HWND hwndOwner, LPCWSTR pwzTitle, DWORD dwFlags,
BOOL fDocObjectOnly, BOOL fAllowControls, BSTR *pbstrResult, UINT *ptype)
{
BYTE buffer[MAX_PATH * sizeof(WCHAR)];
LPCLSID lpNewExcludeList = NULL;
int nNewExcludeCount = 0;
int nNewExcludeLen = 0;
// Make sure they pass a *bstr...
CHECK_NULL_RETURN(pbstrResult, E_POINTER);
*pbstrResult = NULL;
// To limit list to just those marked as DocObject servers, you have to enum
// the registry and create an exclude list for OLE dialog. Exclude all except
// those that are marked DocObject under their ProgID.
if (fDocObjectOnly)
{
HKEY hkCLSID;
HKEY hkItem;
HKEY hkDocObject;
DWORD dwIndex = 0;
CHAR szName[MAX_PATH+1];
if (RegOpenKeyEx(HKEY_CLASSES_ROOT, "CLSID", 0, KEY_READ|KEY_ENUMERATE_SUB_KEYS, &hkCLSID) == ERROR_SUCCESS)
{
while (RegEnumKey(hkCLSID, dwIndex++, szName, MAX_PATH) == ERROR_SUCCESS)
{
if (RegOpenKeyEx(hkCLSID, szName, 0, KEY_READ, &hkItem) == ERROR_SUCCESS)
{
if ((RegOpenKeyEx(hkItem, "DocObject", 0, KEY_READ, &hkDocObject) != ERROR_SUCCESS))
{
CLSID clsid;
LPWSTR pwszClsid = DsoConvertToLPWSTR(szName);
if ((pwszClsid) && SUCCEEDED(CLSIDFromString(pwszClsid, &clsid)))
{
if (lpNewExcludeList == NULL)
{
nNewExcludeCount = 0;
nNewExcludeLen = 16;
lpNewExcludeList = new CLSID[nNewExcludeLen];
}
if (nNewExcludeCount == nNewExcludeLen)
{
LPCLSID lpOldList = lpNewExcludeList;
nNewExcludeLen <<= 2;
lpNewExcludeList = new CLSID[nNewExcludeLen];
memcpy(lpNewExcludeList, lpOldList, sizeof(CLSID) * nNewExcludeCount);
delete [] lpOldList;
}
lpNewExcludeList[nNewExcludeCount] = clsid;
nNewExcludeCount++;
}
SAFE_FREESTRING(pwszClsid);
RegCloseKey(hkDocObject);
}
RegCloseKey(hkItem);
}
}
RegCloseKey(hkCLSID);
}
}
buffer[0] = 0; buffer[1] = 0;
// See if we have Unicode function to call...
if (v_fUnicodeAPI)
{
OLEUIINSERTOBJECTW oidlg = {0};
oidlg.cbStruct = sizeof(OLEUIINSERTOBJECTW);
oidlg.dwFlags = dwFlags;
oidlg.hWndOwner = hwndOwner;
oidlg.lpszCaption = pwzTitle;
oidlg.lpszFile = (LPWSTR)buffer;
oidlg.cchFile = MAX_PATH;
oidlg.lpClsidExclude = lpNewExcludeList;
oidlg.cClsidExclude = nNewExcludeCount;
if (OleUIInsertObjectW(&oidlg) == OLEUI_OK)
{
if ((oidlg.dwFlags & IOF_SELECTCREATENEW) && (oidlg.clsid != GUID_NULL))
{
LPOLESTR posz;
if (SUCCEEDED(ProgIDFromCLSID(oidlg.clsid, &posz)))
{
*pbstrResult = SysAllocString(posz);
CoTaskMemFree(posz);
}
if (ptype) *ptype = IOF_SELECTCREATENEW;
}
else if ((oidlg.dwFlags & IOF_SELECTCREATEFROMFILE) && (buffer[0] != 0))
{
*pbstrResult = SysAllocString((LPWSTR)buffer);
if (ptype) *ptype = IOF_SELECTCREATEFROMFILE;
}
}
}
else
{
OLEUIINSERTOBJECTA oidlg = {0};
oidlg.cbStruct = sizeof(OLEUIINSERTOBJECTA);
oidlg.dwFlags = dwFlags;
oidlg.hWndOwner = hwndOwner;
oidlg.lpszCaption = DsoConvertToMBCS(pwzTitle);
oidlg.lpszFile = (LPSTR)buffer;
oidlg.cchFile = MAX_PATH;
oidlg.lpClsidExclude = lpNewExcludeList;
oidlg.cClsidExclude = nNewExcludeCount;
if (OleUIInsertObjectA(&oidlg) == OLEUI_OK)
{
if ((oidlg.dwFlags & IOF_SELECTCREATENEW) && (oidlg.clsid != GUID_NULL))
{
LPOLESTR posz;
if (SUCCEEDED(ProgIDFromCLSID(oidlg.clsid, &posz)))
{
*pbstrResult = SysAllocString(posz);
CoTaskMemFree(posz);
}
if (ptype) *ptype = IOF_SELECTCREATENEW;
}
else if ((oidlg.dwFlags & IOF_SELECTCREATEFROMFILE) && (buffer[0] != 0))
{
*pbstrResult = DsoConvertToBSTR((LPSTR)buffer);
if (ptype) *ptype = IOF_SELECTCREATEFROMFILE;
}
}
DsoMemFree((void*)(oidlg.lpszCaption));
}
if (lpNewExcludeList)
delete [] lpNewExcludeList;
// If we got a string, then success. All other errors (even user cancel) should
// be treated as a general failure (feel free to change this for more full function).
return ((*pbstrResult == NULL) ? E_FAIL : S_OK);
}
char* BSTR2char(const BSTR bstr)
{
int bstrLength = SysStringLen(bstr);
unsigned long multiByteLength = WideCharToMultiByte(CP_ACP, NULL, bstr, bstrLength, NULL, 0, NULL, NULL);
char* charBuffer = (char *) malloc(multiByteLength + 1);
WideCharToMultiByte(CP_ACP, NULL, bstr, bstrLength, charBuffer, multiByteLength, NULL, NULL);
charBuffer[multiByteLength] = 0;
return charBuffer;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -