You are on page 1of 9

Turbo C++ 3.

1 Code Example For A List


Box
Score: 3.2/5 (61 votes)

INTRODUCTION

Many moons ago in the 1990s, when I was programming business application development
in the old Borland Turbo C++ 3.1 platform for the Windows OS, I frequently had a need to
create list boxes. I used them to hold a variety of things such as customers, inventory
items, bookkeeping transactions, invoices and more.

Below I have illustrated an example of how I created one. This particular one will hold a
list of vendors in a single selection list box control. And yes, its crude in comparison to the
best developer platforms like Microsoft Visual Studio, but it does work!

DECLARE THE NEEDED CLASSES

First, here is the class declaration from one of the projects C++ source code files for the
TVendDlg class that will create the data entry screen for the vendors.

1
2 // declare TvendDlg, a TDialog descendant
3 class TVendDlg : public TDialog {
4 public:
5 virtual void SetupWindow();
6 virtual void VendDel(RTMessage Msg)
7 = [ID_FIRST + ID_DELX_];
8 virtual void VendChs(RTMessage Msg)
9 = [ID_FIRST + ID_CHS1_];
1 virtual void VendPrn(RTMessage Msg)
0 = [ID_FIRST + ID_VPRN_];
1 char Vncode[MAXCCODE];
1 char Vnname[MAXCNAME];
1 char Vnstreet[MAXCSTREET];
2 char Vnstreet2[MAXCSTREET];
1 char Vncity[MAXCCITY];
3 char Vnstate[MAXCSTATE];
1 char Vnzip[MAXCZIP];
4 char VnTell1[MAXCTF1];
1 char VnFax1[MAXCTF1];
5 char Vnatt[MAXATT];
1 char VnPaytrm[MAXTERM];
6 char VnNote1[MAXNOTE];
1 char VnNote2[MAXNOTE];
7
1 TEdit
8 *Edit1,*Edit2,*Edit3,*Edit4,*Edit5,*Edit6,*Edit7,*Edit8,*Edit9,*Edit10
1 ,
9 *Edit11,*Edit12,*Edit13;
2
0 TVendDlg(PTWindowsObject AParent, LPSTR name);
2 virtual BOOL CanClose();
1 };
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
3
2

Next, you see the ListBoxDialog class that will be used to populate the list box and
retrieve the users selection from it.

1
2 // declare ListBoxDialog, a TDialog descendant
3 class ListBoxDialog : public TDialog
4 {
5 public:
6 ListBoxDialog(PTWindowsObject AParent, LPSTR AName)
7 : TDialog(AParent, AName) {};
8 virtual void SetupWindow();
9 virtual void HandleListBoxMsg(RTMessage Msg)
10 = [ID_FIRST + ID_LISTBOX];
11 };
12

CLICK THE CHOOSE BUTTON TO ACTIVATE THE LIST BOX

This member function of the TVendDlg class will be fired upon clicking the Choose
button in the vendor data entry screen. The command under the Choose button,
GetApplication()->ExecDialog(new ListBoxDialog(this, "VENDORDIALOG"));, will
instantiate the ListBoxDialog class that is used to help populate the list box.

1
2 void TVendDlg::VendChs(RTMessage)
3 {
4 int a;
5 streambuf *inn = cin.rdbuf();
6 ifpstream ifile;
7 Globalvar = 0;
8 GetApplication()->ExecDialog(new ListBoxDialog(this,
9 "VENDORDIALOG"));
10
11 // if the Global variable, Globalvar is set to 1 from the
12 // ListBoxDialog::HandleListBoxMsg(RTMessage Msg) member
13 // function, then proceed.
14 if( Globalvar == 1) {
15
16 // set the global flag, hasbeenselected, to signal a vendor
17 // has been selected from the list box.
18 hasbeenselected = 1;
19
20 // display the retrieved vendor data in the vendor data
21 entry
22 // screen after the selection in the list box has been
23 clicked
24 // by the user. the data for the selected vendor will
25 be
26 // assigned to the edit controls in the vendor data
27 entry
28 // screen.
29 ifile.open("vend.txt", ios::in | ios::binary);
30 inn = ifile.rdbuf();
31 // position the filestream ofthe binary vendor
32 // data file to the calculated filestream offset
33 // value of the selected list box item.
34 inn -> seekpos(offsetvar, ios::in);
35 for(a=0; a<MAXCCODE-1; a++) Vncode[a] =
36 ifile.readByte();
37 Vncode[MAXCCODE-1] = 0;
38 Edit1->SetText(Vncode);
39 for(a=0; a<MAXCNAME-1; a++) Vnname[a] =
40 ifile.readByte();
41 Vnname[MAXCNAME-1] = 0;
42 Edit2->SetText(Vnname);
43 for(a=0; a<MAXCSTREET-1; a++) Vnstreet[a] =
44 ifile.readByte();
45 Vnstreet[MAXCSTREET-1] = 0;
46 Edit3->SetText(Vnstreet);
47 for(a=0; a<MAXCSTREET-1; a++) Vnstreet2[a] =
48 ifile.readByte();
49 Vnstreet2[MAXCSTREET-1] = 0;
50 Edit4->SetText(Vnstreet2);
51 for(a=0; a<MAXCCITY-1; a++) Vncity[a] =
52 ifile.readByte();
53 Vncity[MAXCCITY-1] = 0;
54 Edit5->SetText(Vncity);
55 for(a=0; a<MAXCSTATE-1; a++) Vnstate[a] =
56 ifile.readByte();
57 Vnstate[MAXCSTATE-1] = 0;
58 Edit6->SetText(Vnstate);
59 for(a=0; a<MAXCZIP-1; a++) Vnzip[a] = ifile.readByte();
60 Vnzip[MAXCZIP-1] = 0;
61 Edit7->SetText(Vnzip);
62 for(a=0; a<3; a++) VnTell1[a] = ifile.readByte();
63 VnTell1[3] = '-';
64 for(a=0; a<3; a++) VnTell1[4+a] = ifile.readByte();
65 VnTell1[7] = '-';
66 for(a=0; a<4; a++) VnTell1[8+a] = ifile.readByte();
67 VnTell1[MAXCTF1-1] = 0;
68 Edit8->SetText(VnTell1);
69 for(a=0; a<3; a++) VnFax1[a] = ifile.readByte();
70 VnFax1[3] = '-';
71 for(a=0; a<3; a++) VnFax1[4+a] = ifile.readByte();
72 VnFax1[7] = '-';
73 for(a=0; a<4; a++) VnFax1[8+a] = ifile.readByte();
74 VnFax1[MAXCTF1-1] = 0;
75 Edit9->SetText(VnFax1);
76 for(a=0; a<MAXATT-1; a++) Vnatt[a] = ifile.readByte();
77 Vnatt[MAXATT-1] = 0;
78 Edit10->SetText(Vnatt);
79 for(a=0; a<MAXTERM-1; a++) VnPaytrm[a] =
80 ifile.readByte();
81 VnPaytrm[MAXTERM-1] = 0;
82 Edit11->SetText(VnPaytrm);
for(a=0; a<MAXNOTE-1; a++) VnNote1[a] =
ifile.readByte();
VnNote1[MAXNOTE-1] = 0;
Edit12->SetText(VnNote1);
for(a=0; a<MAXNOTE-1; a++) VnNote2[a] =
ifile.readByte();
VnNote2[MAXNOTE-1] = 0;
Edit13->SetText(VnNote2);
ifile.close();

CONSTRUCT THE LIST BOX AND POPULATE IT


This is from the projects resource file, which constructs the layout for the vendors list box.
The resource is named VENDORDIALOG. Notice that it uses the fixed width courier
font, which will make the columns display nice and even.

VENDORDIALOG DIALOG DISCARDABLE LOADONCALL PURE MOVEABLE 30, 18, 208,


1 108
2 STYLE WS_POPUP | WS_DLGFRAME
3 FONT 10, "COURIER"
4 BEGIN
5 CONTROL "Vendor Name Vend. Code ", 10055,
6 "static", SS_LEFT | WS_CHILD, 20, 3, 188, 8
7 CONTROL "&Exit" IDCANCEL, "BUTTON", WS_CHILD | WS_VISIBLE |
8 WS_TABSTOP, 20, 93, 48, 12
9 CONTROL "Vendor Listing", 10056, "static", SS_LEFT | WS_CHILD, 75,
10 93, 200, 8
11 CONTROL "LISTBOX" ID_LISTBOX, "LISTBOX", WS_CHILD | WS_VISIBLE |
WS_BORDER | WS_VSCROLL | 0x3L, 20, 15, 168, 73
END

Next, I present the SetupWindow member function of the ListBoxDialog class that will
populate the list box with data from the vendors binary data file, vend.txt. The command
SendDlgItemMsg(ID_LISTBOX, LB_ADDSTRING, 0, (LONG)char_array);, adds each
vendor name and vendor code pair as a row to the list box identified by the defined
constant, ID_LISTBOX.

1
2 void ListBoxDialog::SetupWindow()
3 {
4 long int fileoffset, sizeofdatafile;
5 int a,fileinfo,t;
6 streambuf *inn = cin.rdbuf();
7 ifpstream ifile;
8
9 // this will loop around the vend.txt binary data file of
10 // vendors and add a data record to the list box, which includes
11 // vendor name and vendor code.
12 fileinfo = open("vend.txt", ios::in | ios::binary);
13 sizeofdatafile = filelength(fileinfo);
14 close(fileinfo);
15 ifile.open("vend.txt", ios::in | ios::binary);
16 inn = ifile.rdbuf();
17 fileoffset = 0;
18 do {
19
20 // initialize the char array, char_array, with space
21 characters.
22 for(a=0; a<100; a++) char_array[a] = 32;
23
24 // read the vendor name and vendor code from the file
25 stream.
26 inn -> seekpos(fileoffset, ios::in);
27 for(a=0; a<MAXCCODE-1; a++) char_array[32+a] =
28 ifile.readByte();
29 inn -> seekpos(fileoffset+MAXCCODE-1, ios::in);
30 for(a=0; a<MAXCNAME-1; a++) char_array[a] =
31 ifile.readByte();
32
33 // mask out white space characters.
34 for(a=0; a<100; a++) {
35 if(char_array[a]<33 || char_array[a]>126)
36 char_array[a] = 32;
37 }
38
39 // read the sequential position of the
40 record in the binary text file.
41 inn -> seekpos(fileoffset+VENDLEN-5,
42 ios::in);
43 for(a=0; a<5; a++) char_array[70+a] =
44 ifile.readByte();
45 // null space the end of the char array
46 to suppress trailing random chars.
47 char_array[99] = 0;
48
49 // convert the char array to
50 lower case.
51 strlwr(char_array);
52
53 // add the vendor name
54 and vendor code pair to the list box control.

SendDlgItemMsg(ID_LISTBOX, LB_ADDSTRING, 0, (LONG)


char_array);

// advance to the next record in the binary text file.


fileoffset = fileoffset + VENDLEN;

} while(fileoffset<sizeofdatafile);

ifile.close();

Finally, the HandleListBoxMsg member function of the ListBoxDialog class will fire
with a click by the user on the selected row in the list box. At this point, the list box will
disappear and the file stream offset of the selected vendor record will be calculated with
help from the selections index component . This offset will then be used in the data
retrieval portion of the VendChs member function of the TVendDlg class mentioned
previously.

1
2 void ListBoxDialog::HandleListBoxMsg(RTMessage Msg)
3 {
4 long int a, convert_to_number[5];
5 DWORD Idx;
6
7 // if the exit button is clicked, then exit and reset global
8 variable to 0.
9 if ( Msg.LP.Hi == LBN_SELCANCEL ) Globalvar = 0;
10
11 // if a selection is made, then reset the global variable to 1
12 and proceed to calculate the
13 // filestream offset after getting the list box index of the
14 selection, Idx.
15 if ( Msg.LP.Hi == LBN_SELCHANGE ) {
16
17 // initialize the char array, char_array, with space
18 characters.
19 for(a=0; a<80; a++) char_array[a] = 32;
20
21 Globalvar = 1;
22
23 // get the index of the selected list box item.
24 Idx = SendDlgItemMsg(ID_LISTBOX, LB_GETCURSEL, 0, 0L);
25
26 char_array[79] = 0;
27
28 // use the index to retrieve the contents of the selected list
29 box row into a char array, char_array.
30 SendDlgItemMsg(ID_LISTBOX, LB_GETTEXT, (WORD)Idx, (DWORD)
31 char_array);
32
33 // close the list box window after retrieving info into the
34 char array from above.
35 CloseWindow();
36
37 // this will take the auto-generated sequential
38 // position of the vendor record stored in each
39 record of the binary text file, vend.txt
40 // from the char array and convert it to a
41 numerical value to be multiplied by the defined constant,
42 // VENDLEN. this will produce the filestream
43 offset I call offsetvar, which is used to locate the
44 // vendor data in the member function VendChs
45 of the TVendDlg dialog class, which will populate
46 // the edit controls in the vendor data entry
47 screen.
48 for(a=0; a<5; a++) {
49 convert_to_number[a] = 0;
50 if(char_array[70+a] == 48) convert_to_number[a]
51 = 0;
52 if(char_array[70+a] == 49) convert_to_number[a]
53 = 1;
54 if(char_array[70+a] == 50) convert_to_number[a]
= 2;
if(char_array[70+a] == 51) convert_to_number[a]
= 3;
if(char_array[70+a] == 52) convert_to_number[a]
= 4;
if(char_array[70+a] == 53) convert_to_number[a]
= 5;
if(char_array[70+a] == 54) convert_to_number[a]
= 6;
if(char_array[70+a] == 55) convert_to_number[a]
= 7;
if(char_array[70+a] == 56) convert_to_number[a]
= 8;
if(char_array[70+a] == 57) convert_to_number[a]
= 9;
}
offsetvar = ( (convert_to_number[0] * 10000) +
(convert_to_number[1] * 1000) + (convert_to_number [2] * 100) +
(convert_to_number [3] * 10 ) + (convert_to_number[4] * 1) ) *
VENDLEN;

THE ABOVE C++ CODE IN PICTURES

Here is the vendor data entry screen created from the TVendDlg class.

After clicking the "Choose" button, this list box appears with a vendor record I entered.
After clicking on the vendor in the list box, it will go away and the internal programming I
made will populate the vendors data entry screen with the selected vendor as shown here.

CONCLUSION

As you can see, this can be challenging to follow if you dont possess the developer skills
needed for object oriented programming. My software design techniques can be a bit drawn
out, but all this does function to quickly achieve its intended purpose without Windows
exception screens, wide eyes, elevated blood pressure and the like. If anything, it makes
one appreciate the modern coding platforms of today that are utilized for custom software
design.