/*--------------------------------------------------------------------------
Dialogs.c -- Cursors dialogs
Description:
This sample is spread across four files, each named for the role
the contained functions play. Each file header contains a brief
description of its purpose and the routines it contains.
DIALOGS.C contains those routines used to display and manage
dialogs. Those functions are:
AddEditControls - Dynamically create edit controls for UPDATE
dialog
AddDlgProc - Manage add row dialog
CenterDialog - Center a dialog over its parent window
DoDialog - Display a dialog
MyCreateDialog - Create a modeless dialog
GetEditControls - Retrieve values from dynamically created
edit controls
IsMsgWaiting - Check for waiting messages
AboutDlgProc - Manage about box
AbsDlgProc - Manage absolute row number dialog
DataDlgProc - Manage large data display dialog
FindDlgProc - Manager dialog to get text string to find in result set
RelDlgProc - Manage relative row number dialog
StmtDlgProc - Manage SQL statement dialog
UpdateDlgProc - Manage update row dialog
SqlTablesDlgProc- handle SQLTables-type request
ClassOnCommand - handle a command message
This code is furnished on an as-is basis as part of the ODBC SDK and is
intended for example purposes only.
--------------------------------------------------------------------------*/
// Includes ----------------------------------------------------------------
#include "headers.h"
#include "resource.h"
#include "crsrdemo.h"
const char szCREATE[] = "CREATE TABLE %s (id int NOT NULL, name char(31) NOT NULL, C3 int)";
const char szDROP[] = "DROP TABLE %s";
const char szINSERT[] = "INSERT INTO %s VALUES (?, '-FakeTable-FakeTable-FakeTable-', NULL)";
const int xFIRST = 10;
const int cxSEP = 6;
const int cySEP = 3;
const int cxNAME = 35;
const int cyNAME = 8;
const int cxEDIT = 180;
const int cyEDIT = 10;
const DWORD dwDLGSTYLE = DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU;
const DWORD dwSTATICSTYLE = WS_CHILD | WS_VISIBLE | SS_RIGHT;
const DWORD dwEDITSTYLE = WS_BORDER | WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL | ES_LEFT;
#define STMTError(x) ODBCError(SQL_NULL_HENV, SQL_NULL_HDBC, lpmtbl->hstmt, (x))
#define USERDATA GWL_USERDATA
// Types -------------------------------------------------------------------
typedef struct tagMTBL { // Make table structure
SQLHSTMT hstmt; // HSTMT in use
SDWORD i; // Rows inserted
} MTBL, FAR *LPMTBL;
// Prototypes --------------------------------------------------------------
void INTFUNC AddEditControls(HWND, LPCHILD);
void INTFUNC CenterDialog(HWND);
BOOL INTFUNC GetEditControls(HWND, LPCHILD);
BOOL INTFUNC IsMsgWaiting(HWND);
BOOL INTFUNC DlgProcFilter(HWND, UINT, WPARAM, LPARAM);
/* AddEditControls ---------------------------------------------------------
Description: Add one edit control for each updateable bound column to
the dialog box
--------------------------------------------------------------------------*/
void INTFUNC AddEditControls(HWND hDlg, LPCHILD lpChild)
{
#define DLGX(x) (((x) * LOWORD(dwBaseUnits)) / 4)
#define DLGY(y) (((y) * HIWORD(dwBaseUnits)) / 8)
HWND hWnd;
HFONT hfont;
RECT rc;
LPCOL lpcol;
char sz[cbMAXSQL];
char szFmt[cbSTRLEN];
DWORD dwBaseUnits;
UINT idName, idEdit;
int xName, yName;
int cxName, cyName;
int xEdit, yEdit;
int cxEdit, cyEdit;
int i;
HDC hdc;
SIZE size;
// Determine basic characteristics and start position in dialog
hfont = (HFONT)SendDlgItemMessage(hDlg, IDC_STATIC1,
WM_GETFONT, 0, 0L);
dwBaseUnits = GetDialogBaseUnits();
cxName = DLGX(cxNAME);
cyName = DLGY(cyNAME);
cxEdit = DLGX(cxEDIT);
cyEdit = DLGY(cyEDIT);
LoadString(g_hinst, IDS_COLNAME, szFmt, sizeof(szFmt));
// Calculate the size of the largest name label
hdc = GetDC(NULL);
if( hdc ) {
for( i = 0, lpcol = lpChild->lpcol; i < lpChild->ccol; i++, lpcol++ )
if( IsUpdateable(lpcol->fSqlType) ) {
wsprintf(sz, szFmt, lpcol->szName);
GetTextExtentPoint(hdc, sz, lstrlen(sz), &size);
if( size.cx > cxName )
cxName = size.cx;
}
ReleaseDC(NULL, hdc);
}
GetWindowRect(GetDlgItem(hDlg, IDOK), &rc);
xName = DLGX(xFIRST);
yName = (4 * DLGY(cySEP)) + (DLGY(cySEP) / 2) + (2 * (rc.bottom - rc.top));
xEdit = xName + cxName + DLGX(cxSEP);
idName = stc1;
idEdit = edt1;
// For each bound, updateable column, create and add an edit control
for (i=0, lpcol=lpChild->lpcol; i < lpChild->ccol; i++, lpcol++) {
if (IsUpdateable(lpcol->fSqlType)) {
// Create control label
wsprintf(sz, szFmt, lpcol->szName);
hWnd = CreateWindow(szSTATICCLASS, sz, dwSTATICSTYLE,
xName, yName, cxName, cyName, hDlg,
(HMENU)idName, g_hinst, NULL);
FORWARD_WM_SETFONT(hWnd, hfont, 0, SendMessage);
// Create (and intialize) edit control
yEdit = yName - ((cyEDIT - cyNAME) / 2);
GetCurrentValue(sz, lpcol, lpChild);
hWnd = CreateWindow(szEDITCLASS, sz, dwEDITSTYLE,
xEdit, yEdit, cxEdit, cyEdit, hDlg,
(HMENU)idEdit, g_hinst, NULL);
FORWARD_WM_SETFONT(hWnd, hfont, 0, SendMessage);
// Limit number of characters user can type to column display size
Edit_LimitText(hWnd, lpcol->cbc-1);
yName += cyEdit + DLGY(cySEP);
idName++;
idEdit++;
}
}
// Grow dialog so that all controls are visible
GetClientRect(hDlg, &rc);
rc.top = 0;
rc.bottom = yName + DLGY(cySEP);
rc.left = 0;
rc.right = (2 * DLGX(xFIRST)) + DLGX(cxNAME) + DLGX(cxEDIT) + DLGX(cxSEP);
AdjustWindowRect(&rc, dwDLGSTYLE, FALSE);
MoveWindow(hDlg, 0, 0, rc.right - rc.left, rc.bottom - rc.top, TRUE);
// Place OK and Cancel buttons appropriately
GetClientRect(hDlg, &rc);
{ RECT rcButton;
int x, y;
GetWindowRect(GetDlgItem(hDlg, IDOK), &rcButton);
x = rc.right - DLGX(cxSEP) - (rcButton.right - rcButton.left);
y = DLGY(cySEP);
MoveWindow(GetDlgItem(hDlg, IDOK),
x, y,
rcButton.right - rcButton.left,
rcButton.bottom - rcButton.top,
TRUE);
y += rcButton.bottom - rcButton.top + (DLGY(cySEP) / 2);
GetWindowRect(GetDlgItem(hDlg, IDCANCEL), &rcButton);
MoveWindow(GetDlgItem(hDlg, IDCANCEL),
x, y,
rcButton.right - rcButton.left,
rcButton.bottom - rcButton.top,
TRUE);
}
return;
}
/* CenterDialog ------------------------------------------------------------
Description: Center dialog over its owning parent window
If the entire dialog does not fit on the desktop,
ensure upper left corner is always visible
--------------------------------------------------------------------------*/
void INTFUNC CenterDialog(HWND hDlg)
{
RECT rcDlg, rcScr, rcParent;
int cx, cy;
GetWindowRect(hDlg, &rcDlg);
cx = rcDlg.right - rcDlg.left;
cy = rcDlg.bottom - rcDlg.top;
GetWindowRect(GetParent(hDlg), &rcParent);
rcDlg.top = rcParent.top +
(((rcParent.bottom - rcParent.top) - cy) >> 1);
rcDlg.left = rcParent.left +
(((rcParent.right - rcParent.left) - cx) >> 1);
rcDlg.bottom = rcDlg.top + cy;
rcDlg.right = rcDlg.left + cx;
GetWindowRect(GetDesktopWindow(), &rcScr);
if (rcDlg.bottom > rcScr.bottom) {
rcDlg.bottom = rcScr.bottom;
rcDlg.top = rcDlg.bottom - cy;
}
if (rcDlg.right > rcScr.right) {
rcDlg.right = rcScr.right;
rcDlg.left = rcDlg.right - cx;
}
if (rcDlg.left < 0) rcDlg.left = 0;
if (rcDlg.top < 0) rcDlg.top = 0;
MoveWindow(hDlg, rcDlg.left, rcDlg.top, cx, cy, FALSE);
return;
}
/* DoDialog ----------------------------------------------------------------
Description: Launch a dialog passing child window variables
--------------------------------------------------------------------------*/
int INTFUNC DoDialog(HWND hWndParent,
int nDlgResNum,
DLGPROC lpDlgProc)
{
HWND hWnd;
LPCHILD lpChild;
int nRC;
hWnd = FORWARD_WM_MDIGETACTIVE(g_hwndClient, SendMessage);
lpChild = (hWnd
? (LPCHILD)GetWindowLong(hWnd, 0)
: NULL);
nRC = DialogBoxParam(g_hinst,
MAKEINTRESOURCE(nDlgResNum),
hWndParent,
lpDlgProc,
(LONG)lpChild);
return nRC;
}
/* MyCreateDialog ------------------------------------------------------------
Description: Launch a modeless dialog passing child window variables
--------------------------------------------------------------------------*/
HWND INTFUNC MyCreateDialog(HWND hWndParent,
int nDlgResNum,
DLGPROC lpDlgProc)
{
HWND hWnd, hWndRet;
LPCHILD lpChild;
hWnd = FORWARD_WM_MDIGETACTIVE(g_hwndClient, SendMessage);
lpChild = (hWnd
? (LPCHILD)GetWindowLong(hWnd, 0)
: NULL);
hWndRet = CreateDialogParam(g_hinst,
MAKEINTRESOURCE(nDlgResNum),
hWndParent,
lpDlgProc,
(LPARAM)lpChild);
return hWndRet;
}
/* GetEditControls ---------------------------------------------------------
Description: Get values from edit controls and move to row-set buffers
--------------------------------------------------------------------------*/
BOOL INTFUNC GetEditControls(HWND hDlg, LPCHILD lpChild)
{
LPCOL lpcol;
char sz[cbMAXSQL];
UINT idEdit;
BOOL fChangeMade;
int i;
fChangeMade = FALSE;
idEdit = edt1;
// For each bound, updateable column, retrieve the value
for (i=0, lpcol=lpChild->lpcol; i < lpChild->ccol; i++, lpcol++) {
if (IsUpdateable(lpcol->fSqlType)) {
// Get the control value
SendDlgItemMessage(hDlg, idEdit, WM_GETTEXT,
(WPARAM)sizeof(sz), (LPARAM)((LPSTR)sz));
// Move into row-set buffer
if (SetCurrentValue(sz, lpcol, lpChild) && !fChangeMade)
fChangeMade = TRUE;
idEdit++;
}
}
return fChangeMade;
}
/* IsMsgWaiting ------------------------------------------------------------
Description: Return TRUE if the Cancel button has been pressed
--------------------------------------------------------------------------*/
BOOL INTFUNC IsMsgWaiting(HWND hWnd)
{
MSG msg;
UNREF_PARAM (hWnd);
// Check all waiting messages
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
// Process message
TranslateMessage(&msg);
DispatchMessage(&msg);
// Return TRUE if the Cancel button was pressed
if ((msg.message == WM_COMMAND
&& GET_WM_COMMAND_ID(msg.wParam, msg.lParam) == IDCANCEL)
|| msg.message == WMU_CANCEL)
return TRUE;
}
return FALSE;
}
/* OptionsDlgProc ----------------------------------------------------------
Description: handle options dialog
----------------------------------------------------------------------------*/
BOOL EXPFUNC OptionsDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG:
CenterDialog(hDlg);
SetWindowLong(hDlg, USERDATA, (LONG)lParam);
InitializeDialogControls(hDlg, (LPCHILD) lParam);
return TRUE;
case WM_COMMAND:
(void) HANDLE_WM_COMMAND(hDlg,wParam,lParam,ClassOnCommand);
break;
// New option dialog selected
case WMU_NEWOPTION:
{
LPCHILD lpChild = (LPCHILD) GetWindowLong(hDlg, USERDATA);
if (g_hwndChildDialog)
DestroyWindow(g_hwndChildDialog);
g_hwndChildDialog = MyCreateDialog(hDlg,
(int) lParam,
ChildOptDlgProc);
SetFocus(GetDlgItem(hDlg, IDC_OPTIONLIST));
break;
}
// Set title of option area
case WMU_SETSUBTEXT:
{
char szBuffer[1000];
ListBox_GetText(GetDlgItem(hDlg, wParam),
ListBox_GetCurSel(GetDlgItem(hDlg,wParam)),
szBuffer);
Static_SetText( GetDlgItem(hDlg, IDC_OPTIONAREA_TITLE),
szBuffer);
break;
}
}
return DlgProcFilter(hDlg, msg, wParam, lParam);
}
/* ChildOptDlgProc --------------------------------------------------------
Description: handle generic dialog
----------------------------------------------------------------------------*/
BOOL EXPFUNC ChildOptDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG:
SetWindowLong(hDlg, USERDATA, (LONG)lParam);
InitializeDialogControls(hDlg, (LPCHILD) lParam);
// Align the window to a hidden static in the parent
(void) AlignToControl(hDlg, GetParent(hDlg), IDC_OPTION_WINPOS);
return TRUE;
case WM_COMMAND:
return (BOOL)HANDLE_WM_COMMAND(hDlg,wParam,lParam,ClassOnCommand);
}
return DlgProcFilter(hDlg, msg, wParam, lParam);
}
/* AboutDlgProc ------------------------------------------------------------
Description: Display about box
--------------------------------------------------------------------------*/
BOOL EXPFUNC AboutDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
UNREF_PARAM (lParam);
switch (msg) {
case WM_INITDIALOG:
CenterDialog(hDlg);
return TRUE;
case WM_COMMAND:
if (GET_WM_COMMAND_ID(wParam, lParam) == IDOK
|| GET_WM_COMMAND_ID(wParam, lParam) == IDCANCEL) {
EndDialog(hDlg, GET_WM_COMMAND_ID(wParam, lParam));
return TRUE;
}
break;
}
return DlgProcFilter(hDlg, msg, wParam, lParam);
}
/* AbsDlgProc --------------------------------------------------------------
Description: Get absolute row number to fetch
--------------------------------------------------------------------------*/
BOOL EXPFUNC AbsDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
LPCHILD lpChild;
char sz[11];
char *EndPtr;
SDWORD arow;
lpChild = (LPCHILD)GetWindowLong(hDlg, USERDATA);
switch (msg) {
case WM_INITDIALOG:
CenterDialog(hDlg);
lpChild = (LPCHILD)lParam;
SetWindowLong(hDlg, USERDATA, (LONG)lpChild);
wsprintf(sz, "%ld", lpChild->arow);
SetWindowText(GetDlgItem(hDlg, IDC_EDIT1), sz);
SendDlgItemMessage(hDlg, IDC_EDIT1,
EM_LIMITTEXT, sizeof(sz)-1, 0L);
return TRUE;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
case IDOK:
GetWindowText(GetDlgItem(hDlg, IDC_EDIT1), sz, sizeof(sz));
arow = strtol((char*) sz, &EndPtr, 10);
for (; *EndPtr &&
ISWHITE(*EndPtr); EndPtr = AnsiNext(EndPtr));
// the number inputed is within '0' to '9' or + or -
if (*EndPtr != '\0') {
MessageBox(hDlg,
"Invalid absolute row number",
NULL,
MB_ICONSTOP);
return TRUE;
}
lpChild->arow = arow;
case IDCANCEL:
EndDialog(hDlg, GET_WM_COMMAND_ID(wParam, lParam));
return TRUE;
}
break;
}
return DlgProcFilter(hDlg, msg, wParam, lParam);
}
/* DataDlgProc -------------------------------------------------------------
Description: Display large data value (retrieved via SQLGetData)
--------------------------------------------------------------------------*/
BOOL EXPFUNC DataDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG: {
LPBIGCOL lpbc;
char sz[cbSTRLEN];
char szNum[cbSTRLEN];
char szFmt[cbSTRLEN];
CenterDialog(hDlg);
lpbc = (LPBIGCOL)lParam;
if (lpbc->cb == SQL_NULL_DATA) {
lstrcpy(lpbc->lpsz, g_szNull);
lpbc->cb = 0;
_ltoa(0, szNum, 10);
}
else if (lpbc->cb == SQL_NO_TOTAL)
lstrcpy(szNum, g_szUnknown);
else
_ltoa(lpbc->cb, szNum, 10);
LoadString(g_hinst, IDS_DATADLG, szFmt, sizeof(szFmt));
wsprintf(sz, szFmt, lpbc->szName, szNum);
SetWindowText(GetDlgItem(hDlg, IDC_TEXT1), sz);
SetWindowText(GetDlgItem(hDlg, IDC_EDIT1), lpbc->lpsz);
return TRUE;
}
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
case IDOK:
case IDCANCEL:
EndDialog(hDlg, GET_WM_COMMAND_ID(wParam, lParam));
return TRUE;
}
break;
}
return DlgProcFilter(hDlg, msg, wParam, lParam);
}
/* RelDlgProc --------------------------------------------------------------
Description: Get relative row offset to fetch
--------------------------------------------------------------------------*/
BOOL EXPFUNC RelDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
LPCHILD lpChild;
char sz[7];
lpChild = (LPCHILD)GetWindowLong(hDlg, USERDATA);
switch (msg) {
case WM_INITDIALOG:
CenterDialog(hDlg);
lpChild = (LPCHILD)lParam;
SetWindowLong(hDlg, USERDATA, (LONG)lpChild);
wsprintf(sz, "%ld", lpChild->rrow);
SetWindowText(GetDlgItem(hDlg, IDC_EDIT1), sz);
SendDlgItemMessage(hDlg, IDC_EDIT1,
EM_LIMITTEXT, sizeof(sz)-1, 0L);
return TRUE;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
case IDOK: {
SDWORD rrow;
char *EndPtr;
GetWindowText(GetDlgItem(hDlg, IDC_EDIT1), sz, sizeof(sz));
rrow = strtol((char*) sz, &EndPtr, 10);
for (; *EndPtr &&
ISWHITE(*EndPtr); EndPtr = AnsiNext(EndPtr));
// the number inputed is within '0' to '9' or + or -
if (*EndPtr != '\0' || rrow < -100000 || rrow > 100000) {
MessageBox(hDlg,
"Step amount must be between -100,000 and 100,000",
NULL,
MB_ICONSTOP);
return TRUE;
}
lpChild->rrow = rrow;
}
case IDCANCEL:
EndDialog(hDlg, GET_WM_COMMAND_ID(wParam, lParam));
return TRUE;
}
break;
}
return DlgProcFilter(hDlg, msg, wParam, lParam);
}
/* StmtDlgProc -------------------------------------------------------------
Description: Get SQL statement to execute
--------------------------------------------------------------------------*/
BOOL EXPFUNC StmtDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
LPCHILD lpChild;
lpChild = (LPCHILD)GetWindowLong(hDlg, USERDATA);
switch (msg) {
case WM_INITDIALOG:
CenterDialog(hDlg);
lpChild = (LPCHILD)lParam;
SetWindowLong(hDlg, USERDATA, (LONG)lpChild);
SetWindowText(GetDlgItem(hDlg, IDC_EDIT1), lpChild->sql);
SendDlgItemMessage(hDlg, IDC_EDIT1, EM_LIMITTEXT, cbMAXSQL-1, 0L);
return TRUE;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
case IDOK:
GetWindowText(GetDlgItem(hDlg, IDC_EDIT1),
lpChild->sql, cbMAXSQL);
lpChild->dwOperation = OPER_SELECT;
case IDCANCEL:
EndDialog(hDlg, wParam);
return TRUE;
}
break;
}
return DlgProcFilter(hDlg, msg, wParam, lParam);
}
/* UpdateDlgProc -----------------------------------------------------------
Description: Get new values with which to update the current row
--------------------------------------------------------------------------*/
BOOL EXPFUNC UpdateDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
LPCHILD lpChild;
lpChild = (LPCHILD)GetWindowLong(hDlg, USERDATA);
switch (msg) {
// Build dialog dynamically, adding appropriate edit controls
case WM_INITDIALOG:
lpChild = (LPCHILD)lParam;
SetWindowLong(hDlg, USERDATA, (LONG)lpChild);
AddEditControls(hDlg, lpChild);
SendDlgItemMessage(hDlg,edt1,EM_SETSEL,GET_EM_SETSEL_MPS(0, -1));
CenterDialog(hDlg);
SetFocus(GetDlgItem(hDlg, edt1));
return FALSE;
// Close dialog updating row-set buffer (if OK) with new values
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
case IDOK:
if (!GetEditControls(hDlg, lpChild))
GET_WM_COMMAND_ID(wParam, lParam) = IDCANCEL;
case IDCANCEL:
EndDialog(hDlg, GET_WM_COMMAND_ID(wParam, lParam));
return TRUE;
}
break;
}
return DlgProcFilter(hDlg, msg, wParam, lParam);
}
/* FindDlgProc -------------------------------------------------------------
Description: Get text string to find in result set
--------------------------------------------------------------------------*/
BOOL EXPFUNC FindDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
LPCHILD lpChild;
lpChild = (LPCHILD)GetWindowLong(hDlg, USERDATA);
switch (msg) {
case WM_INITDIALOG:
CenterDialog(hDlg);
lpChild = (LPCHILD)lParam;
SetWindowLong(hDlg, USERDATA, (LONG)lpChild);
SetWindowText(GetDlgItem(hDlg, IDC_EDIT1), lpChild->sql);
SendDlgItemMessage(hDlg, IDC_EDIT1, EM_LIMITTEXT, cbMAXSQL-1, 0L);
return TRUE;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
case IDOK:
GetWindowText(GetDlgItem(hDlg, IDC_EDIT1),
lpChild->sql, cbMAXSQL);
case IDCANCEL:
EndDialog(hDlg, wParam);
return TRUE;
}
break;
}
return DlgProcFilter(hDlg, msg, wParam, lParam);
}
/*---------------------------------------------------------------------------
** SQLTablesDlgProc -- get information for SQLTables and similar functions
----------------------------------------------------------------------------*/
BOOL EXPFUNC SQLTablesDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
LPCHILD lpChild;
lpChild = (LPCHILD)GetWindowLong(hDlg, USERDATA);
switch (msg) {
case WM_INITDIALOG:
CenterDialog(hDlg);
lpChild = (LPCHILD)lParam;
SetWindowLong(hDlg, USERDATA, (LONG)lpChild);
// Set the default button
if (!(lpChild->dwGuiFlags & GUIF_TABLES_RADIO)) {
lpChild->dwOperation = IDC_TABLE_RAD_TABLE;
lpChild->dwRadioButton = IDC_TABLE_RAD_TABLE;
}
// Set the dialog up
ControlValue( lpChild,
hDlg,
GetDlgItem(hDlg,lpChild->dwRadioButton),
lpChild->dwRadioButton,
ACT_INIT);
ControlValue( lpChild,
hDlg,
GetDlgItem(hDlg,lpChild->dwRadioButton),
lpChild->dwRadioButton,
ACT_TRIGGER);
ControlValue( lpChild,
hDlg,
GetDlgItem(hDlg,IDC_TABLEINFO_QUALIFIER),
IDC_TABLEINFO_QUALIFIER,
ACT_INIT);
ControlValue( lpChild,
hDlg,
GetDlgItem(hDlg,IDC_TABLEINFO_NAME),
IDC_TABLEINFO_NAME,
ACT_INIT);
ControlValue( lpChild,
hDlg,
GetDlgItem(hDlg,IDC_TABLEINFO_OWNER),
IDC_TABLEINFO_OWNER,
ACT_INIT);
ControlValue( lpChild,
hDlg,
GetDlgItem(hDlg,IDC_TABLEINFO_TYPE),
IDC_TABLEINFO_TYPE,
ACT_INIT);
ControlValue( lpChild,
hDlg,
GetDlgItem(hDlg,IDC_TABLEINFO_COLNAME),
IDC_TABLEINFO_COLNAME,
ACT_INIT);
return TRUE;
case WM_COMMAND:
return (BOOL)HANDLE_WM_COMMAND(hDlg, wParam, lParam, ClassOnCommand);
break;
}
return DlgProcFilter(hDlg, msg, wParam, lParam);
}
/*---ClassCommand---------------------------------------------------------
Filters commands for dialogs. Forwards those messages that we think
are interesting to a handler that processes the events.
---------------------------------------------------------------------------*/
VOID INTFUNC ClassOnCommand(HWND hWnd, int iId, HWND hWndCtl, UINT uNotify)
{
LPCHILD lpChild;
lpChild = (LPCHILD)GetWindowLong(hWnd,USERDATA);
if (!(lpChild))
return;
switch (uNotify) {
case BN_CLICKED: // button control selected
case EN_UPDATE: // edit box has been updated
case LBN_SELCHANGE: // listbox has gotten a message
ControlValue(lpChild, hWnd, hWndCtl, iId, ACT_TRIGGER);
break;
}
}
/*
** ControlValue -- Initialize a control's value from the child's state, or
** set the child's state from the control. All control-
** specific logic should go here.
**
** Parameters:
** lpChild -- child state
** hDlg -- id of the active dialog
** hCtl -- control's window
** iId -- control's id
** iAction -- Action to take -- ACT_INIT or ACT_TRIGGER
**
** No return value
*/
VOID INTFUNC ControlValue (LPCHILD lpChild,
HWND hDlg,
HWND hCtl,
int iId,
int iAction)
{
int iLbSelection;
DWORD dwListData;
BOOL fTemp;
UCHAR szBuffer[MAXNAME];
const DIALOG_PAIR dpOptList[] = {
{"Binding", IDD_BIND_OPTIONS},
{"General options", IDD_GENERAL_OPTIONS},
{"Scrolling Options", IDD_SCROLLING_OPTIONS},
{"Concurrency Options", IDD_CONCURRENCY_OPTIONS}};
switch (iId) {
case IDOK: // generic OK
case IDCANCEL: // generic CANCEL
if (iAction == ACT_TRIGGER) {
if (g_hwndChildDialog) {
g_hwndChildDialog = NULL;
}
EndDialog(hDlg, iId);
}
break;
case IDC_RADIO_BINDROW:
case IDC_RADIO_BINDCOL:
if (SetOrGetCheck(hCtl, iAction, (iId == lpChild->fBindByRow))) {
lpChild->fBindByRow = iId;
}
break;
case IDC_RADIO_READONLY:
if (SetOrGetCheck(hCtl, iAction,
(lpChild->fConcurrency == SQL_CONCUR_READ_ONLY))) {
lpChild->fConcurrency = SQL_CONCUR_READ_ONLY;
}
break;
case IDC_RADIO_LOCKING:
if (SetOrGetCheck(hCtl, iAction,
(lpChild->fConcurrency == SQL_CONCUR_LOCK))) {
lpChild->fConcurrency = SQL_CONCUR_LOCK;
}
break;
case IDC_RADIO_OPTIMISTIC:
if (SetOrGetCheck(hCtl, iAction,
(lpChild->fConcurrency == SQL_CONCUR_ROWVER))) {
lpChild->fConcurrency = SQL_CONCUR_ROWVER;
}
break;
case IDC_RADIO_OPTIMVALUE:
if (SetOrGetCheck(hCtl, iAction,
(lpChild->fConcurrency == SQL_CONCUR_VALUES))) {
lpChild->fConcurrency = SQL_CONCUR_VALUES;
}
break;
case IDC_RADIO_FORWARD:
if (SetOrGetCheck(hCtl, iAction,
(lpChild->crowKeyset == SQL_CURSOR_FORWARD_ONLY))) {
lpChild->crowKeyset = SQL_CURSOR_FORWARD_ONLY;
}
break;
case IDC_RADIO_SNAPSHOT:
if (SetOrGetCheck(hCtl, iAction,
(lpChild->crowKeyset == SQL_CURSOR_STATIC))) {
lpChild->crowKeyset = SQL_CURSOR_STATIC;
}
break;
case IDC_RADIO_KEYSET:
if (SetOrGetCheck(hCtl, iAction,
(lpChild->crowKeyset == SQL_CURSOR_KEYSET_DRIVEN))) {
lpChild->crowKeyset = SQL_CURSOR_KEYSET_DRIVEN;
}
break;
case IDC_RADIO_DYNAMIC:
if (SetOrGetCheck(hCtl, iAction,
(lpChild->crowKeyset == SQL_CURSOR_DYNAMIC))) {
lpChild->crowKeyset = SQL_CURSOR_DYNAMIC;
}
break;
case IDC_CHECK_BINDALL:
fTemp = SetOrGetCheck(hCtl,iAction, (lpChild->fBindAll));
lpChild->fBindAll = fTemp;
Edit_Enable(GetDlgItem(hDlg,IDC_EDIT_BIND), !(fTemp));
Static_Enable(GetDlgItem(hDlg, IDC_STATIC_NBIND), !(fTemp));
break;
case IDC_EDIT_BIND:
if (lpChild->fBind)
wsprintf((LPSTR)szBuffer,"%s", lpChild->szBind);
else wsprintf((LPSTR)szBuffer,"%u", lpChild->cBind);
SetOrGetEditArray(hCtl, szBuffer, iAction);
if (iAction == ACT_TRIGGER) {
lpChild->fBind = TRUE;
strncpy(lpChild->szBind, szBuffer, cbINTLEN);
lpChild->szBind[cbINTLEN-1] = '\0';
}
break;
case IDC_EDIT_ROWSETSIZE:
if (lpChild->fRowset)
wsprintf((LPSTR)szBuffer,"%s", lpChild->szRowset);
else wsprintf((LPSTR)szBuffer,"%u", lpChild->crowRowset);
SetOrGetEditArray(hCtl, szBuffer, iAction);
if (iAction == ACT_TRIGGER) {
lpChild->fRowset = TRUE;
strncpy(lpChild->szRowset, szBuffer, cbINTLEN);
lpChild->szRowset[cbINTLEN-1] = '\0';
}
break;
case IDC_MAXCOL:
if (lpChild->fMaxBind)
wsprintf((LPSTR)szBuffer, "%s", lpChild->szMaxBind);
else wsprintf((LPSTR)szBuffer, "%ld", lpChild->crowMaxBind);
SetOrGetEditArray(hCtl, szBuffer, iAction);
if (iAction == ACT_TRIGGER) {
lpChild->fMaxBind = TRUE;
strncpy(lpChild->szMaxBind, szBuffer, cbINTLEN);
lpChild->szMaxBind[cbINTLEN-1] = '\0';
}
break;
case IDC_TABLE_RAD_STATISTICS: // TABLEINFO->STATSTICS
case IDC_TABLE_RAD_COLUMN: // TABLEINFO->COLUMNS
case IDC_TABLE_RAD_PRIV: // TABLEINFO->PRIVILEGES
case IDC_TABLE_RAD_PROC: // TABLEINFO->PROCEDURES
case IDC_TABLE_RAD_TABLE: // TABLEINFO->TABLES
// Initialize the button, or set iAction to its value
// Hide any fields not related to the button, show fields related
if( SetOrGetCheck(hCtl, iAction,
(iId == (int)lpChild->dwRadioButton)) )
lpChild->dwOperation = (UWORD) iId;
if (iAction == ACT_TRIGGER) {
lpChild->dwGuiFlags |= GUIF_TABLES_RADIO;
lpChild->dwRadioButton = iId;
(void) SetHiddenFields(hDlg, iId);
}
break;
case IDC_CHECK_FETCH:
if (SetOrGetCheck(hCtl, iAction, (int)IS_ALLWFETCH(lpChild)))
lpChild->dwGuiFlags |= GUIF_ALWAYSFETCH;
else
lpChild->dwGuiFlags &= ~GUIF_ALWAYSFETCH;
break;
case IDC_CHECK_ASYNC:
lpChild->fAsync = SetOrGetCheck(hCtl,iAction,lpChild->fAsync);
break;
case IDC_TABLEINFO_QUALIFIER: // TABLEINFO->QUALIFIER
SetOrGetEditArray(hCtl, lpChild->szQualifier, iAction);
break;
case IDC_TABLEINFO_NAME: // TABLEINFO->NAME
SetOrGetEditArray(hCtl, lpChild->szTable, iAction);
break;
case IDC_TABLEINFO_OWNER: // TABLEINFO->OWNER
SetOrGetEditArray(hCtl, lpChild->szUser, iAction);
break;
case IDC_TABLEINFO_TYPE: // TABLEINFO->TYPE
SetOrGetEditArray(hCtl, lpChild->szType, iAction);
break;
case IDC_TABLEINFO_COLNAME: // TABLEINFO->COLUMN NAME
SetOrGetEditArray(hCtl, lpChild->szColName, iAction);
break;
case IDC_OPTIONLIST: // OPTIONS->options
{
if (iAction == ACT_INIT) {
InitializeListBox(hDlg,
IDC_OPTIONLIST,
&dpOptList[0],
sizeof(dpOptList) / sizeof(DIALOG_PAIR),
IDD_GENERAL_OPTIONS);
}
// Get the title and data for the currently-selected list box
iLbSelection = ListBox_GetCurSel(hCtl);
dwListData = ListBox_GetItemData(hCtl, iLbSelection);
SendMessage(hDlg,WMU_NEWOPTION, iLbSelection,(LPARAM)dwListData);
SendMessage(hDlg,WMU_SETSUBTEXT,iId, 0);
break;
}
}
}
/*
** SetOrGetCheck -- set a value based upon a button action, or set a
** check button if the action is equal to a value
** Also used for radios
**
** Parameters:
** hCtl -- control handle
** iAction -- ACT_INIT or ACT_TRIGGER
** bEqual -- Initialization -- should value be set?
**
** Returns:
** TRUE if checkbox is now set
*/
INLINE BOOL SetOrGetCheck(
HWND hCtl,
int iAction,
BOOL bEqual)
{
if (iAction == ACT_INIT) {
Button_SetCheck(hCtl, bEqual);
return bEqual;
}
if (iAction == ACT_TRIGGER) {
Button_SetCheck(hCtl, Button_GetCheck(hCtl));
return Button_GetCheck(hCtl);
}
return FALSE;
}
/*
** SetOrGetEditArray -- set the value of an array from an edit control, or
** set the edit control from the array (inline)
**
** Parameters:
** hCtl -- control
** lpStr -- string
** iAction -- ACT_INIT or ACT_TRIGGER
**
** Notes: Assumes lpStr is MAXNAME bytes long
*/
INLINE VOID SetOrGetEditArray(
HWND hCtl,
UCHAR FAR *lpStr,
int iAction)
{
if (iAction == ACT_INIT)
Edit_SetText(hCtl, (LPSTR)lpStr);
else
if (iAction == ACT_TRIGGER)
Edit_GetText(hCtl, (LPSTR)lpStr, MAXNAME - 1);
}
/*
** SetHiddenFields -- show or hide hidden fields in a dialog box, depending
** upon the action taken.
**
** Parameters:
** hDlg -- dialog we are dealing with
** iAct -- action
**
*/
BOOL INTFUNC SetHiddenFields(
HWND hWnd,
int iAct)
{
HWND hTTag, hCol;
HWND hType, hCTag;
// Get handles for all of the windows we want to deal with
hTTag = GetDlgItem(hWnd, IDC_TYPETAG);
hCol = GetDlgItem(hWnd, IDC_COLTAG);
hType = GetDlgItem(hWnd, IDC_TABLEINFO_TYPE);
hCTag = GetDlgItem(hWnd, IDC_TABLEINFO_COLNAME);
if (hType) {
Edit_Enable(hType, (iAct == IDC_TABLE_RAD_TABLE) ? 1 : 0);
ShowWindow(hType, (iAct == IDC_TABLE_RAD_TABLE) ? SW_SHOW : SW_HIDE);
ShowWindow(hTTag, (iAct == IDC_TABLE_RAD_TABLE) ? SW_SHOW : SW_HIDE);
Edit_Enable(hCTag, (iAct == IDC_TABLE_RAD_COLUMN) ? 1 : 0);
ShowWindow(hCol, (iAct == IDC_TABLE_RAD_COLUMN) ? SW_SHOW : SW_HIDE);
ShowWindow(hCTag, (iAct == IDC_TABLE_RAD_COLUMN) ? SW_SHOW : SW_HIDE);
return TRUE;
}
return FALSE;
}
/*
** InitializeListBox -- initialize a listbox from a DIALOG_PAIR
** structure.
**
** Parameters:
** hWnd -- window the list box lives in
** lbId -- resource id of the list box
** dpOptList -- pointer to option list structure
** iEntries -- number of entries in the list box
** iDefId -- default to select
**
**
** Returns: FALSE
**
*/
BOOL INTFUNC InitializeListBox(
HWND hWnd,
int lbId,
const DIALOG_PAIR FAR *dpOptList ,
int iEntries,
int iDefId)
{
int iDlg, iIndex;
HWND hOptionBox;
LPSTR szDefaultTitle;
hOptionBox = GetDlgItem(hWnd, lbId);
for (iDlg = 0; iDlg < iEntries; iDlg++) {
iIndex = ListBox_AddString(hOptionBox,
dpOptList[iDlg].szDlgPairTitle);
ListBox_SetItemData(hOptionBox,
iIndex,
dpOptList[iDlg].iDlgPairDlgId);
if (iDefId == dpOptList[iDlg].iDlgPairDlgId) {
szDefaultTitle = dpOptList[iDlg].szDlgPairTitle;
}
}
ListBox_SetCurSel(hOptionBox,
ListBox_FindStringExact(hOptionBox, 0, szDefaultTitle));
return FALSE;
}
/*
** InitializeDialogControls -- Initialize all of the controls in a dialog
** from the lpchild structure. Callback function.
**
** Parameters:
** hDlg -- dialog handle
** lpChild -- state structure
**
*/
VOID INTFUNC InitializeDialogControls(
HWND hDlg,
LPCHILD lpChild)
{
FARPROC ControlInstance = MakeProcInstance((FARPROC)InitControlCallback,
g_hinst);
EnumChildWindows(hDlg, (WNDENUMPROC)ControlInstance, (LPARAM)lpChild);
FreeProcInstance(ControlInstance);
}
/*
** InitControlCallback -- callback function for initializing controls
**
** Parameters:
** hwndChild -- child window handle
** lParam -- lparam (lpChild from EnumChildProc
*/
BOOL CALLBACK InitControlCallback(
HWND hwndChild,
LPARAM lParam)
{
int iControl= GetDlgCtrlID(hwndChild);
if (iControl) {
ControlValue((LPCHILD) lParam,
GetParent(hwndChild),
hwndChild,
iControl,
ACT_INIT);
}
return TRUE;
}
BOOL INTFUNC DlgProcFilter(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_SETTEXT:
case WM_NCPAINT:
case WM_NCACTIVATE:
SetWindowLong(hDlg, DWL_MSGRESULT,0L);
return TRUE;
}
return FALSE;
}
/*
** AlignToControl -- align a window to a control in a dialog
**
** Parameters:
** hWnd -- window to align
** hParent -- parent dialog
** iCtlId -- control Id
**
** Returns: BOOL that moveWindow returns
*/
BOOL INTFUNC AlignToControl(
HWND hWnd,
HWND hParent,
int iCtlId)
{
HWND hwndDrawArea;
RECT rcDrawArea, rcChildWnd;
POINT ptPoint;
hwndDrawArea = GetDlgItem(hParent, iCtlId);
GetWindowRect(hwndDrawArea, &rcDrawArea);
GetWindowRect(hWnd, &rcChildWnd);
ptPoint.x = rcDrawArea.left;
ptPoint.y = rcDrawArea.top;
ScreenToClient(hWnd, &ptPoint);
return (MoveWindow( hWnd,
ptPoint.x,
ptPoint.y,
rcChildWnd.right- rcChildWnd.left,
rcChildWnd.bottom - rcChildWnd.top,
FALSE));
}