October 06, 2022, 09:59:52 AM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


Address book example

Started by Ionic Wind Support Team, February 18, 2006, 01:16:39 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Ionic Wind Support Team

Something to learn from.  A complete addressbook using the database class and lots of dialog stuff.


#autodefine "off"
import int EnableWindow(unsigned int hwnd,int bEnable);
//constants for menus and controls
#define IDE_FIRST 10
#define IDE_STREET1 12
#define IDE_LAST 11
#define IDE_STREET2 13
#define IDE_CITY 14
#define IDE_STATE 15
#define IDE_POSTAL 16
#define IDE_PHONE 17
#define IDE_EMAIL 18
#define IDB_PREV 30
#define IDB_NEXT 31
#define IDS_RECNO 37
#define IDS_RECID 35
#define IDB_UPDATE 32
#define IDB_NEW 33
#define IDM_QUIT 100
#define IDM_NEW 33
#define IDM_UPDATE 32
#define IDM_DELETE 34

class AddressBook:CDialog
{
//the class constructor
declare AddressBook();
//virtual overrides
declare OnInitDialog(),int;
declare OnClose(),int;
declare OnControl(int nID, int nNotifyCode, unsigned int hControl),int;
declare OnMenuInit(unsigned int hMenu),int;
declare OnMenuPick(int nID),int;
declare OnTimer(int nIDEvent),int;
//methods
declare UpdateData(int bDirection);
declare OpenDatabase(),int;
declare CloseAll();
declare SetupControls();
declare DoUpdate();
declare DoNew();
declare DoDelete();
declare DoIdle();
declare InitSelect();
//member variables
//variables for recieving and updating
dstring m_lname[41],m_fname[41],m_street[256],m_street2[256],m_city[41],m_state[11],
m_phone[21],m_email[256],m_zipcode[10],m_date[41];

int m_id,m_count;
int hstmt_select,hstmt_update,hstmt_insert,hstmt_delete;
//The database object
CDatabase m_db;
//for future use
string m_filter;
//to mark a new entry as unsaved
int m_bDirty;
//access to control classes
CEdit *m_editFirst,*m_editLast,*m_editStreet1,*m_editStreet2,
*m_editCity,*m_editState,*m_editPostal,*m_editEmail,
*m_editPhone;
CStatic *m_staticID,*m_staticRECNO;
CButton *m_buttonNext,*m_buttonPrev,*m_buttonUpdate;
}

global sub main()
{
AddressBook mainwin;
mainwin.Create(0,0,505,273,0x80CA0080,0,"The Address Book",0);
mainwin.AddControl(CTEDIT,"",99,24,130,20,0x50810080,0x200,IDE_FIRST);
mainwin.AddControl(CTEDIT,"",300,24,130,20,0x50810080,0x200,IDE_LAST);
mainwin.AddControl(CTEDIT,"",99,51,331,20,0x50810080,0x200,IDE_STREET1);
mainwin.AddControl(CTEDIT,"",99,78,331,20,0x50810080,0x200,IDE_STREET2);
mainwin.AddControl(CTSTATIC,"First Name",39,27,57,17,0x5000010B,0x0,25);
mainwin.AddControl(CTSTATIC,"Last Name",241,28,55,18,0x5000010B,0x0,27);
mainwin.AddControl(CTSTATIC,"Street1",54,54,38,17,0x5000010B,0x0,23);
mainwin.AddControl(CTSTATIC,"Street2",54,83,38,17,0x5000010B,0x0,20);
mainwin.AddControl(CTEDIT,"",99,105,130,20,0x50810080,0x200,IDE_CITY);
mainwin.AddControl(CTSTATIC,"City",68,110,24,17,0x5000010B,0x0,19);
mainwin.AddControl(CTEDIT,"",314,105,116,20,0x50810080,0x200,IDE_STATE);
mainwin.AddControl(CTSTATIC,"State/Province",237,108,76,17,0x5000010B,0x0,21);
mainwin.AddControl(CTSTATIC,"Postal Code",30,136,62,17,0x5000010B,0x0,22);
mainwin.AddControl(CTEDIT,"",99,133,130,20,0x50810080,0x200,IDE_POSTAL);
mainwin.AddControl(CTSTATIC,"Phone",237,137,39,17,0x5000010B,0x0,24);
mainwin.AddControl(CTEDIT,"",278,133,152,20,0x50810080,0x200,IDE_PHONE);
mainwin.AddControl(CTSTATIC,"Email Address",20,163,74,17,0x5000010B,0x0,26);
mainwin.AddControl(CTEDIT,"",99,160,331,20,0x50810080,0x200,IDE_EMAIL);
mainwin.AddControl(CTBUTTON,"<<",75,222,70,20,0x5000000B,0x0,IDB_PREV);
mainwin.AddControl(CTBUTTON,">>",154,222,70,20,0x5000000B,0x0,IDB_NEXT);
mainwin.AddControl(CTSTATIC,"Number of Records:",67,192,97,17,0x5000010B,0x0,36);
mainwin.AddControl(CTSTATIC,"REC_NO",167,193,70,15,0x50000000,0x0,IDS_RECNO);
mainwin.AddControl(CTSTATIC,"Record ID:",269,192,59,17,0x5000010B,0x0,34);
mainwin.AddControl(CTSTATIC,"REC_ID",325,192,70,17,0x50000000,0x0,IDS_RECID);
mainwin.AddControl(CTBUTTON,"Update",280,222,70,20,0x5000000B,0x0,IDB_UPDATE);
mainwin.AddControl(CTBUTTON,"New",359,222,70,20,0x5000000B,0x0,IDB_NEW);

mainwin.ShowDialog();
do{wait();}until mainwin.m_hwnd = 0;
return 0;
}

AddressBook::AddressBook()
{
m_bDirty = false;
hstmt_select = NULL;
hstmt_update = NULL;
hstmt_insert = NULL;
hstmt_delete = NULL;
m_lname = "";
m_fname = "";
m_street = "";
m_street2 = "";
m_city = "";
m_state = "";
m_zipcode = "";
m_email = "";
m_phone = "";
m_date = "";
m_filter = "";
m_id = 0;
m_count = 0;
}

AddressBook::OnClose(),int
{
if m_bDirty DoUpdate();
CloseAll();
return true;
}

AddressBook::OnInitDialog(),int
{
//add the menu
menu m;
m.BeginMenu();
m.MenuTitle( "&File");
m.MenuItem( "&Quit",0,IDM_QUIT);
m.MenuTitle( "&Edit");
m.MenuItem( "&Update",0,IDM_UPDATE);
m.MenuItem( "&New",0,IDM_NEW);
m.MenuItem( "&Delete",0,IDM_DELETE);
m.EndMenu();
SetMenu(m.Detach());
/* Initialize any controls here */
m_editFirst = GetControl(IDE_FIRST);
m_editLast = GetControl(IDE_LAST);
m_editStreet1 = GetControl(IDE_STREET1);
m_editStreet2 = GetControl(IDE_STREET2);
m_editCity = GetControl(IDE_CITY);
m_editState = GetControl(IDE_STATE);
m_editPostal = GetControl(IDE_POSTAL);
m_editEmail = GetControl(IDE_EMAIL);
m_editPhone = GetControl(IDE_PHONE);
m_staticID = GetControl(IDS_RECID);
m_staticRECNO = GetControl(IDS_RECNO);
m_buttonUpdate = GetControl(IDB_UPDATE);
m_buttonNext = GetControl(IDB_NEXT);
m_buttonPrev = GetControl(IDB_PREV);
CenterWindow();
//open our database
if(OpenDatabase() = 0)
return false;
SetupControls();
if(hstmt_select) m_db.GetFirst(hstmt_select);
UpdateData(1);
//start the idle time
StartTimer(1000);
return true;
}

AddressBook::OnTimer(int nIDEvent),int
{
DoIdle();
return True;
}

AddressBook::OnControl(int nID, int nNotifyCode, unsigned int hControl),int
{
select nID
{
case IDE_FIRST:
case& IDE_STREET1:
case& IDE_LAST:
case& IDE_STREET2:
case& IDE_CITY:
case& IDE_STATE:
case& IDE_POSTAL:
case& IDE_PHONE:
case& IDE_EMAIL:
/* respond to edit notifications here */
if nNotifyCode = ENCHANGE
m_bDirty = TRUE;
case IDB_PREV:
if(nNotifyCode = 0)
{
/*button clicked*/
IF m_bDirty DoUpdate();
if(hstmt_select)
{
if m_db.GetPrev(hstmt_select)
EnableWindow(m_buttonNext->m_hWnd,1)
else
{
m_db.GetFirst(hstmt_select);
EnableWindow(m_buttonPrev->m_hWnd,0);
}
UpdateData(1);
}
}
case IDB_NEXT:
if(nNotifyCode = 0)
{
/*button clicked*/
IF m_bDirty DoUpdate();
if(hstmt_select)
{
if m_db.GetNext(hstmt_select)
EnableWindow(m_buttonPrev->m_hWnd,1)
else
{
m_db.GetLast(hstmt_select);
EnableWindow(m_buttonNext->m_hWnd,0);
}
UpdateData(1);
}
}
case IDB_UPDATE:
if(nNotifyCode = 0)
{
/*button clicked*/
DoUpdate();
}
case IDB_NEW:
if(nNotifyCode = 0)
{
IF m_bDirty DoUpdate();
DoNew();
/*button clicked*/
}
}
return true;
}

AddressBook::OnMenuPick(int nID),int
{
select(nID)
{
case IDM_QUIT:
IF m_bDirty DoUpdate();
CloseAll();
case IDM_DELETE:
DoDelete();
case IDM_NEW:
DoNew();
case IDM_UPDATE:
DoUpdate();
}
return true;
}

AddressBook::OnMenuInit(unsigned int hMenu),int
{
menu m;
m.Attach(hMenu);
m.EnableMenuItem(IDM_UPDATE,m_bDirty);
m.EnableMenuItem(IDM_DELETE,m_count <> 0);
m.Detach();
return true;
}

AddressBook::UpdateData(int bDirection),int
{
IF bDirection = 1
{
//from variables to edit controls
m_staticID->SetText(TrimLeft(NumToStr(m_id)));
m_staticRECNO->SetText(TrimLeft(NumToStr(m_count)));
m_editFirst->SetText(m_fname);
m_editLast->SetText(m_lname);
m_editStreet1->SetText(m_street);
m_editStreet2->SetText(m_street2);
m_editCity->SetText(m_city);
m_editState->SetText(m_state);
m_editPostal->SetText(m_zipcode);
m_editPhone->SetText(m_phone);
m_editEmail->SetText(m_email);
//setting a controls text also sends the ENCHANGE notification
//so mark the form as not modified
m_bDirty = FALSE;
}
else
{
//from edit controls to variables
m_id = StrToNum(m_staticID->GetText());
m_fname = m_editFirst->GetText();
m_lname = m_editLast->GetText();
m_street = m_editStreet1->GetText();
m_street2 = m_editStreet2->GetText();
m_city = m_editCity->GetText();
m_state = m_editState->GetText();
m_zipcode = m_editPostal->GetText();
m_phone = m_editPhone->GetText();
m_email = m_editEmail->GetText();
}
}

AddressBook::OpenDatabase(),int
{
int nReturn = 0;
unsigned int hStmt=0;
nReturn = m_db.Connect("Microsoft Access Driver (*.mdb)",GetStartPath() + "addressbook.mdb","",this);
IF nReturn = 0
{
//couldn't open so try creating
m_db.CreateMDB(GetStartPath() + "addressbook.mdb");
nReturn = m_db.Connect("Microsoft Access Driver (*.mdb)",GetStartPath() + "addressbook.mdb","",this);
IF nReturn
{
//add a table
hStmt = m_db.ExecSQL("CREATE TABLE addresses (id counter(1,1),fname varchar(40),lname varchar(40),street varchar(255),street2 varchar(255) )");
//check for errors
IF LEN(m_db.GetErrorCode(hstmt))
MessageBox( this,m_db.GetErrorText(hstmt),m_db.GetErrorCode(hstmt));
m_db.FreeSQL(hStmt);
//alter the table
hStmt = m_db.ExecSQL("ALTER TABLE addresses ADD city varchar(40),state varchar(10),zip varchar(9),phone varchar(20),email varchar(255),dtadded date");
//check for errors
IF LEN(m_db.GetErrorCode(hstmt))
MessageBox(this,m_db.GetErrorText(hstmt),m_db.GetErrorCode(hstmt));
m_db.FreeSQL(hstmt);
}
ELSE
MessageBox(this,"Could not connect/create database","Error");


}
//are we open?
IF nReturn
//get the initial count of records
m_count = m_db.Cardinality("addresses");

RETURN nReturn;
}

AddressBook::CloseAll()
{
//check and close all statments just to be on the safe side
IF hstmt_select
m_db.FreeSQL(hstmt_select);
IF hstmt_update
m_db.FreeSQL(hstmt_update);
IF hstmt_insert
m_db.FreeSQL(hstmt_insert);
IF hstmt_delete
m_db.FreeSQL(hstmt_delete);
IF m_db.m_hDBC <> NULL
m_db.Disconnect();
StopTimer();
CloseDialog(1);
}

AddressBook::SetupControls()
{
m_staticRECNO->SetText(TrimLeft(NumToStr(m_count)));
EnableWindow(m_buttonUpdate->m_hWnd,0);

IF m_count = 0
{
EnableWindow(m_buttonPrev->m_hWnd,0);
EnableWindow(m_buttonNext->m_hWnd,0);
DoIdle();
}
ELSE
{
EnableWindow(m_buttonPrev->m_hWnd,0);
InitSelect();
}
m_editFirst->SetLimitText(40);
m_editLast->SetLimitText(40);
m_editStreet1->SetLimitText(255);
m_editStreet2->SetLimitText(255);
m_editCity->SetLimitText(40);
m_editState->SetLimitText(10);
m_editPostal->SetLimitText(9);
m_editPhone->SetLimitText(20);
m_editEmail->SetLimitText(255);
}

AddressBook::DoNew()
{
//insert a blank record
IF hstmt_select
m_db.FreeSQL(hstmt_select);
hstmt_select = NULL;
hstmt_insert = m_db.ExecSQL("INSERT INTO addresses (fname,lname,street,street2,city,state,zip,phone,email) VALUES('','','','','','','','','')");
m_db.FreeSQL(hstmt_insert);
hstmt_insert = NULL;
m_count = m_db.Cardinality("addresses");
InitSelect();
m_db.GetLast(hstmt_select);
UpdateData(1);
EnableWindow(m_buttonNext->m_hWnd,0);
EnableWindow(m_buttonPrev->m_hWnd,1);
EnableWindow(m_buttonUpdate->m_hWnd,1);
//make sure the edit controls are enabled
EnableWindow(m_editFirst->m_hWnd,1);
EnableWindow(m_editLast->m_hWnd,1);
EnableWindow(m_editStreet1->m_hWnd,1);
EnableWindow(m_editStreet2->m_hWnd,1);
EnableWindow(m_editCity->m_hWnd,1);
EnableWindow(m_editState->m_hWnd,1);
EnableWindow(m_editPostal->m_hWnd,1);
EnableWindow(m_editPhone->m_hWnd,1);
EnableWindow(m_editEmail->m_hWnd,1);
//set focus to the first control
m_editFirst->SetFocus();
m_bDirty = TRUE;
}

AddressBook::DoUpdate()
{
//save the currently displayed record
UpdateData(0);
hstmt_update = m_db.PrepareSQL("UPDATE addresses SET fname=?,lname=?,street=?,street2=?,city=?,state=?,zip=?,phone=?,email=?,dtadded=? WHERE id="+NumToStr(m_id));
m_db.BindParameter(hstmt_update,1,m_fname,TYPE_STRING,40);
m_db.BindParameter(hstmt_update,2,m_lname,TYPE_STRING,40);
m_db.BindParameter(hstmt_update,3,m_street,TYPE_STRING,255);
m_db.BindParameter(hstmt_update,4,m_street2,TYPE_STRING,255);
m_db.BindParameter(hstmt_update,5,m_city,TYPE_STRING,40);
m_db.BindParameter(hstmt_update,6,m_state,TYPE_STRING,10);
m_db.BindParameter(hstmt_update,7,m_zipcode,TYPE_STRING,10);
m_db.BindParameter(hstmt_update,8,m_phone,TYPE_STRING,20);
m_db.BindParameter(hstmt_update,9,m_email,TYPE_STRING,255);
m_db.BindParameter(hstmt_update,10,m_date,TYPE_STRING,40);
m_date = FormatDate();
m_db.Execute(hstmt_update);
m_db.FreeSQL(hstmt_update);
hstmt_update = NULL;
m_bDirty = FALSE;
}

AddressBook::DoDelete()
{
IF m_count AND hstmt_select
{
m_db.FreeSQL(hstmt_select);
hstmt_select = NULL;
hstmt_delete = m_db.ExecSQL("DELETE FROM addresses WHERE id =" + NumToStr(m_id));
m_db.FreeSQL(hstmt_delete);
hstmt_delete = NULL;
m_count = m_db.Cardinality("addresses");
if(m_count)
{
InitSelect();
m_db.GetFirst(hstmt_select);
UpdateData(1);
EnableWindow(m_buttonNext->m_hWnd,1);
EnableWindow(m_buttonPrev->m_hWnd,0);
}
else
{
EnableWindow(m_buttonNext->m_hWnd,0);
EnableWindow(m_buttonPrev->m_hWnd,0);
EnableWindow(m_buttonUpdate->m_hWnd,0);
m_lname = "";m_fname="";m_street="";m_street2="";m_city="";
m_state="";m_zipcode="";m_phone="";m_email="";
UpdateData(1);
}
}
}

AddressBook::DoIdle()
{
STRING strCaption = GetCaption();
INT pos = StrFind(strCaption,"*");
IF m_bDirty
{
IF pos = 0
{
strCaption += "*";
SetCaption(strCaption);
EnableWindow(m_buttonUpdate->m_hWnd,1);
}
}
ELSE
{
IF pos <> 0
{
strCaption = StrLeft(strCaption,pos-1);
SetCaption(strCaption);
EnableWindow(m_buttonUpdate->m_hWnd,0);
}
}
//if count = 0 then disable the edit controls
IF m_count = 0
{
EnableWindow(m_editFirst->m_hWnd,0);
EnableWindow(m_editLast->m_hWnd,0);
EnableWindow(m_editStreet1->m_hWnd,0);
EnableWindow(m_editStreet2->m_hWnd,0);
EnableWindow(m_editCity->m_hWnd,0);
EnableWindow(m_editState->m_hWnd,0);
EnableWindow(m_editPostal->m_hWnd,0);
EnableWindow(m_editPhone->m_hWnd,0);
EnableWindow(m_editEmail->m_hWnd,0);
m_staticID->SetText("*");
}
}

AddressBook::InitSelect()
{
string sel;
sel = "SELECT * FROM addresses";
IF LEN(m_filter)
sel += " WHERE " + m_filter;
hstmt_select = m_db.ExecSQL(sel);
IF hstmt_select
{
m_db.BindVariable(hstmt_select,1,m_id,TYPE_INT);
m_db.BindVariable(hstmt_select,2,m_fname,TYPE_STRING);
m_db.BindVariable(hstmt_select,3,m_lname,TYPE_STRING);
m_db.BindVariable(hstmt_select,4,m_street,TYPE_STRING);
m_db.BindVariable(hstmt_select,5,m_street2,TYPE_STRING);
m_db.BindVariable(hstmt_select,6,m_city,TYPE_STRING);
m_db.BindVariable(hstmt_select,7,m_state,TYPE_STRING);
m_db.BindVariable(hstmt_select,8,m_zipcode,TYPE_STRING);
m_db.BindVariable(hstmt_select,9,m_phone,TYPE_STRING);
m_db.BindVariable(hstmt_select,10,m_email,TYPE_STRING);
}
}


Ionic Wind Support Team

Doc

Nifty!
Works well and will prove to be a lot of help down the road.

Thanks!
-Doc-

Ionic Wind Support Team

It's just one of many ways to approach application design.  Works well enough.
Ionic Wind Support Team

donh

Paul

On the case statement what does the case& mean I have not seen that before
just curious so I can add to my notes.

Don

LarryMc

It's like case 1 or case 2 or case 3 so that if you take the same action for multiple cases you can group them together.
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Parker

Since we don't need to use break at the end of each case - the compiler does it automatically, we need the case& to let it know all of those conditions can fall through. In C you would just write a bunch of case labels and put break at the end of the action block. In Aurora you use case& to combine cases and no break.

donh

thanks a bunch I understan now

Ionic Wind Support Team

I find the reverse logic to C to be more natural.  Can't tell you how many times I've forgotten a 'break' and having unpredictable results that are hard to debug.

Ionic Wind Support Team