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

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

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

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 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 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125

Открыть новую тему     Написать ответ в эту тему

ShIvADeSt



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

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


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


    Некоторые "родственные" топики:
     
  • Вопросы по Delphi (версии 2009-2010 Weaver)
  • Вопросы по компонентам для Delphi, C++ Builder
  • Использование DevExpress
  • Вопросы по Ehlib
  • Компоненты и утилиты для Delphi/BCB/FreePascal/Lazarus - только Open Source
  • Коммерческие компоненты и утилиты для Delphi/BCB
  • кабак программистов :)
     
    См. также: Некоторые полезные ресурсы о Delphi
     
    И старайтесь, чтобы ваш код не попал сюда :)

  • Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 05:13 19-05-2010 | Исправлено: akaGM, 02:33 15-07-2020
    Ichigo2



    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    ArtSnegirev
    Ха, получилось! Я бы не догадался. Всем спасибо.

    Всего записей: 153 | Зарегистр. 01-05-2011 | Отправлено: 10:18 06-03-2012
    Grande



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Уважаемые знатоки, не поможете ли с такой проблемой.
    Необходимо создать несколько (на начальном этапе количество неизвестно) экземпляров TForm - задача тривиальная. Но в каждом экземпляре одноименные переменные должны иметь своё, уникальное значение. На практике эти переменные принимают значение переменных последней созданной формы.
    Что-то голову сломал - не приходит ничего на ум. Помогите, пожалуйста.
    С уважением, Сергей ака Grande.

    Всего записей: 588 | Зарегистр. 18-09-2003 | Отправлено: 08:30 13-03-2012
    wasilissk

    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Grande
    Наследник класса TForm имеет несколько полей, при создании несколькоих экземпляров этого класса, необходимо инициализировать эти поля случайными неповторяющимися значениями.  
    Я правильно перевел?

    Всего записей: 293 | Зарегистр. 25-12-2006 | Отправлено: 08:57 13-03-2012
    Grande



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

    Всего записей: 588 | Зарегистр. 18-09-2003 | Отправлено: 09:14 13-03-2012
    wasilissk

    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Grande
    Завети генератор для этих полей и передавать его экземпляр в конструктор наследника TForm.

    Код:
     
    TGenerator = class
    private
      FCurValue: Integer;
    public
      function GetValue: Integer; // Result := Inc(FCurValue);
    end;
     
    TMyForm = class(TForm)
    private
      FSomeValue: Integer;
    public  
      constructor Create(.., Generator: TGenerator);
    end;  
     
    ........
     
    TMyForm.Create(.., Generator: TGenerator);
    begin
      ...
      FSomeValue := Generator.GetValue;
      ...
    end;
     

    Всего записей: 293 | Зарегистр. 25-12-2006 | Отправлено: 09:24 13-03-2012
    Grande



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    wasilissk
    Ага... Сейчас попробую, спасибо.

    Всего записей: 588 | Зарегистр. 18-09-2003 | Отправлено: 09:26 13-03-2012
    ant0ni02004

    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Grande
     
    Через class function + class var проще будет пожалуй

    Всего записей: 442 | Зарегистр. 26-10-2004 | Отправлено: 18:18 13-03-2012
    ArtSnegirev



    Newbie
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Grande
    создать статичный метод (или несколько), генерирующий уникальные данные на момент вызова
    class function TForm.GetUniqueValue; static;
    и вызывать его при создании формы в TForm.Create, заполняя нужные поля

    Всего записей: 20 | Зарегистр. 24-05-2004 | Отправлено: 21:54 13-03-2012
    wasilissk

    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    ArtSnegirev
    И текущие значения хранить в глобальных переменных?
    ant0ni02004
    Как начсет неповторяемости? Или все наследники должны знать друг о друге и проверять неповторяемость в цикле?
     
     
     
    Добавлено:
    ant0ni02004
    Кстати class var будет одна для всех экземпляров.

    Всего записей: 293 | Зарегистр. 25-12-2006 | Отправлено: 07:10 14-03-2012
    ArtSnegirev



    Newbie
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    wasilissk
    согласен, где-то придется хранить значения статического генератора, что неудобно
    видимо, предложенный вами вариант наиболее удобный

    Всего записей: 20 | Зарегистр. 24-05-2004 | Отправлено: 09:57 14-03-2012
    wasilissk

    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Проблемы с TOpenDialog и TSaveDialog.
    Открываем/Сохраняем  файл из/в расшаренной папки, этот путь где-то запоминается. Далее если это комп в сети более недоступен (я коннектился по сети к виртуальной машине), при вызове OpenDialog.Execute приложение наглухо виснет. Подобное же поведение наблюдается даже при перезапуске приложения, т.е. где-то в реестре запоминает эту папку, и в этом случае InitialDir = EmptyStr.  
    В качестве костыля можно указывать явно InitialDir каждый раз, но в таком случае теряем последнюю папку с которой работал пользователь.  
    Как грамонтно выйти из этой ситуации? Чтобы запоминать последнюю посещенную папку, но либо удалять ее если она указывает на папку в сети, либо указать таймаут для OpenDialog.Execute?

    Всего записей: 293 | Зарегистр. 25-12-2006 | Отправлено: 13:35 14-03-2012
    Grande



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    С этим прошло
    Нельзя ли еще вопрос?
    Создается несколько экземпляров TSocket, им назначается некая процедура приема (одна на всех).
    Сокеты делают запросы на сервер и получают ответ. А как потом выделить информацию для каждого сокета, ведь процедура приема-то одна?

    Всего записей: 588 | Зарегистр. 18-09-2003 | Отправлено: 16:50 14-03-2012
    ant0ni02004

    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    wasilissk
     
    кроме InitialDir нужно еще и FileName чистить

    Всего записей: 442 | Зарегистр. 26-10-2004 | Отправлено: 16:54 14-03-2012
    wasilissk

    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    ant0ni02004
    С этим нет проблем. При установке InitialDir все работает, я же хочу сохранить папку с которой пользователь работал.
    При запуске приложения когда InitialDir и FileName пусты, диалог открывает последнюю открытую папку (откуда он ее берет?) и если она в данный момент недоступна, виснет.
     
    Добавлено:
    Grande
    Процедура это обработчик чтоли? Там наверняка есть Sender, приводите его к вашему типу TSocket и работайте.

    Всего записей: 293 | Зарегистр. 25-12-2006 | Отправлено: 18:50 14-03-2012
    YuraseK

    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Пример кода
     
    Целый день ломаю голову над проблемой, но никак не могу понять. Проблема заключается в передаче метода в поток, а затем его выполнение в контексте основного потока. Я создал два варианта конструктора для класса TTestThread. Так вот проблема отражена при использовании второго конструктора constructor TTestThread.Create(const P: Pointer) и заключается в доступе к свойству Value класса TTest. Если экземпляр класса TTest является свойством класса TForm1, то возникает проблема в виде Access Violation, а в случае использвания в качестве глобальной переменной - нет. Как сделать так, чтобы работал первый вариант?

    Всего записей: 529 | Зарегистр. 12-12-2003 | Отправлено: 22:44 14-03-2012 | Исправлено: YuraseK, 22:53 14-03-2012
    delover

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    YuraseK
    Тут я любитель Delphi порекомендую вам СиШапр. Но только из гуманных соображений.

    Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 22:59 14-03-2012
    Frodo_Torbins

    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    YuraseK
    Ваш Button1Click это не просто процедура, это метод объекта. Указатели на методы объектов имеют длину не 4 байта, как все остальные, а 8. Во втором конструкторе вы теряете половину указателя.
    А вообще очень советую взглянуть на более новые версии делфей, там появились анонимные методы. Похоже именно они вам и нужны, если хотите полной универсальности.

    Всего записей: 2318 | Зарегистр. 24-05-2007 | Отправлено: 23:28 14-03-2012 | Исправлено: Frodo_Torbins, 23:32 14-03-2012
    YuraseK

    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Frodo_Torbins
    Спасибо за ответ. Требуется решение для 7-й версии. Я посмотрел в отладчике вызов метода идёт через [esp], а указатель на объект берётся из [esp+4], а там пусто.
    Я сделал небольшой финт, но работает:

    Код:
      asm
        mov eax, Form1;
        mov dword ptr [esp + 4], eax;
      end;

    Всего записей: 529 | Зарегистр. 12-12-2003 | Отправлено: 23:41 14-03-2012 | Исправлено: YuraseK, 23:52 14-03-2012
    Frodo_Torbins

    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    YuraseK
    А как быть с передачей параметров если они есть? Думаю самое время попробовать готовые библиотеки для организации многопоточности.

    Всего записей: 2318 | Зарегистр. 24-05-2007 | Отправлено: 00:07 15-03-2012 | Исправлено: Frodo_Torbins, 00:08 15-03-2012
    YuraseK

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

    Код:
    type
      PMethod = ^TMethod;
      TMethod = record
        Code, Data: Pointer;
      end;

       
      TTestThread = class(TThread)
        FObject: TObject;
        ...
      public
        ...
      end;
     
    procedure TForm1.Button2Click(Sender: TObject);
    var
      TestThread: TTestThread;
      NotifyEvent: TNotifyEvent;
    begin
      NotifyEvent:= Button3Click;
      TestThread:= TTestThread.Create(@@NotifyEvent); //указатель на указатель метода
      TestThread.Resume;
      TestThread.WaitFor;
      TestThread.Resume;
    end;
     
    constructor TTestThread.Create(const P: Pointer);
    begin
      inherited Create(True);
      FType:= True;
      with PMethod(P)^ do
        begin
          FObject:= Data;
          FProc:= Code;
        end;

    end;
     
    procedure TTestThread.DoProc;
    var
      NotifyEvent: TNotifyEvent;
    begin
      with PMethod(@@NotifyEvent)^ do
        begin
          Code:= FProc;
          Data:= FObject;
        end;

      NotifyEvent(FObject);
    end;

    Вполне даже элегантное решение.

    Всего записей: 529 | Зарегистр. 12-12-2003 | Отправлено: 00:43 15-03-2012 | Исправлено: YuraseK, 00:47 15-03-2012
    Открыть новую тему     Написать ответ в эту тему

    Страницы: 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 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125

    Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по Delphi (до версии 2009) - часть 6


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

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

    BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

    Рейтинг.ru