⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 formfamtree.cpp

📁 用C++制作家谱
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//----------------------------------------------------------------------------
//
//  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 + -