home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windoware
/
WINDOWARE_1_6.iso
/
source
/
cdbw
/
sclient.c
< prev
next >
Wrap
Text File
|
1991-05-16
|
20KB
|
669 lines
/*
* SCLIENT.C
*
* This module contains functions associated with the client dialog box
* in SAMPLE.EXE.
*
* Copyright (C) 1991 by Daytris. All rights reserved.
*/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#ifndef ZORTECH
#include <memory.h>
#endif
#include "dbmgr.h"
#include "sampledb.h"
#include "sample.h"
/************************************************
* Local data
************************************************/
static CLIENT client;
static enum
{
MODE_ADD,
MODE_UPDATE,
MODE_DELETE
} eMode;
static BOOL bAddressChange;
static HANDLE hAddresses;
/************************************************
* Function Declarations
************************************************/
BOOL AddClientDlg( HWND hWnd);
BOOL UpdateClientDlg( HWND hWnd);
BOOL DeleteClientDlg( HWND hWnd);
static BOOL GetSelectedClient( HWND hWnd, CLIENT *pClient, short *pIndexSel);
static BOOL AddClientAddresses( HWND hWnd);
static BOOL DeleteClientAddresses( HWND hWnd);
static BOOL FreeClientAddresses( HWND hWnd);
BOOL FAR PASCAL ClientProc( HWND hDlg, unsigned iMessage, WORD wParam,
LONG lParam);
static void SetClientFields( HWND hDlg);
static BOOL GetClientFields( HWND hDlg);
static BOOL StoreAddressHandles( HWND hDlg);
/***************************************************************************
* Function : AddClientDlg
*
* Purpose : This function drives the add client dialog box.
*
* Returns : TRUE - client added
* FALSE - add aborted or error in add
***************************************************************************/
BOOL AddClientDlg( HANDLE hWnd)
{
short nStatus;
DWORD dwStatus;
FARPROC lpfnClientProc;
/* Set static variables */
eMode = MODE_ADD;
bAddressChange = FALSE;
/* Initialize the client structure */
memset( &client, 0, sizeof( CLIENT));
client.lClientNbr = setup.lNextClientNbr;
/* Create an instance and open the Client window */
lpfnClientProc = MakeProcInstance( ClientProc, hInst);
nStatus = DialogBox( hInst, "client", hWnd, lpfnClientProc);
FreeProcInstance( lpfnClientProc);
/* User selected OK */
if( nStatus == IDOK)
{
/* Add the client */
if( dwStatus = XDbRecordAdd( hDb, "client", &client,
sizeof( CLIENT)) )
{
DbError( hWnd, dwStatus, __FILE__, __LINE__);
return FALSE;
}
/* Add the member addresses */
if( bAddressChange)
{
if( ! AddClientAddresses( hWnd))
return FALSE;
}
/* Increment the client number counter and update the setup
record */
setup.lNextClientNbr++;
if( dwStatus = XDbRecordUpdate( hDb, "setup", &setup,
sizeof( SETUP)))
{
DbError( hWnd, dwStatus, __FILE__, __LINE__);
return FALSE;
}
/* Flush the database */
DbFlush( hDb);
/* Add the client to the list box */
AddToClientListBox( hWnd, &client);
}
else /* IDCANCEL */
{
/* Free all address handles for this client */
if( ! FreeClientAddresses( hWnd))
return FALSE;
}
return TRUE;
}
/***************************************************************************
* Function : UpdateClientDlg
*
* Purpose : This function drives the add client dialog box.
*
* Returns : TRUE - client added
* FALSE - update aborted or error in update
***************************************************************************/
BOOL UpdateClientDlg( HANDLE hWnd)
{
short nStatus, nIndex;
DWORD dwStatus;
FARPROC lpfnClientProc;
/* Set the mode */
eMode = MODE_UPDATE;
/* Initialize the client structure */
if( ! GetSelectedClient( hWnd, &client, &nIndex))
{
MessageBeep( 0);
return FALSE;
}
/* Create an instance and open the Client window */
lpfnClientProc = MakeProcInstance( ClientProc, hInst);
nStatus = DialogBox( hInst, "client", hWnd, lpfnClientProc);
FreeProcInstance( lpfnClientProc);
/* User selected OK */
if( nStatus == IDOK)
{
/* Update the client */
if( dwStatus = XDbRecordUpdate( hDb, "client", &client,
sizeof( CLIENT)) )
{
DbError( hWnd, dwStatus, __FILE__, __LINE__);
return FALSE;
}
/* If any address has changed, delete all member addresses and
add addresses in handle table. */
if( bAddressChange)
{
if( ! DeleteClientAddresses( hWnd))
return FALSE;
if( ! AddClientAddresses( hWnd))
return FALSE;
}
/* Flush the database */
DbFlush( hDb);
/* Update the listbox */
DeleteFromClientListBox( hWnd, nIndex);
AddToClientListBox( hWnd, &client);
}
else /* IDCANCEL */
{
/* Free all address handles for this client */
if( ! FreeClientAddresses( hWnd))
return FALSE;
}
return TRUE;
}
/***************************************************************************
* Function : DeleteClientDlg
*
* Purpose : This function drives the client record deletion process.
*
* Returns : TRUE - client deleted
* FALSE - delete aborted or error in delete
***************************************************************************/
BOOL DeleteClientDlg( HWND hWnd)
{
short nStatus, nIndex;
DWORD dwStatus;
/* Initialize the client structure */
if( ! GetSelectedClient( hWnd, &client, &nIndex))
{
MessageBeep( 0);
return FALSE;
}
/* Ask user if they're sure */
nStatus = MessageBox( hWnd, "Are you sure?", "Delete Client",
MB_ICONQUESTION | MB_YESNO);
/* User selected YES */
if( nStatus == IDYES)
{
/* Delete all member addresses */
if( ! DeleteClientAddresses( hWnd))
return FALSE;
/* Delete the client */
if( dwStatus = DbRecordDelete( hDb, "client"))
{
DbError( hWnd, dwStatus, __FILE__, __LINE__);
return FALSE;
}
/* Flush the database */
DbFlush( hDb);
/* Remove client from listbox */
if( ! DeleteFromClientListBox( hWnd, nIndex))
return FALSE;
}
return TRUE;
}
/***************************************************************************
* Function : GetSelectedClient
*
* Purpose : This function retrieves the selected client record from
* the database. It uses the client number in the string
* of the listbox as a key value to retrieve upon. The
* listbox index is also returned.
*
* Returns : TRUE - client retrieved
* FALSE - error
***************************************************************************/
static BOOL GetSelectedClient( HWND hWnd, CLIENT *pClient, short *pIndex)
{
LONG lKey;
DWORD dwStatus;
char szBuffer[64], *pTemp;
/* Get the listbox selection */
if( (*pIndex = (short)SendMessage( hWndClientLB, LB_GETCURSEL, 0, 0L))
== LB_ERR)
{
return FALSE;
}
if( SendMessage( hWndClientLB, LB_GETTEXT, *pIndex,
(LONG)(LPSTR)szBuffer) == LB_ERR)
{
MessageBox( hWnd, "SendMessage / LB_GETTEXT", "Fatal Error",
MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
/* Find the client number in the selected string */
if( bSortByNumber)
pTemp = strtok( szBuffer, " ");
else
{
pTemp = strchr( szBuffer, 0);
for( pTemp-- ; *pTemp != ' ' ; pTemp--)
;
pTemp++;
}
lKey = atol( pTemp);
/* Retrieve the record */
if( dwStatus = XDbRecordGetByKey( hDb, "client", "lClientNbr", pClient,
sizeof( CLIENT), &lKey, sizeof( LONG)))
{
DbError( hWnd, dwStatus, __FILE__, __LINE__);
return FALSE;
}
return TRUE;
}
/***************************************************************************
* Function : AddClientAddresses
*
* Purpose : This function adds the addresses associated with the client
* record. A base handle, 'hAddresses', contains a null
* terminated array of address handles (records) to be added.
*
* Returns : TRUE - add ok
* FALSE - error in add
***************************************************************************/
static BOOL AddClientAddresses( HWND hWnd)
{
HANDLE FAR *lpAddressHandle;
DWORD dwStatus;
/* If no addresses, return */
if( ! hAddresses)
return TRUE;
/* Get a pointer to the array of address handles */
if( ! (lpAddressHandle = (HANDLE FAR *)GlobalLock( hAddresses)))
{
MessageBox( hWnd, "Memory: GlobalLock", "Fatal Error",
MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
for( ; *lpAddressHandle ; lpAddressHandle++)
{
/* Add the address record */
if( dwStatus = DbRecordAdd( hDb, "address", *lpAddressHandle))
{
DbError( hWnd, dwStatus, __FILE__, __LINE__);
return FALSE;
}
/* Make a set connection between the client and address. The
address record will be a member of the client. */
if( dwStatus = DbSetAdd( hDb, "client", "address"))
{
DbError( hWnd, dwStatus, __FILE__, __LINE__);
return FALSE;
}
/* Free the address handle */
if( GlobalFree( *lpAddressHandle))
{
MessageBox( hWnd, "Memory: GlobalFree", "Fatal Error",
MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
}
/* Unlock and free the array of address handles */
GlobalUnlock( hAddresses);
if( GlobalFree( hAddresses))
{
MessageBox( hWnd, "Memory: GlobalFree", "Fatal Error",
MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
return TRUE;
}
/***************************************************************************
* Function : DeleteClientAddresses
*
* Purpose : This function deletes all address records that are members
* of the selected client.
*
* Returns : TRUE - delete ok
* FALSE - error in delete
***************************************************************************/
static BOOL DeleteClientAddresses( HWND hWnd)
{
DWORD dwStatus;
while( 1)
{
/* Set currency to first member record in the set */
dwStatus = DbSetFindFirst( hDb, "client", "address");
/* Check for errors */
if( dwStatus == E_NOTFOUND)
break;
if( dwStatus)
{
DbError( hWnd, dwStatus, __FILE__, __LINE__);
return FALSE;
}
/* IMPORTANT: All set connections must be deleted before the member
record of a set is deleted */
/* Delete the set connection between client (owner) and address
(member) */
if( dwStatus = DbSetDelete( hDb, "client", "address"))
{
DbError( hWnd, dwStatus, __FILE__, __LINE__);
return FALSE;
}
/* Delete the address record */
if( dwStatus = DbRecordDelete( hDb, "address"))
{
DbError( hWnd, dwStatus, __FILE__, __LINE__);
return FALSE;
}
}
return TRUE;
}
/***************************************************************************
* Function : FreeClientAddresses
*
* Purpose : This function frees all addresses associated with the
* selected client. 'hAddresses' contains a handle to
* a null terminated array of address handles in the listbox.
*
* Returns : TRUE - free ok
* FALSE - error in free
***************************************************************************/
static BOOL FreeClientAddresses( HWND hWnd)
{
HANDLE FAR *lpAddressHandle;
/* If no addresses, return */
if( ! hAddresses)
return TRUE;
/* Get a pointer to the array of address handles */
if( ! (lpAddressHandle = (HANDLE FAR *)GlobalLock( hAddresses)))
{
MessageBox( hWnd, "Memory: GlobalLock", "Fatal Error",
MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
for( ; *lpAddressHandle ; lpAddressHandle++)
{
/* Free the address handle */
if( GlobalFree( *lpAddressHandle))
{
MessageBox( hWnd, "Memory: GlobalFree", "Fatal Error",
MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
}
/* Unlock and free the array of address handles */
GlobalUnlock( hAddresses);
if( GlobalFree( hAddresses))
{
MessageBox( hWnd, "Memory: GlobalFree", "Fatal Error",
MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
return TRUE;
}
/***************************************************************************
* Function : ClientProc
*
* Purpose : This function is the window procedure for 'add' and 'update'
* client.
*
* Returns : TRUE - message processed
* FALSE - message not processed
***************************************************************************/
BOOL FAR PASCAL ClientProc( HWND hDlg, unsigned iMessage, WORD wParam,
LONG lParam)
{
switch( iMessage)
{
case WM_INITDIALOG:
{
short nTab;
if( eMode == MODE_ADD)
SetWindowText( hDlg, "Add Client");
else
SetWindowText( hDlg, "Update Client");
/* Set a tab stop in the listbox out of sight. The handle
to the ADDRESS structure will be stored here (in ASCII) */
nTab = (LOWORD( GetDialogBaseUnits()) * 100) / 4;
SendDlgItemMessage( hDlg, IDC_ADDR_LISTBOX, LB_SETTABSTOPS, 1,
(LONG)(LPSTR)&nTab);
SetClientFields( hDlg);
/* If update mode, load the address listbox */
if( eMode == MODE_UPDATE)
LoadAddressListBox( hDlg);
/* Set focus to Name field */
SetFocus( GetDlgItem( hDlg, IDC_EDIT_NAME));
return TRUE;
}
case WM_COMMAND:
switch( wParam)
{
case IDOK:
if( ! GetClientFields( hDlg))
break;
StoreAddressHandles( hDlg);
EndDialog( hDlg, IDOK);
break;
case IDCANCEL:
StoreAddressHandles( hDlg);
EndDialog( hDlg, IDCANCEL);
break;
case IDC_ADD_ADDR:
if( AddAddressDlg( hDlg))
bAddressChange = TRUE;
break;
case IDC_UPDATE_ADDR:
if( UpdateAddressDlg( hDlg))
bAddressChange = TRUE;
break;
case IDC_DELETE_ADDR:
if( DeleteAddressDlg( hDlg))
bAddressChange = TRUE;
break;
}
return TRUE;
}
return FALSE;
}
/***************************************************************************
* Function : SetClientFields
*
* Purpose : This function initializes the client dialog fields. It
* uses the static 'client' structure.
*
* Returns : n/a
***************************************************************************/
static void SetClientFields( HWND hDlg)
{
char szBuffer[36];
/* Set client number */
ltoa( client.lClientNbr, szBuffer, 10);
SetDlgItemText( hDlg, IDC_EDIT_NUMBER , szBuffer);
/* Set client name */
SendDlgItemMessage( hDlg, IDC_EDIT_NUMBER, EM_LIMITTEXT,
sizeof( client.szName) - 1, 0L);
SetDlgItemText( hDlg, IDC_EDIT_NAME, client.szName);
/* Set client description */
SendDlgItemMessage( hDlg, IDC_EDIT_DESC, EM_LIMITTEXT,
sizeof( client.szDescription) - 1, 0L);
SetDlgItemText( hDlg, IDC_EDIT_DESC, client.szDescription);
/* Set client balance */
sprintf( szBuffer, "%.2f", client.dBalance);
SendDlgItemMessage( hDlg, IDC_EDIT_BALANCE, EM_LIMITTEXT, 10, 0L);
SetDlgItemText( hDlg, IDC_EDIT_BALANCE, szBuffer);
}
/***************************************************************************
* Function : GetClientFields
*
* Purpose : This function retrieves the client dialog fields. It
* also performs minor field error checking. Client fields
* are stored in the static 'client' structure.
*
* Returns : TRUE - fields ok
* FALSE - error in field (focus is set)
***************************************************************************/
static BOOL GetClientFields( HWND hDlg)
{
char szBuffer[36];
GetDlgItemText( hDlg, IDC_EDIT_NAME, client.szName,
sizeof( client.szName));
GetDlgItemText( hDlg, IDC_EDIT_DESC, client.szDescription,
sizeof( client.szDescription));
GetDlgItemText( hDlg, IDC_EDIT_BALANCE, szBuffer, sizeof( szBuffer));
client.dBalance = atof( szBuffer);
/* Name field required */
if( ! *client.szName)
{
MessageBox( hDlg, "Name required", "Invalid Input",
MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
/* Set focus to Name field */
SetFocus( GetDlgItem( hDlg, IDC_EDIT_NAME));
return FALSE;
}
return TRUE;
}
/***************************************************************************
* Function : StoreAddressFields
*
* Purpose : This function stores all the address handles associated
* with a client in a null-terminated array. 'hAddresses'
* contains a handle to the array.
*
* Returns : TRUE - address handles stored
* FALSE - error
***************************************************************************/
static BOOL StoreAddressHandles( HWND hDlg)
{
short nCount, i;
HANDLE FAR *lpAddressHandle;
/* Set handle to address handle array to NULL */
hAddresses = NULL;
/* Get the number of addresses in listbox */
nCount = (short)SendMessage( GetDlgItem( hDlg, IDC_ADDR_LISTBOX), LB_GETCOUNT,
0, 0L);
if( ! nCount)
return TRUE;
/* Allocate space to store address handles. Leave last entry NULL
to trigger end of addresses. */
if( ! (hAddresses = GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT,
(DWORD)(sizeof( HANDLE) * (nCount + 1)))) )
{
MessageBox( hDlg, "Out of memory", "Fatal Error",
MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
/* Lock handle */
if( ! (lpAddressHandle = (HANDLE FAR *)GlobalLock( hAddresses)) )
{
MessageBox( hDlg, "Memory: GlobalLock", "Fatal Error",
MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
/* Get each address handle and store it */
for( i=0 ; i<nCount ; i++)
{
*lpAddressHandle = GetAddressHandle( hDlg, i);
if( ! *lpAddressHandle)
return FALSE;
lpAddressHandle++;
}
/* Unlock handle */
GlobalUnlock( hAddresses);
return TRUE;
}