📄 cdialog.cpp
字号:
//-----------------------------------------------------------------------------
// Microsoft OLE DB RowsetViewer
// Copyright (C) 1994 - 1998 By Microsoft Corporation.
//
// @doc
//
// @module CDIALOG.CPP
//
//-----------------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////
// Includes
//
/////////////////////////////////////////////////////////////////
#include "common.h"
#include "CDialog.h"
#include "Main.h"
#include <richedit.h> //RichEdit Control Header
/////////////////////////////////////////////////////////////////////
// Defines
//
/////////////////////////////////////////////////////////////////////
enum PROPICONS
{
IMAGE_NORMAL = 0,
IMAGE_READONLY = 1,
IMAGE_ERROR = 2,
};
//PROPINFO
enum PROPINFO_COLUMNS
{
PROPINFO_NAME,
PROPINFO_TYPE,
PROPINFO_VALUE,
PROPINFO_FLAGS,
PROPINFO_DESC,
};
//PROPERTY
enum PROP_COLUMNS
{
PROP_NAME,
PROP_TYPE,
PROP_VALUE,
PROP_OPTIONS,
PROP_COLID,
PROP_DESC,
};
enum STATEICONS
{
STATE_NORMAL = 0,
STATE_CHECKED = 1,
STATE_UNCHECKED = 2,
};
#define NOTSET -2
#define HKEY_ROWSETVIEWER HKEY_CURRENT_USER
#define szCONFIG_KEY "Software\\Microsoft\\OLE DB\\RowsetViewer\\Config"
#define szRECENTCONFIG_KEY "Software\\Microsoft\\OLE DB\\RowsetViewer\\RecentConfig"
#define szRECENTFILE_KEY "Software\\Microsoft\\OLE DB\\RowsetViewer\\RecentFile"
#define szRECENTINITSTRING_KEY "Software\\Microsoft\\OLE DB\\RowsetViewer\\RecentInitString"
#define szOPTIONS_KEY "Software\\Microsoft\\OLE DB\\RowsetViewer\\Options"
//JOLT specific schema rowsets
//Only included here so the provider specific guids have a name map rather than
//trying to indentify them by guid value
const GUID DBSCHEMA_JETOLEDB_REPLPARTIALFILTERLIST = {0xe2082df0,0x54ac,0x11d1,{0xbd,0xbb,0x00,0xc0,0x4f,0xb9,0x26,0x75}};
const GUID DBSCHEMA_JETOLEDB_REPLCONFLICTTABLES = {0xe2082df2,0x54ac,0x11d1,{0xbd,0xbb,0x00,0xc0,0x4f,0xb9,0x26,0x75}};
const GUID DBSCHEMA_JETOLEDB_USERROSTER = {0x947bb102,0x5d43,0x11d1,{0xbd,0xbf,0x00,0xc0,0x4f,0xb9,0x26,0x75}};
const GUID DBSCHEMA_JETOLEDB_ISAMSTATS = {0x8703b612,0x5d43,0x11d1,{0xbd,0xbf,0x00,0xc0,0x4f,0xb9,0x26,0x75}};
/////////////////////////////////////////////////////////////////////
// Schema Constraint Mapping and Information
//
/////////////////////////////////////////////////////////////////////
static const SCHEMAINFO g_rgSchemaInfo[] =
{
& VALUE_CHAR(DBSCHEMA_ASSERTIONS), 3, {1, "CONSTRAINT_CATALOG", 2, "CONSTRAINT_SCHEMA", 3, "CONSTRAINT_NAME"},
& VALUE_CHAR(DBSCHEMA_CATALOGS), 1, {1, "CATALOG_NAME"},
& VALUE_CHAR(DBSCHEMA_CHARACTER_SETS), 3, {1, "CHARACTER_SET_CATALOG",2, "CHARACTER_SET_SCHEMA", 3, "CHARACTER_SET_NAME"},
& VALUE_CHAR(DBSCHEMA_CHECK_CONSTRAINTS), 3, {1, "CONSTRAINT_CATALOG", 2, "CONSTRAINT_SCHEMA", 3, "CONSTRAINT_NAME"},
& VALUE_CHAR(DBSCHEMA_COLLATIONS), 3, {1, "COLLATIONS_CATALOG", 2, "COLLATIONS_SCHEMA", 3, "COLLATIONS_NAME"},
& VALUE_CHAR(DBSCHEMA_COLUMN_DOMAIN_USAGE), 4, {1, "DOMAIN_CATALOG", 2, "DOMAIN_SCHEMA", 3, "DOMAIN_NAME", 4, "COLUMN_NAME"},
& VALUE_CHAR(DBSCHEMA_COLUMN_PRIVILEGES), 6, {1, "TABLE_CATALOG", 2, "TABLE_SCHEMA", 3, "TABLE_NAME", 4, "COLUMN_NAME", 5, "GRANTOR", 6, "GRANTEE"},
& VALUE_CHAR(DBSCHEMA_COLUMNS), 4, {1, "TABLE_CATALOG", 2, "TABLE_SCHEMA", 3, "TABLE_NAME", 4, "COLUMN_NAME"},
& VALUE_CHAR(DBSCHEMA_CONSTRAINT_COLUMN_USAGE), 4, {1, "TABLE_CATALOG", 2, "TABLE_SCHEMA", 3, "TABLE_NAME", 4, "COLUMN_NAME"},
& VALUE_CHAR(DBSCHEMA_CONSTRAINT_TABLE_USAGE), 3, {1, "TABLE_CATALOG", 2, "TABLE_SCHEMA", 3, "TABLE_NAME"},
& VALUE_CHAR(DBSCHEMA_FOREIGN_KEYS), 6, {1, "PK_TABLE_CATALOG", 2, "PK_TABLE_SCHEMA", 3, "PK_TABLE_NAME", 4, "FK_TABLE_CATALOG", 5, "FK_TABLE_SCHEMA", 6, "FK_TABLE_NAME"},
& VALUE_CHAR(DBSCHEMA_INDEXES), 5, {1, "TABLE_CATALOG", 2, "TABLE_SCHEMA", 3, "INDEX_NAME", 4, "TYPE", 5, "TABLE_NAME"},
& VALUE_CHAR(DBSCHEMA_KEY_COLUMN_USAGE), 7, {1, "CONSTRAINT_CATALOG", 2, "CONSTRAINT_SCHEMA", 3, "CONSTRAINT_NAME", 4, "TABLE_CATALOG", 5, "TABLE_SCHEMA", 6, "TABLE_NAME", 7, "COLUMN_NAME"},
& VALUE_CHAR(DBSCHEMA_PRIMARY_KEYS), 3, {1, "TABLE_CATALOG", 2, "TABLE_SCHEMA", 3, "TABLE_NAME"},
& VALUE_CHAR(DBSCHEMA_PROCEDURE_COLUMNS), 4, {1, "PROCEDURE_CATALOG", 2, "PROCEDURE_SCHEMA", 3, "PROCEDURE_NAME", 4, "COLUMN_NAME"},
& VALUE_CHAR(DBSCHEMA_PROCEDURE_PARAMETERS), 4, {1, "PROCEDURE_CATALOG", 2, "PROCEDURE_SCHEMA", 3, "PROCEDURE_NAME", 4, "PARAMETER_NAME"},
& VALUE_CHAR(DBSCHEMA_PROCEDURES), 4, {1, "PROCEDURE_CATALOG", 2, "PROCEDURE_SCHEMA", 3, "PROCEDURE_NAME", 4, "PROCEDURE_TYPE"},
& VALUE_CHAR(DBSCHEMA_PROVIDER_TYPES), 2, {1, "DATA_TYPE", 2, "BEST_MATCH"},
& VALUE_CHAR(DBSCHEMA_REFERENTIAL_CONSTRAINTS), 3, {1, "CONSTRAINT_CATALOG", 2, "CONSTRAINT_SCHEMA", 3, "CONSTRAINT_NAME"},
& VALUE_CHAR(DBSCHEMA_SCHEMATA), 3, {1, "CATALOG_NAME", 2, "SCHEMA_NAME", 3, "SCHEMA_OWNER"},
& VALUE_CHAR(DBSCHEMA_SQL_LANGUAGES), 0, {1, ""},
& VALUE_CHAR(DBSCHEMA_STATISTICS), 3, {1, "TABLE_CATALOG", 2, "TABLE_SCHEMA", 3, "TABLE_NAME"},
& VALUE_CHAR(DBSCHEMA_TABLE_CONSTRAINTS), 7, {1, "CONSTRAINT_CATALOG", 2, "CONSTRAINT_SCHEMA", 3, "CONSTRAINT_NAME", 4, "TABLE_CATALOG", 5, "TABLE_SCHEMA", 6, "TABLE_NAME", 7, "CONSTRAINT_TYPE"},
& VALUE_CHAR(DBSCHEMA_TABLE_PRIVILEGES), 5, {1, "TABLE_CATALOG", 2, "TABLE_SCHEMA", 3, "TABLE_NAME", 4, "GRANTOR", 5, "GRANTEE"},
& VALUE_CHAR(DBSCHEMA_TABLES), 4, {1, "TABLE_CATALOG", 2, "TABLE_SCHEMA", 4, "TABLE_NAME", 3, "TABLE_TYPE"},
& VALUE_CHAR(DBSCHEMA_TRANSLATIONS), 3, {1, "TRANSLATION_CATALOG", 2, "TRANSLATION_SCHEMA", 3, "TRANSLATION_NAME"},
& VALUE_CHAR(DBSCHEMA_USAGE_PRIVILEGES), 6, {1, "OBJECT_CATALOG", 2, "OBJECT_SCHEMA", 3, "OBJECT_NAME", 4, "OBJECT_TYPE", 5, "GRANTOR", 6, "GRANTEE"},
& VALUE_CHAR(DBSCHEMA_VIEW_COLUMN_USAGE), 3, {1, "VIEW_CATALOG", 2, "VIEW_SCHEMA", 3, "VIEW_NAME"},
& VALUE_CHAR(DBSCHEMA_VIEW_TABLE_USAGE), 3, {1, "VIEW_CATALOG", 2, "VIEW_SCHEMA", 3, "VIEW_NAME"},
& VALUE_CHAR(DBSCHEMA_VIEWS), 3, {1, "TABLE_CATALOG", 2, "TABLE_SCHEMA", 3, "TABLE_NAME"},
//2.0
& VALUE_CHAR(DBSCHEMA_TABLES_INFO), 4, {1, "TABLE_CATALOG", 2, "TABLE_SCHEMA", 4, "TABLE_NAME", 3, "TABLE_TYPE"},
//OLAP Extensions
& VALUE_CHAR(MDSCHEMA_CUBES), 3, {1, "CATALOG_NAME", 2, "SCHEMA_NAME", 3, "CUBE_NAME"},
& VALUE_CHAR(MDSCHEMA_DIMENSIONS), 5, {1, "CATALOG_NAME", 2, "SCHEMA_NAME", 3, "CUBE_NAME", 4, "DIMENSION_NAME", 5, "DIMENSION_UNIQUE_NAME"},
& VALUE_CHAR(MDSCHEMA_HIERARCHIES), 6, {1, "CATALOG_NAME", 2, "SCHEMA_NAME", 3, "CUBE_NAME", 4, "DIMENSION_UNIQUE_NAME", 5, "HIERARCHY_NAME", 6, "HIERARCHY_UNIQUE_NAME"},
& VALUE_CHAR(MDSCHEMA_LEVELS), 7, {1, "CATALOG_NAME", 2, "SCHEMA_NAME", 3, "CUBE_NAME", 4, "DIMENSION_UNIQUE_NAME", 5, "HIERARCHY_UNIQUE_NAME", 6, "LEVEL_NAME", 7, "LEVEL_UNIQUE_NAME"},
& VALUE_CHAR(MDSCHEMA_MEASURES), 5, {1, "CATALOG_NAME", 2, "SCHEMA_NAME", 3, "CUBE_NAME", 4, "MEASURE_NAME", 5, "MEASURE_UNIQUE_NAME"},
& VALUE_CHAR(MDSCHEMA_PROPERTIES), 9, {1, "CATALOG_NAME", 2, "SCHEMA_NAME", 3, "CUBE_NAME", 4, "DIMENSION_UNIQUE_NAME", 5, "HIERARCHY_UNIQUE_NAME", 6, "LEVEL_UNIQUE_NAME", 7, "MEMBER_UNIQUE_NAME", 8, "PROPERTY_NAME", 9, "PROPERTY_TYPE"},
& VALUE_CHAR(MDSCHEMA_MEMBERS), 11,{1, "CATALOG_NAME", 2, "SCHEMA_NAME", 3, "CUBE_NAME", 4, "DIMENSION_UNIQUE_NAME", 5, "HIERARCHY_UNIQUE_NAME", 6, "LEVEL_UNIQUE_NAME", 7, "LEVEL_NUMBER", 8, "MEMBER_NAME", 9, "MEMBER_UNIQUE_NAME", 10, "MEMBER_TYPE", 11, "MDTREE_OPERATOR"},
//JOLT specific schema rowsets
//Only included here so the provider specific guids have a name map rather than
//trying to indentify them by guid value
& VALUE_CHAR(DBSCHEMA_JETOLEDB_REPLPARTIALFILTERLIST), 0, {1, ""},
& VALUE_CHAR(DBSCHEMA_JETOLEDB_REPLCONFLICTTABLES), 0, {1, ""},
& VALUE_CHAR(DBSCHEMA_JETOLEDB_USERROSTER), 0, {1, ""},
& VALUE_CHAR(DBSCHEMA_JETOLEDB_ISAMSTATS), 0, {1, ""},
};
/////////////////////////////////////////////////////////////////////
// Helper Functions
//
/////////////////////////////////////////////////////////////////////
void* SetThis(HWND hWnd, LONG lParam)
{
ASSERT(hWnd);
SetWindowLong(hWnd, GWL_USERDATA, lParam);
return (void*)lParam;
}
void* GetThis(HWND hWnd)
{
ASSERT(hWnd);
return (void*)GetWindowLong(hWnd, GWL_USERDATA);
}
/////////////////////////////////////////////////////////////////////
// CDialogBase::CDialogBase
//
/////////////////////////////////////////////////////////////////////
CDialogBase::CDialogBase(HWND hWnd, HINSTANCE hInst)
{
ASSERT(hInst);
m_hWnd = hWnd;
m_hInst = hInst;
}
/////////////////////////////////////////////////////////////////////
// CDialogBase::~CDialogBase
//
/////////////////////////////////////////////////////////////////////
CDialogBase::~CDialogBase()
{
// Destroy();
}
/////////////////////////////////////////////////////////////////////
// ULONG CDialogBase::Destroy
//
/////////////////////////////////////////////////////////////////////
ULONG CDialogBase::Destroy()
{
if(m_hWnd)
{
EndDialog(m_hWnd, 0);
m_hWnd = NULL;
}
return 0;
}
////////////////////////////////////////////////////////////////
// CListBox::CListBox
//
/////////////////////////////////////////////////////////////////
CListBox::CListBox(HWND hWnd, HINSTANCE hInst, CMainWindow* pCMainWindow)
: CDialogBase(hWnd, hInst)
{
//Data
ASSERT(pCMainWindow);
m_pCMainWindow = pCMainWindow;
//Timeings
m_timerValue.QuadPart = 0;
m_timerFreq.QuadPart = 0;
QueryPerformanceFrequency(&m_timerFreq);
//Other
m_iNotificationIndex = LB_APPEND;
}
////////////////////////////////////////////////////////////////
// CListBox::~CListBox
//
/////////////////////////////////////////////////////////////////
CListBox::~CListBox()
{
//This window has already been removed, From the WM_DESTROY...
m_hWnd = NULL;
}
////////////////////////////////////////////////////////////////
// CListBox::Display
//
/////////////////////////////////////////////////////////////////
ULONG CListBox::Display(HWND hWndParent, UINT x, UINT y, UINT iWidth, UINT iHeight, DWORD dwFlags, void* lParam)
{
//CreateListBox
ASSERT(m_hWnd == NULL);
m_hWnd = CreateWindowEx(
WS_EX_CLIENTEDGE, // ex style
m_pCMainWindow->m_hLibRichEdit ? "RICHEDIT" : "EDIT", // class name - defined in commctrl.h
NULL, // window text
dwFlags | WS_TABSTOP | WS_CHILD | WS_BORDER | WS_HSCROLL | WS_VSCROLL | ES_LEFT | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_MULTILINE | ES_WANTRETURN | /*ES_NOHIDESEL |*/ ES_READONLY,
x, // x position
y, // y position
iWidth, // width
iHeight, // height
hWndParent, // parent
(HMENU)IDC_LISTBOX, // ID
m_hInst, // instance
lParam); // lParam
SetThis(m_hWnd, (LPARAM)lParam);
SendMessage(m_hWnd, EM_SETTEXTMODE , TM_PLAINTEXT | TM_MULTILEVELUNDO, 0);
return (ULONG)m_hWnd;
}
////////////////////////////////////////////////////////////////
// CListBox::GetOptionsObj
//
/////////////////////////////////////////////////////////////////
COptionsDlg* CListBox::GetOptionsObj()
{
ASSERT(m_pCMainWindow);
ASSERT(m_pCMainWindow->m_pCOptionsDlg);
return m_pCMainWindow->m_pCOptionsDlg;
}
////////////////////////////////////////////////////////////////
// CListBox::InitControls
//
/////////////////////////////////////////////////////////////////
BOOL CListBox::InitControls(HWND hWnd)
{
m_hWnd = hWnd;
return TRUE;
}
////////////////////////////////////////////////////////////////
// CListBox::RefreshControls
//
/////////////////////////////////////////////////////////////////
BOOL CListBox::RefreshControls()
{
return TRUE;
}
////////////////////////////////////////////////////////////////
// CListBox::CopyTo
//
/////////////////////////////////////////////////////////////////
BOOL CListBox::CopyTo(HWND hWndTo)
{
//No-op
if(hWndTo == NULL)
return FALSE;
CHAR szBuffer[MAX_QUERY_LEN];
//Move the Caret to the Begining
SendMessage(hWndTo, EM_SETSEL, 0, 0);
//Copy the contents of this ListBox to the destination...
LONG iCount = SendMessage(m_hWnd, EM_GETLINECOUNT, 0, 0);
for(LONG i=0; i<iCount; i++)
{
//Get the Text for this Line
//EM_GETLINE assumes the first byte of the buffer
//indicates the total size of the buffer
((DWORD*)szBuffer)[0] = MAX_QUERY_LEN-1;
LONG iChars = SendMessage(m_hWnd, EM_GETLINE, i, (LPARAM)szBuffer);
//Supposedly EM_GETLINE doesn't contain a NULL Terminator?!
ASSERT(iChars >=0 && iChars < MAX_QUERY_LEN);
szBuffer[iChars] = EOL;
if(szBuffer[0])
{
//Now Copy this text to the Destination
SendMessage(hWndTo, EM_REPLACESEL, TRUE, (LPARAM)szBuffer);
//Carriage return in EditControl is (2 carriage returns, 1 line feed)
SendMessageA(hWndTo, EM_REPLACESEL, TRUE, (LPARAM)"\r\r\n");
}
}
return TRUE;
}
//////////////////////////////////////////////////////////////////
// LONG CListBox::OutputLineEnd
//
//////////////////////////////////////////////////////////////////
LONG CListBox::OutputLineEnd()
{
//Standard MultiLine Edit Controls require (\r\r\n)
//Anything else results in no line break
//Even RichEdit controls "\n" works but when copying to text files they are lost
SendMessageA(m_hWnd, EM_REPLACESEL, TRUE, (LPARAM)"\r\r\n");
return 0;
}
//////////////////////////////////////////////////////////////////
// LONG CListBox::OutputText
//
//////////////////////////////////////////////////////////////////
LONG CListBox::OutputText(LONG iIndex, CHAR* pszFmt, ...)
{
ASSERT(pszFmt);
//No-op - no output window...
if(m_hWnd == NULL)
return 0;
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_NAME_LEN
szBuffer[MAX_QUERY_LEN-1] = EOL;
//Delegate
if(iIndex == LB_APPEND)
{
//Move the Caret to the End
SendMessageA(m_hWnd, EM_SETSEL, LONG_MAX, LONG_MAX);
//Save the Begining Char Location (so we can overwrite with Post Message)
SendMessageA(m_hWnd, EM_GETSEL, (WPARAM)&iIndex, 0);
//Append the New String
SendMessageA(m_hWnd, EM_REPLACESEL, TRUE, (LPARAM)szBuffer);
//Carriage return in EditControl is (2 carriage returns, 1 line feed)
OutputLineEnd();
}
else
{
//Need to find the Length of the Saved Line
LONG iLength = SendMessageA(m_hWnd, EM_LINELENGTH, iIndex, 0);
//We need to Place the Post Message in the Saved Location...
SendMessageA(m_hWnd, EM_SETSEL, iIndex, iIndex + iLength);
//Now display the Post Message
SendMessageA(m_hWnd, EM_REPLACESEL, TRUE, (LPARAM)szBuffer);
//Move the Caret to the End
SendMessageA(m_hWnd, EM_SETSEL, LONG_MAX, LONG_MAX);
iIndex = LB_APPEND;
}
//Since we added a new item, scroll down to it...
// SendMessage(m_hWnd, WM_VSCROLL,(WPARAM)SB_BOTTOM,(LPARAM)NULL);
return iIndex;
}
//////////////////////////////////////////////////////////////////
// HRESULT CListBox::OutputNotification
//
//////////////////////////////////////////////////////////////////
HRESULT CListBox::OutputNotification(DWORD dwNotifyType, CHAR* pszFmt, ...)
{
ASSERT(pszFmt);
//Only if the user is interested in this message
if(GetOptionsObj()->m_dwNotifyOpts & dwNotifyType)
{
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -