home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Total C++ 2
/
TOTALCTWO.iso
/
borland
/
32addres.pak
/
ADR_MAIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-05-06
|
76KB
|
2,314 lines
// BDE32 3.x - (C) Copyright 1996 by Borland International
#include "address.h"
static bReset = FALSE;
//=================================================================
// Name: WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
//
// Input: hInstance - The handle that represents the applications
// unique instance ID.
// hPrevInstance - Indicates if this is the first instance
// of the app.
// lpCmdLine - Command line parameters (up to the app to parse).
// nCmdShow - TRUE = Show as non-icon application
//
// Return: ???
//
// Description: This is the application entry point for the
// Windows driver. It will set up the app, init
// the Windows instance, process all event driven
// messages, and clean up the suite prior to
// returning to Windows.
//=================================================================
#ifdef __BORLANDC__
#pragma argsused
#endif
int PASCAL
WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
#ifndef WIN32
lpCmdLine = lpCmdLine;
nCmdShow = nCmdShow;
#endif
// Make this a single instance program
if (hPrevInstance)
{
MessageBox(GetFocus(), "This application is already running!",
"AddressBook Manager", MB_OK | MB_ICONHAND);
return(FALSE);
}
// Register CTL3D
Ctl3dRegister(hInstance);
Ctl3dAutoSubclass(hInstance);
Ctl3dColorChange();
// Start the application, and set the main dialog to no show until
// everything is setup.
hInst = hInstance;
if (InitApp(SW_HIDE) == FALSE)
{
return(FALSE);
}
// Process all event driven messages...
while (GetMessage(&msg, NULL, NULL, NULL))
{
if (!IsDialogMessage(hMainWnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// Unregister CTL3D
Ctl3dUnregister(hInstance);
return msg.wParam;
}
//====================================================================
// Name: InitApp();
//
// Input: None.
//
// Return: TRUE - Init worked
// FALSE - Init failed
//
// Description: Create the application window & init any default
// of the main window.
//====================================================================
BOOL
InitApp (int nCmdShow)
{
WNDCLASS wc;
unsigned uCount;
// Make certain to allocate enough space for the message.
char szMessage[(DBIMAXMSGLEN * 2) + 1];
char szRelativeTblDirectory[DBIMAXPATHLEN+1];
// Init the application & create the needed windows
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hInstance = hInst;
wc.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(9999));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
wc.lpszMenuName = NULL;
wc.lpszClassName = "MainWindowClass";
// Register the class
if(!RegisterClass(&wc))
{
MessageBox(NULL, "RegisterClass failed!", "System Error",
MB_OK | MB_ICONHAND);
return(FALSE);
}
// Increase the number of file handles that are available to the
// system.
uCount = SetHandleCount(FILEHANDLESNEEDED);
if (uCount < FILEHANDLESNEEDED)
{
MessageBox(NULL, "Not enough file handles available. 'Set files=40'"
" in CONFIG.SYS.", "System Error", MB_OK | MB_ICONHAND);
return FALSE;
}
// Get the directory which contains the tables.
GetPrivateProfileString("ADDRESS", "TblDir",
"..\\..\\TABLES",
(LPSTR)szRelativeTblDirectory,
sizeof(szRelativeTblDirectory),
"bde.ini");
// Create a fully qualified pathname for the table directory
if (MakeFullPath(szTblDirectory, szRelativeTblDirectory))
{
sprintf(szMessage,"Table Directory does not exist: %s",
szTblDirectory);
MessageBox(NULL, szMessage, "System Error", MB_OK | MB_ICONHAND);
return FALSE;
}
// Get the private directory. Needed in case example is run off a
// CD-ROM.
GetPrivateProfileString("ADDRESS", "PrivateDir",
".", (LPSTR)szRelativeTblDirectory,
sizeof(szRelativeTblDirectory),
"bde.ini");
// Create a fully qualified path for the table private.
if (MakeFullPath(szPrivDirectory, szRelativeTblDirectory))
{
sprintf(szMessage,"Private Directory does not exist: %s",
szPrivDirectory);
MessageBox(NULL, szMessage, "System Error", MB_OK | MB_ICONHAND);
return FALSE;
}
// Create the dialog that serves as the main window
hMainWnd = CreateDialog(hInst, "MainDlg", 0, NULL);
if (hMainWnd == NULL)
{
MessageBox(NULL, "CreateDialog failed!", "System Error",
MB_OK | MB_ICONHAND);
return(FALSE);
}
_wpOrigWndProc = SubClassWindow(GetDlgItem(hMainWnd, IDE_COMMENTS),
EditSubClassProc);
ShowWindow(hMainWnd, nCmdShow);
return(TRUE);
}
// ===============================================================
// Name: MainWndProc(hWnd, msg, wParam, lParam);
//
// Desc: This routine will process all messaged for the primary
// application window. Included in this are all menu
// commands.
// ===============================================================
LRESULT CALLBACK
MainWndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
UINT32 lRet = FALSE;
pCHAR pszTableInfo;
CHAR szInitIndex[]="FullName";
CHAR szMdxName[DBIMAXPATHLEN];
UINT iRangeVal;
UINT16 i;
CHAR szABType[DBIMAXPATHLEN];
CHAR szTable[DBIMAXPATHLEN];
CHAR szMsg[150];
UINT iType;
BOOL bFlag;
ABHANDLES AbHandle;
pCS pCreate;
#ifndef WIN32
DLGPROC lpProc;
#endif
HWND hwnd;
HBRUSH hBrush;
// The following variables are static so that the original state that
// is passed into the window proc is kept after we fall through it.
static hDBIDb hDb;
static hDBICur hCur;
static hDBIDb hTempDb;
static hDBICur hTempCur;
static CHAR szTempName[DBIMAXPATHLEN];
static CHAR szTempDir[DBIMAXPATHLEN];
// These variables are used for the FileOpen/FileSave dialogs
LPFOCHUNK lpFOChunk;
hErrorWnd = hWnd;
switch (msg)
{
case WM_CREATE:
#ifndef WIN32
if((lpfnFileHook = (FARHOOK)MakeProcInstance(
(FARPROC)FileHook, hInst))==NULL)
{
WinMsg("Could not create Common Dialog Hook",
MB_ICONHAND, MB_OK);
}
#endif
PostMessage(hWnd, WM_DBIINIT, 0, 0);
break;
case WM_DBIINIT:
hwnd = GetWindow(hWnd, GW_CHILD);
while (hwnd != NULL)
{
Ctl3dSubclassCtl(hwnd);
hwnd = GetWindow(hwnd, GW_HWNDNEXT);
}
// Check to see if the engine could not initialize.
if(DbInit()!=DBIERR_NONE)
{
// There was an error so shut down.
PostQuitMessage(0);
break;
}
// Get memory to hold the full table name with path.
pszTableInfo = (pCHAR)malloc((DBIMAXPATHLEN + 1) * sizeof(CHAR));
if (pszTableInfo == NULL)
{
WinMsg("You have run out of memory!", MB_ICONHAND,
MB_OK);
PostMessage(hWnd, WM_DESTROY, 0, 0L);
return 0;
}
OpenDB(&hDb, NULL, NULL, NULL);
// Create the two tables - the Paradox Business table and the
// dBASE personal table.
for(i=0; i<2; i++)
{
if(i==1)
{
strcpy((pCHAR)szTblName, szPERSONAL);
strcpy((pCHAR)szTblType, szDBASE);
strcpy(szABType, szPERSONAL);
}
else
{
strcpy((pCHAR)szTblName, szBUSINESS);
strcpy((pCHAR)szTblType, szPARADOX);
strcpy(szABType, szBUSINESS);
}
// Check if the table exists or empty.
if(!TableExist(pszTableInfo))
{
if(CreateTable(hDb, &hCur, szABType)==DBIERR_NONE)
{
// Fill it with the data that is inside the resource
// file.
if(FillTable(hCur, szABType))
{
CloseTable(&hCur);
}
}
}
pszTableInfo[0] = 0;
}
free(pszTableInfo);
if(!GetTable(hDb, &hCur))
{
// Get the Production index's name.
GetMdxName(hCur, szMdxName);
// Switch to the an index. This is done because we are
// using a dBASE table which defaults to no index upon being
// opened. You can choose any index by changing the
// szInitIndex variable.
SetIndex(&hCur, szInitIndex);
// Goto the top of the table and move forward one record.
GoTop(hCur, TRUE);
}
else
{
wsprintf(szMsg, "The following table: %s is corrupt - please"
" delete it and rerun the program.", szTblName);
WinMsg(szMsg, MB_ICONHAND, MB_OK);
PostMessage(hWnd, WM_DESTROY, 0, 0L);
return FALSE;
}
if(hCur==NULL)
{
WinMsg("Error opening tables!", MB_ICONHAND, MB_OK);
PostMessage(hWnd, WM_DESTROY, 0, 0L);
}
else
{
ShowWindow(hWnd, SW_SHOW);
// Display the field names for this table in the main
// window.
SetFieldNames(hCur);
// Get the message number for the common dialog hook.
iMSGFileOK = RegisterWindowMessage(FILEOKSTRING);
// Display the first record.
PostMessage(hWnd, WM_DISPLAY, 0, 0L);
}
break;
#ifdef WIN32
case WM_CTLCOLORSCROLLBAR:
case WM_CTLCOLORBTN:
case WM_CTLCOLORDLG:
case WM_CTLCOLOREDIT:
case WM_CTLCOLORLISTBOX:
case WM_CTLCOLORMSGBOX:
case WM_CTLCOLORSTATIC:
#else
case WM_CTLCOLOR:
#endif
hBrush = Ctl3dCtlColorEx(msg, wParam, lParam);
if (hBrush != (HBRUSH)0)
{
return (long)(WORD)hBrush;
}
else
{
return DefWindowProc(hWnd, msg, wParam, lParam);
}
case WM_SYSCOLORCHANGE:
Ctl3dColorChange();
return TRUE;
case WM_NCPAINT:
case WM_NCACTIVATE:
case WM_SETTEXT:
return Ctl3dDlgFramePaint(hWnd, msg, wParam, lParam);
case WM_SETFOCUS:
SetFNameFocus();
break;
case WM_DISPLAY:
// Check the navigational buttons.
CheckButtons(hCur);
// Display the current record.
DisplayTable(hCur);
// Setup the edit controls so that the user can only
// enter the correct amount of information.
SetupEdits();
break;
case WM_ABFILECREATE:
iType = wParam;
if(iType == 1)
{
strcpy((pCHAR)szABType, szBUSINESS);
}
else
{
strcpy((pCHAR)szABType, szPERSONAL);
}
if(bIsServer)
{
strcpy((pCHAR)szTable, (pCHAR)lParam);
// Strip out any periods.
StripChar((pCHAR)szTblName, szTable, 46);
}
if(CreateTable(hTempDb, &hTempCur, szABType)==DBIERR_NONE)
{
if(FillTable(hTempCur, szABType))
{
if(CloseTable(&hTempCur)==DBIERR_NONE)
{
SendMessage(hWnd, WM_ABFILEOPEN, 0, lParam);
}
}
}
else
{
strcpy((pCHAR)szTblName, szTempName);
strcpy((pCHAR)szTblDirectory, szTempDir);
if(hTempDb)
{
CloseDb(&hTempDb);
}
hTempCur = 0;
hTempDb = 0;
if(hCur)
{
GetTblType(hCur, (pCHAR)szTblType);
}
}
break;
case WM_ABFILEOPEN:
if(!CanContinue("Do you wish to save your changes"
" before opening the new table", ID_UNDO_REC))
{
SaveRec(hCur, FALSE);
}
if(bIsServer)
{
strcpy((pCHAR)szTable, (pCHAR)lParam);
}
else
{
strcpy((pCHAR)szTblName, (pCHAR)lParam);
}
if(GetTable(hTempDb, &hTempCur) == DBIERR_NONE)
{
CheckTable(hTempCur, &bFlag);
if(bFlag)
{
EnableMenuItem(GetMenu(hMainWnd),ID_CLEAR_RANGE,
MF_GRAYED);
if(hDb)
{
CloseDb(&hDb);
}
hDb = hTempDb;
hCur = hTempCur;
hTempCur = 0;
hTempDb = 0;
if(AtBOF(hCur) && AtEOF(hCur))
{
WinMsg("Filling the empty table with the default "
"data.", MB_ICONHAND, MB_OK);
FillTable(hCur, szBUSINESS);
}
GoTop(hCur, TRUE);
InitIndex1(&hCur);
SetAll(TRUE);
// Display the field names for this table in the
// main window.
SetFieldNames(hCur);
// Display the current record.
PostMessage(hWnd, WM_DISPLAY, 0, 0L);
}
else
{
wsprintf(szMsg, "The Table named: %s is not a valid "
"AddressBook table. Please try again",
szTblName);
WinMsg(szMsg, MB_ICONHAND, MB_OK);
strcpy((pCHAR)szTblName, szTempName);
strcpy((pCHAR)szTblDirectory, szTempDir);
if(hTempDb)
{
CloseDb(&hTempDb);
}
hTempCur = 0;
hTempDb = 0;
if(hCur!=NULL)
{
GetTblType(hCur, (pCHAR)szTblType);
}
}
}
else
{
strcpy((pCHAR)szTblName, szTempName);
strcpy((pCHAR)szTblDirectory, szTempDir);
if(hTempDb)
{
CloseDb(&hTempDb);
}
if(hCur)
{
GetTblType(hCur, (pCHAR)szTblType);
}
hTempDb = 0;
}
break;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam,lParam))
{
// These messages are two buttons that are not visible
// until the user sends an ID_ADD_REC message by pressing
// the add button or choosing the add menu option. Once
// that is done the OK button will stay dimmed until the
// user has input valid data. Which consists of some first
// and last name and a valid date.
case IDOK:
// Insert the record.
HourGlassCursor(TRUE);
SaveRec(hCur, TRUE);
HourGlassCursor(FALSE);
// Reset the controls back to normal.
EndNewRec(hCur);
SetFNameFocus();
break;
case IDCANCEL:
// Confirm if the data will be lost.
if(CanContinue("Data not saved cancel anyway?", IDOK))
{
// Reset the controls and cancel any data.
EndNewRec(hCur);
}
break;
// Check all the edits at once for any changes. Then
// check if the data is valid.
case IDE_FIRST_NAME:
case IDE_LAST_NAME:
case IDE_LAST_DATE:
case IDE_ADDRESS1:
case IDE_ADDRESS2:
case IDE_CITY:
case IDE_STATE:
case IDE_ZIP:
case IDE_PHONE1:
case IDE_PHONE2:
case IDE_COMMENTS:
if ((GET_WM_COMMAND_CMD(wParam,lParam) == EN_UPDATE)
&& !bReset)
{
if(Varified())
{
// If in add mode enable the OK button.
if(NewRecMode)
{
EnableWindow(GetDlgItem(hMainWnd, IDOK),
TRUE);
}
else
{
SetControl(ID_MOD_REC, TRUE);
SetControl(ID_UNDO_REC, TRUE);
}
}
else
{
if(NewRecMode)
{
// Disable the OK button, so that the
// user cannot save the invalid data.
EnableWindow(GetDlgItem(hMainWnd, IDOK),
FALSE);
}
else
{
// Disable the save button but do not
// disable the Undo button.
SetControl(ID_MOD_REC, FALSE);
SetControl(ID_UNDO_REC, TRUE);
}
}
}
break;
case ID_DELETETABLE:
if(WinMsg("Delete This table?", MB_ICONHAND,
MB_YESNO)==IDYES)
{
HourGlassCursor(TRUE);
if((DeleteTable(&hCur, hDb, (pCHAR)szTblName,
(pCHAR)szTblType)) == DBIERR_NONE)
{
ClearDlg();
SetAll(FALSE);
}
HourGlassCursor(FALSE);
}
break;
case ID_NEW:
if((lpFOChunk = (LPFOCHUNK) malloc(sizeof(FOCHUNK)))
== NULL)
{
return 0;
}
if((pCreate = (pCS) malloc(sizeof(ABCREATESTRUCT)))
== NULL)
{
return 0;
}
pCreate->phDb = &hTempDb;
pCreate->uType = 1;
// Clear the variable before re-using the variable.
memset(szTempName, '\0', DBIMAXNAMELEN);
memset(szTempDir, '\0', DBIMAXPATHLEN);
memset(szTable, '\0', DBIMAXNAMELEN);
OpenDB(&hTempDb, NULL, NULL, NULL);
InitializeStruct((LPSTR)lpFOChunk, pCreate);
strcpy((pCHAR)szTable, szTblName);
if ( GetSaveFileName( &(lpFOChunk->ofn) ) )
{
strcpy(szTempDir, szTblDirectory);
memset((pCHAR)szTblDirectory, '\0', DBIMAXPATHLEN);
if(bIsServer)
{
strcpy((pCHAR)szTempName, szTable);
strcpy((pCHAR)szTblType, "");
}
else
{
strcpy((pCHAR)szTempName, szTblName);
memset((pCHAR)szTblName, '\0', DBIMAXNAMELEN);
GetFileTitle(lpFOChunk->ofn.lpstrFile,
(pCHAR)szTblName, DBIMAXTBLNAMELEN - 1);
strncpy((pCHAR)szTblDirectory,
lpFOChunk->ofn.lpstrFile,
(lpFOChunk->ofn.nFileOffset)-1);
strlwr((pCHAR)szTblName);
if(strstr(szTblName, ".dbf")==NULL)
{
strcpy((pCHAR)szTblType, szPARADOX);
}
else
{
strcpy((pCHAR)szTblType, szDBASE);
}
}
iType = pCreate->uType;
SendMessage(hWnd, WM_ABFILECREATE, iType,
(LPARAM)szTblName);
}
else
{
ProcessCDError(CommDlgExtendedError());
// The user pressed cancel so we must close the
// temporary database handle.
if(hTempDb)
{
CloseDb(&hTempDb);
}
strcpy((pCHAR)szTblName, szTable);
}
free(lpFOChunk);
free(pCreate);
break;
case ID_OPEN:
if((lpFOChunk = (LPFOCHUNK) malloc(sizeof(FOCHUNK)))
== NULL)
{
return 0;
}
if((pCreate = (pCS) malloc(sizeof(ABCREATESTRUCT)))
== NULL)
{
return 0;
}
pCreate->phDb = &hTempDb;
pCreate->uType = 0;
// Clear the variable before re-using the variable.
memset(szTempName, '\0', DBIMAXNAMELEN);
memset(szTempDir, '\0', DBIMAXPATHLEN);
memset(szTable, '\0', DBIMAXNAMELEN);
OpenDB(&hTempDb, NULL, NULL, NULL);
InitializeStruct((LPSTR)lpFOChunk, pCreate);
strcpy((pCHAR)szTable, szTblName);
#ifndef WIN32
if((lpfnFileHook = (FARHOOK)MakeProcInstance(
(FARPROC)FileHook, hInst))==NULL)
{
WinMsg("Could not create Common Dialog Hook",
MB_ICONHAND, MB_OK);
}
#endif
if ( GetOpenFileName( &(lpFOChunk->ofn) ) )
{
strcpy(szTempDir, szTblDirectory);
memset((pCHAR)szTblDirectory, '\0', DBIMAXPATHLEN);
if(bIsServer)
{
strcpy((pCHAR)szTempName, szTable);
}
else
{
strcpy((pCHAR)szTempName, szTblName);
memset((pCHAR)szTblName, '\0', DBIMAXNAMELEN);
GetFileTitle(lpFOChunk->ofn.lpstrFile,
(pCHAR)szTblName, DBIMAXTBLNAMELEN - 1);
strncpy((pCHAR)szTblDirectory,
lpFOChunk->ofn.lpstrFile,
(lpFOChunk->ofn.nFileOffset)-1);
}
SendMessage(hWnd, WM_ABFILEOPEN, 0,
(LPARAM)szTblName);
}
else
{
// The user pressed cancel so we must close the
// temporary database handle.
if(hTempDb != NULL)
{
CloseDb(&hTempDb);
}
strcpy((pCHAR)szTblName, szTable);
}
free(lpFOChunk);
free(pCreate);
break;
// Display the About dialog box.
case ID_ABOUT:
#ifndef WIN32
lpProc = (DLGPROC)MakeProcInstance((FARPROC) AboutDlg,
hInst);
DialogBox(hInst, "AboutDlg", hMainWnd, lpProc);
FreeProcInstance((FARPROC) lpProc);
#else
DialogBox(hInst, "AboutDlg", hMainWnd, AboutDlg);
#endif
SetFNameFocus();
break;
// Display the Order dialog box.
case ID_ORDER:
#ifndef WIN32
lpProc = (DLGPROC)MakeProcInstance((FARPROC) OrderDlg,
hInst);
#endif
AbHandle.phCur = &hCur;
AbHandle.hDb = hDb;
#ifndef WIN32
// Pass the pointer to the ABHandle structure so it
// can be modified inside the dialogbox.
if(DialogBoxParam(hInst, "OrderDlg", hMainWnd, lpProc,
(LONG)(void far*)&AbHandle)==IDOK)
#else
if(DialogBoxParam(hInst, "OrderDlg", hMainWnd, OrderDlg,
(LONG)(void far*)&AbHandle)==IDOK)
#endif
{
// Display the current record.
DisplayTable(hCur);
CheckButtons(hCur);
}
#ifndef WIN32
FreeProcInstance((FARPROC) lpProc);
#endif
SetFNameFocus();
break;
// Display the Range dialog box.
case ID_RANGE:
#ifndef WIN32
lpProc = (DLGPROC)MakeProcInstance((FARPROC)RangeDlg,
hInst);
#endif
AbHandle.phCur = &hCur;
AbHandle.hDb = hDb;
// Pass the pointer to the ABHandle structure so it
// can be modified inside the dialogbox.
#ifndef WIN32
iRangeVal = DialogBoxParam(hInst, "RangeDlg", hMainWnd,
lpProc,
(LONG)(void far*)&AbHandle);
#else
iRangeVal = DialogBoxParam(hInst, "RangeDlg", hMainWnd,
RangeDlg,
(LONG)(void far*)&AbHandle);
#endif
if(iRangeVal == IDOK)
{
// Set the global variable RangeSet to TRUE as
// we did set a range for the present cursor.
RangeSet = TRUE;
// Display the current record.
DisplayTable(hCur);
CheckButtons(hCur);
// Enable the Clear Range menu option.
EnableMenuItem(GetMenu(hMainWnd), ID_CLEAR_RANGE,
MF_ENABLED);
}
else
{
SetFNameFocus();
}
#ifndef WIN32
FreeProcInstance((FARPROC) lpProc);
#endif
break;
// This menu option is enabled ONLY after a range has
// been set.
case ID_CLEAR_RANGE:
ResetRange(hCur);
// Go to the first record in the table.
GoTop(hCur, TRUE);
// Disable the Reset Range menu option.
EnableMenuItem(GetMenu(hMainWnd), ID_CLEAR_RANGE,
MF_GRAYED);
// Set the global variable to FALSE.
RangeSet = FALSE;
// Display the current record.
DisplayTable(hCur);
CheckButtons(hCur);
break;
// Display the Search dialog box.
case ID_SEARCH:
#ifndef WIN32
lpProc = (DLGPROC)MakeProcInstance((FARPROC) SearchDlg,
hInst);
#endif
AbHandle.phCur = &hCur;
AbHandle.hDb = hDb;
// Pass the pointer to the ABHandle structure so it
// can be modified inside the dialogbox.
#ifndef WIN32
if(DialogBoxParam(hInst, "SearchDlg", hMainWnd, lpProc,
(LONG)(void far*)&AbHandle)==IDOK)
#else
if(DialogBoxParam(hInst, "SearchDlg", hMainWnd, SearchDlg,
(LONG)(void far*)&AbHandle)==IDOK)
#endif
{
// Move one record past the crack that the Search
// function leaves you at.
CHKERR(GetNextRec(hCur));
}
#ifndef WIN32
FreeProcInstance((FARPROC) lpProc);
#endif
// Display the current record.
DisplayTable(hCur);
CheckButtons(hCur);
break;
case ID_ADD_REC:
// Change the "mode" of the main window so as to allow
// for a new name to be entered. This "mode" will not
// be deactivated until the IDOK and IDCANCEL messages
// are processed in this message switch!
ChangeEntryMode(hCur);
// Clear the edit controls to allow the user to input
// the new data easily.
ClearDlg();
// Enable the Cancel button.
EnableWindow(GetDlgItem(hMainWnd, IDCANCEL), TRUE);
// Disable the OK button until valid data has been
// input.
EnableWindow(GetDlgItem(hMainWnd, IDOK), FALSE);
// Put the current date into the Date Edit control.
SetDefaultDate();
SetFNameFocus();
break;
case ID_NEXT_REC:
// Move one record forward.
MoveRec(hCur, NEXT_REC);
break;
case ID_PREV_REC:
// Move back one record.
MoveRec(hCur, PREV_REC);
break;
case ID_FIRST_REC:
// Move to the first record in the table.
MoveRec(hCur, TOP);
break;
case ID_LAST_REC:
// Move to the last record in the table.
MoveRec(hCur, BOTTOM);
break;
case ID_MOD_REC:
if(CanContinue("Do you want to modify this record?",
ID_UNDO_REC))
{
// Modify record.
SaveRec(hCur, FALSE);
// Set the navigational controls.
CheckButtons(hCur);
SetControl(ID_MOD_REC, FALSE);
SetControl(ID_UNDO_REC, FALSE);
}
break;
case ID_DEL_REC:
if(WinMsg("Do you want to delete this record?",
MB_ICONHAND, MB_YESNO)== IDYES)
{
// Delete the record.
DeleteRecord(hCur);
CheckButtons(hCur);
}
break;
case ID_UNDO_REC:
if(CanContinue("All changes will be lost - Undo "
"anyway?", ID_UNDO_REC))
{
// Redisplay the original data from the table.
PostMessage(hWnd, WM_DISPLAY, 0, 0L);
}
break;
case ID_EXIT:
PostMessage(hWnd, WM_CLOSE, 0, 0L);
break;
default:
lRet = DefWindowProc(hWnd, msg, wParam, lParam);
break;
}
break;
case WM_CLOSE:
if(CanContinue("Data not saved quit anyway?", IDOK))
{
DestroyWindow(hWnd);
}
else
{
SetFNameFocus();
}
break;
case WM_DESTROY:
if(hCur)
{
CloseTable(&hCur);
}
if(hDb)
{
CloseDb(&hDb);
}
DbExit();
// Quit the application.
PostQuitMessage(0);
break;
default:
// Otherwise default to the DefWindowProc.
lRet = DefWindowProc(hWnd, msg, wParam, lParam);
break;
}
return(lRet);
}
//======================================================================
// Name: FillStruct()
//
// Input: Record structure pointer (RecordType *), Starting Resource ID
// (UINT16), AddressBook type (pCHAR).
//
// Return: TRUE - The structure is filled.
//
// Desc: This routine will fill the structure with the strings that start
// at Offset and are found in the resource file.
//======================================================================
BOOL
FillStruct (RecordType *pRec, UINT16 iOffSet, pCHAR pszABType)
{
// Used to keep count of the resource ID. We add one to the uNumFields
// to take into account the extra #define for the Bussiness/Spouse pair.
UINT j=IDS_FIRST_NAME_1 + (iOffSet*(uNumFields + 1));
memset(pRec, 0, sizeof(RecordType));
// Get the string into the structure
LoadString(hInst, j++, (pCHAR)pRec->FName, sizeof(pRec->FName));
LoadString(hInst, j++, (pCHAR)pRec->LName, sizeof(pRec->LName));
// Check if this is a personal addressbook.
if(strcmpi(pszABType, szPERSONAL) == 0)
{
LoadString(hInst, j++, (pCHAR)pRec->Spouse, sizeof(pRec->Spouse));
// Increment j to get past the Business data.
j++;
}
else
{
j++;
LoadString(hInst, j++, (pCHAR)pRec->Spouse, sizeof(pRec->Spouse));
}
LoadString(hInst, j++, (pCHAR)pRec->Addrs1, sizeof(pRec->Addrs1));
LoadString(hInst, j++, (pCHAR)pRec->Addrs2, sizeof(pRec->Addrs2));
LoadString(hInst, j++, (pCHAR)pRec->City, sizeof(pRec->City));
LoadString(hInst, j++, (pCHAR)pRec->State, sizeof(pRec->State));
LoadString(hInst, j++, (pCHAR)pRec->Zip, sizeof(pRec->Zip));
LoadString(hInst, j++, (pCHAR)pRec->Phone1, sizeof(pRec->Phone1));
LoadString(hInst, j++, (pCHAR)pRec->Phone2, sizeof(pRec->Phone2));
LoadString(hInst, j++, (pCHAR)pRec->Date1, sizeof(pRec->Date1));
LoadString(hInst, j++, (pCHAR)pRec->Comment, sizeof(pRec->Comment));
return TRUE;
}
//======================================================================
// Name: DisplayTable()
//
// Input: Cursor handle (hDBICur).
//
// Return: TRUE - The record is displayed.
// FALSE - The record Structure allocation failed.
//
// Desc: This routine will fill a structure with the record pointed
// to by the cursor and then display the record in the main Window.
//======================================================================
BOOL
DisplayTable (hDBICur hCur)
{
RecordType *pRecord;
// Allocate a temporary buffer to read information that is pointed
// to by the cursor.
if((pRecord = (RecordType *) malloc(1 * sizeof(RecordType))) == NULL)
{
WinMsg("You have run out of memory!", MB_ICONHAND, MB_OK);
return FALSE;
}
memset(pRecord, 0, sizeof(RecordType));
// Set the Reset Variable to TRUE.
bReset = TRUE;
// Fill the structure with the record.
GetData(hCur, pRecord);
// Display the record.
DispRec(pRecord);
// Set the Reset Variable to FALSE.
bReset = FALSE;
SetControl(ID_MOD_REC, FALSE);
SetControl(ID_UNDO_REC, FALSE);
SetFNameFocus();
free(pRecord);
return TRUE;
}
//======================================================================
// Name: TableExist()
//
// Input: Char string that holds the table's FULL name and path (pCHAR).
//
// Return: TRUE - The table exists and IS NOT empty.
// FALSE - The table is empty or does not exist.
//
// Desc: This routine takes in a table name and checks if the table
// exists. If it exists it checks if the table is empty.
//======================================================================
BOOL
TableExist (pCHAR pszTableInfo)
{
BOOL bRetVal;
int iExist ;
hDBIDb hDb;
hDBICur hCur;
// Create the full path string of the table.
strcpy(pszTableInfo, szTblDirectory);
strcat(pszTableInfo, "\\");
strcat(pszTableInfo, szTblName);
if(strcmpi(szTblType, szDBASE)==0)
{
strcat(pszTableInfo, ".dbf");
strcat((pCHAR)szTblName, ".dbf");
}
else
{
strcat(pszTableInfo, ".db");
strcat((pCHAR)szTblName, ".db");
}
iExist = access(pszTableInfo, 00); // Check if the table exists
if(iExist == -1)
{
bRetVal = FALSE;
}
else
{
OpenDB(&hDb, NULL, NULL, NULL);
GetTable(hDb, &hCur);
// Go to the top of the table and stay at the BOF crack.
GoTop(hCur, FALSE);
// If we are at the EOF as well we have an empty table.
if(AtEOF(hCur))
{
bRetVal = FALSE;
}
else
{
bRetVal = TRUE;
}
// Close up and return the bool RetVal.
CloseTable(&hCur);
CloseDb(&hDb);
}
return bRetVal;
}
//======================================================================
// Name: FillTable()
//
// Input: Cursor handle (hDBICur), and AddressBook Type (pCHAR).
//
// Return: TRUE - The record was added to the table.
// FALSE - The record Structure allocation failed.
//
// Desc: This function fills the table with all the strings that are
// in the resource file.
//======================================================================
BOOL
FillTable (hDBICur hCur, pCHAR pszABType)
{
RecordType *pRecord;
UINT16 i;
BOOL bRet = FALSE;
// Allocate a temporary buffer to read information sitting in
// the resource file.
if((pRecord = (RecordType *) malloc(1 * sizeof(RecordType))) == NULL)
{
WinMsg("You have run out of memory!", MB_ICONHAND, MB_OK);
return FALSE;
}
for(i=0; i<uNumRecs; i++)
{
memset(pRecord, 0, sizeof(RecordType));
// Fill a structure with the data sitting in the resource file.
if(FillStruct(pRecord, i, pszABType))
{
// Add the record to the table and insert it rather than
// overwriting an old record (TRUE parameter).
if(AddRecord(hCur, pRecord, TRUE)==DBIERR_NONE)
{
bRet = TRUE;
}
}
}
free(pRecord);
return bRet;
}
//======================================================================
// Name: DispRec()
//
// Input: Record structure pointer (RecordType *).
//
// Return: TRUE - The record was displayed.
//
// Desc: This function displays the data in the record structure
// into the main Window.
//======================================================================
BOOL DispRec(RecordType *pRecord)
{
SetDlgItemText(hMainWnd, IDE_FIRST_NAME, pRecord->FName);
SetDlgItemText(hMainWnd, IDE_LAST_NAME, pRecord->LName);
SetDlgItemText(hMainWnd, IDE_SP_COMP, pRecord->Spouse);
SetDlgItemText(hMainWnd, IDE_ADDRESS1, pRecord->Addrs1);
SetDlgItemText(hMainWnd, IDE_ADDRESS2, pRecord->Addrs2);
SetDlgItemText(hMainWnd, IDE_CITY, pRecord->City);
SetDlgItemText(hMainWnd, IDE_STATE, pRecord->State);
SetDlgItemText(hMainWnd, IDE_ZIP, pRecord->Zip);
SetDlgItemText(hMainWnd, IDE_PHONE1, pRecord->Phone1);
SetDlgItemText(hMainWnd, IDE_PHONE2, pRecord->Phone2);
SetDlgItemText(hMainWnd, IDE_LAST_DATE, pRecord->Date1);
SetDlgItemText(hMainWnd, IDE_COMMENTS, pRecord->Comment);
return TRUE;
}
//======================================================================
// Name: MoveRec()
//
// Input: Cursor handle (hDBICur) and Movement (INT16).
//
// Return: None.
//
// Desc: This function moves the cursor to the bottom or the top
// of the table. Or it moves it a record forward or backwards.
//======================================================================
DBIResult
MoveRec (hDBICur hCur, INT16 iMovement)
{
// Check if data has been changed by looking at the status of the Undo
// button. Then ask if the user wishes to lose the data by moving.
if(CanContinue("Data not saved move to next record anyway?",
ID_UNDO_REC))
{
HourGlassCursor(TRUE);
switch(iMovement)
{
// These macros are defined in the header file.
case TOP:
GoTop(hCur, TRUE);
break;
case BOTTOM:
GoBottom(hCur, TRUE);
break;
case NEXT_REC:
if(!AtEOF(hCur))
{
CHKERR(GetNextRec(hCur));
}
break;
case PREV_REC:
if(!AtBOF(hCur))
{
GetPrevRec(hCur);
}
break;
default:
return DBIERR_NOTSUPPORTED;
}
// Check the navigational controls and display the current record.
CheckButtons(hCur);
DisplayTable(hCur);
}
else
{
SetFNameFocus();
}
HourGlassCursor(FALSE);
return DBIERR_NONE;
}
//======================================================================
// Name: CheckButtons()
//
// Input: Cursor handle (hDBICur).
//
// Return: None.
//
// Desc: This function checks the position of the cursor and then
// enables or disables the naviagtional buttons AND menu options.
//======================================================================
void
CheckButtons (hDBICur hCur)
{
if(AtEOF(hCur))
{
// If at EOF disable the Next and Last record buttons and
// menu options.
SetControl(ID_NEXT_REC, FALSE);
SetControl(ID_LAST_REC, FALSE);
}
else
{
// Else enable them.
SetControl(ID_NEXT_REC, TRUE);
SetControl(ID_LAST_REC, TRUE);
}
if(AtBOF(hCur))
{
// If at BOF disable the Prev and First record buttons
// and menu options.
SetControl(ID_PREV_REC, FALSE);
SetControl(ID_FIRST_REC, FALSE);
}
else
{
// Else enable them.
SetControl(ID_PREV_REC, TRUE);
SetControl(ID_FIRST_REC, TRUE);
}
// If the table is empty.
if(AtBOF(hCur) && AtEOF(hCur))
{
if(GetPrevRec(hCur)==DBIERR_BOF && GetNextRec(hCur)==DBIERR_EOF)
{
SetControl(ID_DEL_REC, FALSE);
SetControl(ID_ORDER, FALSE);
SetControl(ID_RANGE, FALSE);
SetControl(ID_SEARCH, FALSE);
}
else
{
SetControl(ID_DEL_REC, TRUE);
SetControl(ID_ORDER, TRUE);
SetControl(ID_RANGE, TRUE);
SetControl(ID_SEARCH, TRUE);
}
}
else
{
SetControl(ID_DEL_REC, TRUE);
SetControl(ID_ORDER, TRUE);
SetControl(ID_RANGE, TRUE);
SetControl(ID_SEARCH, TRUE);
}
SetFNameFocus();
}
//======================================================================
// Name: SetupEdits()
//
// Input: None.
//
// Return: None.
//
// Desc: This function sets the text input limit of each of the edit
// controls that are in the main window.
//======================================================================
void
SetupEdits (void)
{
// Use the constants -1 to allow room for the NULL terminator.
Edit_LimitText(GetDlgItem(hMainWnd, IDE_FIRST_NAME), NAMELEN-1);
Edit_LimitText(GetDlgItem(hMainWnd, IDE_LAST_NAME), NAMELEN-1);
Edit_LimitText(GetDlgItem(hMainWnd, IDE_SP_COMP), ADDRESSLEN-1);
Edit_LimitText(GetDlgItem(hMainWnd, IDE_COMMENTS), COMMENTLEN-1);
Edit_LimitText(GetDlgItem(hMainWnd, IDE_ADDRESS1), ADDRESSLEN-1);
Edit_LimitText(GetDlgItem(hMainWnd, IDE_ADDRESS2), ADDRESSLEN-1);
Edit_LimitText(GetDlgItem(hMainWnd, IDE_CITY), CITYLEN-1);
Edit_LimitText(GetDlgItem(hMainWnd, IDE_STATE), STATELEN-1);
Edit_LimitText(GetDlgItem(hMainWnd, IDE_ZIP), ZIPLEN-1);
Edit_LimitText(GetDlgItem(hMainWnd, IDE_PHONE1), PHONELEN-1);
Edit_LimitText(GetDlgItem(hMainWnd, IDE_PHONE2), PHONELEN-1);
Edit_LimitText(GetDlgItem(hMainWnd, IDE_LAST_DATE), DATELEN-1);
// Disable the Cancel and OK buttons that are hidden.
EnableWindow(GetDlgItem(hMainWnd, IDCANCEL), FALSE);
EnableWindow(GetDlgItem(hMainWnd, IDOK), FALSE);
}
//======================================================================
// Name: SaveRec()
//
// Input: Cursor handle (hDBICur), Add or Overwrite bool (BOOL).
//
// Return: TRUE: If the memory is allocated.
// FALSE: If the memory allocation fails.
//
// Desc: This function takes the data from off the main window and
// puts it in a record structure. Then based upon the bAdd Bool
// it inserts the record or overwrites the old record.
//======================================================================
BOOL
SaveRec (hDBICur hCur, BOOL bAdd)
{
RecordType *pRecord;
// Allocate a temporary buffer to store data that is inside the
// main Window.
if((pRecord = (RecordType *) malloc(1 * sizeof(RecordType))) == NULL)
{
WinMsg("You have run out of memory!", MB_ICONHAND, MB_OK);
return FALSE;
}
// Clear the record structure.
memset(pRecord, 0, sizeof(RecordType));
// Get the data from the main Window and put it into the record
// structure.
GetRec(pRecord);
// Add the record or insert the record based upon the bAdd value.
AddRecord(hCur, pRecord, bAdd);
free(pRecord);
CheckButtons(hCur);
return TRUE;
}
//======================================================================
// Name: GetRec()
//
// Input: Record structure pointer (RecordType *).
//
// Return: TRUE.
//
// Desc: This function fills the record structure with the data that
// is in the main Window.
//======================================================================
BOOL
GetRec (RecordType *pRecord)
{
GetDlgItemText(hMainWnd, IDE_FIRST_NAME, pRecord->FName, NAMELEN);
GetDlgItemText(hMainWnd, IDE_LAST_NAME, pRecord->LName, NAMELEN);
GetDlgItemText(hMainWnd, IDE_SP_COMP, pRecord->Spouse, ADDRESSLEN);
GetDlgItemText(hMainWnd, IDE_ADDRESS1, pRecord->Addrs1, ADDRESSLEN);
GetDlgItemText(hMainWnd, IDE_ADDRESS2, pRecord->Addrs2, ADDRESSLEN);
GetDlgItemText(hMainWnd, IDE_CITY, pRecord->City, CITYLEN);
GetDlgItemText(hMainWnd, IDE_STATE, pRecord->State, STATELEN);
GetDlgItemText(hMainWnd, IDE_ZIP, pRecord->Zip, ZIPLEN);
GetDlgItemText(hMainWnd, IDE_PHONE1, pRecord->Phone1, PHONELEN);
GetDlgItemText(hMainWnd, IDE_PHONE2, pRecord->Phone2, PHONELEN);
GetDlgItemText(hMainWnd, IDE_LAST_DATE, pRecord->Date1, DATELEN);
GetDlgItemText(hMainWnd, IDE_COMMENTS, pRecord->Comment, COMMENTLEN);
return TRUE;
}
//======================================================================
// Name: FillDropList()
//
// Input: Window Handle (HWND), Cursor handle(hDBICur), Database Handle
// (hDBIDb), Resource ID (UINT16), and Active Index name (pCHAR).
//
// Return: The name of presently active index on the AddressBook table.
//
// Desc: This function fills the combobox represented by Id with the all
// names that are open on the table. It also returns the name
// of the currently active index inside of the pszActiveIndex
// string.
//======================================================================
UINT16
FillDropList (HWND hWnd, UINT16 iId, UINT16 iNumIdxs, pABIDXDESC pABIdxDesc,
pCHAR pszIndex)
{
UINT16 i; // used for loop counter
UINT32 lOff;
UINT32 lIndex;
// Fill the combobox with all the index names that are listed in the
// pABIdxDesc structure.
for(i=0; i<iNumIdxs ; i++)
{
lOff = ComboBox_AddString(GetDlgItem(hWnd, iId),
pABIdxDesc[i].szTagName);
// Send the listbox item its data. The data is the offset of the
// index name inside of the index structure.
(void)ComboBox_SetItemData(GetDlgItem(hWnd, iId), lOff, i);
}
// Select the currently active index from the ComboBox.
lOff = ComboBox_SelectString(GetDlgItem(hWnd, iId), -1, pszIndex);
lIndex = ComboBox_GetItemData(GetDlgItem(hWnd, iId), lOff);
// Set the description text into the static text box based upon
// the active index's item data.
if(iId == IDE_ORDER_COMBOBOX)
{
SetWindowText(GetDlgItem(hWnd, IDE_ORDER_INFO),
pABIdxDesc[(UINT16)lIndex].szKeyExp);
}
// Return the current index's order inside the index structure array.
return (UINT16)lIndex;
}
//======================================================================
// Name: SetFNameFocus()
//
// Input: None.
//
// Return: None.
//
// Desc: This function sets focus to the First Name edit control of
// the main Window.
//======================================================================
void
SetFNameFocus (void)
{
SetFocus(GetDlgItem(hMainWnd, IDE_FIRST_NAME));
}
//======================================================================
// Name: DeleteRecord()
//
// Input: Cursor handle (hDBICur).
//
// Return: TRUE: If the record is deleted.
// FALSE: If the record is not deleted.
//
// Desc: This function simply deletes the record that the cursor is
// pointing to. It then moves forward one record to get off the
// crack that the deleted record created.
//======================================================================
BOOL
DeleteRecord (hDBICur hCur)
{
BOOL bFlag = TRUE;
if(DeleteRec(hCur)!=DBIERR_NONE)
{
bFlag = FALSE;
}
if(!AtEOF(hCur))
{
GetNextRec(hCur);
}
else
{
if(!AtBOF(hCur))
{
GetPrevRec(hCur);
}
}
// Display the current record.
DisplayTable(hCur);
CheckButtons(hCur);
return bFlag;
}
//======================================================================
// Name: SetControl()
//
// Input: Id resource(UINT16), and Set bool(BOOL).
//
// Return: None.
//
// Desc: This function sets the button and menu option of the Id to the
// bool value.
//======================================================================
void
SetControl (UINT16 iId, BOOL bSetMod)
{
if(bSetMod)
{
if(!IsWindowEnabled(GetDlgItem(hMainWnd, iId)))
{
EnableWindow(GetDlgItem(hMainWnd, iId), bSetMod);
EnableMenuItem(GetMenu(hMainWnd), iId, MF_ENABLED);
}
}
else
{
if(IsWindowEnabled(GetDlgItem(hMainWnd, iId)))
{
EnableWindow(GetDlgItem(hMainWnd, iId), bSetMod);
EnableMenuItem(GetMenu(hMainWnd), iId, MF_GRAYED);
}
}
}
//======================================================================
// Name: ClearDlg()
//
// Input: None.
//
// Return: TRUE: If the memory allocation was successful.
// FALSE: If the memory allocation was unsuccessful.
//
// Desc: This function clears all the edit controls in the main Window.
//======================================================================
BOOL
ClearDlg (void)
{
RecordType *pRecord;
// Allocate a temporary record structure to use in clearing the
// main Window.
if((pRecord = (RecordType *) malloc(1 * sizeof(RecordType))) == NULL)
{
WinMsg("You have run out of memory!", MB_ICONHAND, MB_OK);
return FALSE;
}
// Clear the record structure so that we display an empty structure.
memset(pRecord, 0, sizeof(RecordType));
// Display the empty structure so that we clear the main Window.
DispRec(pRecord);
SetFNameFocus();
free(pRecord);
return TRUE;
}
//======================================================================
// Name: Varified()
//
// Input: None.
//
// Return: TRUE: If the memory allocation was successful and if the
// data is valid.
//
// FALSE: If the memory allocation was unsuccessful, or if
// the data is not valid.
//
// Desc: This function varifies if the data in the edit controls
// are valid.
//======================================================================
BOOL
Varified (void)
{
struct dosdate_t d;
pCHAR pszFName;
pCHAR pszLName;
pCHAR pDate;
pCHAR pVal;
BOOL bRetVal;
UINT iFName;
UINT iLName;
DBIDATE TempDate;
pFMTDate pFmtDate;
DBIResult rslt;
if((pszFName = (pCHAR) malloc(NAMELEN * sizeof(CHAR))) == NULL)
{
WinMsg("You have run out of memory!", MB_ICONHAND, MB_OK);
return FALSE;
}
if((pszLName = (pCHAR) malloc(NAMELEN * sizeof(CHAR))) == NULL)
{
WinMsg("You have run out of memory!", MB_ICONHAND, MB_OK);
free(pszFName);
return FALSE;
}
if((pDate = (pCHAR) malloc(DATELEN * sizeof(CHAR))) == NULL)
{
WinMsg("You have run out of memory!", MB_ICONHAND, MB_OK);
free(pszFName);
free(pszLName);
return FALSE;
}
if((pFmtDate = (pFMTDate) malloc(sizeof(FMTDate))) == NULL)
{
WinMsg("You have run out of memory!", MB_ICONHAND, MB_OK);
free(pszFName);
free(pszLName);
free(pDate);
return FALSE;
}
rslt = AdrGetDateFormat(pFmtDate);
if(rslt!=DBIERR_NONE)
{
free(pszFName);
free(pszLName);
free(pDate);
free(pFmtDate);
return FALSE;
}
iFName = GetDlgItemText(hMainWnd, IDE_FIRST_NAME, pszFName, NAMELEN);
iLName = GetDlgItemText(hMainWnd, IDE_LAST_NAME, pszLName, NAMELEN);
// Check if there is data in the First and Last Name edit controls.
if((iFName > 0) && (iLName >0))
{
bRetVal = TRUE;
}
else
{
bRetVal = FALSE;
}
GetDlgItemText(hMainWnd, IDE_LAST_DATE, pDate, DATELEN);
// Need to convert the string to a Date structure
pVal = strtok(pDate, pFmtDate->szDateSeparator);
if(pVal && bRetVal)
{
d.month = (INT16)atoi(pVal);
pVal = strtok(NULL, pFmtDate->szDateSeparator);
if(pVal && bRetVal)
{
d.day = (INT16)atoi(pVal);
pVal = strtok(NULL, pFmtDate->szDateSeparator);
if(pVal && bRetVal)
{
d.year = atoi(pVal);
}
else
{
bRetVal = FALSE;
}
}
else
{
bRetVal = FALSE;
}
}
else
{
bRetVal = FALSE;
}
if(bRetVal)
{
// Check if the date is legal.
rslt = DateEncode(d.month, d.day, d.year, &TempDate);
if(rslt == DBIERR_NONE)
{
bRetVal = TRUE;
}
else
{
bRetVal = FALSE;
}
}
free(pszFName);
free(pszLName);
free(pDate);
free(pFmtDate);
return bRetVal;
}
//======================================================================
// Name: SetDefaultDate()
//
// Input: None.
//
// Return: None.
//
// Desc: This function puts the current date into the Last Date edit
// control so that we have a valid date to start.
//======================================================================
DBIResult
SetDefaultDate (void)
{
#ifndef WIN32
struct dosdate_t d;
#else
SYSTEMTIME ST;
#endif
pFMTDate pFmtDate;
CHAR szDateString[DATELEN];
if((pFmtDate = (pFMTDate) malloc(sizeof(FMTDate))) == NULL)
{
WinMsg("You have run out of memory!", MB_ICONHAND, MB_OK);
return DBIERR_NOMEMORY;
}
CHKERR(AdrGetDateFormat(pFmtDate));
#ifndef WIN32
_dos_getdate(&d);
#else
GetLocalTime(&ST);
#endif
if(pFmtDate->iDateMode==0)
{
#ifndef WIN32
wsprintf(szDateString, "%02d%s%02d%s%02d", d.month,
pFmtDate->szDateSeparator, d.day, pFmtDate->szDateSeparator,
d.year);
#else
wsprintf(szDateString, "%02d%s%02d%s%02d", ST.wMonth,
pFmtDate->szDateSeparator, ST.wDay, pFmtDate->szDateSeparator,
ST.wYear);
#endif
}
if(pFmtDate->iDateMode==1)
{
#ifndef WIN32
wsprintf(szDateString, "%02d%s%02d%s%02d", d.day,
pFmtDate->szDateSeparator, d.month, pFmtDate->szDateSeparator,
d.year);
#else
wsprintf(szDateString, "%02d%s%02d%s%02d", ST.wDay,
pFmtDate->szDateSeparator, ST.wMonth, pFmtDate->szDateSeparator,
ST.wYear);
#endif
}
if(pFmtDate->iDateMode==2)
{
#ifndef WIN32
wsprintf(szDateString, "%02d%s%02d%s%02d", d.year,
pFmtDate->szDateSeparator, d.month, pFmtDate->szDateSeparator,
d.day);
#else
wsprintf(szDateString, "%02d%s%02d%s%02d", ST.wYear,
pFmtDate->szDateSeparator, ST.wMonth, pFmtDate->szDateSeparator,
ST.wDay);
#endif
}
SetDlgItemText(hMainWnd, IDE_LAST_DATE, szDateString);
free(pFmtDate);
return DBIERR_NONE;
}
//======================================================================
// Name: EndNewRec()
//
// Input: Cursor handle (hDBICur).
//
// Return: None.
//
// Desc: This function is called during the end of the Add new person
// function. It changes the current state of the NewRecMode
// global variable. Then it checks the navigational controls
// and sets focus unto the First Name edit control.
//======================================================================
void
EndNewRec (hDBICur hCur)
{
ChangeEntryMode(hCur);
DisplayTable(hCur);
CheckButtons(hCur);
SetFNameFocus();
}
//======================================================================
// Name: PutField()
//
// Input: Record structure pointer (RecordType *), pointer to the input
// text (pCHAR), and Array element number (UINT16).
//
// Return: None.
//
// Desc: This function puts input text into the correct field of the
// record structure pointer based upon MemberNum.
//======================================================================
void
PutField (RecordType *pRec, pCHAR pszText, UINT iMemberNum)
{
switch(iMemberNum)
{
case 0:
strcpy(pRec->FName, pszText);
break;
case 1:
strcpy(pRec->LName, pszText);
break;
case 2:
strcpy(pRec->Spouse, pszText);
break;
case 3:
strcpy(pRec->Addrs1, pszText);
break;
case 4:
strcpy(pRec->Addrs2, pszText);
break;
case 5:
strcpy(pRec->City, pszText);
break;
case 6:
strcpy(pRec->State, pszText);
break;
case 7:
strcpy(pRec->Zip, pszText);
break;
case 8:
strcpy(pRec->Phone1, pszText);
break;
case 9:
strcpy(pRec->Phone2, pszText);
break;
case 10:
strcpy(pRec->Date1, pszText);
break;
}
}
//======================================================================
// Name: GetField()
//
// Input: Record structure pointer (RecordType *), pointer to the input
// text (pCHAR), and Array element number (UINT16).
//
// Return: None.
//
// Desc: This function gets data from the field in the record structure,
// based upon the input variable - MemberNum.
//======================================================================
void
GetField (RecordType *pRec, pCHAR pszText, UINT16 iMemberNum)
{
switch(iMemberNum)
{
case 0:
strcpy(pszText, pRec->FName);
break;
case 1:
strcpy(pszText, pRec->LName);
break;
case 2:
strcpy(pszText, pRec->Spouse);
break;
case 3:
strcpy(pszText, pRec->Addrs1);
break;
case 4:
strcpy(pszText, pRec->Addrs2);
break;
case 5:
strcpy(pszText, pRec->City);
break;
case 6:
strcpy(pszText, pRec->State);
break;
case 7:
strcpy(pszText, pRec->Zip);
break;
case 8:
strcpy(pszText, pRec->Phone1);
break;
case 9:
strcpy(pszText, pRec->Phone2);
break;
case 10:
strcpy(pszText, pRec->Date1);
break;
}
}
//======================================================================
// Name: GetCond()
//
// Input: Handle to the window that has the check boxes.
//
// Return: Which check box is checked.
//
// Desc: This function simply returns a number based upon which check
// box is checked.
//======================================================================
DBISearchCond
GetCond (HWND hWnd)
{
DBISearchCond eRet;
UINT32 iCond=0;
UINT16 i=IDC_GREATEREQ;
while(iCond!=1)
{
iCond = Button_GetCheck(GetDlgItem(hWnd, i));
i++;
}
// Subtract 1 to counteract the last i++
i--;
switch(i)
{
case IDC_EQUAL:
eRet = keySEARCHEQ;
break;
case IDC_GREATER:
eRet = keySEARCHGT;
break;
case IDC_GREATEREQ:
eRet = keySEARCHGEQ;
break;
}
return eRet;
}
//======================================================================
// Name: CanContinue()
//
// Input: Pointer to the string that is to be displayed (pCHAR), and
// a resource ID (UINT16).
//
// Return: If the resource is enabled, then it returns the user's response.
// Otherwise, it returns a TRUE.
//
// Desc: This function checks if the Id is enabled. If it is then it
// prompts the user with the pString and returns the response.
// Otherwise it returns a TRUE.
//======================================================================
BOOL
CanContinue (pCHAR pszString, UINT16 iId)
{
BOOL bRetVal = TRUE;
// Check to see if the button is enabled.
if(IsWindowEnabled(GetDlgItem(hMainWnd, iId)))
{
if(WinMsg(pszString, MB_ICONHAND, MB_YESNO) == IDNO)
{
bRetVal = FALSE;
}
}
return bRetVal;
}
//=========================================================================
// Function: FillAliasCBBox()
//
// Input: Pointer to the Alias Structures(pDBDesc), Number of aliases
// (UINT32), and the Combo Box's ID to fill (UINT16)
//
// Returns: None
//
// Desc: This function is used to fill the CB whose ID is CBId. The
// CB is filled with the Aliases that are available to the
// client.
//=========================================================================
void
FillAliasCBBox (pDBDesc pAliases, UINT32 lNumAliases, UINT16 iCBId,
HWND hWnd)
{
UINT16 i;
UINT32 lSel;
CHAR szString[]="NULL - Std Tables";
// First put all the aliases into the CB.
for(i=0; i<(UINT16)lNumAliases; i++)
{
(void)ComboBox_AddString(GetDlgItem(hWnd, iCBId), pAliases[i].szName);
}
// Now add the NULL alias which is the local tables.
(void)ComboBox_AddString(GetDlgItem(hWnd, iCBId), szString);
// Now get the Paradox item number and display Paradox in the Alias CB.
lSel = ComboBox_FindString(GetDlgItem(hWnd, iCBId), -1, szString);
(void)ComboBox_SetCurSel(GetDlgItem(hWnd, iCBId), lSel);
}
//=========================================================================
// Function: FillFileList()
//
// Input: Window handle(HWND), Number of tables to display (UINT32),
// Handle of the database (hDBIDb).
//
// Returns: TRUE if the names of the table are uppercase on the server.
// FALSE if the names of the table are lowercase on the server.
//
// Desc: This function is used to fill the listbox whose ID is LBId
// with all the table names who are available to the database
// (hDb). We use this to fill the list box in the common
// dialogbox with all the table names in the remote database.
//=========================================================================
BOOL
FillFileList (HWND hWnd, UINT16 iLBId, hDBIDb hDb)
{
hDBICur hTblCur;
BOOL bRet = TRUE;
TBLBaseDesc baseDesc;
HourGlassCursor(TRUE);
GetTableList(hDb, &hTblCur);
// Go to the top of the table.
GoTop(hTblCur, FALSE);
// Put all the Tablenames into the Filelist.
while((GetNextTblRec(hTblCur, &baseDesc))!=DBIERR_EOF)
{
(void)ListBox_AddString(GetDlgItem(hWnd, iLBId), baseDesc.szName);
}
if(islower(baseDesc.szName[0]))
{
bRet = FALSE;
}
CloseTable(&hTblCur);
HourGlassCursor(FALSE);
return bRet;
}
//=========================================================================
// Function: SetFieldNames()
//
// Input: Cursor handle (hDBICur).
//
// Returns: None
//
// Desc: This function is used to set the field names into the dialog
// box. It gets the field names and displays them in proper
// format with a trailing :.
//=========================================================================
void
SetFieldNames (hDBICur hCur)
{
UINT16 i;
pFIELDName pFieldNames;
CHAR szName[DBIMAXTBLNAMELEN];
if((pFieldNames = (pFIELDName) malloc(sizeof(FIELDNAME) * uNumFields))
== NULL)
{
WinMsg("You have run out of memory!", MB_ICONHAND, MB_OK);
return;
}
// Get the field names and the amount of fields.
GetFldNames(hCur, pFieldNames);
for(i=0; i<uNumFields; i++)
{
strcat(pFieldNames[i].FieldName, ":");
}
SetWindowText(GetDlgItem(hMainWnd, IDS_FIELD1),
Proper(pFieldNames[0].FieldName));
SetWindowText(GetDlgItem(hMainWnd, IDS_FIELD2),
Proper(pFieldNames[1].FieldName));
SetWindowText(GetDlgItem(hMainWnd, IDS_FIELD3),
Proper(pFieldNames[2].FieldName));
SetWindowText(GetDlgItem(hMainWnd, IDS_FIELD4),
Proper(pFieldNames[3].FieldName));
SetWindowText(GetDlgItem(hMainWnd, IDS_FIELD5),
Proper(pFieldNames[4].FieldName));
SetWindowText(GetDlgItem(hMainWnd, IDS_FIELD6),
Proper(pFieldNames[5].FieldName));
SetWindowText(GetDlgItem(hMainWnd, IDS_FIELD7),
Proper(pFieldNames[6].FieldName));
SetWindowText(GetDlgItem(hMainWnd, IDS_FIELD8),
Proper(pFieldNames[7].FieldName));
SetWindowText(GetDlgItem(hMainWnd, IDS_FIELD9),
Proper(pFieldNames[8].FieldName));
SetWindowText(GetDlgItem(hMainWnd, IDS_FIELD10),
Proper(pFieldNames[9].FieldName));
SetWindowText(GetDlgItem(hMainWnd, IDS_FIELD11),
Proper(pFieldNames[10].FieldName));
SetWindowText(GetDlgItem(hMainWnd, IDS_FIELD12),
Proper(pFieldNames[11].FieldName));
memset(szName, 0, DBIMAXTBLNAMELEN);
strcpy(szName, szTblName);
SetWindowText(GetDlgItem(hMainWnd, IDS_TABLENAME),
Proper((pCHAR)szName));
SetWindowText(GetDlgItem(hMainWnd, IDS_DBTYPE), (pCHAR)szTblType);
free(pFieldNames);
}
//=========================================================================
// Function: Proper()
//
// Input: String to properize (pCHAR).
//
// Returns: Properized string (pCHAR).
//
// Desc: This function is used to change the case of a string. When
// the function returns the string - the string will have its
// first letter put into uppercase while the rest of the
// letters will be in lowercase.
//=========================================================================
pCHAR
Proper (pCHAR pszString)
{
CHAR szFirst[3];
// First set all the letters lowercase.
strlwr(pszString);
// Next clear the temporary string.
memset(szFirst, '\0', 3);
// Next get first letter in the string to convert into uppercase.
szFirst[0] = pszString[0];
strcat(szFirst, " \0");
// Uppercase the temporary string.
strupr(szFirst);
// Copy the first letter of the temporary string into the first letter
// of the string to convert.
pszString[0] = szFirst[0];
return pszString;
}
//=========================================================================
// Function: SetAll()
//
// Input: Action to take (BOOL).
//
// Returns: None.
//
// Desc: This function is used to set the various controls off or on,
// based upon the the value sent in.
//=========================================================================
void
SetAll (BOOL bAction)
{
SetControl(ID_FIRST_REC, bAction);
SetControl(ID_PREV_REC, bAction);
SetControl(ID_NEXT_REC, bAction);
SetControl(ID_LAST_REC, bAction);
SetControl(ID_ADD_REC, bAction);
SetControl(ID_DEL_REC, bAction);
SetControl(ID_MOD_REC, bAction);
SetControl(ID_ORDER, bAction);
SetControl(ID_RANGE, bAction);
EnableMenuItem(GetMenu(hMainWnd), ID_CLEAR_RANGE, MF_GRAYED);
if(bAction)
{
EnableMenuItem(GetMenu(hMainWnd), ID_DELETETABLE, MF_ENABLED);
}
else
{
EnableMenuItem(GetMenu(hMainWnd), ID_DELETETABLE, MF_GRAYED);
SetWindowText(GetDlgItem(hMainWnd, IDS_TABLENAME), (pCHAR)"");
SetWindowText(GetDlgItem(hMainWnd, IDS_DBTYPE), (pCHAR)"");
}
SetControl(ID_SEARCH, bAction);
SetControl(ID_UNDO_REC, bAction);
}
//======================================================================
// Name: HourGlassCursor()
//
// Input: turnOn - Turn on or off the Hourglass cursor
//
// Return: TRUE
//
// Description:
// Turns the hourglass cursor on or off according to value
// specified in turnOn.
//======================================================================
BOOL
HourGlassCursor (BOOL bTurnOn)
{
if (bTurnOn)
{
if (SetCursor(LoadCursor(NULL, IDC_WAIT)))
{
ShowCursor(TRUE);
}
}
else
{
if (SetCursor(LoadCursor(NULL, IDC_ARROW)))
{
ShowCursor(TRUE);
}
}
return TRUE;
}