Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.10.2014, 16:02   #1
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,897
Вопрос Получить данные из объекта TabControl

Доброго времени суток!
Есть код
Код:
unit frm_1;

...

var
  Form1: TForm1;

implementation

uses frm_2;

{$R *.dfm}

procedure TForm1.LVUsersDblClick(Sender: TObject);
var
  UserData: TTabData;
begin
  if LVUsers.Selected = nil then Exit;

  UserData.Nick := LVUsers.Items[LVUsers.ItemIndex].SubItems[0];
  UserData.UserID := StrToIntDef(LVUsers.Items[LVUsers.ItemIndex].SubItems[2], -1);

  Form2.ProcAddTab(UserData, True, True);
end;

end.

unit frm_2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, StdCtrls, ComCtrls, ToolWin, ExtCtrls, Contnrs;

type
  TTabData = record
    UserID: Integer;
    Nick: string;
    TempMessage: string;
  end;

...
  private
    { Private declarations }
  public
    { Public declarations }
    procedure ProcAddTab(UserData: TTabData; ChangeTab, ShowForm: Boolean);
  end;

var
  Form2: TForm2;
  UserData: TTabData;

implementation

uses frm_1;

{$R *.dfm}

procedure TForm2.ProcAddTab(UserData: TTabData; ChangeTab, ShowForm: Boolean);
var
  i: Integer;
begin
  if UserData.UserID = -1 then Exit;
  // Ищем пользователя на вкладках
  i := TabControl1.Tabs.IndexOfObject(TObject(UserData.UserID));

  if i = -1 then // Нет такого пользователя
  i := TabControl1.Tabs.AddObject(UserData.Nick, TObject(UserData.UserID));

  if ChangeTab then TabControl1.TabIndex := i; // Сделаем вкладку активной
  // Покажем форму если разрешено
  if ShowForm then ShowAs;
end;

procedure TForm2.TabControl1Change(Sender: TObject); // Событие после перехода на вкладку
var
  tbInd: Integer;
begin
  // Получаем пользователя на текущей вкладке
  tbInd := TabControl1.TabIndex;
  // Заполняем новыми данными
  LNick.Caption := ???;
  LID.Caption := IntToStr(???);
  MMessage.Text := ???;
end;

end.
Подскажите, пожалуйста, как в событии TabControl1Change из объекта TabControl1 (туда мы добавляем UserID, Name, Message (TabControl1.Tabs.AddObject)) вывести данные для выбранной вкладки.
Shouldercannon вне форума Ответить с цитированием
Старый 14.10.2014, 16:39   #2
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

Цитата:
i := TabControl1.Tabs.AddObject(UserData .Nick, TObject(UserData.UserID));
Код:
tbInd := TabControl1.TabIndex;
userid:=integer(TabControl1.Tabs.Objects(tbind));
программа — запись алгоритма на языке понятном транслятору
evg_m на форуме Ответить с цитированием
Старый 14.10.2014, 16:40   #3
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Ну коль записал UserID в Objects, то и выдерни его от туда:
Код:
Integer(TabControl1.Tabs.Objects[TabControl1.TabIndex])
А дальше ищи по нем данные в LVUsers
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 14.10.2014, 17:25   #4
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,897
По умолчанию

ListView трогать не надо. Берём данные только из самого объекта TabCotrol (Ник, ID (уже есть), что-то ещё (не знаю, допустим ли третий параметр или более)).
Код:
i := TabControl1.Tabs.AddObject(UserData.Nick, TObject(UserData.UserID)); // Создаём вкладку с привязанной к ней UserID
Получается, что Nick не храниться в объекте TabControl и его нужно брать из Caption вкладки?
Запутался в коде.
Код:
UserData: TTabData;
Это всего лишь контейнер, который постоянно перезаписывается при кликах по ListView и держать в себе весь список данных не может, так как не массив. Верно?

Последний раз редактировалось Shouldercannon; 14.10.2014 в 17:47.
Shouldercannon вне форума Ответить с цитированием
Старый 14.10.2014, 18:15   #5
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Nick из Caption и UserID есть. Нет TempMessage. А нужен? Ни где и не передается
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 14.10.2014, 20:38   #6
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,897
По умолчанию

TempMessage нужен обязательно
Код из старой версии проекта
Код:
procedure TForm2.TabControl1Change(Sender: TObject); // Событие после перехода на вкладку
begin
  // Получаем пользователя на текущей вкладке
  tbInd := TabControl1.TabIndex;
  // Заполняем новыми данными
  LNick.Caption := TTabData(TabControl1.Tabs.Objects[tbInd]).Nick;
  LID.Caption := IntToStr(TTabData(TabControl1.Tabs.Objects[tbInd]).UserID);
  MMessage.Text := TTabData(TabControl1.Tabs.Objects[tbInd]).TempMessage;
  // Загрузим историю переписки приватного чата
  LoadHistory(LID.Caption);
end;

procedure TForm2.TabControl1Changing(Sender: TObject;
  var AllowChange: Boolean); // Событие до перехода на вкладку
begin
  // Получаем пользователя на текущей вкладке
  tbInd := TabControl1.TabIndex;
  // Запишем данные пользователя. Работаем с полями пользоваьтельской записи напрямую
  if MMessage.Text <> '' then TTabData(TabControl1.Tabs.Objects[tbInd]).TempMessage := MMessage.Text; // Нечего пустоту записывать
end;

Последний раз редактировалось Shouldercannon; 14.10.2014 в 20:44.
Shouldercannon вне форума Ответить с цитированием
Старый 14.10.2014, 20:44   #7
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Значит нужно где-то держать. Или массив, или TList, или TObjectList, например с указателями на записи TTabData. И в Objects записывать не UserID, а индекс указателя. И позаботиться о корректной чистке, что бы утечек не было
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 14.10.2014, 21:44   #8
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,897
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
Значит нужно где-то держать. Или массив, или TList, или TObjectList, например с указателями на записи TTabData. И в Objects записывать не UserID, а индекс указателя. И позаботиться о корректной чистке, что бы утечек не было
Уже пробовал подобное здесь, но запнулся на моменте со сравнением объектов, при каждом обновлении ListView указатель каждый раз новый и появляются дубликаты вкладок.
Shouldercannon вне форума Ответить с цитированием
Старый 14.10.2014, 22:01   #9
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Примерно так не пробовал?
Код:
procedure TForm1.LVUsersDblClick(Sender: TObject);
begin
  if LVUsers.Selected = nil then Exit;
  Form2.ProcAddTab(LVUsers.Selected, True, True);
end;

procedure TForm2.ProcAddTab(UserData: TListItem; ChangeTab, ShowForm: Boolean);
var i: Integer;
begin
  i := TabControl1.Tabs.IndexOfObject(UserData);
  if i = -1 then i := TabControl1.Tabs.AddObject(UserData.SubItems[0],UserData);
end;

procedure TForm2.TabControl1Change(Sender: TObject);
var UserData: TListItem;
begin
  UserData:=TListItem(TabControl1.Tabs.Objects[TabControl1.TabIndex]);
  LNick.Caption := UserData.SubItems[0];
  LID.Caption := UserData.SubItems[2];
  MMessage.Text := UserData.SubItems[3];
end;
И при обновлении ListView не рушить итемы
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 14.10.2014 в 22:04.
Аватар вне форума Ответить с цитированием
Старый 15.10.2014, 06:55   #10
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,897
По умолчанию

К сожалению не вариант. В ListView только ID, Nick, ничего лишнего там не должно быть.
Может UserData: TTabData; превратить в UserData: array of TTabData; - это и будет наш массив с данными пользователей?
Честно, уже весь мозг вынес, пытаясь реализовать работу с вкладками TabControl как в ICQ или подобным им программам. Варианты есть, но у каждого серьёзные недостатки.

Последний раз редактировалось Shouldercannon; 15.10.2014 в 07:00.
Shouldercannon вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Получить 2 объекта особым образом hepr SQL, базы данных 1 12.03.2014 20:07
Jquery как из $(this) получить имя объекта? Abuhamed JavaScript, Ajax 2 12.02.2012 03:43
DelphiX, как получить текущие координаты объекта? codermoder Gamedev - cоздание игр: Unity, OpenGL, DirectX 3 17.03.2011 00:26
Как получить переменные из объекта Session? olgavv JavaScript, Ajax 1 16.03.2010 21:49
Как получить адрес свойства объекта? Lim Общие вопросы Delphi 3 30.11.2007 19:46