📄 main.cpp
字号:
//---------------------------------------------------------------------------
// Microsoft OLE DB Programmer's Reference Sample
// Copyright (C) 1998 By Microsoft Corporation.
//
// @doc
//
// @module MAIN.CPP
//
//---------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////
// Includes
//
/////////////////////////////////////////////////////////////////
#define DBINITCONSTANTS // Store all OLE DB consts inside this .obj file
#include "prsample.h" // Programmer's Reference Sample includes
/////////////////////////////////////////////////////////////////
// Globals
//
/////////////////////////////////////////////////////////////////
DWORD g_dwFlags = USE_PROMPTDATASOURCE | DISPLAY_METHODCALLS;
/////////////////////////////////////////////////////////////////
// main
//
// This is a simple OLE DB application that will display a
// rowset and will allow basic navigation of that rowset by the
// user.
//
// In the sample, functions that begin with 'my' are implemented
// in the sample code; all other functions are either OLE DB
// methods or standard system methods. In addition, two
// macros are used repeatedly throughout the sample:
// - CHECK_HR(hr) - this macro goes to the CLEANUP label if
// FAILED(hr), where hr is usually a method call.
// - XCHECK_HR(hr) - this macro prints the string
// representation of hr to stderr and if FAILED(hr), attempts
// to obtain and display any extended error information
// posted by the last method call and then jumps to the CLEANUP
// label.
//
// This is the entry point for the sample. This function will:
// - parse command line arguments passed to the sample.
// - display appropriate instructions based on these arguments.
// - create an OLE DB data source object for a user-chosen
// provider.
// - create an OLE DB session object from the provider's
// data source object.
// - create an OLE DB rowset object, over a table specified by
// the user, from the provider's session object.
// - display the rowset data and will allow the user to
// navigate over the rowset.
//
/////////////////////////////////////////////////////////////////
int main()
{
HRESULT hr;
IUnknown * pUnkDataSource = NULL;
IUnknown * pUnkSession = NULL;
IUnknown * pUnkRowset = NULL;
// Parse command line arguments, if any; this will update
// the value of g_dwFlags as appropriate for the arguments
if( !myParseCommandLine() )
return EXIT_FAILURE;
// Display instructions for the given command line arguments
myDisplayInstructions();
// Initialize OLE
hr = CoInitialize(NULL);
if( FAILED(hr) )
return EXIT_FAILURE;
// Create the data source object using the OLE DB service components
CHECK_HR(hr = myCreateDataSource(&pUnkDataSource));
// Create a session object from the data source object
CHECK_HR(hr = myCreateSession(pUnkDataSource, &pUnkSession));
// Create a rowset object from the session object, either directly
// from the session or through a command object
CHECK_HR(hr = myCreateRowset(pUnkSession, &pUnkRowset));
// Display the rowset object data to the user
CHECK_HR(hr = myDisplayRowset(pUnkRowset, NULL, 0, NULL));
CLEANUP:
if( pUnkRowset )
pUnkRowset->Release();
if( pUnkSession )
pUnkSession->Release();
if( pUnkDataSource )
pUnkDataSource->Release();
CoUninitialize();
if( FAILED(hr) )
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
/////////////////////////////////////////////////////////////////
// myParseCommandLine
//
// This function parses the application's command line arguments
// and sets the appropriate bits in g_dwFlags. If an invalid
// argument is encountered, a usage message is displayed and
// the function returns FALSE; otherwise, TRUE is returned.
//
/////////////////////////////////////////////////////////////////
BOOL myParseCommandLine(void)
{
int iArg;
CHAR * psz;
// Set the locale for all C run-time functions
setlocale(LC_ALL, ".ACP");
// Go through each command line argument and set the appropriate
// bits in g_dwFlags, depending on the chosen options
for( iArg = 1; iArg < __argc; iArg++ )
{
// Inspect the current argument string
psz = __argv[iArg];
// Valid options begin with '-' or '/'
if( psz[0] == '-' || psz[0] == '/' )
{
// The next character is the option
switch( tolower(psz[1]) )
{
case 'u':
// Use the service components UI to prompt for and create
// the data source object; the enumerator is not used
g_dwFlags |= USE_PROMPTDATASOURCE;
g_dwFlags &= ~USE_ENUMERATOR;
continue;
case 'e':
// Use the enumerator to select the provider, and then use
// IDataInitialize to create the data source object.
// Don't use the UI to prompt for the data source.
g_dwFlags |= USE_ENUMERATOR;
g_dwFlags &= ~USE_PROMPTDATASOURCE;
continue;
case 'c':
// Use ICommand instead of IOpenRowset
g_dwFlags |= USE_COMMAND;
continue;
case 'b':
// Use ISequentialStream to fetch BLOB column data
g_dwFlags |= USE_ISEQSTREAM;
continue;
case 'n':
// Don't display method call strings as part of
// the extended error checking macro
g_dwFlags &= ~DISPLAY_METHODCALLS;
continue;
}
}
// Invalid argument; show the usage flags to the user
fprintf(stderr, "Usage: %s [-u] [-e] [-c] [-b] [-n]\n\nWhere:\n\t" \
"u = Use the Microsoft Data Links UI " \
"to create the DataSource\n\t" \
"e = Use the Enumerator and IDataInitialize " \
"to create the DataSource\n\t" \
"c = Use ICommand instead of IOpenRowset to create the Rowset\n\t" \
"b = Use ISequentialStream for BLOB columns\n\t" \
"n = Don't display method call strings\n",
__argv[0]);
return FALSE;
}
return TRUE;
}
/////////////////////////////////////////////////////////////////
// myDisplayInstructions
//
// This function asks the user whether they would like
// instructions displayed for the application. If so, it
// displays the instructions appropriate to the flags set
// in g_dwFlags.
//
/////////////////////////////////////////////////////////////////
void myDisplayInstructions(void)
{
CHAR ch;
// Display header and ask the user if they want instructions
printf( "\nOLE DB Programmer's Reference Sample\n" \
"====================================\n\n");
printf("Display instructions [Y or N]? ");
do
{
ch = myGetChar();
}
while( ch != 'y' && ch != 'n' );
printf("%c\n\n", ch);
// No instructions, so we're done
if( ch == 'n' )
return;
// Display basic instructions
printf( "This application is a simple OLE DB sample that will display\n" \
"a rowset and will allow basic navigation of that rowset by\n" \
"the user. The application will perform the following steps:\n\n");
// Display data source creation instructions
if( g_dwFlags & USE_PROMPTDATASOURCE )
{
printf( " - Creates a DataSource object through the Microsoft Data\n" \
" Links UI. This allows the user to select the OLE DB\n" \
" provider to use and to set connection properties.\n");
}
else
{
printf( " - Creates a DataSource object through IDataInitialize::\n" \
" CreateDBInstance, which allows the OLE DB service\n" \
" component manager to add additional functionality to\n" \
" the provider as requested. The user will select the\n" \
" provider to use from a rowset obtained from the OLE DB\n" \
" enumerator.\n");
}
// Display session creation and table-selection instructions
printf( " - Creates a Session object from the DataSource object.\n");
printf( " - If the provider supports the schema rowset interface,\n" \
" creates a TABLES schema rowset and allows the user to\n" \
" select a table name from this rowset.\n");
// Display rowset creation instructions
if( g_dwFlags & USE_COMMAND )
{
printf( " - Creates a Command object from the Session object and\n" \
" allows the user to specify command text for this Command,\n" \
" then executes the command to create the final rowset.\n");
}
else
{
printf( " - Creates the final rowset over the table specified by the\n" \
" user.\n");
}
printf( " - Displays this rowset and allows the user to perform basic\n" \
" navigation of that rowset.\n\n");
// Wait for the user to press a key before continuing
printf("Press a key to continue...");
myGetChar();
printf("\n\n");
}
/////////////////////////////////////////////////////////////////
// myGetInputFromUser
//
// This function prompts the user with the contents of pwszFmt
// and any accompanying variable arguments and then gets a string
// as input from the user. If the string is non-empty, it is
// copied into pwszInput and the function returns TRUE;
// otherwise, this function returns FALSE.
//
/////////////////////////////////////////////////////////////////
BOOL myGetInputFromUser(
LPWSTR pwszInput,
LPCWSTR pwszFmt,
)
{
va_list vargs;
WCHAR wszBuffer[MAX_NAME_LEN + 1]= {0};
// Create the string with variable arguments...
va_start(vargs, pwszFmt);
_vsnwprintf(wszBuffer, MAX_NAME_LEN, pwszFmt, vargs);
va_end(vargs);
// Output the string...
wprintf(wszBuffer);
// Now get the Input from the user...
_getws(wszBuffer);
if( wszBuffer[0] )
{
wcscpy(pwszInput, wszBuffer);
return TRUE;
}
return FALSE;
}
/////////////////////////////////////////////////////////////////
// myGetChar
//
// This function gets a character from the keyboard and
// converts it to lowercase before returning it
//
/////////////////////////////////////////////////////////////////
CHAR myGetChar(void)
{
CHAR ch;
// Get a character from the keyboard
ch = _getch();
// Re-read for the actual key value if necessary
if( !ch || ch == 0xE0 )
ch = _getch();
return tolower(ch);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -