Логин: Пароль:    Регистрация Всеми возможностями сайта можно пользоваться
только после авторизации.
   Забыли пароль?

Поиск
L



Статистика
u
Пользователи онлайн: нет
Гостей онлайн: 3
Всего онлайн: 3
Зарегистрировано юзеров: 6362
Комментариев на сайте: 645
Новый юзер: Pseulairrerve



Последние комментарии
c
Aqel прокомментировал "Урок 71 - Работа с сжатыми файлами":
GZip псевдоархив, на мой вопрос тоже не отвечают, как распаковать отдельные файлы/папки...
Pingitrus прокомментировал "Урок 71 - Работа с сжатыми файлами":
Есть еще кто нибудь живой на этом сайте, кто сможет помочь? Так то все работает, zip и rar распаковывает, но у меня есть файл dat который сжат GZip, почему то его не удается распаковать или так не получится так как этот файл не является архивом или является?)) пишет ошибку что неверная функция



Мы в соцсетях
c
Delphi
Невизуальное наследование форм в Delphi

Создание класса.
Создадим базовый класс, наследник TForm, от которого в дальнейшем будем наследовать все наши формы. Для этого в новый или существующий пакет, добавим компонент TBaseForm.

Рис. 1. Создание нового компонента TBaseForm


Для Delphi 6 в пункте Requires нашего пакета добавляем "Borland Designer IDE Package" (по умолчанию находится в C:\Program_Files\Borland\Delphi6\Lib\designide.dcp). Для Delphi 5 все для нас необходимое содержится в "Borland Visual Component Library" (он включается в пакет автоматически). В раздел uses для Delphi 5 добавляем DsgnIntf, а для Delphi 6 DesignIntf и DesignEditors. Изменим процедуру Register только что созданного компонента.

    procedure Register;
    begin
      RegisterCustomModule(TBaseForm, TCustomModule);
    end;
Листинг 1. Изменение процедуры Register.
Компилируем наш пакет - класс TBaseForm готов к использованию.

Использование класса.
Для того чтобы какая-либо форма проекта была наследником класса TBaseForm, для этого в раздел uses формы нужно включить юнит BaseForm, а объявление класса новой формы class(TForm) переделать на class(TBaseForm). Затем форму нужно закрыть и снова открыть. После этого наша форма станет полноценным наследником класса TBaseForm.

Пример использования.
Пусть перед нами стоит задача: все формы проекта должны содержать информацию о версии формы (что необходимо, когда один и тот же проект подгоняется под разных заказчиков) и отображать информацию о форме каким-либо способом.

Для реализации этих целей изменим класс TBaseForm как это показано в листинге 2. Здесь добавлены соответствующие переменные и свойства для хранения информации о версии формы и создан механизм показа информации о форме посредством системного меню окна - добавлен новый пункт системного меню "О форме".

    /////////////////////////////////////////////////////////////
    //        описание класса базовой формы
    //        Рощупкин А.В. 2003 г.
    /////////////////////////////////////////////////////////////
    unit BaseForm;

    interface

    uses
      Windows, Messages, SysUtils, Classes, Controls, Forms,
      //DsgnIntf;                //при использовании Delphi5
      DesignIntf, DesignEditors; //при использовании Delphi6

    const
      ItmID = $00a0; //идентификатор нового пункта системного меню

    type
      TBaseForm = class(TForm)
      private
      FVersion: integer;          //версия формы
      FMnuItmAbout: MENUITEMINFO; //структура нового пункта меню
      FOldWndProc : Pointer;      //указатель на старую функцию обработки
                    //сообщений окна (формы)
      FNewWndProc : Pointer;      //указатель на новую функцию обработки
                    //сообщений окна (формы)

      // возвращает информацию о форме в виде строки
      function GetAboutString: string;

      protected
      public
      //конструктор
      constructor Create(AOwner: TComponent); override;
      //деструктор :)
      destructor  Destroy; override;
      //возвращает указатель на старую функцию обработки сообщений окна (формы)
      function    GetOldWindowProc: Pointer;
      //показывает информацию о форме
      procedure   ShowFormInfo;

      published
      property Version: integer read FVersion write FVersion default 1;

      end;

    //новую функцию обработки сообщений окна (формы)
    function  NewWndProc(wnd: HWND; Msg: UINT; wPrm: WPARAM; lPrm: LPARAM): LRESULT stdcall;
    //процедура регистрации класса
    procedure Register;

    implementation

    constructor TBaseForm.Create(AOwner: TComponent);
    begin
       inherited;

       //у наших окон всегда должно быть системное меню!!!
       if not ( biSystemMenu in Self.BorderIcons ) then
        Self.BorderIcons := Self.BorderIcons + [biSystemMenu];

       //создаем новый пункт систменого меню, по выборе которого
       //будет показана информация о форме
       FMnuItmAbout.cbSize := 44;
       FMnuItmAbout.fMask := MIIM_DATA or MIIM_ID or MIIM_STATE or MIIM_TYPE;
       FMnuItmAbout.fType := MFT_STRING;
       FMnuItmAbout.fState := MFS_ENABLED;
       FMnuItmAbout.wID := ItmID;
       FMnuItmAbout.hSubMenu := 0;
       FMnuItmAbout.hbmpChecked := 0;
       FMnuItmAbout.hbmpUnchecked := 0;
       FMnuItmAbout.dwTypeData := PChar('О форме');
       InsertMenuItem(GetSystemMenu(Self.Handle, False), 0, True, FMnuItmAbout);

       //регистрация новой процедуры обработки сообщений окна (формы)
       FNewWndProc := Pointer(@NewWndProc);
       FOldWndProc := Pointer(GetWindowLong(Self.Handle, GWL_WNDPROC));
       SetWindowLong(Self.Handle, GWL_WNDPROC, Longint(FNewWndProc));
    end;

    destructor TBaseForm.Destroy;
    begin
       inherited;
    end;

    function TBaseForm.GetOldWindowProc: Pointer;
    begin
       Result := FOldWndProc;
    end;

    procedure TBaseForm.ShowFormInfo;
    var
       InfStr: string;
    begin
       InfStr := GetAboutString;
       MessageBox(Self.Handle, PChar(InfStr), PChar('Сведения о форме'), MB_OK);
    end;

    function TBaseForm.GetAboutString: string;
    begin
       Result := 'Имя класса формы:  ' + Self.ClassName + #13 +
        'Имя формы:  ' + Self.Name + '  версия  ' + IntToStr(FVersion);
    end;

    ////////////////////////////////////////////////////////////////
    // в данном примере новая процедура обработки сообщений
    // окна (формы) создана только для одного сообщения -
    // ловить выбор пункта системного меню "О форме"
    ////////////////////////////////////////////////////////////////
    function NewWndProc(wnd: HWND; Msg: UINT; wPrm: WPARAM; lPrm: LPARAM): LRESULT stdcall;
    var
       FrmHWND: HWND;
       wctrl: TWinControl;
       BFrm: TBaseForm;
    begin
       Result := 0;
       FrmHWND := wnd;
       wctrl := FindControl(FrmHWND);
       if ( wctrl = nil ) then Exit;
       FrmHWND := GetParentForm(wctrl).Handle;
       if ( FrmHWND = 0 ) then Exit;
       BFrm := TBaseForm(FindControl(FrmHWND));
       if ( BFrm = nil ) then
        Exit;
       Result := CallWindowProc(BFrm.GetOldWindowProc, wnd, Msg, wPrm, lPrm);
       case ( Msg ) of
        //выбран пункт системного меню "О форме"
        WM_SYSCOMMAND :
         begin
          if ( LOWORD(wPrm) = ItmID ) then
          begin
             wctrl := FindControl(wnd);
             if ( wctrl <> nil ) then
              if ( wctrl is TBaseForm ) then
               TBaseForm(wctrl).ShowFormInfo;
          end;
         end;
       end;
    end;

    procedure Register;
    begin
      RegisterCustomModule(TBaseForm, TCustomModule);
    end;

    end.
Листинг 2.

Теперь, наследуя все формы проекта от класса TBaseForm, мы можем сохранять версию формы и получать информацию о форме через системное меню окна (формы).

Конечно, данным примером не исчерпывается использование данного метода. Из явных применений видятся: 1) сохранение параметров окон; 2) разграничение прав доступа (если где-нибудь, например, в базе данных, мы храним права доступа к элементам окна, то эти права можно реализовать в конструкторе TBaseForm); 3) табуляция между элементами окна по нажатию клавиши Enter в TEdit (для этого нужно в NewWndProc включить соответствующий обработчик) и т.д.

К недостаткам метода относится то, что в построенном классе TBaseForm крайне сложно будет создавать визуальные компоненты.

Вот и всё, Удачи!

Источник: www.thedelphi.ru
Автор: Савельев Александр
Опубликовано: 25 Мая 2017
Просмотров: 1236


Зарегистрируйтесь или авторизуйтесь, чтобы добавлять комментарии.