[Back to OOP SWAG index] [Back to Main SWAG index] [Original]
{From: q3817075@bonsai (Olaf Lueder)}
{
: I'm writing a program using BP7.0 and TurboVision. I have DialogBox
: which contains some Datafields and a listbox. The problem is now that
: when the selection in the listbox changes I want to change the
: contents of the datafields. The way i'm doing it now is first get the
: data with Dlg^.GetData(Data) and then delete Dlg^ from the destkop
: (and ofcourse dispose it). Now I modify the data and creates the
: dialogbox all over before I insert it again. This is not really what I
: wannet - How do I do the same without having to delete and then insert
: the dialogbox...
There are various ways to solve your problem...
At first: There is the 'FocusItem'-method, which is called by the
HandleEvent
of the ListBox, whenever a new Item is focused by pressing the
arrow-
keys or using the mouse.
That's the method you'll have to modify.
You could do it in the follow way:
procedure tNewListBox.FocusItem(Item: integer);
var Data: record
InputLine1: string[20];
InputLine2: integer;
CheckBox1 : word;
.
.
List : pCollection;
Item : integer;
end;
begin
inherited FocusItem(Item);
Owner^.GetData(Data);
(* here you can modify Data using the values of your actually list-item*)
(* for example: Data.InputLine1:=pListBoxItem(List^.at(Item))^.Name *)
Owner^.SetData(Data);
end;
But there still be a problem...
Owner^.SetData calls ListBox^.SetData, and ListBox^.SetData calls
ListBox^.NewList and this method calls dispose(List, done)...
So you have to redefine the NewList-method:
procedure tNewListBox.NewList(AList: pCollection);
begin
List := AList;
if AList = nil then SetRange(0)
else SetRange(AList^.Count);
if Range > 0 then FocusItem(0);
DrawView;
(* we don't call dispose(List, done *)
end;
It's a solution of your problem, but it isn't a nice one...
Much better way is to use messages.
What does we have ?
We've a ListBox, and of course a Collection with our data.
Now you can send a Message from the ListBox to the Owner of itself and
every
subview of your dialog can hear that a new list-item was focused...
Storing a pointer of the focused list-item at the InfoPtr of the
Event-record-
every subview can take required data and change itself.
Short (???) Demo:
}
program Test;
uses Objects, Drivers, App, Menus, Views, Dialogs, Validate;
const cmListItemFocused = 1000;
cmTestDialog = 1001;
type pListData = ^tListData;
tListData = record
FirstName: string[20];
LastName : string[30];
Age : longint;
Sex : word;
end;
pDataCollection = ^tDataCollection;
tDataCollection = object(tCollection)
constructor Init;
procedure FreeItem(Item: pointer); virtual;
(* you have to add 'GetItem' and 'PutItem' and to registrate it *)
end;
pNewInputLine = ^tNewInputLine;
tNewInputLine = object(tInputLine)
constructor Init(var Bounds: TRect; AMaxLen: Integer);
procedure HandleEvent(var Event: tEvent); virtual;
procedure Modify(AData: pointer); virtual;
end;
pFirstNameInputLine = ^tFirstNameInputLine;
tFirstNameInputLine = object(tNewInputLine)
procedure Modify(AData: pointer); virtual;
end;
pLastNameInputLine = ^tLastNameInputLine;
tLastNameInputLine = object(tNewInputLine)
procedure Modify(AData: pointer); virtual;
end;
pAgeInputLine = ^tAgeInputLine;
tAgeInputLine = object(tNewInputLine)
procedure Modify(AData: pointer); virtual;
end;
pNewRadioButtons = ^tNewRadioButtons;
tNewRadioButtons = object(tRadioButtons)
constructor Init(var Bounds: TRect; AStrings: PSItem);
procedure HandleEvent(var Event: tEvent); virtual;
procedure Modify(AData: pointer); virtual;
end;
pSexRadioButtons = ^tSexRadioButtons;
tSexRadioButtons = object(tNewRadioButtons)
procedure Modify(AData: pointer); virtual;
end;
pNewListBox = ^tNewListBox;
tNewListBox = object(tListBox)
procedure FocusItem(Item: integer); virtual;
end;
pTestListBox = ^tTestListBox;
tTestListBox = object(tNewListBox)
function GetText(Item: integer; MaxLen: integer): string; virtual;
destructor Done; virtual;
end;
pTestDialog = ^tTestDialog;
tTestDialog = object(tDialog)
constructor Init;
end;
tTestApp = object(tApplication)
procedure HandleEvent(var Event: TEvent); virtual;
procedure InitMenuBar; virtual;
procedure TestDialog;
end;
var TestApp: tTestApp;
FUNCTION NewDataItem(AFirstName, ALastName: string; AAge: longint;
ASex: word): pListData;
var Item: pListData;
begin
GetMem(Item, SizeOf(tListData));
with Item^ do begin
FirstName:=AFirstName;
LastName:=ALastName;
Age:=AAge;
Sex:=ASex;
end;
NewDataItem:=Item;
end;
CONSTRUCTOR tDataCollection.Init;
begin
inherited Init( 5, 0);
insert(NewDataItem('Olaf', 'Lueder', 23, 1));
insert(NewDataItem('second', 'person', 55, 0));
insert(NewDataItem('third', 'person', 77, 1));
insert(NewDataItem('fourth', 'person', 11, 0));
insert(NewDataItem('fifth', 'person', 33, 1));
end;
PROCEDURE tDataCollection.FreeItem(Item: pointer);
begin
FreeMem(Item, SizeOf(tListData));
end;
CONSTRUCTOR tNewInputLine.Init(var Bounds: TRect; AMaxLen: Integer);
begin
inherited Init(Bounds, AMaxLen);
Options:=Options or ofPostProcess;
end;
PROCEDURE tNewInputLine.HandleEvent(var Event: tEvent);
begin
inherited HandleEvent(Event);
if (Event.What=evCommand) and (Event.Command=cmListItemFocused) then
Modify(Event.InfoPtr);
end;
PROCEDURE tNewInputLine.Modify(AData: pointer);
begin
Abstract;
end;
PROCEDURE tFirstNameInputLine.Modify(AData: pointer);
var Str: string;
begin
Str:=Copy(tListData(AData^).FirstName, 1, MaxLen);
SetData(Str);
end;
PROCEDURE tLastNameInputLine.Modify(AData: pointer);
var Str: string;
begin
Str:=Copy(tListData(AData^).LastName, 1, MaxLen);
SetData(Str);
end;
PROCEDURE tAgeInputLine.Modify(AData: pointer);
var S: string[3];
begin
Str(pListData(AData)^.Age, S);
SetData(S);
end;
CONSTRUCTOR tNewRadioButtons.Init(var Bounds: TRect; AStrings: PSItem);
begin
inherited Init(Bounds, AStrings);
Options:=Options or ofPostProcess;
end;
PROCEDURE tNewRadioButtons.HandleEvent(var Event: tEvent);
begin
inherited HandleEvent(Event);
if (Event.What=evCommand) and (Event.Command=cmListItemFocused) then
Modify(Event.InfoPtr);
end;
PROCEDURE tNewRadioButtons.Modify(AData: pointer);
begin
SetData(pListData(AData)^.Sex);
end;
PROCEDURE tSexRadioButtons.Modify(AData: pointer);
begin
SetData(pListData(AData)^.Sex);
end;
PROCEDURE tNewListBox.FocusItem(Item: integer);
begin
inherited FocusItem(Item);
Message(Owner, evCommand, cmListItemFocused, List^.At(Item));
end;
FUNCTION tTestListBox.GetText(Item: integer; MaxLen: integer): string;
var S: string;
begin
with pListData(List^.At(Item))^ do begin
Str(Age, S);
case Sex of
0: S:=S+', male';
1: S:=S+', female';
end;
GetText:=LastName+', '+FirstName+', '+S;
end;
end;
DESTRUCTOR tTestListBox.Done;
begin
NewList(nil);
inherited Done;
end;
CONSTRUCTOR tTestDialog.Init;
var R: tRect;
View: pView;
begin
R.Assign( 0, 0, 76, 10);
inherited Init(R, 'Test-Dialog');
Options:=Options or ofCentered;
R.Assign( 15, 2, 37, 3);
View:=New(pFirstNameInputLine, Init(R, 20));
insert(View);
R.Assign( 2, 2, 15, 3);
Insert(New(pLabel, Init(R, '~F~irstName:', View)));
R.Assign( 53, 2, 74, 3);
View:=New(pLastNameInputLine, Init(R, 30));
insert(View);
R.Assign( 41, 2, 52, 3);
Insert(New(pLabel, Init(R, '~L~astName:', View)));
R.Assign( 15, 4, 20, 5);
View:=New(pAgeInputLine, Init(R, 3));
pInputLine(View)^.SetValidator(New(pRangeValidator, Init( 0, 150)));
insert(View);
R.Assign( 2, 4, 15, 5);
Insert(New(pLabel, Init(R, '~A~ge:', View)));
R.Assign( 32, 4, 74, 5);
View:=New(pSexRadioButtons, Init(R,
NewSItem('~f~emale',
NewSItem('~m~ale',
nil))));
insert(View);
R.Assign( 25, 4, 30, 5);
insert(New(pLabel, Init(R, '~S~ex:', View)));
R.Assign( 15, 6, 74, 9);
View:=New(pTestListBox, Init(R, 1, nil));
pListBox(View)^.NewList(New(pDataCollection, Init));
insert(View);
R.Assign( 2, 6, 15, 7);
Insert(New(pLabel, Init(R, 'L~i~st:', View)));
end;
PROCEDURE tTestApp.HandleEvent(var Event: tEvent);
begin
inherited HandleEvent(Event);
if (Event.What = evCommand) and (Event.Command = cmTestDialog) then begin
TestDialog;
ClearEvent(Event);
end;
end;
PROCEDURE tTestApp.InitMenuBar;
var R: tRect;
begin
GetExtent(R);
R.B.Y := R.A.Y + 1;
MenuBar := New(pMenuBar, Init(R, NewMenu(
NewItem('~T~est', '', kbAltT, cmTestDialog, hcNoContext,
nil))));
end;
PROCEDURE tTestApp.TestDialog;
begin
ExecuteDialog(New(pTestDialog, Init), nil);
end;
begin
with TestApp do begin
Init;
Run;
Done;
end;
end.
[Back to OOP SWAG index] [Back to Main SWAG index] [Original]