📄 utilx.cpp
字号:
if (cbDate == 0) {
#if DEBUG
DWORD dwErr;
dwErr = GetLastError();
ASSERT(dwErr == 0);
#endif // DEBUG
IfNullGo(cbDate);
}
// add a space
bufDate[cbDate - 1] = ' ';
bufDate[cbDate] = 0; // null terminate
cbTime = GetTimeFormat(
LOCALE_USER_DEFAULT,
TIME_NOSECONDS, // flags specifying function options
&sysTime, // date to be formatted
0, // time format string - zero means default for locale
bufTime, // buffer for storing formatted string
sizeof(bufTime)/sizeof(bufTime[0]) // size of buffer
);
if (cbTime == 0) {
#if DEBUG
DWORD dwErr;
dwErr = GetLastError();
ASSERT(dwErr == 0);
#endif // DEBUG
IfNullGo(cbTime);
}
//
// concat
//
wcscat(bufDate, bufTime);
//
// convert to BSTR
//
IfNullGo(bstrDate = SysAllocString(bufDate));
// fall through...
Error:
return bstrDate;
}
// helper: gets default property of VARIANT
// pvar [in]
// pvarDefault [out]
//
HRESULT GetDefaultPropertyOfVariant(
VARIANT *pvar,
VARIANT *pvarDefault)
{
IDispatch *pdisp;
LCID lcid = LOCALE_USER_DEFAULT;
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
HRESULT hresult;
pdisp = GetPdisp(pvar);
if (pdisp) {
hresult = pdisp->Invoke(DISPID_VALUE,
IID_NULL,
lcid,
DISPATCH_PROPERTYGET,
&dispparamsNoArgs,
pvarDefault,
NULL, // pexcepinfo,
NULL // puArgErr
);
return hresult;
}
else {
return E_INVALIDARG;
}
}
// helper: gets newenum from object
// pdisp [in]
// ppenum [out]
//
HRESULT GetNewEnumOfObject(
IDispatch *pdisp,
IEnumVARIANT **ppenum)
{
LCID lcid = LOCALE_USER_DEFAULT;
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
VARIANT varNewEnum;
IDispatch *pdispNewEnum = NULL;
HRESULT hresult = NOERROR;
VariantInit(&varNewEnum);
ASSERT(pdisp);
IfFailRet(pdisp->Invoke(DISPID_NEWENUM,
IID_NULL,
lcid,
DISPATCH_PROPERTYGET,
&dispparamsNoArgs,
&varNewEnum,
NULL, // pexcepinfo,
NULL // puArgErr
));
IfFailRet(VariantChangeType(
&varNewEnum,
&varNewEnum,
0,
VT_DISPATCH));
//
// cast to IEnumVariant
//
pdispNewEnum = V_DISPATCH(&varNewEnum);
IfFailRet(pdispNewEnum->QueryInterface(
IID_IEnumVARIANT,
(LPVOID *)ppenum));
return hresult;
}
// helper: gets a VARIANT VT_<number> or VT_<number> | VT_BYREF
// returns -1 if invalid
//
UINT GetNumber(VARIANT *pvar)
{
VARIANT varDest;
HRESULT hresult;
// attempt to convert to an I4
VariantInit(&varDest);
hresult = VariantChangeType(&varDest, pvar, 0, VT_I4);
return (UINT)(SUCCEEDED(hresult) ? varDest.lVal : UINT_MAX);
}
// helper: gets a VARIANT VT_BOOL or VT_BOOL | VT_BYREF
// returns FALSE if invalid
//
BOOL GetBool(VARIANT *pvar)
{
switch (pvar->vt) {
case (VT_BOOL | VT_BYREF):
return (BOOL)*pvar->pboolVal;
case VT_BOOL:
return (BOOL)pvar->boolVal;
default:
return FALSE;
}
}
// helper: gets a VARIANT VT_BSTR or VT_BSTR | VT_BYREF
// returns NULL if invalid
//
BSTR GetBstr(VARIANT *pvar)
{
BSTR bstr;
HRESULT hresult;
hresult = GetTrueBstr(pvar, &bstr);
return FAILED(hresult) ? NULL : bstr;
}
// helper: gets a VARIANT VT_BSTR or VT_BSTR | VT_BYREF
// returns error if invalid
//
HRESULT GetTrueBstr(VARIANT *pvar, BSTR *pbstr)
{
VARIANT varDefault;
HRESULT hresult = NOERROR;
switch (pvar->vt) {
case (VT_BSTR | VT_BYREF):
*pbstr = *pvar->pbstrVal;
break;
case VT_BSTR:
*pbstr = pvar->bstrVal;
break;
default:
// see if it has a default string property
VariantInit(&varDefault);
hresult = GetDefaultPropertyOfVariant(pvar, &varDefault);
if (SUCCEEDED(hresult)) {
return GetTrueBstr(&varDefault, pbstr);
}
break;
}
return hresult;
}
// helper: gets a VARIANT VT_UNKNOWN or VT_UNKNOWN | VT_BYREF
// returns NULL if invalid
//
IUnknown *GetPunk(VARIANT *pvar)
{
if (pvar) {
if (pvar->vt == (VT_UNKNOWN | VT_BYREF)) {
return *pvar->ppunkVal;
}
else if (pvar->vt == VT_UNKNOWN) {
return pvar->punkVal;
}
}
return NULL;
}
// helper: gets a VARIANT VT_DISPATCH or VT_DISPATCH | VT_BYREF
// returns NULL if invalid
//
IDispatch *GetPdisp(VARIANT *pvar)
{
if (pvar) {
if (pvar->vt == (VT_DISPATCH | VT_BYREF)) {
return *pvar->ppdispVal;
}
else if (pvar->vt == VT_DISPATCH) {
return pvar->pdispVal;
}
}
return NULL;
}
// helper: gets a VARIANT VT_DATE or VT_DATE | VT_BYREF
// returns 0 if invalid
//
double GetDateVal(VARIANT *pvar)
{
if (pvar) {
if (pvar->vt == (VT_DATE | VT_BYREF)) {
return *V_DATEREF(pvar);
}
else if (pvar->vt == VT_DATE) {
return V_DATE(pvar);
}
}
return 0;
}
//=--------------------------------------------------------------------------=
// StrOfGuidW
//=--------------------------------------------------------------------------=
// returns a wide string from a CLSID or GUID
//
// Parameters:
// REFIID - [in] clsid to make string out of.
// LPTSTR - [in] buffer in which to place resultant GUID.
//
// Output:
// int - number of chars written out.
//
// Notes:
//
int StrOfGuidW
(
REFIID riid,
LPTSTR pwszBuf,
DWORD ccBuf
)
{
BOOL bRet = SUCCEEDED(StringCchPrintfW(pwszBuf, ccBuf, L"{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", riid.Data1,
riid.Data2, riid.Data3, riid.Data4[0], riid.Data4[1], riid.Data4[2],
riid.Data4[3], riid.Data4[4], riid.Data4[5], riid.Data4[6], riid.Data4[7]));
return bRet ? 1 : 0;
}
#define MAXMSGCHARLEN 1024
/*=======================================================
GetMessageOfId
dwMsgId [in]
szDllFile [in]
fUseDefaultLcid [in]
pbstrMessage [out]
Returns callee-allocated buffer containing message.
Caller must release.
========================================================*/
BOOL GetMessageOfId(
DWORD dwMsgId,
LPTSTR szDllFile,
BOOL fUseDefaultLcid,
BSTR *pbstrMessage)
{
DWORD cbMsg;
HINSTANCE hInst;
WCHAR wszTmp[MAXMSGCHARLEN]; // unicode chars
*pbstrMessage = NULL;
hInst = LoadLibrary(szDllFile);
if (hInst == 0) {
return FALSE;
}
if (fUseDefaultLcid) {
cbMsg = FormatMessage(FORMAT_MESSAGE_FROM_HMODULE |
FORMAT_MESSAGE_MAX_WIDTH_MASK,
hInst,
dwMsgId,
0,
wszTmp,
MAXMSGCHARLEN,
NULL);
}
else {
cbMsg = LoadString(hInst, dwMsgId, wszTmp, MAXMSGCHARLEN);
}
FreeLibrary(hInst);
return (cbMsg != 0);
}
/*=======================================================
GetMessageOfError
Translate an MQError to a string
hardwired to loaded error messages from mqutil.dll
Returns callee-allocated buffer containing message.
Caller must release.
========================================================*/
BOOL GetMessageOfError(DWORD dwMsgId, BSTR *pbstrMessage)
{
return GetMessageOfId(dwMsgId,
L"MQUTIL.DLL",
TRUE, /* fUseDefaultLcid */
pbstrMessage);
}
//=--------------------------------------------------------------------------=
// CreateError
//=--------------------------------------------------------------------------=
// fills in the rich error info object so that both our vtable bound interfaces
// and calls through ITypeInfo::Invoke get the right error informaiton.
//
// Parameters:
// hrExcep - [in] the SCODE that should be associated with this err
// pguid - [in] the interface id of the offending object:
// can be NULL.
// szName - [in] the name of the offending object:
// can be NULL.
//
// Output:
// HRESULT - the HRESULT that was passed in.
//
// Notes:
//
HRESULT CreateError(
HRESULT hrExcep,
GUID *pguid,
LPTSTR wszName)
{
ICreateErrorInfo *pCreateErrorInfo;
IErrorInfo *pErrorInfo;
BSTR bstrMessage = NULL;
HRESULT hresult = NOERROR;
// first get the createerrorinfo object.
//
hresult = CreateErrorInfo(&pCreateErrorInfo);
if (FAILED(hresult)) return hrExcep;
// set up some default information on it.
//
if (pguid) {
pCreateErrorInfo->SetGUID(*pguid);
}
// pCreateErrorInfo->SetHelpFile(wszHelpFile);
// pCreateErrorInfo->SetHelpContext(dwHelpContextID);
// load in the actual error string value. max of 256.
if (!GetMessageOfError(hrExcep, &bstrMessage)) {
return hrExcep;
}
pCreateErrorInfo->SetDescription(bstrMessage);
if (wszName) {
// load in the source
pCreateErrorInfo->SetSource(wszName);
}
// now set the Error info up with the system
//
IfFailGo(pCreateErrorInfo->QueryInterface(IID_IErrorInfo, (void **)&pErrorInfo));
SetErrorInfo(0, pErrorInfo);
pErrorInfo->Release();
Error:
pCreateErrorInfo->Release();
SysFreeString(bstrMessage);
return hrExcep;
}
#define SAFE_GUID_KEY L"{7DD95801-9882-11CF-9FA9-00AA006C42C4}"
//=--------------------------------------------------------------------------=
// RegisterAutomationObjectAsSafe
//=--------------------------------------------------------------------------=
// Declares that a given OA obj is safe by adding a bit of stuff:
// really just a new sub-key.
//
// we add the following information in addition to that set up in
// RegisterAutomationObject:
//
// HKEY_CLASSES_ROOT\
// CLSID\
// <CLSID>\
// Implemented categories\
// {7DD95801-9882-11CF-9FA9-00AA006C42C4}
//
// Parameters:
// REFCLSID - [in] CLSID of the object
//
// Output:
// BOOL - FALSE means not all of it was registered
//
// Notes:
//
BOOL RegisterAutomationObjectAsSafe
(
REFCLSID riidObject
)
{
HKEY hk = NULL, hkSub = NULL, hkSafe = NULL;
WCHAR wszScratch[MAX_PATH];
WCHAR wszGuidStr[MAX_PATH];
DWORD dwDummy;
HRESULT hresult;
// HKEY_CLASSES_ROOT\CLSID\<CLSID>\
// Implemented categories\
// {7DD95801-9882-11CF-9FA9-00AA006C42C4}
//
if (!StrOfGuidW(riidObject, wszGuidStr, MAX_PATH)) goto Error;
if (FAILED(StringCchPrintfW(wszScratch, MAX_PATH, L"CLSID\\%s", wszGuidStr))) goto Error;
IfFailGo(RegCreateKeyEx(
HKEY_CLASSES_ROOT,
wszScratch,
0,
L"",
REG_OPTION_NON_VOLATILE,
KEY_READ | KEY_WRITE,
NULL,
&hk,
&dwDummy));
IfFailGo(RegCreateKeyEx(
hk,
L"Implemented categories",
0,
L"",
REG_OPTION_NON_VOLATILE,
KEY_READ | KEY_WRITE,
NULL,
&hkSub,
&dwDummy));
IfFailGo(RegCreateKeyEx(
hkSub,
SAFE_GUID_KEY,
0,
L"",
REG_OPTION_NON_VOLATILE,
KEY_READ | KEY_WRITE,
NULL,
&hkSafe,
&dwDummy));
RegCloseKey(hkSafe);
RegCloseKey(hkSub);
RegCloseKey(hk);
return TRUE;
Error:
if (hkSafe) RegCloseKey(hkSafe);
if (hkSub) RegCloseKey(hkSub);
if (hk) RegCloseKey(hk);
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -