📄 common.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
// HRESULT GetDBTypeMaxSize
//
/////////////////////////////////////////////////////////////////////////////
HRESULT GetDBTypeMaxSize(DBTYPE wType, ULONG* pulMaxSize, BYTE* pbPrecision, BYTE* pbScale)
{
HRESULT hr = S_OK;
ULONG ulMaxSize = 0;
BYTE bPrecision = 0;
BYTE bScale = 0;
//Values taken from OLE DB Spec, Appendix A
//In some situations we need to know ulMaxSize, Prec, Scale, as defaults or creating
//an accessor before we actually have ColumnsInfo. Useful info, but mainly used
//only for defaults for dialogs...
//Unhandled Modifiers
if ((wType & DBTYPE_RESERVED) ||
(wType & DBTYPE_ARRAY) ||
(wType & DBTYPE_VECTOR))
{
hr = E_FAIL;
goto CLEANUP;
}
if(wType & DBTYPE_BYREF)
{
ulMaxSize = sizeof(void*);
goto CLEANUP;
}
switch(wType)
{
case DBTYPE_EMPTY:
case DBTYPE_NULL:
break;
case DBTYPE_STR:
case DBTYPE_WSTR:
case DBTYPE_BYTES:
case DBTYPE_BSTR:
ulMaxSize = MAX_COL_SIZE;
break;
case DBTYPE_I1:
case DBTYPE_UI1:
ulMaxSize = 1;
bPrecision = 3;
break;
case DBTYPE_I2:
case DBTYPE_UI2:
ulMaxSize = 2;
bPrecision = 5;
break;
case DBTYPE_I4:
case DBTYPE_UI4:
ulMaxSize = 4;
bPrecision = 10;
break;
case DBTYPE_I8:
ulMaxSize = 8;
bPrecision = 19;
break;
case DBTYPE_UI8:
ulMaxSize = 8;
bPrecision = 20;
break;
case DBTYPE_R4:
ulMaxSize = sizeof(float);
bPrecision = 7;
break;
case DBTYPE_R8:
ulMaxSize = sizeof(double);
bPrecision = 16;
break;
case DBTYPE_CY:
ulMaxSize = 8;
bPrecision = 19;
break;
case DBTYPE_NUMERIC:
ulMaxSize = sizeof(DB_NUMERIC);
bPrecision = 38;
break;
case DBTYPE_DATE:
ulMaxSize = sizeof(double);
break;
case DBTYPE_BOOL:
ulMaxSize = 2;
break;
case DBTYPE_VARIANT:
ulMaxSize = sizeof(VARIANT);
break;
case DBTYPE_IDISPATCH:
ulMaxSize = sizeof(IDispatch*);
break;
case DBTYPE_IUNKNOWN:
ulMaxSize = sizeof(IUnknown*);
break;
case DBTYPE_GUID:
ulMaxSize = sizeof(GUID);
break;
case DBTYPE_ERROR:
ulMaxSize = sizeof(SCODE);
break;
case DBTYPE_DBDATE:
ulMaxSize = sizeof(DBDATE);
break;
case DBTYPE_DBTIME:
ulMaxSize = sizeof(DBTIME);
break;
case DBTYPE_DBTIMESTAMP:
ulMaxSize = sizeof(DBTIMESTAMP);
break;
case DBTYPE_DECIMAL:
ulMaxSize = sizeof(DECIMAL);
bPrecision = 28;
break;
}
CLEANUP:
if(pulMaxSize)
*pulMaxSize = ulMaxSize;
if(pbPrecision)
*pbPrecision = bPrecision;
if(pbScale)
*pbScale = bScale;
return hr;
}
/////////////////////////////////////////////////////////////////////////////
// WCHAR* GetDBTypeName
//
/////////////////////////////////////////////////////////////////////////////
WCHAR* GetDBTypeName(DBTYPE wType)
{
return GetMapName(wType, g_cDBTypes, g_rgDBTypes);
}
/////////////////////////////////////////////////////////////////////////////
// DBTYPE GetDBType
//
/////////////////////////////////////////////////////////////////////////////
DBTYPE GetDBType(WCHAR* pwsz)
{
return (DBTYPE)GetMapName(pwsz, g_cDBTypes, g_rgDBTypes);
}
/////////////////////////////////////////////////////////////////////////////
// CHAR* GetVariantTypeName
//
/////////////////////////////////////////////////////////////////////////////
CHAR* GetVariantTypeName(VARTYPE vt)
{
return GetMapName(vt, g_cVariantTypes, g_rgVariantTypes);
}
/////////////////////////////////////////////////////////////////////////////
// CHAR* GetVariantTypeName
//
/////////////////////////////////////////////////////////////////////////////
DBTYPE GetVariantType(CHAR* psz)
{
return (DBTYPE)GetMapName(psz, g_cVariantTypes, g_rgVariantTypes);
}
///////////////////////////////////////////////////////////////
// BOOL FreeBindingData
//
///////////////////////////////////////////////////////////////
BOOL FreeBindingData(ULONG cBindings, DBBINDING* rgBindings, void* pData)
{
ASSERT(pData);
//Need to walk the array and free any other alloc memory
for(ULONG i=0; i<cBindings; i++)
{
//Free any "out-of-line" memory
//VARIANT
if(rgBindings[i].wType == DBTYPE_VARIANT)
{
VARIANT* pVariant = (VARIANT*)&BINDING_VALUE(rgBindings[i], pData);
FreeVariants(1, pVariant);
}
}
return TRUE;
}
///////////////////////////////////////////////////////////////
// BOOL FreeBindings
//
///////////////////////////////////////////////////////////////
BOOL FreeBindings(ULONG* pcBindings, DBBINDING** prgBindings)
{
ASSERT(pcBindings);
ASSERT(prgBindings);
//Need to walk the array and free any other alloc memory
for(ULONG i=0; i<*pcBindings; i++)
{
//Free any pObjects
ASSERT(*prgBindings);
SAFE_FREE((*prgBindings)[i].pObject);
}
//Now we can free the outer struct
*pcBindings = 0;
SAFE_FREE(*prgBindings);
return TRUE;
}
//////////////////////////////////////////////////////////////////
// void SyncSibling
//
//////////////////////////////////////////////////////////////////
void SyncSibling(HWND hToWnd, HWND hFromWnd)
{
ASSERT(hToWnd && hFromWnd);
//Make both windows synched,
//Get the current selection from the Source
LONG iItem = SendMessage(hFromWnd, LVM_GETNEXTITEM, (WPARAM)-1, (LPARAM)LVNI_SELECTED);
//Tell the Target to select the same selection
if(iItem != LVM_ERR)
{
//Get the current selection from the Target and Unselect it
LONG iOldItem = SendMessage(hToWnd, LVM_GETNEXTITEM, (WPARAM)-1, (LPARAM)LVNI_SELECTED);
if(iItem != iOldItem)
{
//Unselect previous one
LV_SetItemState(hToWnd, iOldItem, 0, 0, LVIS_SELECTED);
//Select the new one
LV_SetItemState(hToWnd, iItem, 0, LVIS_SELECTED, LVNI_SELECTED);
//Ensure that it is visible
SendMessage(hToWnd, LVM_ENSUREVISIBLE, (WPARAM)iItem, (LPARAM)FALSE);
}
}
}
/////////////////////////////////////////////////////////////////////
// Exception Handlers
//
/////////////////////////////////////////////////////////////////////
HRESULT HandleException(HWND hWnd, EXCEPTION_SOURCE eSource, WCHAR* pwszFile, ULONG ulLine)
{
//Popup a MessageBox
LONG dwSelection = wMessageBox(
NULL,
MB_TASKMODAL | MB_ICONSTOP | MB_OKCANCEL | MB_DEFBUTTON1,
wsz_EXCEPTION,
L"%s\n"
L"File '%s', Line '%lu'\n\n"
L"Do you wish to Continue?\n"
L"(Press 'OK' to ignore the Exception. Press 'Cancel' to debug.)",
(eSource == EXCEPTION_PROVIDER) ?
L"The OLE DB Provider your using threw an Exception!" :
L"RowsetViewer threw an Exception!",
pwszFile,
ulLine
);
switch(dwSelection)
{
case IDOK:
return 0;
case IDCANCEL:
return 1;
default:
ASSERT(!L"Unhandled Choice");
}
return 0;
}
//////////////////////////////////////////////////////////////////
// int InternalAssert
//
//////////////////////////////////////////////////////////////////
int InternalAssert( // 1 to break, 0 to skip.
char* pszExp, // The expression causing assert
char* pszFile, // The file name
UINT iLine // Line number of assert
)
{
//Popup a MessageBox
LONG dwSelection = wMessageBox(
NULL,
MB_TASKMODAL | MB_ICONSTOP | MB_OKCANCEL | MB_DEFBUTTON1,
wsz_ERROR,
L"Assertion Error!\nFile '%S', Line '%lu'\n"
L"Expression '%S'\n\n"
L"Do you wish to Continue?\n"
L"(Press 'OK' to ignore the assertion. Press 'Cancel' to debug.)",
pszFile,
iLine,
pszExp
);
switch(dwSelection)
{
case IDOK:
return 0;
case IDCANCEL:
return 1;
default:
ASSERT(!L"Unhandled Choice");
}
return 0;
}
//////////////////////////////////////////////////////////////////
// void InternalTrace
//
//////////////////////////////////////////////////////////////////
void InternalTrace(WCHAR* pwszFmt, ...)
{
va_list marker;
WCHAR wszBuffer[MAX_QUERY_LEN];
CHAR szBuffer[MAX_QUERY_LEN];
// Use format and arguements as input
//This version will not overwrite the stack, since it only copies
//upto the max size of the array
va_start(marker, pwszFmt);
_vsnwprintf(wszBuffer, MAX_QUERY_LEN, pwszFmt, marker);
va_end(marker);
//Make sure there is a NULL Terminator, vsnwprintf will not copy
//the terminator if length==MAX_QUERY_LEN
wszBuffer[MAX_QUERY_LEN-1] = wEOL;
//Convert to MBCS
ConvertToMBCS(wszBuffer, szBuffer, MAX_QUERY_LEN);
//Output to the DebugWindow
OutputDebugString(szBuffer);
}
//////////////////////////////////////////////////////////////////
// void InternalTrace
//
//////////////////////////////////////////////////////////////////
void InternalTrace(CHAR* pszFmt, ...)
{
va_list marker;
CHAR szBuffer[MAX_QUERY_LEN];
// Use format and arguements as input
//This version will not overwrite the stack, since it only copies
//upto the max size of the array
va_start(marker, pszFmt);
_vsnprintf(szBuffer, MAX_QUERY_LEN, pszFmt, marker);
va_end(marker);
//Make sure there is a NULL Terminator, vsnwprintf will not copy
//the terminator if length==MAX_QUERY_LEN
szBuffer[MAX_QUERY_LEN-1] = EOL;
OutputDebugStringA(szBuffer);
}
//////////////////////////////////////////////////////////////////
// void Busy
//
//////////////////////////////////////////////////////////////////
void Busy(BOOL bValue)
{
static HCURSOR hWaitCursor = LoadCursor(NULL, IDC_WAIT);
if(bValue)
SetCursor(hWaitCursor);
else
SetCursor(NULL);
}
//////////////////////////////////////////////////////////////////
// void OutOfMemory
//
//////////////////////////////////////////////////////////////////
void OutOfMemory(HWND hWnd)
{
//Unicode version is supported on Win95/WinNT
MessageBoxW(hWnd, L"Out of memory", wsz_ERROR, MB_TASKMODAL | MB_OK);
}
//////////////////////////////////////////////////////////////////
// BOOL CenterDialog
//
//////////////////////////////////////////////////////////////////
BOOL CenterDialog(HWND hdlg)
{
RECT rcParent; // Parent window client rect
RECT rcDlg; // Dialog window rect
int nLeft, nTop; // Top-left coordinates
int cWidth, cHeight; // Width and height
HWND hwnd;
// Get frame window client rect in screen coordinates
hwnd = GetParent(hdlg);
if(hwnd == NULL || hwnd == GetDesktopWindow())
{
rcParent.top = rcParent.left = 0;
rcParent.right = GetSystemMetrics(SM_CXFULLSCREEN);
rcParent.bottom = GetSystemMetrics(SM_CYFULLSCREEN);
}
else
GetWindowRect(hwnd, &rcParent);
// Determine the top-left point for the dialog to be centered
GetWindowRect(hdlg, &rcDlg);
cWidth = rcDlg.right - rcDlg.left;
cHeight = rcDlg.bottom - rcDlg.top;
nLeft = rcParent.left +
(((rcParent.right - rcParent.left) - cWidth ) / 2);
nTop = rcParent.top +
(((rcParent.bottom - rcParent.top ) - cHeight) / 2);
if (nLeft < 0) nLeft = 0;
if (nTop < 0) nTop = 0;
// Place the dialog
return MoveWindow(hdlg, nLeft, nTop, cWidth, cHeight, TRUE);
}
//////////////////////////////////////////////////////////////////
// BOOL MoveWindow
//
//////////////////////////////////////////////////////////////////
BOOL MoveWindow(HWND hWnd, ULONG x, ULONG y)
{
RECT rcParent; // Parent window client rect
RECT rcDlg; // Dialog window rect
int nLeft, nTop; // Top-left coordinates
int cWidth, cHeight; // Width and height
HWND hWndParent;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -