Изменить свойства объекта через dll. Delphi.

Тема в разделе "Другие языки", создана пользователем AndreyD2, 29 май 2009.

Статус темы:
Закрыта.
Модераторы: Цукер
  1. AndreyD2

    AndreyD2

    Регистр.:
    21 окт 2008
    Сообщения:
    194
    Симпатии:
    67
    Такая проблема.
    Как изменить свойсва объектов на форме.
    Например сделать label1.Enabled = false и bitbtn1.Enabled = false при нажатии на кнопку.

    Данные свойство должна изменить dll написанная в delphi, используя данные с формы вызова.
     
  2. jik

    jik

    Регистр.:
    11 мар 2009
    Сообщения:
    243
    Симпатии:
    133
    Нужны уточнения:
    1) Форма находится в чужом exe или в своем? Исходники есть?
    2) Приведите фрагмент кода, как Вы это делаете и что не получается.
    3) Хотелось бы понять уровень Ваших знаний в delphi. То ли Вы хотите в своем проекте создать dll и обращаться из нее к компонентам на главной форме (тогда это вопрос новичка), то ли Вы к чужому exe хотите приложить dll, чтобы он следил за программой и управлял свойствами компонентов на форме налету. Если второе, то где постановка задачи: какова степень свободы? можно влезать в exe и менять его или он должен остаться нетронутым? кто запустит dll? какую часть способны сделать Вы сами?
     
  3. AndreyD2

    AndreyD2

    Регистр.:
    21 окт 2008
    Сообщения:
    194
    Симпатии:
    67
    1. Форма находится в чужом exe, в котором встроен внутренний язык программирования Delphi-script.

    2. Пример.

    Код:
    procedure TSimpleForm.BitBtn2Click(Sender: TObject);
    var
    Wrap;
    begin
     Wrap := CreateOleObject('DynamicWrapper');
    
      Wrap.Register ('D:\Disc C\Projects D7\test dll\Project1.dll', 'GetSimpleText', 'i=l', 'f=s', 'r=l');
      bminformation(Wrap.GetSimpleText(koledit.Value));
    end;
    В примере вылетает сообщение с текстом сгенеренным в длл.

    Подключить dll получается только так
    Код:
    http://www.script-coding.info/dynwrap.html
    3. Что не понятно:
    как из dll Управлять компонентами на форме
     
  4. jik

    jik

    Регистр.:
    11 мар 2009
    Сообщения:
    243
    Симпатии:
    133
    если есть описание формы TSimpleForm, то можно передать указатель на форму в функцию:

    Код:
    procedure TSimpleForm.BitBtn2Click(Sender: TObject);
    var
    Wrap;
    begin
     Wrap := CreateOleObject('DynamicWrapper');
      Wrap.Register ('D:\Disc C\Projects D7\test dll\Project1.dll', 'SendFormToDll', 'i=l', 'f=s', 'r=l');
      Wrap.SendFormToDll(Self);
    end;
    В Project1 добавить функцию SendFormToDll(p: Integer) и преобразовать
    параметр в указатель на форму:
    Код:
    var FormFromExe: TSimpleForm;
    ...
    FormFromExe := TSimpleForm(p);
    ...
    Если описания формы TSimpleForm нет, то нужно попытаться восстановить описание, вытащив dfm из ресурсов exe-файла.
     
  5. AndreyD2

    AndreyD2

    Регистр.:
    21 окт 2008
    Сообщения:
    194
    Симпатии:
    67
    Если я правильно понял то ваш вариант:
    - передать в длл параметры
    - по ним в длл расчитать результат типа 110011, т.е. первая 1 - pr1.visivle = true...
    То это не вариант(, так как основная идея с длл это вынест максимальное количество кода в длл.
    Например данную procedure
    Код:
    procedure CheckStatus;
    begin
      EdPriznak13.Enabled := False; //(EdPriznak12.Value) and (not EdPriznak14.Value) and (EdPriznak13.Tag = 0);
      //всегда закрыт
      EdPriznak12.Enabled := (EdPriznak11.Value) and (not EdPriznak13.Value) and (not EdPriznak5.Value) and (EdPriznak12.Tag = 0);
      EdPriznak11.Enabled := (EdPriznak10.Value) and (not EdPriznak12.Value) and (EdPriznak11.Tag = 0);
      EdPriznak10.Enabled := not (EdPriznak11.Value) and (EdPriznak10.Tag = 0);
      If UsersAccessRasdel('Корректировка закрытых з-н','Учет') = 'Полный' then
        begin
          EdPriznak14.Enabled := EdPriznak12.Value and (EdPriznak14.Tag = 0);
          EdDate14.Enabled := EdPriznak14.Enabled;
          EdDate14.Visible := EdPriznak14.Value;
          EdPriznak7.Enabled := True and (EdPriznak7.Tag = 0);
          edDate7.Enabled := EdPriznak7.Enabled;
          EdDate7.Visible := EdPriznak7.Value;
          EdPriznak8.Enabled := True and (EdPriznak8.Tag = 0);
        end
      else
        begin
          EdPriznak14.Enabled := False;
          EdDate14.Enabled := False;
          EdDate14.Visible := EdDate14.Value <> 0; // False;
          EdPriznak7.Enabled := False;
          edDate7.Enabled := False;
          EdDate7.Visible := EdDate7.Value <> 0; //False;
          EdPriznak8.Enabled := False;
        end;
      If UsersAccessRasdel('Корректировка закрытых з-н','Реализация') = 'Полный' then
        begin
          EdPriznak5.Enabled := True and (EdPriznak5.Tag = 0);
          edDate5.Enabled := EdPriznak5.Enabled and (edDate5.Tag = 0);
          EdDate5.Visible := EdPriznak5.Value;
        end
      Else
        begin
          EdPriznak5.Enabled := False;
          edDate5.Enabled := EdPriznak5.Enabled and (edDate5.Tag = 0);
          EdDate5.Visible := EdPriznak5.Value; // False;
        end;
      If EdPriznak5.Value then
        If UsersAccessRasdel('Корректировка закрытых з-н','Реализация - Снятие') = 'Полный' then
          begin
            EdPriznak5.Enabled := True; //(EdPriznak5.Tag = 0);
            edDate5.Enabled := EdPriznak5.Enabled  and (edDate5.Tag = 0);
            EdDate5.Visible := EdPriznak5.Value;
          end
        Else
          begin
            EdPriznak5.Enabled := False;
            edDate5.Enabled := EdPriznak5.Enabled  and (edDate5.Tag = 0);
            EdDate5.Visible := EdPriznak5.Value;
          end;
    end;
     
  6. jik

    jik

    Регистр.:
    11 мар 2009
    Сообщения:
    243
    Симпатии:
    133
    передать не параметры, а только адрес формы.

    с двоичными данными не нужно работать.
    Передав в dll адрес формы, обращайтесь к свойствам формы напрямую.

    Код:
    implementation
    var FormFromExe: TSimpleForm = nil;
    procedure SendFormToDll(p: Integer);
    begin
      FormFromExe := TSimpleForm(p);
    end;
    
    procedure CheckStatus;
    begin
      if FormFromExe = nil then exit;
      FormFromExe.EdPriznak13.Enabled := False;
    ...
    end;
    В чем смысл введения такого механизма изменения параметров? Нельзя ли динамически подгружать dll из программы и передавать туда форму?
     
  7. AndreyD2

    AndreyD2

    Регистр.:
    21 окт 2008
    Сообщения:
    194
    Симпатии:
    67
    Смысл следующий.
    Для каждого пользователя форма компилируется перед запуском.
    Перед компиляцией идет проверка кода - ее убрать никак нельзя, из-за этого на открытие формы с 3500строк уходит 1-2 сек на проверку кода.

    Пробавали написать эту форму делфи и загрузить ее из длл, но много функции которые описаны в программе не доступны.
     
  8. jik

    jik

    Регистр.:
    11 мар 2009
    Сообщения:
    243
    Симпатии:
    133
    Может быть, под каждого пользователя подстроить форму, делая определенные поля visible:=true/false? Для каждого пользователя создаете свою dll? Может, лучше сразу свой exe генерить? Можно и из пограммы сгенерить форму, динамически создав компоненты и положив их на форму. Если бы более четко была сформулирована задача, то можно было бы подобрать оптимальное решение.
     
  9. AndreyD2

    AndreyD2

    Регистр.:
    21 окт 2008
    Сообщения:
    194
    Симпатии:
    67
    Попробую описать более подробно и понятно.
    foto.JPG
    1. На скриншоте представлен редактор формы и сама форма. Как видно писать можно только процедуры, функции и описать глобальные переменные для формы.
    2. Необходимо реализовать, без малейших изменений логики!!!
    - на кнопку "run dll" запускается процедура(функция) из длл
    - она делает radobutton.enabled = true/false в зависимости от значения edit (если 1 то true иначе false)
    - значение edita не передается в dll, а определяется в ней
    - в форме должен быть только код вызова процедуры из dll

    Если не затруднит, пример в Delphi. Я попробую подогнать для себя.
     
  10. jik

    jik

    Регистр.:
    11 мар 2009
    Сообщения:
    243
    Симпатии:
    133
    Объявление класса TSimpleform присутствует где-то в коде или оно скрыто от пользователя? Это объявление надо будет вставить в исходный код dll-файла, таким образом:

    Код:
    type 
      TSimpleForm = class(TForm)
        CloseButton: TButton;
        buhtaButton1: TButton;
    ...
    Скорее всего buhtaButton1 имеет тип не TButton, а что-то типа TBuhtaButton. Вытащить все эти классы и вставить в dll вряд ли удастся, да и dfm-файла к этой форме у вас скорее всего нет. Остается вариант передать в функцию адреса RadioButton1 и Edit1.

    по кнопке run dll делаем

    Код:
    var Wrap;
    begin
     Wrap := CreateOleObject('DynamicWrapper');
      Wrap.Register ('D:\Disc C\Projects D7\test dll\Project1.dll', 'SendFormToDll', 'i=ll', 'f=s', 'r=l');
      Wrap.SendFormToDll(LongInt(RadioButton1),LongInt(Edit1));
    end;
    в dll описываем SendFormToDll:

    Код:
    function SendFormToDll(pRadioButton1: LongInt; pEdit1: LongInt);
    var
      RadioButton1: TRadioButton;
      Edit1: TEdit; 
    begin
      RadioButton1 := TRadioButton(pRadioButton1);
      Edit1 := TRadioButton(pEdit1);
      Result := StrToIntDef(Edit1.Text,0);
      if Result = 1 then begin
        RadioButton1.Enabled := True;
      end else begin
        RadioButton1.Enabled := False;
      end;
    end;
     
Статус темы:
Закрыта.