Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по Delphi (до версии 2009) - часть 5

Модерирует : ShIvADeSt

ShIvADeSt (19-05-2010 05:14): Продолжаем тут http://forum.ru-board.com/topic.cgi?forum=33&topic=11215  Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101

   

ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Продолжение темы Вопросы по Delphi (до версии 2009) - часть 4

Познаем сами, помогаем другим...
Обсуждаем вопросы, не связанные с юникоидными версиями Delphi - для этого есть соответствующая тема (см. ссылки ниже).

Правила топика:
    Прежде чем спрашивать:
  1. Желательно изучить вопрос, попытаться найти ответ в прилагаемых мануалах, хелпах и анализируя исходники.
  2. Выполнить поиск по топику (открыть "Версия для печати" и поискать ответ там).
  3. Применить фильтр по разделу "Прикладное программирование". Ответы на многие старые вопросы могли быть даны в отдельных темах.
  4. Продумайте вопрос. На поверхностные вопросы вы получите поверхностные ответы, или вообще ответов не получите.
  5. Желательно указывать версии используемого компилятора и операционной системы.
    Прежде чем отвечать:
  1. Если не можете помочь, не мешайте.
  2. Если уж вы отвечаете на вопрос, давайте ответ по сути.
  3. Если вы не уверены, так и говорите! Ошибочный, но авторитетно звучащий ответ хуже, чем отсутствие ответа.
  4. Задавайте дополнительные вопросы, чтобы получить больше информации.
  • Отсутствие ответа не равносильно игнорированию - иногда участники форума просто не знают ответ. Повторная посылка вопроса не приветствуется. Посты типа "неужели никто не знает ответа..." или "может мне все-таки кто-нибудь ответит" недопустимы.  
  • Все большие куски кода (более 5 строк) оформляем в тег [morе] дабы уменьшить размер поста. FAQ по тегу [morе].

  • Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 02:09 28-06-2009 | Исправлено: psa1974, 12:00 02-02-2010
    V1s1ter



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Kursist
    Вам ppkp все правильно подсказал, возможно Вы его не правильно поняли.

    Всего записей: 948 | Зарегистр. 06-02-2007 | Отправлено: 19:27 27-11-2009
    Kursist



    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    data man
    Спасибо за ссылку. Очень интересно было узнать.
     
    ppkp
    Я понял так: в классе дополнительную процедуру, которую себе же присвоишь, не опишешь - так как в классе неизвестно окружение, в котором будет находиться объект. К тому же, это более абстрактная сущность, желательно, самодостаточная. То есть, в любом случае должна присваиваться внешняя процедура. Статья по ссылке от data man очень понравилась.
     
    V1s1ter
    Да, извините, может и я чего не так понял. Но попытался объяснить свое понимание явления.
    Спасибо.

    Всего записей: 137 | Зарегистр. 12-07-2004 | Отправлено: 21:03 27-11-2009
    snike555



    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Помогите пожалуйста этот кусок для 2010 делфи скомпилить, конкретно аналог функции AnsiStrLIComp не могу в юникоде найти
     
    procedure TFrm1.VTIncrementalSearch(
      Sender: TBaseVirtualTree; Node: PVirtualNode;
      const SearchText: String; var Result: Integer);
    var
      Data : PData;
    begin
      Result := 0;
      Data := VT.GetNodeData(Node);
      if Assigned(Data) then
        begin
          if IsIntNumber(SearchText) then
            Result := AnsiStrLIComp(PChar(SearchText),
              PAnsiChar(AnsiString(Data^.ID)),
               Min(Length(SearchText), Length(Data^.ID)))
          else
            Result := AnsiStrLIComp(PChar(SearchText),
              PChar(Data^.R_NAME),
               Min(Length(SearchText), Length(Data^.R_NAME)));
        end;              
    end;

    Всего записей: 380 | Зарегистр. 02-10-2009 | Отправлено: 23:28 27-11-2009
    whitewolfs

    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Помогите плиз, не могу вроде простейшую задачу выполнить.
    Есть форма, на неё кидаю три TPanel + два TSplitter. Нужно чтобы панели делили форму на 3 области и размеры изменялись сплитерами вот так:
     
    --------------------------
    |         |                       |
    |         |----------------|
    |         |                       |
    |         |                       |
    --------------------------
     
    а получается только так:
     
    --------------------------
    |         |                       |
    |         |                       |
    |------------------------|
    |                                 |
    --------------------------
     
    Может кто нибудь подсказать или скинуть форму с нужным расположением панелей?

    Всего записей: 300 | Зарегистр. 21-10-2005 | Отправлено: 06:51 28-11-2009 | Исправлено: whitewolfs, 06:52 28-11-2009
    psa1974



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    whitewolfs
    кидаешь на форму 2 панели, разделяешь вертикальным сплитером. На правую панель кидаешь еще 2 панели, разделяешь горизонтальным сплиттером.

    Всего записей: 438 | Зарегистр. 08-11-2005 | Отправлено: 10:00 28-11-2009
    VMan80

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Туплю с TreeView, прошу помочь.
    Имеем многуровневое "дерево", например:
     
    Node1
    ---Level1
        --Level1
    ----Level2
    ----Level3
    Node2
    ---Level1
    ----Level2
    ----Level3
    и т.д.
     
    Вопрос, как программно перейти на Node1.Level1? Следующий код не срабатывает:
    var
      node : TTreeNode;
    begin
      node := TreeView1.Items[1];
      node.GetNextChild(node);  // вместо следующего уровня выбранного узла почему-то осуществляется переход на следующий узел
    end;
     

    Всего записей: 39 | Зарегистр. 01-09-2008 | Отправлено: 10:56 28-11-2009 | Исправлено: VMan80, 10:56 28-11-2009
    Frodo_Torbins

    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    VMan80
    У TTreeNode тоже есть свойство Item

    Всего записей: 2318 | Зарегистр. 24-05-2007 | Отправлено: 12:38 28-11-2009
    psa1974



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    VMan80
    Всю жизнь индексы в списках отсчитываются с нуля. Строкой node := TreeView1.Items[1]; ты переходишь на узел, имеющий индекс 1 но по счету он второй.

    Всего записей: 438 | Зарегистр. 08-11-2005 | Отправлено: 12:57 28-11-2009
    VMan80

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Frodo_Torbins
    Это я в курсе Но что дальше? К примеру: node.Item[0].Text или даже так: TreeView1.Items[1].Item[0].Text; выдает ошибку "List index out of bounds..
     
    Изначальная задача такая. Пишу компонент для выбора папки (директории) на основе TreeView. Вернее он практически уже готов. Хочу реализовать функцию, чтобы при запуске в дереве TreeView открывалась заданная папка (ветка). К примеру: C:\Test\1\. Хочу сделать так (думаю наиболее оптимальный по скорости работы путь, если нет - поправьте): из искомой строки в цикле поочередно выделяю сегмент для поиска: "C:\", "Test\" и "1\", которые затем поочередно буду искать в каждом соответствующем уровне дерева TreeView.  
    С первым уровнем все понятно (пример условный):
    SearchStr := "C:\";
    CurItem: = TreeView1.Items.GetFirstNode;
    while CurItem<>nil do
      begin
          if CurItem.Text = SearchStr then
              // вот тут нужно выполнить переход на следующий Level, чтобы пройти по его Item-am Но вот как?
              // если указать CurItem :=  CurItem.GetNextChild(CurItem); - то происходит переход на следующий Item  
              // на этом же уровне дерева, а мне надо перейти на новый Level !!!!!
          else
             CurItem: = CurItem.GetNext;
      end;
     

    Всего записей: 39 | Зарегистр. 01-09-2008 | Отправлено: 12:59 28-11-2009 | Исправлено: VMan80, 13:33 28-11-2009
    snike555



    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    функция AnsiStrLIComp - юникод аналог кто-нибудь подскажет?

    Всего записей: 380 | Зарегистр. 02-10-2009 | Отправлено: 12:59 28-11-2009
    psa1974



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    snike555

    Цитата:
    функция AnsiStrLIComp - юникод аналог кто-нибудь подскажет

    ничего военного, взято из Дельфи 2010, смотри за #

    Всего записей: 438 | Зарегистр. 08-11-2005 | Отправлено: 13:19 28-11-2009
    whitewolfs

    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    psa1974

    Цитата:
    кидаешь на форму 2 панели, разделяешь вертикальным сплитером. На правую панель кидаешь еще 2 панели, разделяешь горизонтальным сплиттером.

     
    Спасибо, видимо так и придется делать.

    Всего записей: 300 | Зарегистр. 21-10-2005 | Отправлено: 13:43 28-11-2009
    psa1974



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    VMan80

    Код:
     
      CurItem:= TreeView1.Items.GetFirstNode;
      begin
        if (CurItem.Text = SearchStr) and (CurItem.Count > 0) then
        begin
          // переход на след. вложенный узел:
          CurItem:= CurItem.getFirstChild;
          // переход на след. пункт в текущем узле:
          while Assigned(CurItem) and (CurItem.Text <> SearchStr) do
            CurItem:= CurItem.GetNextChild(CurItem);
        end
        else
           CurItem:= CurItem.GetNext;
      end;
     

    Это для одного уровня вложенности. Ну а полную рекурсию сам придумаешь.

    Всего записей: 438 | Зарегистр. 08-11-2005 | Отправлено: 14:12 28-11-2009 | Исправлено: psa1974, 14:14 28-11-2009
    VMan80

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    psa1974
    Спасибо, но не работает это все. Буду разбираться дальше.
     

    Всего записей: 39 | Зарегистр. 01-09-2008 | Отправлено: 17:11 28-11-2009 | Исправлено: VMan80, 17:12 28-11-2009
    psa1974



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    VMan80
    Или я тебя не понял, или одно из двух То как я понял, работает. Посмотри пример Ссылка тут я начинаю сканировать дерево с самого начала, пока не найду узел  с именем '113333', в метку на форме вывожу имя текущего узла...

    Всего записей: 438 | Зарегистр. 08-11-2005 | Отправлено: 17:38 28-11-2009
    VMan80

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    psa1974
    Не рабочий это код
     
    Суть. Имею дерево:

    Хочу, чтобы при запуске открывалась ветка D:\10\11\
    Начало пробного кода:
     

    Код:
     
    procedure TForm1.Button3Click(Sender: TObject);
    var
    i, j : integer;
    s,a: string;
     
    begin
    s := 'D:\10\11\'; // тестовая строка для поиска
    j:=0;
    node := TreeView1.Items.GetFirstNode;
    while Pos('\',s) > 0 do
      begin
      a:=Copy(s,1,Pos('\',s));  // искомая строка. При первой итерации "D:\"
      s:=Copy(s,Pos('\',s)+1,Length(s)-Pos('\',s)+1);
      j := j + 1;
        if length(a)>1 then
          begin
          if j = 1 then
            begin
            for i := 0 to TreeView1.Items.count-1 do  // сканирую корень дерева в поиске узла "D:\"
              if TreeView1.items[i].Text = a then
                break
              else
                node:=node.GetNextChild(node); // нашел, сохранил node
            end
          else
            if (node <> nil) and (node.HasChildren = true) then // узел "D:\" найден, далее нужно найти "10" на следующем уровне
              begin
              node:=node.GetFirstChild; // И ТУТ ОБЛОМ - NODE становится NIL, хотя мне нужно перейти на следующий Level
              while Assigned(node) and (Node.Text <> a) do
                begin
                  node:=node.GetNextChild(node);
    //            остальное тра-та-та будет потом
                end;
              end;
        end;
      end;
    end;
     

     
    P.S. Удивительно, но в Сети решения для такой вобщем-то тривиальной задачи не нашел. Изначально мне нужно создать диалог выбора папки на форме. Компонент ShellTreeView всем хорошо, но при использовании в качестве параметра Root := rfMyComputer при построении дерева принудительно идет обращение к дисководу, каждый раз при запуске формы порождая раздражающий скрежет. Как убить диск A:\ в ShellCtrls.pas мозга пока не хватило.  

    Всего записей: 39 | Зарегистр. 01-09-2008 | Отправлено: 18:01 28-11-2009 | Исправлено: VMan80, 18:11 28-11-2009
    data man



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    VMan80
    А почему бы не использовать VirtualShellTools ?
    Исходники брать лучше из SVN
     
    Или Virtual Shell Tree
       
     
    Или стоит задача написать именно свой компонент ?

    ----------
    Любой достаточно развитый тролль неотличим от подлинно помешанного на какой-либо идее.
    Кекс. Антибиотики. Ламбада.

    Всего записей: 1696 | Зарегистр. 13-10-2005 | Отправлено: 18:19 28-11-2009 | Исправлено: data man, 18:25 28-11-2009
    VMan80

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    data man
    Спасибо, попробую. Но и самому разобраться тоже интересно.  
     
    Добавлено:
    data man

    Цитата:
    А почему бы не использовать VirtualShellTools ?  


    Цитата:
    Или Virtual Shell Tree

    Попробовал - использовать не лучше. Страшно все тяжеловесное и тормозное. Скомпилированый exe на основе проекта с формой, на которой брошен один лишь такой объект тянет почти на 800 Кбайт. В Virtual Shell Tree сортировка дисков в дереве не по букве, а по типу (Локальный, Съемный и т.д.), т.е. каша полная. А по сути все это более навороченные варианты стандартного ShellTreeView с тем же скрежешущим дисководом при раскрытии ветки "Мой компьютер". Для реализации простейшей функции выбора папки на форме - все это слишком чересчур. Я таких компонент уже около десятка опробовал - фтопку все.

    Всего записей: 39 | Зарегистр. 01-09-2008 | Отправлено: 18:34 28-11-2009 | Исправлено: VMan80, 20:28 28-11-2009
    psa1974



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    VMan80
    Возьми пример:Ссылка или #
    Сдесь в конструкторе строится виртуальное дерево каталогов, затем по нажатию кнопки ищется конечная папка пути, указанного в окне ввода. Вроде это то что ты хочешь...
     

    Всего записей: 438 | Зарегистр. 08-11-2005 | Отправлено: 21:48 28-11-2009 | Исправлено: psa1974, 22:23 28-11-2009
    VMan80

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    psa1974
    Спасибо!!
    Я понял, где тупил: в целях ускорения построения дерева каталогов, у меня новый уровень строился только при его раскрытии. То есть несмотря на то, что HasChild был выставлен в true, узел далее был пустым. Соответственно не срабатывало GetNextChild. Вобщем алгоритм получился несколько другой:
     

    Код:
     
    function GetPath(Path: string; TreeView: TTreeView): boolean;
    var
    i, j : integer;
    a: string;
    begin
    j:=-1; // Level
    node := TreeView.Items.GetFirstNode;
    while Pos('\',path) > 0 do
      begin
      a:=Copy(path,1,Pos('\',path)-1); // искомая строка
      path:=Copy(path,Pos('\',path)+1,Length(path)-Pos('\',path)+1); // "остаток" строки для последующего поиска
      j := j + 1;
        if length(a)>1 then
          begin
          if j = 0 then
            begin
            for i := 0 to TreeView.Items.count-1 do
              if TreeView.items[i].Text = a+'\' then
                break
              else
                node:=node.GetNextChild(node);
            end
          else
            if (node <> nil) and (node.HasChildren = true) then
              begin
              node.Expanded := true;  // тут у меня заполняются чилдрены следующего уровня текущего нода
              while node <> nil do
                if Node.Text = a then break
                  else node:=node.GetPrevSibling;
              end;
        end;
      end;
    if node <> nil then
      begin
      node.Selected:=true;
      TreeView.SetFocus;
      result:=true
      end
    else
      result:=false;
    end;
     
    соответственно вызов:
    procedure TForm1.Button4Click(Sender: TObject);
    begin
      GetPath('D:\10\11\',TreeView1);
    end;
     

     
    Работает моментально  

    Всего записей: 39 | Зарегистр. 01-09-2008 | Отправлено: 10:17 29-11-2009 | Исправлено: VMan80, 10:45 29-11-2009
       

    Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101

    Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по Delphi (до версии 2009) - часть 5
    ShIvADeSt (19-05-2010 05:14): Продолжаем тут http://forum.ru-board.com/topic.cgi?forum=33&topic=11215


    Реклама на форуме Ru.Board.

    Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
    Modified by Ru.B0ard
    © Ru.B0ard 2000-2024

    BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

    Рейтинг.ru