Files
TeslaRel410/BORLAND/BDE/EXAMPLES/C/INVENTRY/INV_MAIN.C
T
CydandClaude Fable 5 63312e07f9 source410: literal 4.10 source reconstruction + BC++ 4.52 fleet toolchain archived
- 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>
2026-07-19 07:33:26 -05:00

2257 lines
78 KiB
C++

// BDE - (C) Copyright 1994 by Borland International
#include "inventry.h"
#define FILEHANDLESNEEDED 40
//=================================================================
// Function:
// 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;
// Used to avoid a warning.
lpCmdLine = lpCmdLine;
// Register CTL3D
Ctl3dRegister(hInstance);
Ctl3dAutoSubclass(hInstance);
Ctl3dColorChange();
// Make this a single instance program
if (hPrevInstance)
{
MessageBox(GetFocus(), "This application is already running!",
"Inventory Program", MB_OK | MB_ICONHAND);
return FALSE;
}
// Start the application
hInst = hInstance;
if (InitApp(nCmdShow) == FALSE)
{
return FALSE;
}
// Process all event driven messages...
while (GetMessage(&msg, NULL, NULL, NULL))
{
if (hMainWnd == 0 || !IsDialogMessage(hMainWnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// Unregister CTL3D
Ctl3dUnregister(hInstance);
return msg.wParam;
}
//====================================================================
// Function:
// InitApp(int nCmdShow)
//
// Input: nCmdShow - If the Window should be visible
//
// 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;
char szWindowName[] = "Inventory";
char szMessage[(DBIMAXMSGLEN * 2) + 1];
char szRelativeTblDirectory[DBIMAXPATHLEN+1];
unsigned uCount;
// Init the application & create the needed windows
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MainDlgProc;
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 = szWindowName;
// 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("INVENTRY", "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."
"\r\nPlease check BDE.INI in the Windows directory.",
szTblDirectory);
MessageBox(NULL, szMessage, "System Error", MB_OK | MB_ICONHAND);
return FALSE;
}
// Get the private directory.
GetPrivateProfileString("INVENTRY", "PrivateDir",
".",
(LPSTR)szRelativeTblDirectory,
sizeof(szRelativeTblDirectory),
"bde.ini");
// Create a fully qualified pathname for the table directory
if (MakeFullPath(szPrivDirectory, szRelativeTblDirectory))
{
sprintf(szMessage,"Private Directory does not exist: %s."
"\r\nPlease check BDE.INI in the Windows directory.",
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;
}
// ===============================================================
// Function:
// MainDlgProc(hWnd, msg, wParam, lParam);
//
// Input: hWnd - Handle to the Window
// msg - Message to Process
// wParam - The Word parameter (if any)
// lParam - The Double Word parameter (if any)
//
// Return: Depends on the message
//
// Description:
// This routine will process all messaged for the primary
// application window. Included in this are all menu
// commands.
// ===============================================================
LRESULT CALLBACK
MainDlgProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
DLGPROC lpProc; // used for createing all the dialog boxes.
pCHAR TableInfo = NULL; // used for the full name of the table.
UINT16 RangeVal = 0; // Used for the Range dialog box return value.
// 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; // used for the database handle.
static hDBICur hCur; // used for the table handle.
long Ret = FALSE;
HBRUSH hBrush;
HWND hwnd;
hErrorWnd = hWnd;
switch (msg)
{
case WM_CREATE:
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.
TableInfo = (pCHAR)malloc(DBIMAXPATHLEN + 1);
// Check if the table exists or if it is empty.
if(!TableExist(TableInfo))
{
// Since the table is either empty or does not exist we
// need to recreate it by overwriting the old table or
// creating a new one.
if (CreateTable(&hDb, &hCur))
{
return FALSE;
}
// Fill the table with data from the resource file.
FillTable(hCur, &hDb);
}
// Get the database and cursor handles.
GetTable(&hDb, &hCur);
if(hCur==NULL)
{
WinMsg("Error opening tables!", MB_ICONHAND, MB_OK);
PostMessage(hWnd, WM_DESTROY, 0, 0L);
}
else
{
SetIndex(&hCur, 0);
// When we move to the top we are sitting
// the first record. Therefore, we need to move one
// record forward to be sitting on the first record,
// which we need to do to display the record using
// the DisplayRecord function.
GoTop(hCur, TRUE);
free((void*)TableInfo);
// Display the current record.
PostMessage(hWnd, WM_DISPLAY, 0, 0L);
ShowWindow(hWnd, SW_SHOW);
}
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:
SetItemFocus();
break;
case WM_DISPLAY:
// Check the navigational buttons and disable or enable each of
// them based upon the position of the cursor.
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_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 avalid date.
case IDOK:
// Add the record.
SaveRec(hCur, TRUE);
// Reset the window's normal look.
EndNewRec(hCur);
SetItemFocus();
break;
case IDCANCEL:
// Check if data has been entered and ask if the user
// wants to lose the entered data.
if(CanContinue("Data not saved cancel anyway?", IDOK))
{
// Set the window's normal look and cancel the data.
EndNewRec(hCur);
}
break;
// Check all the edits at once for any changes. Then check
// if the data is valid.
case IDE_ITEM:
case IDE_ITEMID:
case IDE_NOINSTOCK:
case IDE_BUILDING:
case IDE_COST:
case IDE_ORDERDATE:
case IDE_COMMENTS:
if (HIWORD(lParam) == EN_UPDATE)
{
// Checks if the data is valid.
if(verified())
{
// Check what mode we are in. If we are
// adding a new person to the table then
// enable the OK button.
if(NewRecMode)
{
EnableWindow(GetDlgItem(hMainWnd, IDOK),
TRUE);
}
else
{
// Otherwise enable the Commit and Undo
// buttons, that are visible only when
// we are NOT adding a new person.
SetControl(ID_MOD_REC, TRUE);
SetControl(ID_UNDO_REC, TRUE);
}
}
else
{
// If the data is not valid and we are adding
// a new person.
if(NewRecMode)
{
// Disable the OK button, so that the
// user cannot save the invalid data.
EnableWindow(GetDlgItem(hMainWnd, IDOK),
FALSE);
}
else
{
// The data is not valid and we are NOT
// adding a new person. Therefore,
// disable the Commit button. BUT, we
// still enable the Undo button so that
// the user can undo the changes.
SetControl(ID_MOD_REC, FALSE);
SetControl(ID_UNDO_REC, TRUE);
}
}
}
break;
// Display the About dialog box.
case ID_ABOUT:
lpProc = (DLGPROC)MakeProcInstance((FARPROC)AboutDlg,
hInst);
DialogBox(hInst, "AboutDlg", hMainWnd, lpProc);
FreeProcInstance((FARPROC) lpProc);
SetItemFocus();
UpdateWindow (hWnd);
break;
// Display the Order dialog box.
case ID_ORDER:
lpProc = (DLGPROC)MakeProcInstance((FARPROC) OrderDlg,
hInst);
// Since we have to change indexes within the Order
// Proc we need to pass the pointer to the cursor
// handle.
if(DialogBoxParam(hInst, "OrderDlg", hMainWnd, lpProc,
(LONG)(void far*)&hCur)==IDOK)
{
// Redisplay the record and check the naviagtional
// buttons as the record may have changed position
// with the new index.
DisplayTable(hCur);
CheckButtons(hCur);
}
FreeProcInstance((FARPROC) lpProc);
SetItemFocus();
UpdateWindow (hWnd);
break;
// Display the Range dialog box.
case ID_RANGE:
lpProc = (DLGPROC)MakeProcInstance((FARPROC)RangeDlg,
hInst);
// Since we have to change indexes within the Range
// Proc we need to pass the pointer to the cursor
// handle.
RangeVal = DialogBoxParam(hInst, "RangeDlg", hMainWnd,
lpProc,
(LONG)(void far*)&hCur);
if(RangeVal == IDOK)
{
// Set the global variable RangeSet to TRUE as we
// did set a range for the present cursor.
RangeSet = TRUE;
// Display the first record of this range and set
// the navigational controls.
DisplayTable(hCur);
CheckButtons(hCur);
// Enable the Clear Range menu option.
EnableMenuItem(GetMenu(hMainWnd), ID_CLEAR_RANGE,
MF_ENABLED);
}
else
{
if(RangeVal == RANGEERROR)
{
// Reset the range as the attempted range was
// invalid.
PostMessage(hWnd, WM_COMMAND, ID_CLEAR_RANGE,
0L);
}
else
{
// Otherwise, Cancel was pressed so just reset
// focus to the Item edit control.
SetItemFocus();
}
}
FreeProcInstance((FARPROC) lpProc);
break;
// This menu option is enabled ONLY after a range has been
// set.
case ID_CLEAR_RANGE:
// Reset the 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;
// Redisplay the new range and set the navigational
// controls.
DisplayTable(hCur);
CheckButtons(hCur);
break;
// Display the Search dialog box.
case ID_SEARCH:
lpProc = (DLGPROC)MakeProcInstance((FARPROC) SearchDlg,
hInst);
// Since we have to change indexes within the Search
// Proc we need to pass the pointer to the cursor
// handle.
DialogBoxParam(hInst, "SearchDlg", hMainWnd, lpProc,
(LONG)(void far*)&hCur);
// Move one record past the crack that the Search
// function leaves you at.
GetNextRec(hCur);
FreeProcInstance((FARPROC) lpProc);
// Redisplay the new range and set the navigational
// controls.
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();
// 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();
SetItemFocus();
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:
// This is sent when the Commit button or the Commit
// Changes menu option are chosen.
if(CanContinue("Do you want to modify this record?",
ID_UNDO_REC))
{
// Modify the record.
SaveRec(hCur, FALSE);
// Set the navigational controls and disable the
// Undo and Commit controls.
CheckButtons(hCur);
SetControl(ID_MOD_REC, FALSE);
SetControl(ID_UNDO_REC, FALSE);
}
break;
case ID_DEL_REC:
// This message is sent upon pressing the Delete
// button, or by choosing the Delete menu option.
if(WinMsg("Do you want to delete this record?",
MB_ICONHAND, MB_YESNO)== IDYES)
{
// Delete the record.
DeleteRecord(hCur);
}
break;
case ID_UNDO_REC:
// This message is sent by the Undo button, or by the
// Undo menu option. First we check the status of
// the Undo button and pass the string to the
// CanContinue function.
if(CanContinue("All changes will be lost - Undo"
" anyway?", ID_UNDO_REC))
{
// Redisplay the original record's data.
PostMessage(hWnd, WM_DISPLAY, 0, 0L);
}
break;
case ID_EXIT:
// Quit the program.
PostMessage(hWnd, WM_CLOSE, 0, 0L);
break;
default:
Ret = DefWindowProc(hWnd, msg, wParam, lParam);
break;
}
break;
case WM_CLOSE:
// Check if there is unsaved data by checking if the Undo
// button is enabled.
if(CanContinue("Data not saved quit anyway?", ID_UNDO_REC))
{
DestroyWindow(hWnd);
}
else
{
// Do not quit the program.
SetItemFocus();
}
break;
case WM_DESTROY:
// Clean up - Close the Database and Exit IDAPI
CloseDb(&hDb);
DbExit();
PostQuitMessage(0);
break;
default:
// Otherwise default to the DefWindowProc.
Ret = DefWindowProc(hWnd, msg, wParam, lParam);
break;
}
return(Ret);
}
//======================================================================
// Function:
// EditSubClassProc(HWND hWnd, WORD msg, WORD wParam,
// LONG lParam)
//
// Input: hWnd - Handle to the Windwo
// msg - Message to process
// wParam - Word Parameter
// lParam - Double Word Parameter
//
// Return: It returns the result of the procedure. It can return the
// result of the original edit control if the WM_CHAR is not
// a tab character.
//
// Description:
// This routine will process all I/O for the Comments edit
// control. It does this by first checking if the tab key was
// hit inside of the comment edit control. If it was it moves
// control to the next control item and then does NOT let the
// original edit control process the message. However, if the
// WM_CHAR is not a tab then it lets the original edit control
// process the message.
//======================================================================
long FAR _pascal _export
EditSubClassProc (HWND hWnd, WORD msg, WORD wParam, LONG lParam)
{
LRESULT lResult = 0;
BOOL fCallOrigWndProc = TRUE;
switch (msg)
{
case WM_CHAR:
if(wParam == '\t')
{
if(GetKeyState(VK_SHIFT)<0)
{
SetFocus(GetDlgItem(hMainWnd, IDE_ORDERDATE));
}
else
{
if(!NewRecMode)
{
SetFocus(GetDlgItem(hMainWnd, ID_ORDER));
SendMessage(GetDlgItem(hMainWnd, ID_ORDER),
BM_SETSTYLE, (UINT16)BS_DEFPUSHBUTTON,
1L);
}
else
{
SetFocus(GetDlgItem(hMainWnd, IDOK));
SendMessage(GetDlgItem(hMainWnd, IDOK),
BM_SETSTYLE, (UINT16)BS_DEFPUSHBUTTON,
1L);
}
}
fCallOrigWndProc = FALSE;
}
break;
}
if(fCallOrigWndProc)
{
lResult = CallWindowProc(_wpOrigWndProc, hWnd, msg, wParam,
lParam);
}
return lResult;
}
//======================================================================
// Function:
// AboutDlg(HWND hWnd, WORD msg, WORD wParam, LONG lParam)
//
// Input: hWnd - Handle to the Windwo
// msg - Message to process
// wParam - Word Parameter
// lParam - Double Word Parameter
//
// Return: TRUE - Dialog Created.
// FALSE - Dialog Failed to create.
//
// Description:
// This routine will process all I/O for the ABOUT dialog.
//======================================================================
BOOL FAR _pascal _export
AboutDlg (HWND hWnd, WORD msg, WORD wParam, LONG lParam)
{
BOOL ret = FALSE;
// Done to clear the unused warning.
lParam = lParam;
switch (msg)
{
case WM_COMMAND:
switch (wParam)
{
case IDOK:
case IDCANCEL:
ret = TRUE;
EndDialog(hWnd, ret);
break;
}
break;
}
return ret;
}
//======================================================================
// Function:
// OrderDlg(HWND hWnd, WORD msg, WORD wParam, LONG lParam)
//
// Input: hWnd - Handle to the Windwo
// msg - Message to process
// wParam - Word Parameter
// lParam - Double Word Parameter
// Also contains the pointer to the cursor during
// the WM_INITDIALOG.
//
// Return: TRUE - The Index was set.
// FALSE - Index failed or user canceled the dilaog box.
//
// Description:
// This routine will process all I/O for the dialog that will
// change the order of the table (i.e. place an index).
//======================================================================
BOOL FAR _pascal _export
OrderDlg (HWND hWnd, WORD msg, WORD wParam, LONG lParam)
{
BOOL ret = FALSE; // Return value from IDAPI functions
static phDBICur phCur; // This is the pointer to the cursor of
// the table.
static UINT16 uStartIndex; // This will hold the original index
// number.
UINT32 uIndex; // Selected Index
UINT32 uSel; // Item selected in ListBox
hErrorWnd = hWnd;
switch (msg)
{
case WM_INITDIALOG:
phCur = (phDBICur)lParam;
// Get the original index before entering this dialog box.
// Then we fill the field drop-down list with all the
// possible indexed fields.
uStartIndex=FillDropList(hWnd, *phCur, IDE_ORDER_COMBOBOX);
return TRUE;
case WM_COMMAND:
switch (wParam)
{
case IDE_ORDER_COMBOBOX:
// Since the combobox is sorted we need to have a way
// to match the user's choice and the original place
// of that choice in the index array. So we add an
// item data.
switch(HIWORD(lParam))
{
case CBN_SELCHANGE:
uSel=SendDlgItemMessage(hWnd,
IDE_ORDER_COMBOBOX,
CB_GETCURSEL, 0, 0L);
uIndex=SendDlgItemMessage(hWnd,
IDE_ORDER_COMBOBOX,
CB_GETITEMDATA,
(WPARAM)uSel, 0L);
// Put the Index description in the static
// text box.
SetWindowText(GetDlgItem(hWnd, IDE_ORDER_INFO),
IndexList[(UINT16)uIndex]);
break;
}
break;
case IDOK:
// Now get the selected item and its item data.
uSel=SendDlgItemMessage(hWnd, IDE_ORDER_COMBOBOX,
CB_GETCURSEL, 0, 0L);
uIndex=SendDlgItemMessage(hWnd, IDE_ORDER_COMBOBOX,
CB_GETITEMDATA, (WPARAM)uSel,
0L);
// Check if it is the original index or a new index.
if(uStartIndex != uIndex)
{
if(RangeSet)// If there was a range set - tell the
// user that they are about to lose
// it with the new index choice.
{
if(WinMsg("You will lose the current Range"
" settings do you want to change"
" indexes anyway?",
MB_ICONHAND, MB_YESNO)== IDYES)
{
// Switch the index.
SetIndex(phCur, (UINT16)uIndex);
// Disable the Reset Range menu option.
EnableMenuItem(GetMenu(hMainWnd),
ID_CLEAR_RANGE, MF_GRAYED);
// Reset thge global RangeSet variable to
// FALSE.
RangeSet = FALSE;
ret = TRUE;
}
else
{
ret = FALSE;
}
}
else
{
// Switch Index.
SetIndex(phCur, (UINT16)uIndex);
ret = TRUE;
}
}
else
{
ret = FALSE;
}
EndDialog(hWnd, ret);
break;
case IDCANCEL:
EndDialog(hWnd, ret);
ret = FALSE;
break;
}
break;
}
return ret;
}
//======================================================================
// Function:
// RangeDlg(HWND hWnd, WORD msg, WORD wParam, LONG lParam)
//
// Input: hWnd - Handle to the Windwo
// msg - Message to process
// wParam - Word Parameter
// lParam - Double Word Parameter
// Also contains the pointer to the cursor during
// the WM_INITDIALOG.
//
// Return: TRUE - The Range was set.
// FALSE - Range failed or user canceled the dilaog box.
//
// Description:
// This routine will process all I/O for the dialog that will
// change the Range of the present cursor AND Index.
//======================================================================
BOOL FAR _pascal _export
RangeDlg (HWND hWnd, WORD msg, WORD wParam, LONG lParam)
{
BOOL ret = FALSE;
static phDBICur phCur; // Pointer to the cursor of the table.
// Two Record structure pointers to pass to the SetRange function.
static RecordType *pHighRec;
static RecordType *pLowRec;
static UINT16 uStartIndex; // Used to hold the original index.
BOOL bLowInclude; // Bool to include or not include low
// value in range.
BOOL bHighInclude; // Bool to include or not include high
// value in range.
UINT32 Ret;
UINT32 uIndex;
char szString[220];
// Used to hold the input string from the range edit control.
CHAR Temp[FLDLENGTH];
UINT32 uSel;
// Bools to know whether the low or high ranges were not entered.
BOOL bLowEmpty=FALSE;
BOOL bHighEmpty=FALSE;
hErrorWnd = hWnd;
switch (msg)
{
case WM_INITDIALOG:
phCur = (phDBICur)lParam; // Get the Cursor pointer.
// Fill the combobox with the index names and get the present
// index.
uStartIndex=FillDropList(hWnd, *phCur, IDE_RANGE_COMBO);
// Allocate memory for the High and Low record structures.
if((pHighRec = (RecordType *) malloc(1 * sizeof(RecordType)))
== NULL)
{
WinMsg("You have run out of memory!", MB_ICONHAND, MB_OK);
return FALSE;
}
if((pLowRec = (RecordType *) malloc(1 * sizeof(RecordType)))
== NULL)
{
WinMsg("You have run out of memory!", MB_ICONHAND, MB_OK);
return FALSE;
}
// Clear the structures of any unwanted data.
memset(pLowRec, 0, sizeof(RecordType));
memset(pHighRec, 0, sizeof(RecordType));
// Finally set the length of the input field to the appropriate
// size based upon the present index.
SetFieldLength(hWnd, uStartIndex, IDE_LOWRANGE, IDE_HIGHRANGE,
TRUE);
LoadString(hInst, IDS_RANGE, szString, 220);
SetDlgItemText(hWnd, IDS_RANGE_TEXT, (pCHAR)szString);
ret = TRUE;
break;
case WM_COMMAND:
switch (wParam)
{
case IDE_RANGE_COMBO:
switch(HIWORD(lParam))
{
case CBN_SELCHANGE:
// Add an item data to track the item in the
// sorted listbox.
uSel=SendDlgItemMessage(hWnd, IDE_RANGE_COMBO,
CB_GETCURSEL, 0, 0L);
uIndex=SendDlgItemMessage(hWnd, IDE_RANGE_COMBO,
CB_GETITEMDATA,
(WPARAM)uSel, 0L);
// Get the text that was entered for that
// index the last time it was chosen.
GetField(pLowRec, Temp, (UINT16)uIndex);
SetWindowText(GetDlgItem(hWnd, IDE_LOWRANGE),
Temp);
GetField(pHighRec, Temp, (UINT16)uIndex);
SetWindowText(GetDlgItem(hWnd, IDE_HIGHRANGE),
Temp);
// Set the field length for the present index.
SetFieldLength(hWnd, (UINT16)uIndex,
IDE_LOWRANGE, IDE_HIGHRANGE,
TRUE);
ret = TRUE;
break;
}
break;
case IDE_LOWRANGE:
case IDE_HIGHRANGE:
switch(HIWORD(lParam))
{
case EN_KILLFOCUS:
// Get the index and data.
uSel=SendDlgItemMessage(hWnd, IDE_RANGE_COMBO,
CB_GETCURSEL, 0, 0L);
uIndex=SendDlgItemMessage(hWnd, IDE_RANGE_COMBO,
CB_GETITEMDATA,
(WPARAM)uSel, 0L);
// Get the inputed range text and save that
// in the record structure to display again.
GetDlgItemText(hWnd, IDE_LOWRANGE, Temp,
FLDLENGTH);
PutField(pLowRec, Temp, (UINT16)uIndex);
GetDlgItemText(hWnd, IDE_HIGHRANGE, Temp,
FLDLENGTH);
PutField(pHighRec, Temp, (UINT16)uIndex);
ret = TRUE;
break;
}
break;
case IDOK:
// Get the present state of the check boxes.
Ret = SendDlgItemMessage(hWnd, IDE_BM_LOW, BM_GETCHECK,
0, 0L);
if(Ret == 1)
{
bLowInclude = TRUE;
}
else
{
bLowInclude = FALSE;
}
Ret = SendDlgItemMessage(hWnd, IDE_BM_HIGH, BM_GETCHECK,
0, 0L);
if(Ret == 1)
{
bHighInclude = TRUE;
}
else
{
bHighInclude = FALSE;
}
// Clear the record structures, then fill the
// appropriate fields in the record structures
// with the range text.
memset(pLowRec, 0, sizeof(RecordType));
memset(pHighRec, 0, sizeof(RecordType));
uSel=SendDlgItemMessage(hWnd, IDE_RANGE_COMBO,
CB_GETCURSEL, 0, 0L);
uIndex=SendDlgItemMessage(hWnd, IDE_RANGE_COMBO,
CB_GETITEMDATA, (WPARAM)uSel,
0L);
GetDlgItemText(hWnd, IDE_LOWRANGE, Temp, FLDLENGTH);
// If the range was left empty then set the bool to
// TRUE.
if(strlen(Temp)==0)
{
bLowEmpty = TRUE;
}
// Put the text into the correct field of the
// record structure, that is to be used by the
// SetRange function.
PutField(pLowRec, Temp, (UINT16)uIndex);
GetDlgItemText(hWnd, IDE_HIGHRANGE, Temp, FLDLENGTH);
// If the range was left empty then set the bool to
// TRUE.
if(strlen(Temp)==0)
{
bHighEmpty = TRUE;
}
// Put the text into the correct field of the
// record structure, that is to be used by the
// SetRange function.
PutField(pHighRec, Temp, (UINT16)uIndex);
if(uStartIndex != uIndex)
{
SetIndex(phCur, (UINT16)uIndex);
}
// Set the range. If the function fails return FALSE.
if(SetRange(pHighRec, pLowRec, bHighInclude,
bLowInclude, *phCur, bHighEmpty,
bLowEmpty)==DBIERR_NONE)
{
if(AtEOF(*phCur))
{
MessageBox(hWnd, "No Records exist within the"
" specified range. Resetting to"
" original range.", "Range Error",
MB_ICONHAND | MB_OK);
// Reset the range.
ResetRange(*phCur); // Reset the index.
SetIndex(phCur, uStartIndex);
// Set the return value to RANGEERROR, which is
// defined in the header file.
ret = RANGEERROR;
}
else
{
ret = TRUE;
// Since there was no error than move one
// record forward to move past the crack
// that SetRange puts you at.
GetNextRec(*phCur);
}
}
else
{
ret = FALSE;
}
// Close the dialog and free the pointers.
// Dialog closed first because the pointers are used
// as part of the killfocus.
if(ret!=RANGEERROR)
{
EndDialog(hWnd, ret);
free(pLowRec);
free(pHighRec);
}
break;
case IDCANCEL:
EndDialog(hWnd, FALSE);
free(pLowRec);
free(pHighRec);
ret = TRUE;
// Set ret = TRUE to return a TRUE value to Windows.
break;
}
break;
}
return ret;
}
//======================================================================
// Function:
// SearchDlg(HWND hWnd, WORD msg, WORD wParam, LONG lParam)
//
// Input: hWnd - Handle to the Windwo
// msg - Message to process
// wParam - Word Parameter
// lParam - Double Word Parameter
// Also contains the pointer to the cursor during
// the WM_INITDIALOG.
//
// Return: TRUE - The Search was successful.
// FALSE - The search failed or user canceled the dilaog box.
//
// Description:
// This routine will process all I/O for the dialog that will
// search for a record in the table.
//======================================================================
BOOL FAR _pascal _export
SearchDlg (HWND hWnd, WORD msg, WORD wParam, LONG lParam)
{
BOOL ret = FALSE;
static BOOL ErrorRet = FALSE;
static phDBICur phCur;
static UINT16 uStartIndex;
CHAR cKey[FLDLENGTH];
UINT16 uSearch;
UINT32 uIndex;
UINT32 uSel;
DBIResult rslt;
char szString[220];
hErrorWnd = hWnd;
switch (msg)
{
case WM_INITDIALOG:
phCur = (phDBICur)lParam;
// Get original index and fill combobox with index list.
uStartIndex=FillDropList(hWnd, *phCur, IDE_SEARCH_COMBO);
// Set the field length to the appropriate size.
SetFieldLength(hWnd, uStartIndex, IDE_SEARCH, 0, FALSE);
// Set the Checkbox to Greater than or equal.
SendDlgItemMessage(hWnd, IDC_GREATEREQ, BM_SETCHECK,
(WPARAM)TRUE, 0L);
LoadString(hInst, IDS_SEARCH, szString, 220);
SetDlgItemText(hWnd, IDS_SEARCH_TEXT, (pCHAR)szString);
break;
case WM_COMMAND:
switch (wParam)
{
case IDE_SEARCH_COMBO:
switch(HIWORD(lParam))
{
case CBN_SELCHANGE:
// Get the new index that was chosen and set
// the edit control's limit to the index's
// limit.
uSel = SendDlgItemMessage(hWnd,
IDE_SEARCH_COMBO,
CB_GETCURSEL, 0, 0L);
uIndex = SendDlgItemMessage(hWnd,
IDE_SEARCH_COMBO,
CB_GETITEMDATA,
(WPARAM)uSel, 0L);
SetFieldLength(hWnd, (UINT16)uIndex,
IDE_SEARCH, 0, FALSE);
// Clear the edit control.
SendDlgItemMessage(hWnd, IDE_SEARCH,
WM_SETTEXT, 0, NULL);
break;
}
break;
case IDOK:
// Get the new index to search on.
uSel=SendDlgItemMessage(hWnd, IDE_SEARCH_COMBO,
CB_GETCURSEL, 0, 0L);
uIndex=SendDlgItemMessage(hWnd, IDE_SEARCH_COMBO,
CB_GETITEMDATA, (WPARAM)uSel,
0L);
// If it is the same as the original index do NOT
// reindex.
if(uStartIndex != uIndex)
{
SetIndex(phCur, (UINT16)uIndex);
}
GetDlgItemText(hWnd, IDE_SEARCH, cKey, FLDLENGTH);
uSearch = GetCond(hWnd); // Get the Condition checkbox.
// Search based upon the condition and the search
// string.
rslt = Search(*phCur, (DBISearchCond)uSearch,
(pBYTE)cKey);
if(rslt == DBIERR_NONE)
{
ret = TRUE;
ErrorRet = FALSE;
}
else
{
// Check if no match was found.
if (rslt == DBIERR_RECNOTFOUND)
{
MessageBox(hWnd, "Could not find a match",
"Search Error",
MB_ICONINFORMATION | MB_OK);
// Go to the first record as the failed search
// has left us at a the end of the table.
GoTop(*phCur, TRUE);
ErrorRet = TRUE;
}
}
if(!ErrorRet)
{
EndDialog(hWnd, ret);
}
break;
case IDCANCEL:
EndDialog(hWnd, FALSE);
break;
}
break;
}
return ret;
}
//======================================================================
// Function:
// FillStruct(RecordType *pRec, UINT16 OffSet)
//
// Input: pRec - Record structure pointer
// offSet - Starting Resource ID
//
// Return: TRUE - The structure is filled.
//
// Description:
// 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 OffSet)
{
// used to keep count of the resource ID
UINT16 j=IDS_ITEM_1 + (OffSet*uNumFields);
memset(pRec, 0, sizeof(RecordType));
// Get the string into the structure
LoadString(hInst, j++, (pCHAR)pRec->Item, sizeof(pRec->Item));
LoadString(hInst, j++, (pCHAR)pRec->ItemId, sizeof(pRec->ItemId));
LoadString(hInst, j++, (pCHAR)pRec->In_Stock, sizeof(pRec->In_Stock));
LoadString(hInst, j++, (pCHAR)pRec->Building, sizeof(pRec->Building));
LoadString(hInst, j++, (pCHAR)pRec->Cost, sizeof(pRec->Cost));
LoadString(hInst, j++, (pCHAR)pRec->DateD, sizeof(pRec->DateD));
LoadString(hInst, j++, (pCHAR)pRec->Message, sizeof(pRec->Message));
return TRUE;
}
//======================================================================
// Function:
// DisplayTable(hDBICur hCur)
//
// Input: hCur - Handle to the Cursor
//
// Return: TRUE - The record is displayed.
// FALSE - The record Structure allocation failed.
//
// Description:
// 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));
// Fill the structure with the record.
GetData(hCur, pRecord);
// Display the record.
DispRec(pRecord);
// Disable the buttons and menu options for Undo and Commit.
SetControl(ID_MOD_REC, FALSE);
SetControl(ID_UNDO_REC, FALSE);
SetItemFocus();
free(pRecord);
return TRUE;
}
//======================================================================
// Function:
// TableExist(pCHAR pTableInfo)
//
// Input: pTableInfo - Table's FULL name and path
//
// Return: TRUE - The table exists and IS NOT empty.
// FALSE - The table is empty or does not exist.
//
// Description:
// 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 pTableInfo)
{
BOOL RetVal;
INT16 iExist = 0;
hDBIDb hDb;
hDBICur hCur;
// Create the full path string of the table.
strcpy(pTableInfo, szTblDirectory);
strcat(pTableInfo, "\\");
strcat(pTableInfo, szTblName);
strcat(pTableInfo, ".db");
iExist = access(pTableInfo, 00); // Check if the table exists
if(iExist == -1)
{
RetVal = FALSE;
}
else
{
// It exists but we need to now if it is empty or not.
// So we get a handle to the cursor and the Database.
GetTable(&hDb, &hCur);
// Go to the top of the table but, DO NOT move a record forward.
// Rather stay at the crack and check if there is a record in
// the table.
GoTop(hCur, FALSE);
// Check if the table is empty.
if(AtEOF(hCur))
{
RetVal = FALSE;
}
else
{
RetVal = TRUE;
}
// Close up and return the bool RetVal.
CloseDb(&hDb);
}
return RetVal;
}
//======================================================================
// Function:
// FillTable(hDBICur hCur, phDBIDb phDb)
//
// Input: hCur - Handle to the Cursor
// phDb - Pointer to the Database handle
//
// Return: TRUE - The record was added to the table.
// FALSE - The record Structure allocation failed.
//
// Description:
// This function fills the table with all the strings that are
// in the resource file.
//======================================================================
BOOL
FillTable (hDBICur hCur, phDBIDb phDb)
{
RecordType *pRecord = NULL;
UINT16 i;
DBIResult rslt;
// 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;
}
// Loop through the amount of records of data that is sitting in the
// resource file.
for(i=0; i<uNumRecs; i++)
{
memset(pRecord, 0, sizeof(RecordType));
// Fill a structure with the data sitting in the resource file.
FillStruct(pRecord, i);
// Add the record to the table.
rslt = AddRecord(hCur, pRecord, TRUE);
if(rslt != DBIERR_NONE)
{
PostMessage(hMainWnd, WM_DISPLAY, 0, 0L);
}
}
free(pRecord);
CloseDb(phDb);
return TRUE;
}
//======================================================================
// Function:
// DispRec(RecordType *pRecord)
//
// Input: pRecord - Record structure pointer
//
// Return: TRUE - The record was displayed.
//
// Description:
// This function displays the data in the record structure
// into the main Window.
//======================================================================
BOOL
DispRec (RecordType *pRecord)
{
SetDlgItemText(hMainWnd, IDE_ITEM, pRecord->Item);
SetDlgItemText(hMainWnd, IDE_ITEMID, pRecord->ItemId);
SetDlgItemText(hMainWnd, IDE_NOINSTOCK, pRecord->In_Stock);
SetDlgItemText(hMainWnd, IDE_BUILDING, pRecord->Building);
SetDlgItemText(hMainWnd, IDE_COST, pRecord->Cost);
SetDlgItemText(hMainWnd, IDE_ORDERDATE, pRecord->DateD);
SetDlgItemText(hMainWnd, IDE_COMMENTS, pRecord->Message);
return TRUE;
}
//======================================================================
// Function:
// MoveRec(hDBICur hCur, INT16 Movement)
//
// Input: hCur - Handle to the Cursor
// Movement - Where to move the record
//
// Return: None.
//
// Description:
// This function moves the cursor to the bottom or the top
// of the table. Or it moves it a record forward or backwards.
//======================================================================
void
MoveRec (hDBICur hCur, INT16 Movement)
{
// 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))
{
switch(Movement)
{
// 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))
{
GetNextRec(hCur);
}
break;
case PREV_REC:
if(!AtBOF(hCur))
{
GetPrevRec(hCur);
}
break;
default:
return;
}
// After moving check the navigational controls and dsiplay the new
// record.
CheckButtons(hCur);
DisplayTable(hCur);
}
else
{
SetItemFocus();
}
}
//======================================================================
// Function:
// CheckButtons(hDBICur hCur)
//
// Input: hCur - Handle to the cursor
//
// Return: None.
//
// Description:
// 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);
}
SetItemFocus();
}
//======================================================================
// Function:
// SetupEdits()
//
// Input: None.
//
// Return: None.
//
// Description:
// This function sets the text input limit of each of the edit
// controls that are in the main window.
//======================================================================
void
SetupEdits (void)
{
// All the macros are the same macros used to create the table.
// Therefore we need to leave room for the '\0', so we use each
// macro -1.
SendDlgItemMessage(hMainWnd, IDE_ITEM, EM_LIMITTEXT,
(WPARAM)FLDLENGTH-1, 0L);
SendDlgItemMessage(hMainWnd, IDE_ITEMID, EM_LIMITTEXT,
(WPARAM)IDLENGTH-1, 0L);
SendDlgItemMessage(hMainWnd, IDE_NOINSTOCK, EM_LIMITTEXT,
(WPARAM)FLTLENGTH-1, 0L);
SendDlgItemMessage(hMainWnd, IDE_BUILDING, EM_LIMITTEXT,
(WPARAM)FLDLENGTH-1, 0L);
SendDlgItemMessage(hMainWnd, IDE_COST, EM_LIMITTEXT,
(WPARAM)FLTLENGTH-1, 0L);
SendDlgItemMessage(hMainWnd, IDE_ORDERDATE, EM_LIMITTEXT,
(WPARAM)DATELEN-1, 0L);
SendDlgItemMessage(hMainWnd, IDE_COMMENTS, EM_LIMITTEXT,
(WPARAM)COMMENTLEN-1, 0L);
// Disable the Cancel and OK buttons that are hidden.
EnableWindow(GetDlgItem(hMainWnd, IDCANCEL), FALSE);
EnableWindow(GetDlgItem(hMainWnd, IDOK), FALSE);
}
//======================================================================
// Function:
// SaveRec(hDBICur hCur, BOOL bAdd)
//
// Input: hCur - Handle to the cursor handle
// bAdd - Add or Overwrite bool
//
// Return: TRUE: If the memory is allocated.
// FALSE: If the memory allocation fails.
//
// Description:
// 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;
DBIResult rslt;
// 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.
rslt = AddRecord(hCur, pRecord, bAdd);
if(rslt != DBIERR_NONE)
{
PostMessage(hMainWnd, WM_DISPLAY, 0, 0L);
}
// Free pRecord and check the navigational controls.
free(pRecord);
CheckButtons(hCur);
return TRUE;
}
//======================================================================
// Function:
// GetRec(RecordType *pRecord)
//
// Input: pRecord - Record structure pointer
//
// Return: TRUE.
//
// Description:
// This function fills the record structure with the data that
// is in the main Window.
//======================================================================
BOOL
GetRec (RecordType *pRecord)
{
GetDlgItemText(hMainWnd, IDE_ITEM, pRecord->Item, FLDLENGTH);
GetDlgItemText(hMainWnd, IDE_ITEMID, pRecord->ItemId, IDLENGTH);
GetDlgItemText(hMainWnd, IDE_NOINSTOCK, pRecord->In_Stock, FLTLENGTH);
GetDlgItemText(hMainWnd, IDE_BUILDING, pRecord->Building, FLDLENGTH);
GetDlgItemText(hMainWnd, IDE_COST, pRecord->Cost, FLTLENGTH);
GetDlgItemText(hMainWnd, IDE_ORDERDATE, pRecord->DateD, DATELEN);
GetDlgItemText(hMainWnd, IDE_COMMENTS, pRecord->Message, COMMENTLEN);
return TRUE;
}
//======================================================================
// Function:
// FillDropList(HWND hWnd, hDBICur hCur, UINT16 Id)
//
// Input: hWnd - Window Handle
// hCur - Handle to the Cursor
// Id - Resource ID
//
// Return: The present index based upon the idxDesc array.
//
// Description:
// This function fills the combobox represented by Id with the
// list of indexes. Then it gets the current index and returns
// it.
//======================================================================
UINT16
FillDropList (HWND hWnd, hDBICur hCur, UINT16 Id)
{
UINT16 i; // used for loop counter
UINT32 uOff; //Index offset
UINT32 uIndex;
// Fill the combobox with all the indexes that are listed in the
// IndexList array. Then send the data item that represents the
// correct position of that index in the original array, so that
// we can sort the list and still retrieve the correct index.
for(i=0; i<uNumIndexes; i++)
{
uOff = SendDlgItemMessage(hWnd, Id, CB_ADDSTRING, 0,
(LPARAM)idxDesc[i].szName);
SendDlgItemMessage(hWnd, Id, CB_SETITEMDATA,
(WPARAM)uOff, (LPARAM)i);
}
// Get the Present index number.
i = GetIndexNum(hCur);
// Select that index from the combo box list.
uOff=SendDlgItemMessage(hWnd, Id, CB_SELECTSTRING, (WPARAM)-1,
(LPARAM)idxDesc[i].szName);
uIndex=SendDlgItemMessage(hWnd, Id, CB_GETITEMDATA,
(WPARAM)uOff, 0L);
// Set the description text into the static text box based upon
// the index's item data.
if(Id == IDE_ORDER_COMBOBOX)
{
SetWindowText(GetDlgItem(hWnd, IDE_ORDER_INFO),
IndexList[(UINT16)uIndex]);
}
// Return the current index.
return i;
}
//======================================================================
// Function:
// SetItemFocus()
//
// Input: None.
//
// Return: None.
//
// Description:
// This function sets focus to the 'Item' edit control of
// the main Window.
//======================================================================
void
SetItemFocus (void)
{
SetFocus(GetDlgItem(hMainWnd, IDE_ITEM));
}
//======================================================================
// Function:
// DeleteRecord(hDBICur hCur)
//
// Input: hCur - Handle to the cursor
//
// Return: TRUE: If the record is deleted.
// FALSE: If the record is not deleted.
//
// Description:
// 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 Flag = TRUE;
DeleteRec(hCur);
if(!AtEOF(hCur))
{
GetNextRec(hCur);
}
else
{
if(!AtBOF(hCur))
{
GetPrevRec(hCur);
}
else
{
// The table is now empty and disable the delete controls.
Flag = FALSE;
SetControl(ID_DEL_REC, FALSE);
}
}
// Redisplay the new record. If the table is empty, we will put up a
// blank screen into the main Window. Then check the navigational
// controls.
DisplayTable(hCur);
CheckButtons(hCur);
return Flag;
}
//======================================================================
// Function:
// SetControl(UINT16 Id, BOOL SetMod)
//
// Input: Id - Resource Id
// SetMod - Set bool
//
// Return: None.
//
// Description:
// This function sets the button and menu option of the Id to
// the bool value.
//======================================================================
void
SetControl (UINT16 Id, BOOL SetMod)
{
EnableWindow(GetDlgItem(hMainWnd, Id), SetMod);
if(SetMod)
{
EnableMenuItem(GetMenu(hMainWnd), Id, MF_ENABLED);
}
else
{
EnableMenuItem(GetMenu(hMainWnd), Id, MF_GRAYED);
}
}
//======================================================================
// Function:
// ClearDlg()
//
// Input: None.
//
// Return: TRUE: If the memory allocation was successful.
// FALSE: If the memory allocation was unsuccessful.
//
// Description:
// 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);
SetItemFocus();
free(pRecord);
return TRUE;
}
//======================================================================
// Function:
// verified()
//
// 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.
//
// Description:
// This function varifies if the data in the edit controls are
// valid.
//======================================================================
BOOL
verified (void)
{
DBIResult rslt; // Return value from IDAPI functions
pCHAR pItem; // Item data
pCHAR pItemId; // Item ID data
pCHAR pDate; // Date data
pCHAR val; // Temporary used in createing a date
BOOL RetVal; // Record Valid? True/False
UINT16 uItem; // Item Number
UINT16 uItemId; // Item ID
struct dosdate_t d; // Date
DATE TempDate; // Temporary date used in formatting
if((pItem = (pCHAR) malloc(IDLENGTH * sizeof(CHAR))) == NULL)
{
WinMsg("You have run out of memory!", MB_ICONHAND, MB_OK);
return FALSE;
}
if((pItemId = (pCHAR) malloc(FLDLENGTH * sizeof(CHAR))) == NULL)
{
WinMsg("You have run out of memory!", MB_ICONHAND, MB_OK);
return FALSE;
}
if((pDate = (pCHAR) malloc(DATELEN * sizeof(CHAR))) == NULL)
{
WinMsg("You have run out of memory!", MB_ICONHAND, MB_OK);
return FALSE;
}
uItem = GetDlgItemText(hMainWnd, IDE_ITEM, pItem, IDLENGTH);
uItemId = GetDlgItemText(hMainWnd, IDE_ITEMID, pItemId, FLDLENGTH);
// Check if there is data in the First and Last Name edit controls.
if((uItem > 0) && (uItemId >0))
{
// Make certain ItemId contains a valid value
if (atof(pItemId) == 0)
{
RetVal = FALSE;
}
else
{
RetVal = TRUE;
}
}
else
{
RetVal = FALSE;
}
GetDlgItemText(hMainWnd, IDE_ORDERDATE, pDate, DATELEN);
// Validate the Date if items are on order.
if (strcmp(pDate, szNoneOnOrder))
{
val = strtok(pDate, "-"); // Need to convert the string to a Date
// structure
if(val && RetVal)
{
d.month = atoi(val); // Date.da_day set to 0 if invalid date.
val = strtok(NULL, "-");
if(val && RetVal)
{
d.day = atoi(val); // Date.da_day set to 0 if invalid date.
val = strtok(NULL, "-");
if(val && RetVal)
{
d.year = atoi(val); // Date.da_year set to 0 if invalid
// date.
}
else
{
RetVal = FALSE;
}
}
else
{
RetVal = FALSE;
}
}
else
{
RetVal = FALSE;
}
if(RetVal)
{
// Check if the date is legal.
rslt = DateEncode(d.month, d.day, d.year, &TempDate);
if(rslt == DBIERR_NONE)
{
RetVal = TRUE;
}
else
{
RetVal = FALSE;
}
}
}
free((void*)pItem);
free((void*)pItemId);
free((void*)pDate);
return RetVal;
}
//======================================================================
// Function:
// SetDefaultDate()
//
// Input: None.
//
// Return: None.
//
// Description:
// This function puts the current date into the Last Date edit
// control so that we have a valid date to start.
//======================================================================
void
SetDefaultDate (void)
{
SetDlgItemText(hMainWnd, IDE_ORDERDATE, szNoneOnOrder);
}
//======================================================================
// Function:
// EndNewRec(hDBICur hCur
//
// Input: hCur - Handle to the cursor.
//
// Return: None.
//
// Description:
// This function is called during the end of Addind a new record.
// It changes the current state of the NewRecMode global
// variable. Then it checks the navigational controls and sets
// focus to the first edit control.
//======================================================================
void
EndNewRec (hDBICur hCur)
{
ChangeEntryMode();
DisplayTable(hCur);
CheckButtons(hCur);
SetItemFocus();
}
//======================================================================
// Function:
// PutField(RecordType *pRec, pCHAR Text, UINT16 MemberNum)
//
// Input: pRec - Record structure pointer
// Text - Pointer to the input text
// MemberNum - Array element number
//
// Return: None.
//
// Description:
// This function puts input text into the correct field of the
// record structure pointer based upon MemberNum.
//======================================================================
void
PutField (RecordType *pRec, pCHAR Text, UINT16 MemberNum)
{
switch(MemberNum)
{
case 0:
strcpy(pRec->ItemId, Text);
break;
case 1:
strcpy(pRec->In_Stock, Text);
break;
case 2:
strcpy(pRec->Item, Text);
break;
}
}
//======================================================================
// Function:
// GetField(RecordType *pRec, pCHAR Text, UINT16 MemberNum)
//
// Input: pRec - Record structure pointer
// Text - Pointer to the input text
// MemberNum - Array element number
//
// Return: None.
//
// Description:
// This function gets data from the field in the record structure,
// based upon the input variable - MemberNum.
//======================================================================
void
GetField (RecordType *pRec, pCHAR Text, UINT16 MemberNum)
{
switch(MemberNum)
{
case 0:
strcpy(Text, pRec->ItemId);
break;
case 1:
strcpy(Text, pRec->In_Stock);
break;
case 2:
strcpy(Text, pRec->Item);
break;
}
}
//======================================================================
// Function:
// SetFieldLength(HWND hWnd, UINT16 uSel, UINT16 Id1,
// UINT16 Id2, BOOL bTwo)
//
// Input: hWnd - Handle to the window
// uSel - Field Number
// Id1 - Resource ID1
// Id2 - Resource ID2
// bTwo - Bool of if there is a second ID
//
// Return: None.
//
// Description:
// This function sets the text input limit of the resource to a
// value based upon the Field Number (uSel).
//======================================================================
void
SetFieldLength (HWND hWnd, UINT16 uSel, UINT16 Id1, UINT16 Id2, BOOL bTwo)
{
UINT16 LimitLen;
switch(uSel)
{
case 0:
LimitLen = IDLENGTH;
break;
case 1:
case 2:
LimitLen = FLDLENGTH;
break;
case 3:
case 4:
LimitLen = FLTLENGTH;
break;
}
// Set the limit and if there is a second resource id set that one
// too.
SendDlgItemMessage(hWnd, Id1, EM_LIMITTEXT, (WPARAM)LimitLen-1, 0L);
if(bTwo)
{
SendDlgItemMessage(hWnd, Id2, EM_LIMITTEXT, (WPARAM)LimitLen-1,
0L);
}
}
//======================================================================
// Function:
// GetCond(HWND hWnd)
//
// Input: hWnd - Handle to the window that has the check boxes.
//
// Return: Which check box is checked.
//
// Description:
// This function simply returns a number based upon which check
// box is checked.
//======================================================================
UINT16
GetCond (HWND hWnd)
{
UINT32 Ret=0;
UINT16 i=IDC_GREATEREQ;
while(Ret!=1)
{
Ret = SendDlgItemMessage(hWnd, i, BM_GETCHECK, 0, 0L);
i++;
}
// Subtract 1 to counteract the last i++
i--;
switch(i)
{
case IDC_EQUAL:
Ret = keySEARCHEQ;
break;
case IDC_GREATER:
Ret = keySEARCHGT;
break;
case IDC_GREATEREQ:
Ret = keySEARCHGEQ;
break;
}
return (UINT16)Ret;
}
//======================================================================
// Function:
// GetCond(pCHAR pString, UINT16 uId)
//
// Input: pString - Pointer to the string that is to be displayed
// uId - resource ID
//
// Return: If the resource is enabled, then it returns the user's
// response. Otherwise, it returns a TRUE.
//
// Description:
// 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 pString, UINT16 uId)
{
BOOL RetVal = TRUE;
// Check to see if the button is enabled.
if(IsWindowEnabled(GetDlgItem(hMainWnd, uId)))
{
if(WinMsg(pString, MB_ICONHAND, MB_YESNO) == IDNO)
{
RetVal = FALSE;
}
}
return RetVal;
}