- BORLAND/: Borland C++ 4.52 (chosen over 4.5 by byte-match: CODE/RP/CW32.LIB
is identical to 4.52's install lib). BCC32/TLINK32/TLIB/MAKE run natively on
Win11; CODE/BT/OPT.MAK is the shipped BTL4OPT.EXE's exact flag recipe
(extender = Borland PowerPack DPMI32, not Phar Lap TNT).
- restoration/source410/: the literal 1995-form reconstruction of the missing
BT game source (never mixed into CODE/). Round 1-3 state:
* 6 of 10 surviving original TUs COMPILE CLEAN under the period toolchain
(BTMSSN, BTCNSL, BTSCNRL, BTTEAM, BTL4MODE, BTL4ARND) - first builds
since 1996.
* BT_L4/BTL4APP.CPP pilot reconstruction: 12/12 functions, Fail() lands on
its binary-recorded line 400 exactly.
* BT/BTCNSL.HPP: console wire IDs recovered from the binary's ctors
(Killed=9, Damaged=10, ScoreUpdate=13, DeathWithoutHonor=15 [T1];
TeamScore=12 flagged [T4]).
* MUNGA/: 8 engine-header backfills back-dated from the BT412 WinTesla tree
(VDATA numbering decomp-verified; AUDREND's OpenAL-era virtual removed -
the period compiler is the drift detector).
* Tooling: backdate.py (WinTesla->1995 header transform), compile410.sh
(per-TU verification sweep under authentic OPT.MAK flags).
* README: corrected roadmap - MECH.HPP is the capstone grown with the mech
TU reconstructions; BTREG.CPP green = the header-family milestone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2258 lines
74 KiB
C++
2258 lines
74 KiB
C++
// BDE - (C) Copyright 1994 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.
|
|
//=================================================================
|
|
int _pascal
|
|
WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
|
|
int nCmdShow)
|
|
{
|
|
MSG msg;
|
|
|
|
lpCmdLine = lpCmdLine;
|
|
nCmdShow = nCmdShow;
|
|
|
|
// Register CTL3D
|
|
Ctl3dRegister(hInstance);
|
|
Ctl3dAutoSubclass(hInstance);
|
|
Ctl3dColorChange();
|
|
|
|
|
|
// Make this a single instance program
|
|
if (hPrevInstance)
|
|
{
|
|
MessageBox(GetFocus(), "This application is already running!",
|
|
"AddressBook Manager", MB_OK | MB_ICONHAND);
|
|
return(FALSE);
|
|
}
|
|
|
|
// 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 = NULL;
|
|
UINT16 iSize;
|
|
CHAR szInitIndex[]="FullName";
|
|
CHAR szMdxName[DBIMAXPATHLEN];
|
|
UINT16 iRangeVal = 0;
|
|
UINT16 i;
|
|
CHAR szABType[DBIMAXNAMELEN];
|
|
CHAR szTable[DBIMAXNAMELEN];
|
|
CHAR szMsg[150];
|
|
UINT16 iType;
|
|
BOOL bFlag;
|
|
ABHANDLES AbHandle;
|
|
pCS pCreate = NULL;
|
|
DLGPROC lpProc;
|
|
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[DBIMAXNAMELEN];
|
|
static CHAR szTempDir[DBIMAXPATHLEN];
|
|
|
|
// These variables are used for the FileOpen/FileSave dialogs
|
|
LPFOCHUNK lpFOChunk;
|
|
hErrorWnd = hWnd;
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_CREATE:
|
|
if((lpfnFileHook = (FARHOOK)MakeProcInstance(
|
|
(FARPROC)FileHook, hInst))==NULL)
|
|
{
|
|
WinMsg("Could not create Common Dialog Hook",
|
|
MB_ICONHAND, MB_OK);
|
|
}
|
|
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 the length of the table name plus the path plus 10 bytes.
|
|
iSize = strlen(szTblDirectory) + strlen(szTblName) + 10;
|
|
|
|
// Create the two tables - the Paradox Business table and the
|
|
// dBASE personal table.
|
|
for(i=0; i<2; i++)
|
|
{
|
|
// Get memory to hold the full table name with path.
|
|
if((pszTableInfo = (pCHAR)malloc(iSize * sizeof(CHAR)))
|
|
==NULL)
|
|
{
|
|
WinMsg("You have run out of memory!", MB_ICONHAND,
|
|
MB_OK);
|
|
SendMessage(hWnd, WM_DESTROY, 0, 0L);
|
|
}
|
|
|
|
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))
|
|
{
|
|
OpenDB(&hDb, NULL, NULL, NULL);
|
|
if(CreateTable(hDb, &hCur, szABType)==DBIERR_NONE)
|
|
{
|
|
// Fill it with the data that is inside the resource
|
|
// file.
|
|
if(FillTable(hCur, szABType))
|
|
{
|
|
CloseTable(&hCur);
|
|
}
|
|
}
|
|
CloseDb(&hDb);
|
|
}
|
|
free(pszTableInfo);
|
|
}
|
|
|
|
OpenDB(&hDb, NULL, NULL, NULL);
|
|
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;
|
|
|
|
case WM_CTLCOLOR:
|
|
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(wParam)
|
|
{
|
|
// 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 (HIWORD(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);
|
|
|
|
if((lpfnFileHook = (FARHOOK)MakeProcInstance(
|
|
(FARPROC)FileHook, hInst))==NULL)
|
|
{
|
|
WinMsg("Could not create Common Dialog Hook",
|
|
MB_ICONHAND, MB_OK);
|
|
}
|
|
|
|
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:
|
|
lpProc = (DLGPROC)MakeProcInstance((FARPROC) AboutDlg,
|
|
hInst);
|
|
DialogBox(hInst, "AboutDlg", hMainWnd, lpProc);
|
|
FreeProcInstance((FARPROC) lpProc);
|
|
SetFNameFocus();
|
|
break;
|
|
|
|
// Display the Order dialog box.
|
|
case ID_ORDER:
|
|
lpProc = (DLGPROC)MakeProcInstance((FARPROC) OrderDlg,
|
|
hInst);
|
|
|
|
AbHandle.phCur = &hCur;
|
|
AbHandle.hDb = hDb;
|
|
|
|
// 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)
|
|
{
|
|
// Display the current record.
|
|
DisplayTable(hCur);
|
|
CheckButtons(hCur);
|
|
}
|
|
FreeProcInstance((FARPROC) lpProc);
|
|
SetFNameFocus();
|
|
break;
|
|
|
|
// Display the Range dialog box.
|
|
case ID_RANGE:
|
|
lpProc = (DLGPROC)MakeProcInstance((FARPROC)RangeDlg,
|
|
hInst);
|
|
|
|
AbHandle.phCur = &hCur;
|
|
AbHandle.hDb = hDb;
|
|
|
|
// Pass the pointer to the ABHandle structure so it
|
|
// can be modified inside the dialogbox.
|
|
iRangeVal = DialogBoxParam(hInst, "RangeDlg", hMainWnd,
|
|
lpProc,
|
|
(LONG)(void far*)&AbHandle);
|
|
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();
|
|
}
|
|
FreeProcInstance((FARPROC) lpProc);
|
|
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:
|
|
lpProc = (DLGPROC)MakeProcInstance((FARPROC) SearchDlg,
|
|
hInst);
|
|
|
|
AbHandle.phCur = &hCur;
|
|
AbHandle.hDb = hDb;
|
|
|
|
// Pass the pointer to the ABHandle structure so it
|
|
// can be modified inside the dialogbox.
|
|
if(DialogBoxParam(hInst, "SearchDlg", hMainWnd, lpProc,
|
|
(LONG)(void far*)&AbHandle)==IDOK)
|
|
{
|
|
// Move one record past the crack that the Search
|
|
// function leaves you at.
|
|
CHKERR(GetNextRec(hCur));
|
|
}
|
|
FreeProcInstance((FARPROC) lpProc);
|
|
|
|
// 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.
|
|
UINT16 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 = NULL;
|
|
|
|
// 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;
|
|
INT16 iExist = 0;
|
|
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.
|
|
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 = NULL;
|
|
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.
|
|
SendDlgItemMessage(hMainWnd, IDE_FIRST_NAME, EM_LIMITTEXT,
|
|
(WPARAM)NAMELEN-1, 0L);
|
|
SendDlgItemMessage(hMainWnd, IDE_LAST_NAME, EM_LIMITTEXT,
|
|
(WPARAM)NAMELEN-1, 0L);
|
|
SendDlgItemMessage(hMainWnd, IDE_SP_COMP, EM_LIMITTEXT,
|
|
(WPARAM)ADDRESSLEN-1, 0L);
|
|
SendDlgItemMessage(hMainWnd, IDE_COMMENTS, EM_LIMITTEXT,
|
|
(WPARAM)COMMENTLEN-1, 0L);
|
|
SendDlgItemMessage(hMainWnd, IDE_ADDRESS1, EM_LIMITTEXT,
|
|
(WPARAM)ADDRESSLEN-1, 0L);
|
|
SendDlgItemMessage(hMainWnd, IDE_ADDRESS2, EM_LIMITTEXT,
|
|
(WPARAM)ADDRESSLEN-1, 0L);
|
|
SendDlgItemMessage(hMainWnd, IDE_CITY, EM_LIMITTEXT,
|
|
(WPARAM)CITYLEN-1, 0L);
|
|
SendDlgItemMessage(hMainWnd, IDE_STATE, EM_LIMITTEXT,
|
|
(WPARAM)STATELEN-1, 0L);
|
|
SendDlgItemMessage(hMainWnd, IDE_ZIP, EM_LIMITTEXT,
|
|
(WPARAM)ZIPLEN-1, 0L);
|
|
SendDlgItemMessage(hMainWnd, IDE_PHONE1, EM_LIMITTEXT,
|
|
(WPARAM)PHONELEN-1, 0L);
|
|
SendDlgItemMessage(hMainWnd, IDE_PHONE2, EM_LIMITTEXT,
|
|
(WPARAM)PHONELEN-1, 0L);
|
|
SendDlgItemMessage(hMainWnd, IDE_LAST_DATE, EM_LIMITTEXT,
|
|
(WPARAM)DATELEN-1, 0L);
|
|
|
|
// 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=NULL;
|
|
|
|
// 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 = SendDlgItemMessage(hWnd, iId, CB_ADDSTRING, 0,
|
|
(LPARAM)pABIdxDesc[i].szTagName);
|
|
|
|
// Send the listbox item its data. The data is the offset of the
|
|
// index name inside of the index structure.
|
|
SendDlgItemMessage(hWnd, iId, CB_SETITEMDATA,
|
|
(WPARAM)lOff, (LPARAM)i);
|
|
}
|
|
|
|
// Select the currently active index from the ComboBox.
|
|
lOff=SendDlgItemMessage(hWnd, iId, CB_SELECTSTRING, (WPARAM)-1,
|
|
(LPARAM)pszIndex);
|
|
|
|
lIndex=SendDlgItemMessage(hWnd, iId, CB_GETITEMDATA,
|
|
(WPARAM)lOff, 0L);
|
|
// 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=NULL;
|
|
|
|
// 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;
|
|
UINT16 iFName;
|
|
UINT16 iLName;
|
|
DATE 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 = GetDateFormat(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 = atoi(pVal);
|
|
pVal = strtok(NULL, pFmtDate->szDateSeparator);
|
|
if(pVal && bRetVal)
|
|
{
|
|
d.day = 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)
|
|
{
|
|
struct dosdate_t d;
|
|
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(GetDateFormat(pFmtDate));
|
|
_dos_getdate(&d);
|
|
|
|
if(pFmtDate->iDateMode==0)
|
|
{
|
|
wsprintf(szDateString, "%02d%s%02d%s%02d", d.month,
|
|
pFmtDate->szDateSeparator, d.day, pFmtDate->szDateSeparator,
|
|
d.year);
|
|
}
|
|
|
|
if(pFmtDate->iDateMode==1)
|
|
{
|
|
wsprintf(szDateString, "%02d%s%02d%s%02d", d.day,
|
|
pFmtDate->szDateSeparator, d.month, pFmtDate->szDateSeparator,
|
|
d.year);
|
|
}
|
|
|
|
if(pFmtDate->iDateMode==2)
|
|
{
|
|
wsprintf(szDateString, "%02d%s%02d%s%02d", d.year,
|
|
pFmtDate->szDateSeparator, d.month, pFmtDate->szDateSeparator,
|
|
d.day);
|
|
}
|
|
|
|
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, UINT16 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 = SendDlgItemMessage(hWnd, i, BM_GETCHECK, 0, 0L);
|
|
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++)
|
|
{
|
|
SendMessage(GetDlgItem(hWnd, iCBId), CB_ADDSTRING, 0,
|
|
(LPARAM)pAliases[i].szName);
|
|
}
|
|
|
|
// Now add the NULL alias which is the local tables.
|
|
SendMessage(GetDlgItem(hWnd, iCBId), CB_ADDSTRING, 0, (LPARAM)szString);
|
|
|
|
// Now get the Paradox item number and display Paradox in the Alias CB.
|
|
lSel = SendMessage(GetDlgItem(hWnd, iCBId), CB_FINDSTRING, (WPARAM)-1,
|
|
(LPARAM)szString);
|
|
SendMessage(GetDlgItem(hWnd, iCBId), CB_SETCURSEL, (UINT16)lSel, 0L);
|
|
}
|
|
|
|
//=========================================================================
|
|
// 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)
|
|
{
|
|
SendMessage(GetDlgItem(hWnd, iLBId), LB_ADDSTRING, 0,
|
|
(LPARAM)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;
|
|
}
|