C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Помогите перевести куски кода с Delphi
nut
Отправлено: 26.12.2006, 00:08


Ученик-кочегар

Группа: Участник
Сообщений: 22



Код взят из стаить http://forum.vingrad.ru/index.php?act=ST&f=84&t=97620 про Virtual Treeview хочу освоить но Dilphi незнаю.
CODE

Names: array[0..4] of WideString = (
 'Вася',
 'Петя',
 'Маша',
 'Костя',
 'Дима'
);
Phones: array[0..4] of WideString = (
 '433-56-49',
 '545-67-79',
 '777-50-50',
 '911-03-05',
 '02'
);

CODE

procedure TfrmMain.BtnLoadClick(Sender: TObject);
var
 i: Integer;
begin
 for i := 0 to Length(Names) — 1 do
   VT.AddChild(nil);
end;

CODE

procedure TfrmMain.VTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
 Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
begin
 case Column of
   // Текст для колонки имени
   0: CellText := Names[Node.Index];
   // Текст для колонки телефонного номера
   1: CellText := Phones[Node.Index];
 end;
end;

CODE

property Text[Node: PVirtualNode; Column: TColumnIndex]: WideString;

CODE

type
 PPhoneNode = ^TPhoneNode;

 TPhoneNode = record
   Name, // Имя контакта
   Phone: WideString; // Телефон
 end;

CODE

function TBaseVirtualTree.GetNodeData(Node: PVirtualNode): Pointer;

CODE

procedure TfrmMain.FormCreate(Sender: TObject);
begin
 VT.NodeDataSize := SizeOf(TPhoneNode);
end;

CODE

procedure TfrmMain.BtnAddClick(Sender: TObject);
var
 NewNode: PVirtualNode;
 NewPhone: PPhoneNode;
begin
 NewNode := VT.AddChild(VT.FocusedNode);
 NewPhone := VT.GetNodeData(NewNode);
 if Assigned(NewPhone) then
   with NewPhone^ do
   begin
     Name := EdName.Text;
     Phone := EdPhone.Text;
   end;
end;
Tantos
Отправлено: 26.12.2006, 15:08


Станционный диспетчер

Группа: Участник
Сообщений: 108



CODE

WideString Names[4]={
"Петя",
"Маша",
"Костя",
"Дима"
};
WideString Phones[4]={
"433-56-49",
"545-67-79",
"777-50-50",
"911-03-05"
};


CODE

void __fastcall TfrmMain::BtnLoadClick(TObject *Sender)
{
for( int i = 0; i < Length(Names); i++)
VT->AddChild(NULL);
}


CODE

void __fastcall TfrmMain::VTGetText(/*сгенерируется при написании*/)
{
switch( Column )
{
case 0:
CellText = Names[Node->Index];
break;
case 1:
CellText = Phones[Node->Index];
break;
default:
break;
}
}


CODE

struct TPhoneNode {
WideString Name;
WideString Phone;
} *PPhoneNode;


CODE

void __fastcall TfrmMain::FormCreate(TObject *Sender)
{
VT->NodeDataSize = sizeof(TPhoneNode);
}


CODE

void __fastcall TfrmMain::BtnAddClick(TObject *Sender);
{
PVirtualNode *NewNode;//или  так: PVirtualNode *NewNode(NULL);
PPhoneNode *NewPhone;//или  так: PPhoneNode *NewPhone(NULL);

NewNode = VT->AddChild(VT->FocusedNode);
NewPhone = VT->GetNodeData(NewNode);
if( NewPhone )
{
NewPhone->Name = EdName->Text;
NewPhone->Phone = EdPhone->Text;
}
}


Отредактировано Tantos — 26.12.2006, 22:14
nut
Отправлено: 26.12.2006, 20:36


Ученик-кочегар

Группа: Участник
Сообщений: 22



Спасибо но возникают ошибки.
Вот моя прога.
CODE

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "VirtualTrees"
#pragma resource "*.dfm"
TForm1 *Form1;
WideString Names[5]={"Вася", "Петя", "Маша", "Костя", "Дима"};
WideString Phones[5]={"3466", "1515", "27547", "15567", "262476"};

struct TPhoneNode {
 WideString Name;
 WideString Phone;
} *PPhoneNode;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button8Click(TObject *Sender)
{
for (int i=0; i <= 4; i++) {
 VirtualStringTree1->AddChild(NULL);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::VirtualStringTree1GetText(TBaseVirtualTree *Sender,
     PVirtualNode Node, TColumnIndex Column, TVSTTextType TextType,
     WideString &CellText)
{
switch (Column) {
 case 0: CellText = Names[Node->Index];
 break;
 case 1: CellText = Phones[Node->Index];
 break;
 }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button7Click(TObject *Sender)
{
PVirtualNode *NewNode;//или  так: PVirtualNode *NewNode(NULL);
PPhoneNode   *NewPhone;//или  так: PPhoneNode   *NewPhone(NULL);
NewNode  = VirtualStringTree1->AddChild(VirtualStringTree1->FocusedNode);
NewPhone = VirtualStringTree1->GetNodeData(NewNode);
if( NewPhone )
{
 NewPhone->Name  = EdName->Text;
 NewPhone->Phone = EdPhone->Text;
}
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
VirtualStringTree1->NodeDataSize = sizeof(TPhoneNode);
}
//---------------------------------------------------------------------------

Вот на этой строке
PPhoneNode   *NewPhone;//или  так: PPhoneNode   *NewPhone(NULL);
возникает ошибка
[C++ Error] Unit1.cpp(70): E2451 Undefined symbol 'NewPhone'

//---------------------------------------------------------------------------

На этой NewPhone = VirtualStringTree1->GetNodeData(NewNode);
[C++ Error] Unit1.cpp(72): E2034 Cannot convert 'TVirtualNode * *' to 'TVirtualNode *'
[C++ Error] Unit1.cpp(72): E2342 Type mismatch in parameter 'Node' (wanted 'TVirtualNode *', got 'TVirtualNode * *')

//---------------------------------------------------------------------------

на этих
 NewPhone->Name  = EdName->Text;
 NewPhone->Phone = EdPhone->Text;

[C++ Error] Unit1.cpp(75): E2451 Undefined symbol 'EdName'
[C++ Error] Unit1.cpp(76): E2451 Undefined symbol 'EdPhone'

//---------------------------------------------------------------------------
Tantos
Отправлено: 27.12.2006, 04:41


Станционный диспетчер

Группа: Участник
Сообщений: 108



Кинь на форму 2 TEdit'a и дай им соответствующие имена wink.gif .

P.S. Тэги CODE очень помогают восприятию оного.

Отредактировано Tantos — 27.12.2006, 11:58
nut
Отправлено: 28.12.2006, 00:54


Ученик-кочегар

Группа: Участник
Сообщений: 22



Помогло но неполностью вот остались ошибки
CODE

PPhoneNode *NewPhone;//или так: PPhoneNode *NewPhone(NULL);
[C++ Error] Unit1.cpp(70): E2451 Undefined symbol 'NewPhone'

CODE

NewPhone = VirtualStringTree1->GetNodeData(NewNode);
[C++ Error] Unit1.cpp(72): E2034 Cannot convert 'TVirtualNode * *' to 'TVirtualNode *'
[C++ Error] Unit1.cpp(72): E2342 Type mismatch in parameter 'Node' (wanted 'TVirtualNode *', got 'TVirtualNode * *')
Tantos
Отправлено: 28.12.2006, 05:30


Станционный диспетчер

Группа: Участник
Сообщений: 108



Перепиши объявление структуры так:
CODE

struct TPhoneNode {
WideString Name;
WideString Phone;
};
typedef TPhoneNode* PPhoneNode;

А потом вот так:
CODE

PVirtualNode NewNode;
PPhoneNode NewPhone;

Извиняюсь, внимательнее надо было смотреть исходник angry2.gif .

Отредактировано Tantos — 28.12.2006, 12:32
nut
Отправлено: 28.12.2006, 17:04


Ученик-кочегар

Группа: Участник
Сообщений: 22



Спасибо помогло но осталась одна ошибка.
CODE

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "VirtualTrees"
#pragma resource "*.dfm"
TForm1 *Form1;

WideString Names[5]={"Вася", "Петя", "Маша", "Костя", "Дима"};
WideString Phones[5]={"3466", "1515", "27547", "15567", "262476"};

struct TPhoneNode {
WideString Name;
WideString Phone;
};

typedef  TPhoneNode* PPhoneNode;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button8Click(TObject *Sender)
{
for (int i=0; i <= 4; i++) {
 VirtualStringTree1->AddChild(NULL);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::VirtualStringTree1GetText(TBaseVirtualTree *Sender,
     PVirtualNode Node, TColumnIndex Column, TVSTTextType TextType,
     WideString &CellText)
{
switch (Column) {
 case 0: CellText = Names[Node->Index];
 break;
 case 1: CellText = Phones[Node->Index];
 break;
 }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button7Click(TObject *Sender)
{
PVirtualNode NewNode;
PPhoneNode NewPhone;
NewNode  = VirtualStringTree1->AddChild(VirtualStringTree1->FocusedNode);
NewPhone = VirtualStringTree1->GetNodeData(NewNode);
if( NewPhone )
{
 NewPhone->Name  = EdName->Text;
 NewPhone->Phone = EdPhone->Text;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
VirtualStringTree1->NodeDataSize = sizeof(TPhoneNode);
}

вот на этой строке ошибка
CODE

NewPhone = VirtualStringTree1->GetNodeData(NewNode);
[C++ Error] Unit1.cpp(53): E2034 Cannot convert 'void *' to 'TPhoneNode
Tantos
Отправлено: 29.12.2006, 02:09


Станционный диспетчер

Группа: Участник
Сообщений: 108



Попробуй так:
CODE

NewPhone = (TPhoneData*)VirtualStringTree1->GetNodeData(NewNode);
nut
Отправлено: 29.12.2006, 15:46


Ученик-кочегар

Группа: Участник
Сообщений: 22



Спасиб вот только за место TPhoneData* надо было TPhoneNode.
Но вот текст неотображается, точнее отображается "Node", а как запихнуть свой незнаю?
Tantos
Отправлено: 16.01.2007, 09:15


Станционный диспетчер

Группа: Участник
Сообщений: 108



Поднимаю тему.
Во-первых, смущает обращение к свойству через ^. в примере с сортировкой:
CODE

procedure TfrmMain.VTCompareNodes(Sender: TBaseVirtualTree; Node1,
 Node2: PVirtualNode; Column: TColumnIndex; var Result: Integer);
var
 Data1, Data2: PDataNode;
begin
 Data1 := Sender.GetNodeData(Node1);
 Data2 := Sender.GetNodeData(Node2);
 if Data1^.Value > Data2^.Value then
   Result := 1
 else if Data1^.Value < Data2^.Value then
   Result := -1
 else if Data1^.Value = Data1^.Value then
   Result := 0;
end;

Свойство Value отсутствует и у TBaseVirtualTree и у PVirtualNode.
Во-вторых, не могу разобраться с отображением картинок:
CODE

void __fastcall TfrmMain::vstMainGetImageIndexEx(TBaseVirtualTree *Sender,
     PVirtualNode Node, TVTImageKind Kind, TColumnIndex Column,
     bool &Ghosted, int &ImageIndex, TCustomImageList *&ImageList)
{
PDataNode NewRecord;

NewRecord = (PDataNode)vstMain->GetNodeData( Node );

if( NewRecord )
 {
   if( Column != 8 ) return;
   else
    {
     if( NewRecord->bDocuments ) ImageIndex = -1;
     else                        ImageIndex =  4;
    }
 }
}

Почему-то отображается картинка только с ItemIndex = 0.
В-третьих, многострочность в узлах отображается только после наведения мышкой на этот узел.
В-четвертых, как сделать многострочный заголовок? Попробовал такой код, но событие HeaderDraw не вызывается вообще:
CODE

void __fastcall TfrmMain::vstMainHeaderDraw(TVTHeader *Sender,
     TCanvas *HeaderCanvas, TVirtualTreeColumn *Column, TRect &R,
     bool Hover, bool Pressed, TVTDropMarkMode DropMark)
{
DWORD AlignFlags[]={ DT_LEFT |DT_WORDBREAK | DT_EXPANDTABS | DT_NOPREFIX,
                      DT_RIGHT | DT_WORDBREAK | DT_EXPANDTABS | DT_NOPREFIX,
                      DT_CENTER | DT_WORDBREAK | DT_EXPANDTABS | DT_NOPREFIX };

TCanvas *cCanv      = HeaderCanvas;
int sdc             = SaveDC(cCanv->Handle);
unsigned int height = vstMain->Header->Height;

cCanv->Brush->Color = Column->Color;
cCanv->Font         = ((TVTHeader *)Sender)->Font;

::DrawText(cCanv->Handle, (AnsiString(Column->Text)).c_str(), Column->Text.Length()+1,
             &R, AlignFlags[Column->Alignment]|DT_CALCRECT);

if(height < (unsigned)R.Bottom — R.Top + 4) height = R.Bottom-R.Top + 4;
RestoreDC(cCanv->Handle, sdc);
if(height > vstMain->Header->Height)        vstMain->Header->Height = height;
}
olegenty
Отправлено: 16.01.2007, 11:46


Ветеран

Группа: Модератор
Сообщений: 2412



1. Верное замечание, оно присутствует у PDataNode
2. не пробовал пока (но см. пример Doga)
3. надо сделать ReinitNode
Tantos
Отправлено: 17.01.2007, 05:46


Станционный диспетчер

Группа: Участник
Сообщений: 108



1. PDataNode описан только в обработке сравнения, нигде в исходных текстах VirtualTreeView он не описан.
2. После двухчасовой переделки примера Doga под 5 Билдер ничего принципиально нового в этом плане не увидел — присваивается ItemIndex нужной картинки из TImageList. Кроме того, он забыл положить файлы данных в каталог Data, так что никакие картинки не отображаются вообще.
4. А есть какие-нибудь соображения по поводу многострочных заголовков?

Отредактировано Tantos — 17.01.2007, 12:56
Doga
Отправлено: 17.01.2007, 14:29


Мастер участка

Группа: Участник
Сообщений: 575



2Tantos
QUOTE

он забыл положить файлы данных в каталог Data, так что никакие картинки не отображаются вообще.


В каталоге Data и не должно быть никаких файлов. Похоже, переделку под BCB5 Вы выполнили не совсем корректно... wink.gif
Tantos
Отправлено: 17.01.2007, 16:11


Станционный диспетчер

Группа: Участник
Сообщений: 108



QUOTE (Doga @ 17.01.2007, 21:29)
В каталоге Data и не должно быть никаких файлов. Похоже, переделку под BCB5 Вы выполнили не совсем корректно... wink.gif

Скорее всего cool.gif . Завтра еще помучаюсь. Отображение картинки меня не особо волнует. Все-таки хотелось бы разобраться с многострочным заголовком.

Вернуться в Вопросы программирования в C++Builder