📄 formfamtree.cpp
字号:
//----------------------------------------------------------------------------
//
// formfamtree.cpp
// Chapter 30 - How To - Tree View Component Example
//
// Paul Gustavson
// pgustavson@simventions.com
//
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "formfamtree.h"
#include "tree_util.h"
#include <stdio.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TFormFamilyTree *FormFamilyTree;
//---------------------------------------------------------------------------
__fastcall TFormFamilyTree::TFormFamilyTree(TComponent* Owner)
: TForm(Owner)
{
nodetoremember = NULL; // use to keep track of entry info that has been modified, but not saved into the record
}
//---------------------------------------------------------------------------
void __fastcall TFormFamilyTree::FormActivate(TObject *Sender)
{
ImageListTreeViewIcons->Overlay(gDeleted,0);
}
//---------------------------------------------------------------------------
void __fastcall TFormFamilyTree::FormClose(TObject *Sender,
TCloseAction &Action)
{
ActionFileClearExecute(Sender);
}
//---------------------------------------------------------------------------
AnsiString __fastcall TFormFamilyTree::CreateLabel(AnsiString FirstName, AnsiString LastName)
{
AnsiString text = ""; // the return variable
// first, let's see if we have last name entered
if (LastName.Length() == 0)
return text; // no name, this is invalid, return an empty string
if (FirstName.Length() > 0)
// do we have a first name entered, if so let's show it in our tree view
text = LastName + ", " + FirstName;
else
// don't have a first name, we'll just use the last
text = LastName;
return text;
}
//---------------------------------------------------------------------------
void __fastcall TFormFamilyTree::ReflectNodeLabel(TTreeNode* node)
{
AnsiString label = node->Text;
StripParenCount(label);
int pos = label.AnsiPos(",");
if (pos == 0) // no first name
{
EditLastName->Text = label;
EditFirstName->Text = "";
}
else
{
int length = label.Length();
EditLastName->Text = label.SubString(1, (pos-1));
EditFirstName->Text = label.SubString((pos+2),(length-pos));
}
ActionNodeDeleteHard->Enabled = true;
ActionNodeDeleteSoft->Enabled = true;
if (node->Data)
{
TPersonalInfo *info;
info = (TPersonalInfo*)(node->Data); // cast data into TInfo pointer
info->Father = NULL;
info->Mother = NULL;
if (node->Parent)
{
TPersonalInfo *ParentData;
ParentData = (TPersonalInfo*)(node->Parent->Data);
info->DetermineParent(ParentData);
}
info->FirstName = EditFirstName->Text;
info->LastName = EditLastName->Text;
TransferPersonalInfoToEditEntry(info);
}
}
//---------------------------------------------------------------------------
void __fastcall TFormFamilyTree::ClearEntryPanel()
{
EditLastName->Text = "";
EditFirstName->Text = "";
EditDOB->Text = "";
EditDOD->Text = "";
EditEpitath->Text = "";
EditBirthPlace->Text = "";
EditResidence->Text = "";
RadioButtonMale->Checked = true;
EditOccupation->Text = "";
EditEpitath->Text = "";
EditMother->Text = "";
EditMotherID->Text = "";
EditFather->Text = "";
EditFatherID->Text = "";
EditNotes->Text = "";
}
//---------------------------------------------------------------------------
bool __fastcall TFormFamilyTree::TransferPersonalInfoToEditEntry(TPersonalInfo *pinfo)
{
ClearEntryPanel();
if (pinfo == NULL)
return false;
EditFirstName->Text = pinfo->FirstName;
EditLastName->Text = pinfo->LastName;
EditDOB->Text = pinfo->DOB;
EditDOD->Text = pinfo->DOD;
EditEpitath->Text = pinfo->Epitath;
EditBirthPlace->Text = pinfo->BirthPlace;
EditResidence->Text = pinfo->Residence;
RadioButtonMale->Checked = pinfo->Gender;
RadioButtonFemale->Checked = !pinfo->Gender;
EditOccupation->Text = pinfo->Occupation;
EditEpitath->Text = pinfo->Epitath;
char temp[100];
if (pinfo->Mother)
{
EditMother->Text = pinfo->Mother->Name;
sprintf(temp,"%u",pinfo->Mother->ID);
EditMotherID->Text = AnsiString(temp);
}
if (pinfo->Father)
{
EditFather->Text = pinfo->Father->Name;
sprintf(temp,"%u",pinfo->Father->ID);
EditFatherID->Text = AnsiString(temp);
}
sprintf(temp, "%u",pinfo->ID); // can't use ToInt since this is an unsigned int
EditID->Text = AnsiString(temp);
return true;
}
//---------------------------------------------------------------------------
void __fastcall TFormFamilyTree::TransferPersonalInfoFromEditEntry(unsigned int id, AnsiString text,TPersonalInfo *pinfo)
{
pinfo->ID = id;
pinfo->Name = text;
pinfo->FirstName = EditFirstName->Text;
pinfo->LastName = EditLastName->Text;
pinfo->DOB = EditDOB->Text;
pinfo->DOD = EditDOD->Text;
pinfo->Epitath = EditEpitath->Text;
pinfo->BirthPlace = EditBirthPlace->Text;
pinfo->Residence = EditResidence->Text;
pinfo->Gender = RadioButtonMale->Checked;
pinfo->Occupation = EditOccupation->Text;
pinfo->Epitath = EditEpitath->Text;
}
//---------------------------------------------------------------------------
void __fastcall TFormFamilyTree::TreeViewFamilyClick(TObject *Sender)
{
// first save any information that was just modifed (but what was that node?)
ActionNodeModifyExecute(Sender);
// Take name out of treeview and put it in the page control
if (!TreeViewFamily->Selected)
{
if (TreeViewFamily->Items->Count == 0)
return;
TTreeNode *TopNode = TreeViewFamily->Items->GetFirstNode();
TopNode->Selected = true;
}
ReflectNodeLabel(TreeViewFamily->Selected);
}
//---------------------------------------------------------------------------
void __fastcall TFormFamilyTree::TreeViewFamilyKeyUp(TObject *Sender,
WORD &Key, TShiftState Shift)
{
if ((Key == VK_UP) || (Key == VK_DOWN) || (Key == VK_RIGHT) || Key == VK_LEFT)
{
TreeViewFamilyClick(Sender);
}
}
//---------------------------------------------------------------------------
void __fastcall TFormFamilyTree::TreeViewFamilyKeyDown(TObject *Sender,
WORD &Key, TShiftState Shift)
{
if (Key == VK_DELETE)
{
Key = NULL;
ActionNodeDeleteSoftExecute(Sender);
}
}
//---------------------------------------------------------------------------
void __fastcall TFormFamilyTree::TreeViewFamilyDragDrop(TObject *Sender,
TObject *Source, int X, int Y)
{
TTreeNode *pItem = TreeViewFamily->GetNodeAt(X, Y);
if ((Source == (TObject *)TreeViewFamily) && (TreeViewFamily->Selected))
{
THitTests HT = TreeViewFamily->GetHitTestInfoAt(X, Y);
TNodeAttachMode AttachMode;
if (HT.Contains(htOnItem) || HT.Contains(htOnIcon))
AttachMode = naAddChild; // a drop node was selected
else if (HT.Contains(htNowhere))
AttachMode = naAdd; // no drop node was selected
else if (HT.Contains(htOnIndent))
AttachMode = naInsert; // insert before selected node
else
return;
TreeViewFamily->Selected->MoveTo(pItem, AttachMode);
// this will help redetermine the parent
ReflectNodeLabel(TreeViewFamily->Selected);
AddCountToNode(TreeViewFamily->Items);
}
}
//---------------------------------------------------------------------------
void __fastcall TFormFamilyTree::TreeViewFamilyDragOver(TObject *Sender,
TObject *Source, int X, int Y, TDragState State, bool &Accept)
{
if (Source->InheritsFrom(__classid(TTreeView)))
Accept=true; // accept the ability to drag the selected node
}
//---------------------------------------------------------------------------
void __fastcall TFormFamilyTree::TreeViewFamilyEditing(TObject *Sender,
TTreeNode *Node, bool &AllowEdit)
{
if (Node->OverlayIndex != -1)
{
AllowEdit = false;
MessageBeep(MB_OK);
}
else
{
StripParenCount(Node->Text);
AllowEdit = true;
Refresh();
}
}
//---------------------------------------------------------------------------
void __fastcall TFormFamilyTree::TreeViewFamilyEdited(TObject *Sender,
TTreeNode *Node, AnsiString &S)
{
if (S.Length() > 0)
{
Node->Text = S;
ReflectNodeLabel(Node);
}
}
//---------------------------------------------------------------------------
void __fastcall TFormFamilyTree::ActionNodeModifyExecute(TObject *Sender)
{
if (!nodetoremember) return;
TTreeNode *tempnode = nodetoremember;
// call the routine that create the text label for the tree node
AnsiString text = CreateLabel(EditFirstName->Text,EditLastName->Text);
if (text.Length() == 0) // check for an invalid name
return; // no name, this is invalid, let's get out of here
nodetoremember->Text = text;
TPersonalInfo * info;
if (tempnode->Data == NULL) // data not already established for this node
{
info = new TPersonalInfo;
TransferPersonalInfoFromEditEntry(GetNewID(),text,info);
tempnode->Data = info;
}
else
{
info = (TPersonalInfo*)(tempnode->Data); // cast data into TInfo pointer
TransferPersonalInfoFromEditEntry(info->ID,text,info);
}
if (info->Gender)
{
tempnode->ImageIndex = gPersonMale;
tempnode->SelectedIndex = gPersonMaleSelected;
}
else
{
tempnode->ImageIndex = gPersonFemale;
tempnode->SelectedIndex = gPersonFemaleSelected;
}
AddCountToNode(TreeViewFamily->Items);
ActionOtherRestore->Enabled = false;
ActionNodeModify->Enabled = false;
nodetoremember = NULL;
}
//---------------------------------------------------------------------------
void __fastcall TFormFamilyTree::ActionNodeDeleteHardExecute(TObject *Sender)
{
TTreeNode* node;
TTreeNode* parentnode;
TTreeNode* siblingnode;
node = TreeViewFamily->Selected;
parentnode = TreeViewFamily->Selected->Parent;
siblingnode = TreeViewFamily->Selected->getNextSibling();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -