Форум: "Базы";
Текущий архив: 2005.08.28;
Скачать: [xml.tar.bz2];
ВнизГоспода, как можно "привязать" к TTreeNode номер записи Найти похожие ветки
← →
mmms (2005-07-11 08:52) [0]Т.е. предположим есть ветка в TTreeView "Продукты", от нее дочерние ноды "Колбаса", "Хлеб" и т.п. Нужно, чтобы юзер кликнул на "Хлеб", узнать, какой ID записи у "Хлеб", TTreeView заполняю записями из БД. Можно ли TTreeNode заполнить кроме Значениями ещё и скрытые параметры у каждого значения, например как Tag у многих компанетов, и потом, при клике на строку, определять этот параметр, а там всего цифровой код товара (по нему далее вся работа и идет).
Или, как вариант, по LIKE определять ID выбранной строки, но это лишняя нагрузка на БД, т.к. даже скольжение по TTreeView создаст множество запросов к серверу... хотя конечно, ID методом LIKE, по названию, можно не постоянно определять при скольжении, а например при двойном клике не этом товаре.
Т.е. вопрос, можно ли как то рядом с позицией в TTreeView "вбивать" ее код.
← →
k2 © (2005-07-11 08:54) [1]node.data
← →
mmms (2005-07-11 09:00) [2]Можно ли данного примера показать, заполняюю этой процедурой..
{ **** UBPFD *********** by delphibase.endimus.com ****
>> Процедура заполнения компонента TTreeView данными из TDataSet-совместимой выборки
Процедура заполнения компонента TTreeView данными из TDataSet-совместимой
выборки типа: idNode int, idParentNode int, cNodeName varchar, ...
Важно: корневой узел дерева должен быть первой записью выборки.
Зависимости: Windows, SysUtils, DB, ComCtrls
Автор: Delirium, Master_BRAIN@beep.ru, ICQ:118395746, Москва
Copyright: Master BRAIN (Delirium)
Дата: 18 октября 2002 г.
***************************************************** }
procedure FillTree(Tree: TTreeView; Query: TDataSet; idNode, idParent,
cNodeName: string);
var
i: integer;
begin
// Корневой узел, должен быть первым в выборке Query
Query.First;
Tree.Items.Clear;
Tree.Items.AddObject(nil, Query.FieldByName(cNodeName).AsString,
Pointer(Query.FieldByName(idNode).asInteger));
Query.Next;
while not Query.Eof do
begin
i := 0;
while i < Tree.Items.Count do
if Tree.Items.Item[i].Data = Pointer(Query.FieldByName(idParent).asInteger)
then
begin
Tree.Items.AddChildObject(Tree.Items.Item[i],
Query.FieldByName(cNodeName).AsString,
Pointer(Query.FieldByName(idNode).asInteger));
break;
end
else
Inc(i);
Query.Next;
end;
end;
← →
k2 © (2005-07-11 09:15) [3]вместо idParent писать при заполнении дерева в Data букмарку, например:
Tree.Items.AddObject(nil, Query.FieldByName(cNodeName).AsString, Query.GetBookmark);
при клике по нодам дерева переходить в датасете на соответствующую запись
← →
evvcom © (2005-07-11 09:23) [4]А что, запрос не может возвратить уже отсортированное нужным образом дерево, чтобы не сканить после каждого Next весь TreeView? При большом количестве записей в этом месте наступят бАльшие тормоза. База-то какая?
← →
mmms (2005-07-11 09:30) [5]
k2 © (11.07.05 09:15)
Интересное предложение, с GetBookmark попробовал, может что делаю не так (никогда до этого не сталкивался), перестала строится структура с ним, т.е. без Pointer(Query..[4] evvcom © (11.07.05 09:23)
Да, таблица может быть и 1000 позиций, может и 10000 быть. Поэтому захотелось сделать древовидное меню, для быстроты выбора товара по его типу. Процедура от Delirium идеально подходит, вот только как "получить" значение ID товара не знаю.
← →
Anatoly Podgoretsky © (2005-07-11 09:39) [6]Третий параметр AddChildObject - это пользовательские данные, если у тебя ID = Integer, то можешь его прямо писать через приведение к Pointer и обратно.
← →
ANB © (2005-07-11 09:42) [7]
> mmms (11.07.05 09:30) [5]
- есть предложение. Имхо. Сами товары храни в плоской таблице с привязкой к древовидной с группами товаров. Тогда легко переключать - дерево / алфавитный список (не всем пользователям и не во всех режимах работы нравится работать с деревом) и инфы в дереве можно по минимуму хранить, а товары группы можно доставать отдельным запросом с любыми полями. И тормозить при закачке сильно не будет, так как групп сильно много не бывает. Кстати, в оракле есть CONNECT BY, который сам дерево строит.
← →
evvcom © (2005-07-11 09:50) [8]
> как "получить" значение ID товара не знаю
В примере Query.FieldByName(idNode).asInteger - это и есть "получение ID", в чем проблема?
> может быть и 1000 позиций, может и 10000 быть
Удивляет игнорирование авторами уточняющих вопросов! 10000 - это довольно много. Даже при одноразовом пробеге по такому количеству записей для построения TreeView будет заметна пауза. А уж при
> while not Query.Eof do
> begin
> i := 0;
> while i < Tree.Items.Count do
эта пауза превратится в "смерть"!
Во-первых, надо подумать о сокращении количества выбираемых данных.
Во-вторых, отсортировать возвращаемый набор средствами SQL. Как? Для этого мы должны услышать ответ на вопрос
> База-то какая?
Который был проигнорирован.
← →
evvcom © (2005-07-11 09:54) [9]
> Кстати, в оракле есть CONNECT BY
Вот и я к тому же. Только фиг знает какой сервак у автора, а то может у него вовсе базы dBase или Paradox? А мы тут надрывайся ему, советуй из чего космический корабль построить, когда у него инструментов на велосипед недостаточно.
← →
mmms (2005-07-11 10:18) [10]
evvcom © (11.07.05 09:54)
прошу прощения, MSSQL2000, в принципе понятно, лучше старым дедовским способом, связанные таблицы, вид-товар. Сортировать... под данную процедуру это сложно, если надо что бы родители были всегда вверху.
← →
mmms (2005-07-11 10:20) [11]
rowid idnode idchildnode caption
1 1 1 Магазин
2 2 1 Продукты
3 30 1 Электроника
4 40 1 Бытовая химия
5 50 2 Фрукты
6 51 2 Овощи
7 52 2 Молочные
8 1 52 Молоко
9 1 52 Кефир
10 1 52 Сгущ. молоко
11 1 52 Ряженка
12 1 52 Сыр
13 1 52 Творог
14 1 51 Картофель
15 1 51 Морковка
16 1 51 Огурцы
17 1 50 Яблоки
18 1 50 Груша
19 1 50 Слива
20 100 30 DVD-плеер
21 101 30 Телевизор
22 102 30 Видеомагнитофон
23 103 30 Музыкальные центры
24 1 100 BBK 911 S
25 1 100 BBK 911
26 1 100 BBK 912 S
27 1 100 BBK 912
28 1 101 Sony 21""
29 1 101 Sony 25""
30 1 102 LG 944
31 1 102 LG 945
Как пример, вывод на экран только DVD-плеера...
← →
msguns © (2005-07-11 10:24) [12]>mmms
Дай мыло, вышлю форму-модуль древовидного справочника
← →
mmms (2005-07-11 10:28) [13]
msguns © (11.07.05 10:24)
worldsite2000 @ mail.ru
Заранее благодарю :)
← →
evvcom © (2005-07-11 10:35) [14]1. idchildnode заменить на idparentnode или вообще на idparent
2. НД лучше отсортировать в виде:
id idparent caption level
1 1 Магазин 1
30 1 Электроника 2
...
40 1 Бытовая химия 2
2 1 Продукты 2
50 2 Фрукты 3
1 50 Яблоки 4 ***
1 50 Груша 4 ***
1 50 Слива 4 ***
51 2 Овощи 3
1 51 Картофель 4 ***
1 51 Морковка 4 ***
1 51 Огурцы 4 ***
52 2 Молочные 3
1 52 Молоко 4 ***
1 52 Кефир 4 ***
1 52 Сгущ. молоко 4 ***
1 52 Ряженка 4 ***
1 52 Сыр 4 ***
1 52 Творог 4 ***
3. id должен быть уникальным, поэтому записи помеченные *** имеют неверные id
4. добавить поле level, для более простого анализа на клиенте
5. пример построения дерева для MSSQL давали мастера на этом форуме. Уже не помню кто. Сейчас сделал поиск: не нашел. Привожу тот код:
CREATE FUNCTION TreeFromTable (@Root INT)
RETURNS @T TABLE (ID INT, Owner INT, level INT) AS
BEGIN
DECLARE @level INT
SET @Level=0
INSERT @T SELECT @Root, 0, 0
while exists(SELECT * FROM @T T, Structure S WHERE
T.level=@level and S.Owner=T.ID)
begin
INSERT @T (ID,Owner,Level)
SELECT S.ID, S.Owner, @level+1 from @T T, Structure S WHERE T.level=@level and S.Owner=T.ID
SET @level=@level+1
end
RETURN
END
← →
msguns © (2005-07-11 11:08) [15]Лови. Комментарии в письме.
← →
mmms (2005-07-11 11:18) [16]
msguns © (11.07.05 11:08)
Сергей, пока ничего нет, там пробелы между собачкой, если в них дело, или должно позже подойти, буду ждать, спасибо.evvcom © (11.07.05 10:35)
Так же спасибо за решение, idnode и idchildnode это не ID товара, а указатели для древовидного меню (кстати, рисуется очень хорошо :) ) а вот rowid и есть ID товара, из за нее весь сыр бор.
← →
msguns © (2005-07-11 11:31) [17]>mmms (11.07.05 11:18) [16]
БД там интербэйз и "ветки" вытаскиваются хранимкой. Уже отсортированной по узлам.
Основа же в том, что записи БД помещаются в объекты, указатели на которых и "засовываются" в тривью. Весь справочник не считывается (для этого есть режим линейного просмотра), т.к. одномоментно надо показывать лишь одну (текущую в тривью) группу/подгруппу. Т.е. юзер кликает на узле тривью и в гриде отображается содержимое его листьев, а также листьев подчиненных узлов.
← →
msguns © (2005-07-11 11:33) [18]>msguns © (11.07.05 11:31) [17]
>Т.е. юзер кликает на узле тривью и в гриде отображается содержимое его листьев, а также листьев подчиненных узлов.
Отображаются только листья текущего узла. Извиняюсь за путаницу - проект старый, уже подзабыл ;)
← →
evvcom © (2005-07-11 11:36) [19]
> а вот rowid и есть ID товара
Тогда idparent должен ссылаться на этот rowid. А вообще смысл rowid несколько иной, поэтому, чтобы избежать кривотолков в будущем, советую все же row из этого названия убрать.
← →
mmms (2005-07-11 11:37) [20]
[18] msguns © (11.07.05 11:33)
Да ничего, хорошо, посмотрю как у других это делается :)
← →
Ega23 © (2005-07-11 11:39) [21]
unit uKdrDBTreeView;
interface
uses Windows, SysUtils, Classes, comctrls, stdctrls, db, graphics, controls,
Dialogs, contnrs;
Type
TCustomKdrDBTreeView=class;
TKdrDBTreeViewItemIdent = class(TObject)
private
FParentKeyFieldValue: Variant;
FKeyFieldValue: Variant;
FDisplayFieldValue: String;
FImageFieldValue: Integer;
FNode: TTreeNode;
public
property KeyFieldValue:Variant Read FKeyFieldValue Write FKeyFieldValue;
property ParentKeyFieldValue:Variant Read FParentKeyFieldValue Write FParentKeyFieldValue;
property DisplayFieldValue:String Read FDisplayFieldValue Write FDisplayFieldValue;
property ImageFieldValue:Integer Read FImageFieldValue Write FImageFieldValue;
property Node:TTreeNode Read FNode Write FNode;
end;
TTreeDataLink = class(TDataLink)
private
FTree: TCustomKdrDBTreeView;
FMinParent: Integer;
FMinValue: Integer;
public
constructor Create(ATree:TCustomKdrDBTreeView);
procedure DataSetChanged; override;
procedure ActiveChanged; override;
property MinParent:Integer Read FMinParent Write FMinParent;
property MinValue:Integer Read FMinValue Write FMinValue;
end;
TCustomKdrDBTreeView = class(TCustomTreeView)
private
FDataLink: TTreeDataLink;
FTreeItems:TObjectList;
FKeyField: String;
FDisplayField: String;
FParentField: String;
FDataSource: TDataSource;
Inh_TVChange: TTVChangedEvent;
procedure SetFDataSource(const Value: TDataSource);
protected
function LocateByNode(Node:TTreeNode):Boolean;
procedure TVChange(Sender: TObject; Node: TTreeNode);
procedure AddAllNodes(ParentID: Integer; ParentNode:TTreeNode);
function SetSelectedNode(const Value:Variant):TTreeNode;
property DataSource:TDataSource Read FDataSource Write SetFDataSource;
property DisplayField:String Read FDisplayField Write FDisplayField;
property KeyField:String Read FKeyField Write FKeyField;
property ParentField:String Read FParentField Write FParentField;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Clear;
procedure DataChanged;
procedure ActiveChanged;
function AddItem:Integer;
end;
TKdrDBTreeView = class (TCustomKdrDBTreeView)
published
property DataSource;
property DisplayField;
property KeyField;
property ParentField;
end;
implementation
{ TTreeDataLink }
//*****************************************************************************
procedure TTreeDataLink.ActiveChanged;
var
i:Integer;
begin
inherited;
FTree.Clear;
if (DataSet.Active) and (FTree<>nil) and (dsBrowse in [DataSet.State]) then
begin
BufferCount:=DataSet.RecordCount;
i:=0;
ActiveRecord:=i;
MinParent:=DataSet.FieldByName(FTree.KeyField).Value;
MinValue:=DataSet.FieldByName(FTree.ParentField).Value;
While (i<BufferCount) do
begin
FTree.AddItem;
With DataSet do
begin
if MinValue>FieldByName(FTree.KeyField).AsInteger then
MinValue:=FieldByName(FTree.KeyField).AsInteger;
if MinParent>FieldByName(FTree.ParentField).AsInteger then
MinParent:=FieldByName(FTree.ParentField).AsInteger;
end;
Inc(i);
ActiveRecord:=i;
end;
FTree.ActiveChanged;
ActiveRecord:=0;
end;
end;
//*****************************************************************************
constructor TTreeDataLink.Create(ATree: TCustomKdrDBTreeView);
begin
inherited Create;
FTree:=ATree;
VisualControl:=True;
end;
← →
Ega23 © (2005-07-11 11:39) [22]
//*****************************************************************************
procedure TTreeDataLink.DataSetChanged;
begin
inherited;
if (DataSet.Active) and (FTree<>nil) and (dsBrowse in [DataSet.State]) then
FTree.DataChanged;
end;
//*****************************************************************************
{ TKdrDBTreeView }
procedure TCustomKdrDBTreeView.ActiveChanged;
begin
Items.BeginUpdate;
AddAllNodes(FDataLink.MinParent, nil);
Items.EndUpdate;
end;
//*****************************************************************************
procedure TCustomKdrDBTreeView.AddAllNodes(ParentID: Integer;
ParentNode: TTreeNode);
var
k:Integer;
CurrNode:TTreeNode;
begin
for k:=0 to FTreeItems.Count-1 do
begin
With TKdrDBTreeViewItemIdent(FTreeItems.Items[k]) do
begin
if (Node<>nil) or (ParentKeyFieldValue<>ParentID) then Continue;
if ParentNode=nil then
CurrNode:=Items.Add(nil, DisplayFieldValue)
else
CurrNode:=Items.AddChild(ParentNode, DisplayFieldValue);
CurrNode.ImageIndex:=ImageFieldValue;
CurrNode.SelectedIndex:=ImageFieldValue;
Node:=CurrNode;
CurrNode.Data:=FTreeItems.Items[k];
AddAllNodes(KeyFieldValue, CurrNode);
end; // With
end; // for
end;
//*****************************************************************************
function TCustomKdrDBTreeView.AddItem: Integer;
var
i:Integer;
begin
try
i:=FTreeItems.Add(TKdrDBTreeViewItemIdent.Create);
With TKdrDBTreeViewItemIdent(FTreeItems.Items[i]) do
begin
KeyFieldValue:=FDataLink.DataSet.FieldByName(KeyField).Value;
ParentKeyFieldValue:=FDataLink.DataSet.FieldByName(ParentField).Value;
DisplayFieldValue:=FDataLink.DataSet.FieldByName(DisplayField).AsString;
end;
except
Result:=-1;
end;
end;
//*****************************************************************************
procedure TCustomKdrDBTreeView.Clear;
var
i:Integer;
begin
FTreeItems.Clear;
Items.Clear;
end;
//*****************************************************************************
constructor TCustomKdrDBTreeView.Create(AOwner: TComponent);
begin
inherited;
HideSelection:=False;
FDataLink:=TTreeDataLink.Create(Self);
FTreeItems:=TObjectList.Create(True);
if Assigned(Self.OnChange) then Inh_TVChange:=Self.OnChange;
Self.OnChange:=TVChange;
end;
//*****************************************************************************
procedure TCustomKdrDBTreeView.DataChanged;
begin
Selected:=SetSelectedNode(FDataLink.DataSet.FieldByName(KeyField).AsInteger);
end;
//*****************************************************************************
destructor TCustomKdrDBTreeView.Destroy;
begin
FTreeItems.Free;
FDataLink.Free;
inherited;
end;
//*****************************************************************************
function TCustomKdrDBTreeView.LocateByNode(Node: TTreeNode): Boolean;
var
i:Integer;
V:Variant;
keyFields:String;
begin
Result:=False;
for i:=0 to FTreeItems.Count-1 do
if TKdrDBTreeViewItemIdent(FTreeItems.Items[i]).Node=Node then
begin
V:=VarArrayCreate([0,1], varVariant);
V[0]:=TKdrDBTreeViewItemIdent(FTreeItems.Items[i]).KeyFieldValue;
V[1]:=TKdrDBTreeViewItemIdent(FTreeItems.Items[i]).ParentKeyFieldValue;
keyFields:=KeyField+";"+ParentField;
Result:=FDataLink.DataSet.Locate(KeyFields,V , []);
end;
end;
//*****************************************************************************
procedure TCustomKdrDBTreeView.SetFDataSource(const Value: TDataSource);
begin
if (Value<>nil) and (FDataSource<>Value) then
begin
FDataSource := Value;
FDataLink.DataSource:=Value;
end;
end;
//*****************************************************************************
function TCustomKdrDBTreeView.SetSelectedNode(
const Value: Variant): TTreeNode;
var
i:Integer;
begin
Result:=nil;
for i:=0 to FTreeItems.Count-1 do
With TKdrDBTreeViewItemIdent(FTreeItems.Items[i]) do
if KeyFieldValue=Value then
begin
Result:=Node;
Break;
end;
end;
//*****************************************************************************
procedure TCustomKdrDBTreeView.TVChange(Sender: TObject; Node: TTreeNode);
begin
LocateByNode(Node);
if (@Inh_TVChange<>nil) then Inh_TVChange(Sender, Node);
end;
//*****************************************************************************
end.
← →
Андрей Жук © (2005-07-11 16:20) [23]
{
Формат елементів усіх дерев
mem_id - обовязково. Ідентифікатор елемента
mem_pid - обовязково. Ідентифікатор "батьківського" елемента
is_leaf - обовязково. Ознака, чи є елемент елементом нижнього рівня
outlevel - обовязково. Рівень елемента
mem_order - обовязково. Порядковий номер в структурі
mem_name - обовязково. Назва елемента
mem_desc - обовязково. Описання елемента
mem_type - не обовязково. Тип елемента
}
type
TMyTreeNodes = record
mem_id: integer;
mem_pid: integer;
is_leaf: boolean;
outlevel: integer;
mem_order: integer;
mem_name: string;
mem_desc: string;
mem_type: string;
changing: boolean; // чи змінювалися дані в обєкті
inserting: boolean; //чи є обєкт доданим (без відображення в базі)
ParentNode: TTreeNode;
end;
PTMyTreeNodes = ^TMyTreeNodes;
function GenerateTree(Tree: TTreeView; DataSet: TDataSet): TFunctionResult;
var
FunctionResult: TFunctionResult;
vData: PTMyTreeNodes;
Node, LastNode: TTreeNode;
begin
Result.Successful := false;
// якщо дерево чи датасет не ініціалізовані, зупинити виконання
if not Assigned(Tree) or not Assigned(DataSet) then
begin
Result.MessageOnError := "Programmer error - not initilized objects on creating tree";
Exit;
end;
// якщо датасет не активний, то зупинити виконання
if not DataSet.Active then
begin
Result.MessageOnError := "Programmer error - not activated Dataset";
Exit;
end;
// очистимо дерево, якщо помилка зупинити виконання
try
LockWindowUpdate(Tree.Parent.Handle);
FunctionResult := ClearTree(Tree);
if not FunctionResult.Successful then
begin
Result.MessageOnError := FunctionResult.MessageOnError;
Exit;
end;
// заповнимо дерево
with DataSet do
begin
LastNode := nil;
First;
while not Eof do
begin
New(vData); // створимо елемент
with vData^ do
begin
// заповнюємо його поля
try
mem_id := FindField("mem_id").AsInteger;
mem_pid := FindField("mem_pid").AsInteger;
is_leaf := boolean(FindField("is_leaf").AsInteger);
outlevel := FindField("outlevel").AsInteger;
mem_order := FindField("mem_order").AsInteger;
mem_name := FindField("mem_name").AsString;
mem_desc := FindField("mem_desc").AsString;
if Assigned(FindField("mem_type")) then
mem_type := FindField("mem_type").AsString
else
mem_type := "general";
changing := false;
inserting := false;
except on E: Exception do
begin
Result.MessageOnError := "Programm error - incompatible structure" + #10#13 + "Details: " + E.Message;
Exit;
end;
end;
// якщо це елемент верхнього рівня, то додамо його в корінь
if vData.outlevel = 1 then
begin
Node := Tree.Items.Add(nil, vData^.mem_desc);
vData.ParentNode := nil;
end
// якщо елемент нижчого рівня, то додати як "сина"
else if PTMyTreeNodes(LastNode.Data)^.outlevel < vData.outlevel then
begin
Node := Tree.Items.AddChild(LastNode, vData^.mem_desc);
vData.ParentNode := LastNode;
end
// якщо елемент одного рівня, то додати як "брата"
else if PTMyTreeNodes(LastNode.Data)^.outlevel = vData.outlevel then
begin
Node := Tree.Items.AddChild(LastNode.Parent, vData^.mem_desc);
vData.ParentNode := LastNode.Parent;
end
// якщо елемент вищогого рівня, то знайти "підходящого батька" та додати як "сина"
else if PTMyTreeNodes(LastNode.Data)^.outlevel > vData.outlevel then
begin
while PTMyTreeNodes(LastNode.Data)^.outlevel >= vData.outlevel do
LastNode := LastNode.Parent;
Node := Tree.Items.AddChild(LastNode, vData^.mem_desc);
vData.ParentNode := LastNode.Parent;
end;
// занесення даних до структури
Node.Data := vData;
LastNode := Node;
Next;
end;
end;
end;
Result.Successful := true;
finally
LockWindowUpdate(0);
end;
end;
← →
Ega23 © (2005-07-11 16:27) [24]2 Андрей Жук © (11.07.05 16:20) [23]
Я бы на твоём месте вот сюда// заповнимо дерево
with DataSet do
begin
LastNode := nil;
First;
while not Eof do
ещё DisableControls поставил (в конце - EnableControls).
← →
mmms (2005-07-18 10:24) [25]Приветствую всех!
Снова с TreeView,
Код от mmms (11.07.05 09:00)
Как можно узнать вот это Pointer(Query.FieldByName(idNode).asInteger) значение, например в Showmessage("");, т.е. привести к string.
← →
mmms (2005-07-18 10:25) [26]Делаю так, ошибка:
procedure TForm1.tvClick(Sender: TObject);
begin
Showmessage(PString(tv.Selected.Data)^);
end;
← →
Ega23 © (2005-07-18 10:46) [27]Слушай, может ты сначала какую-нибудь книжку почитаешь? Про типы данных, например? Про указатели? Про классы?
Чтобы вот с таим-вот Showmessage(PString(tv.Selected.Data)^) не позориться?
← →
Anatoly Podgoretsky © (2005-07-18 10:56) [28]Ega23 © (18.07.05 10:46) [27]
Не царское дело!
← →
mmms (2005-07-18 11:26) [29]Послать к книге понятно, проще всего, я понять не могу, как через указатель, прочитать значение. В данном случае это нетипизированный указатель, который может указывать на данные произвольного типа. Видимо не туда "обращаюсь" чтобы прочитать данные...
И 2й вопрос, можно ли запихнуть в коде[2] mmms (11.07.05 09:00)
Data типа String. Я просто туда буду писать 2 строки, вместо теперешноего одного числа. Вопрос в том, что делая это, у меня не происходит "отрисовки меню", т.е. дальше строки
if Tree.Items.Item[i].Data = Pointer(Query.FieldByName(idParent).asString)
Как будто String не сравнивается...
← →
Ega23 © (2005-07-18 11:28) [30]Читай про PChar
← →
evvcom © (2005-07-18 11:35) [31]
> Я просто туда буду писать 2 строки
Это как? В Pointer можно записать только один указатель. Неважно на что: string, char, integer или вообще на мусор. Важно, как этот указатель будешь потом интерпретировать.
> Как будто String не сравнивается
В [2] никаких указателей на string я не увидел, поэтому делать какие-то выводы просто не из чего.
← →
mmms (2005-07-18 13:57) [32]Ega23
Хорошо, почему так ошибку выдает, что я не так пишу? (прошу извинить за такие вопросы)
procedure TForm1.tvClick(Sender: TObject);
begin
Showmessage(PChar(tv.Selected.Data));
end;
evvcom
Ну да, сейчас пишется ссылка на Integer, я хотел вместо этого Integer TStringList хранить, текст типа "fdfg"+#13#10+"fdgfgfg"... и по TStringList делать сравнение в условии, да что то не сравнивается, и в итоге кроме одного итема на Tree больши ничего нет, что и логично. Но это заморочки мои, мне надо всего лишь записать + вытащить число в Data. Был бы Tag, как бы хорошо было :) То что тут код был.. он конечно хорош, но процедура [2] мне очень подходит, осталось только достать Data.
← →
evvcom © (2005-07-18 14:08) [33]
> почему так ошибку выдает
Что за ошибка? Неужели влом написать?
> ... и по TStringList делать сравнение в условии, да что
> то не сравнивается
Ну долго мы в телепатов будем играть? Ну прям Пельш новоиспеченный с игрой "Угадай, мою писанину!"
← →
mmms (2005-07-18 14:31) [34]EAccessViolation
"Access violation at address ..."
← →
Anatoly Podgoretsky © (2005-07-18 14:34) [35]У тебя указатель не верный!
← →
mmms (2005-07-18 14:45) [36]Анатолий, так я понял, я с утра хочу спросить, как верный то написать :(
Showmessage(PChar(tv.Selected.Data));
← →
mmms (2005-07-18 14:45) [37]Удалено модератором
← →
Ega23 © (2005-07-18 14:47) [38]Блин, ты сначала разберисть, что ты в tv.Selected.Data раньше положил. В каком виде?
← →
Anatoly Podgoretsky © (2005-07-18 14:48) [39]mmms (18.07.05 14:45) [36]
Если в tv.Selected.Data ASCIIZ то приведение правильное
← →
mmms (2005-07-18 14:59) [40]Блин, ты сначала разберисть, что ты в tv.Selected.Data раньше положил. В каком виде?
Разобрался.. Ложу Integer, (код [2] mmms (11.07.05 09:00)), как этот интегер считать?
В режиме отладки посмотрел, tv.Items.Item[0].Data=$64,procedure TForm1.tvClick(Sender: TObject);
begin
if tv.Items.Item[0].Data<> nil then
Showmessage(PChar(tv.Items.Item[0].Data)); //=$64
end;
Страницы: 1 2 вся ветка
Форум: "Базы";
Текущий архив: 2005.08.28;
Скачать: [xml.tar.bz2];
Память: 0.6 MB
Время: 0.038 c