Форум: "Основная";
Текущий архив: 2008.08.31;
Скачать: [xml.tar.bz2];
ВнизInterface Найти похожие ветки
← →
андр (2007-12-19 14:43) [0]Можно ли както обращатся к с труктуре типа:
TType = (tString, tInteger, tBoolean)
через интерфейсы, если можно, то как объявить такой тип ???
← →
oldman © (2007-12-19 14:45) [1]
> то как объявить такой тип
Как record
← →
oldman © (2007-12-19 14:46) [2]или класс
← →
Kolan © (2007-12-19 14:47) [3]> Можно ли както обращатся к с труктуре типа:
А как ты хочешь обрашаться по индексу?TType = (tString, tInteger, tBoolean)
IGetType = interface
function GetType(Index: Intger): TType;
end;TTypeObject = class(TInterfacedObject, IGetType)
function GetType(Index: Intger): TType;
end;
function TTypeObject.GetType(Index: Intger): TType;
begin
case Index of
0: Result := tString;
1: Result := tInteger;
2: Result := tBoolean;
end;
end;
Нафих такое надо — не представляю…
← →
андр (2007-12-19 14:50) [4]
> Kolan © (19.12.07 14:47) [3]
Да плагин пишу, есть в dll форма, если ей передать например tStringб то она один тап выполнять будет, если tInteger то другой, неохото писать в программе и в плагине одно и тоже.....
← →
андр (2007-12-19 14:51) [5]Илиже есть смысл создать SharedTypes ???
← →
oldman © (2007-12-19 14:52) [6]
> андр (19.12.07 14:50) [4]
А не проще передать два параметра?
Первый - че делать, второй - с чем делать?
← →
Kolan © (2007-12-19 14:54) [7]> Да плагин пишу, есть в dll форма, если ей передать например
> tStringб то она один тап выполнять будет, если tInteger
> то другой, неохото писать в программе и в плагине одно и
> тоже…
Покажи код(только сократи), тут можно оч. удобно заюзать паттерн Visitor но без кода объяснить не смогу, кроме того без когда я могу ошибаться…
← →
андр (2007-12-19 15:00) [8]
unit uDialog;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Buttons, StdCtrls, ExtCtrls;
const
SET_ = [ #8, #13];
SET_NUMBER = ["0".."9"];
SET_LOWER_RUS_CHAR = ["à".."ÿ"];
SET_UPPER_RUS_CHAR = ["À".."ß"];
SET_LOWER_ENG_CHAR = ["a".."z"];
SET_UPPER_ENG_CHAR = ["A".."Z"];
type
{ TShowDialog }
TShowDialog = (sdCard, sdCalculation, sdNewCard, sdOther);
{ TDialog }
TDialog = packed record
ShowType: TShowDialog;
end;
{ TfDialog }
TfDialog = class(TForm)
sBtnOk: TSpeedButton;
sBtnCancel: TSpeedButton;
grpBx: TGroupBox;
pnl: TPanel;
edt: TEdit;
chkBxAutoOpen: TCheckBox;
chkBxAutoNew: TCheckBox;
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure FormDeactivate(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormDestroy(Sender: TObject);
procedure sBtnOkClick(Sender: TObject);
procedure sBtnCancelClick(Sender: TObject);
procedure edtChange(Sender: TObject);
procedure edtKeyPress(Sender: TObject; var Key: Char);
procedure chkBxAutoOpenClick(Sender: TObject);
procedure chkBxAutoNewClick(Sender: TObject);
private
{ Private declarations }
FMaxLen: Integer;
FText: String;
FCheck: Boolean;
public
{ Public declarations }
constructor Create(AOwner: TComponent; Rec: TDialog); overload;
end;
function CreateDialog(AOwner: TComponent; Rec: TDialog): Boolean;
resourcestring
rsCaptionCard = "ÄÈÀËÎà ÊÀÐÒÎ×ÊÀ ÀÁÎÍÅÍÒÀ";
rsGrpBxCaptionCard = "ÂÂÅÄÈÒÅ ËÈÖÅÂÎÉ Ñ×ÅÒ:";
rsChkBxAutoOpenCaption = "ÎÒÊÐÛÂÀÒÜ ÀÂÒÎÌÀÒÈ×ÅÑÊÈ";
rsChkBxAutoNewCaption = "ÑÎÇÄÀÂÀÒÜ ÀÂÒÎÌÀÒÈ×ÅÑÊÈ";
var
fDialog: TfDialog;
RecDialog: TDialog;
implementation
uses
uDm, uCard;
{$R *.dfm}
function CreateDialog(AOwner: TComponent; Rec: TDialog): Boolean;
begin
Result := True;
try
if not Assigned(fDialog) then
fDialog := TfDialog.Create(AOwner, Rec);
except
Result := False;
end;
end;
{ TfDialog }
constructor TfDialog.Create(AOwner: TComponent; Rec: TDialog);
begin
inherited Create(AOwner);
RecDialog := Rec;
case RecDialog.ShowType of
sdCard:
begin
Caption := rsCaptionCard;
grpBx.Caption := rsGrpBxCaptionCard;
FMaxLen := 7;
chkBxAutoNew.Visible := True;
end;
end;
edt.MaxLength := FMaxLen;
chkBxAutoOpen.Caption := rsChkBxAutoOpenCaption;
chkBxAutoNew.Caption := rsChkBxAutoNewCaption;
ShowModal;
end;
procedure TfDialog.FormCreate(Sender: TObject);
begin
//
end;
procedure TfDialog.FormShow(Sender: TObject);
begin
//
end;
procedure TfDialog.FormActivate(Sender: TObject);
begin
//
end;
procedure TfDialog.FormDeactivate(Sender: TObject);
begin
//
end;
procedure TfDialog.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
//
end;
procedure TfDialog.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;
procedure TfDialog.FormDestroy(Sender: TObject);
begin
fDialog := nil;
end;
procedure TfDialog.sBtnOkClick(Sender: TObject);
var
RecCard: TCard;
begin
if Length(Trim(FText)) <> 0 then
if not FCheck then
Exit;
case RecDialog.ShowType of
sdCard:
begin
RecCard.Face := FText;
if Length(Trim(RecCard.Face)) <> 0 then
RecCard.ShowType := scCard
else
RecCard.ShowType := scNewCard;
if CreateCard(Application, RecCard) then
begin
Close;
end;
end;
end;
end;
procedure TfDialog.sBtnCancelClick(Sender: TObject);
begin
Close;
end;
procedure TfDialog.edtChange(Sender: TObject);
begin
FText := edt.Text;
FCheck := (Length(Trim(FText)) >= FMaxLen);
if FCheck then
begin
edt.Color := clWindow;
if dm.FaceExists(FText) = 1 then
begin
if chkBxAutoOpen.Checked then
begin
sBtnOkClick(Sender);
end;
end
else
begin
edt.Color := clRed;
if chkBxAutoNew.Checked then
begin
//sBtnOkClick(Sender);
end;
end;
end
else
begin
edt.Color := clYellow;
end;
end;
procedure TfDialog.edtKeyPress(Sender: TObject; var Key: Char);
begin
case RecDialog.ShowType of
sdCard:
begin
if not (Key in SET_NUMBER + SET_) then
Key := #0;
end;
end;
end;
procedure TfDialog.chkBxAutoOpenClick(Sender: TObject);
begin
//
end;
procedure TfDialog.chkBxAutoNewClick(Sender: TObject);
begin
//
end;
end.
...
procedure TfMain.mmProgramCardClick(Sender: TObject);
var
Rec: TDialog;
begin
Rec.ShowType := sdCard;
if CreateDialog(Application, Rec) then
begin
//
end;
end;
...
Окцентирую это:
TShowDialog = (sdCard, sdCalculation, sdNewCard, sdOther);
Хочу просто плагин вызывать....
← →
андр (2007-12-19 15:03) [9]
case RecDialog.ShowType of
sdCard:
begin
Caption := rsCaptionCard;
grpBx.Caption := rsGrpBxCaptionCard;
FMaxLen := 7;
chkBxAutoNew.Visible := True;
end;
sdNewCard:
begin
Caption := rsCaptionCard;
grpBx.Caption := rsGrpBxCaptionCard;
FMaxLen := 7;
chkBxAutoNew.Visible := True;
end;
sdCalculation:
begin
Caption := rsCaptionCard;
grpBx.Caption := rsGrpBxCaptionCard;
FMaxLen := 7;
chkBxAutoNew.Visible := True;
end;
sdOther:
begin
Caption := rsCaptionCard;
grpBx.Caption := rsGrpBxCaptionCard;
FMaxLen := 7;
chkBxAutoNew.Visible := True;
end;
end;
Думаю смысл понятен, диалог дальше вызывает другие формы взависимости от того какого типа он был вызван...
← →
Kolan © (2007-12-19 15:07) [10]> Хочу просто плагин вызывать…
Фразу не понял.
> case RecDialog.ShowType of
> sdCard:
> begin
> Caption := rsCaptionCard;
> grpBx.Caption := rsGrpBxCaptionCard;
> FMaxLen := 7;
> chkBxAutoNew.Visible := True;
> end;
> end;
На сколько я понял ты не хочешь писать тут длинный case, так? Тогда можно как раз использовать посетителя.
Если так, то напишу пример, иначе объясни что надо.
> Думаю смысл понятен, диалог дальше вызывает другие формы
> взависимости от того какого типа он был вызван…
Вызова других форм в зав от типа не видно что-то…
← →
андр (2007-12-19 15:08) [11]Сократил как ты и просил.. ;-)
Короче одним словом вот из этого unit uDialog, хочу сделать плагин...
Предложения принимаются... :-)
← →
андр (2007-12-19 15:10) [12]
> Вызова других форм в зав от типа не видно что-то…
case RecDialog.ShowType of
sdCard:
begin
RecCard.Face := FText;
if Length(Trim(RecCard.Face)) <> 0 then
RecCard.ShowType := scCard
else
RecCard.ShowType := scNewCard;
if CreateCard(Application, RecCard) then
begin
Close;
end;
end;
sdNewCard
...
...
... и т.д.
end;
← →
андр (2007-12-19 15:21) [13]
>
> На сколько я понял ты не хочешь писать тут длинный case,
> так? Тогда можно как раз использовать посетителя.
>
> Если так, то напишу пример, иначе объясни что надо.
Я неосмыслю блин, как мне вызывать плагин диалога разных типов, можно конечно использовать 0,1,2,3.... но как то не осмысленно, хотелось бы вызывать передовая например sdCard или sdOther.... Можно, но прийдется тогда прописовать TShowDialog = (sdCard, sdCalculation, sdNewCard, sdOther);
и в основной программе и в модуле, а хотелось бы както в одном месте прописать и использовать.....
ShareTypes модуль тоже неохото делать, сразу весь код и в программу и модуль попадает...
← →
Kolan © (2007-12-19 15:23) [14]> Короче одним словом вот из этого unit uDialog, хочу сделать
> плагин…
Плохо понял что же именно надо.
А пример тебе напишу.
Этота идея основана на рефакторинге Replace conditional case with polymorphism
Описываем такой интерфейс:IDialogVisitor = interface
procedure ShowDialogForm(DialogForm: TfDialog);
end;
Как обычно общий предок:
TCustomDialogVisitor = class(TInterfacedObject, IDialogVisitor)
public
procedure ShowDialogForm(DialogForm: TfDialog); virtual; abstract;
end;
И одного конкретного потомка для примера:TSomeDialogVisitor = class(TCustomDialogVisitor)
public
procedure ShowDialogForm(DialogForm: TfDialog); override;
end;
Конструктор формы изменяем так:
Было:
constructor Create(AOwner: TComponent; Rec: TDialog); overload; почему overload;?
Стало:constructor Create(AOwner: TComponent; DialogVisitor: IDialogVisitor); reintroduce;
constructor TfDialog.Create(AOwner: TComponent; DialogVisitor: IDialogVisitor);
begin
inherited Create(AOwner);
if Assigned(DialogVisitor) then
DialogVisitor.ShowDialogForm(Self) // Тоесть мы передаем форму в посетителя, а он сам знает че с ней делать.
end;
В конкретных посетителях(у нас он 1 шас — TSomeDialogVisitor) помещаем код из кейсов:procedure TSomeDialogVisitor.ShowDialogForm(DialogForm: TfDialog); override;
begin
if Assigned(DialogForm) then
begin
with DialogForm do
begin
Caption := rsCaptionCard;
grpBx.Caption := rsGrpBxCaptionCard;
FMaxLen := 7;
chkBxAutoNew.Visible := True;
end;
end;
end;
C CreateDialog разбирёшся сам.
А вызов такой:procedure TfMain.mmProgramCardClick(Sender: TObject);
var
DialogVisitor: TCustomDialogVisitor;
begin
DialogVisitor := TSomeDialogVisitor.Create;
try
if CreateDialog(Application, DialogVisitor) then
begin
//
end;
finally
DialogVisitor.Free;
end;
end;
Так как кодcase RecDialog.ShowType of
условный, то и пример тоже. Основная идея в том, что я убрал условие навсегда + можно добавлять сколько угодно новых посетителей…
ЗЫ
Писал прям тут…
← →
Kolan © (2007-12-19 15:26) [15]> Я неосмыслю блин, как
Понял — пример годится.
> и в основной программе и в модуле, а хотелось бы както в
> одном месте прописать и использовать…
В одном месте
в моем примере
надо разместить
IDialogVisitor
в твоем(который тоже вполне приемлим, просто менее удобный)
TShowDialog
То есть в одном pas, который виден и там и там…
← →
Darvin © (2007-12-19 15:26) [16]Такое не подойдет?
procedure P1 (D:Variant; VT: Integer);
P1("cccc", varString)
P1(234, varInteger)
← →
андр (2007-12-19 15:28) [17]
> ShareTypes модуль тоже неохото делать, сразу весь код и
> в программу и модуль попадает...
Ну тогда выходит:
> То есть в одном pas, который виден и там и там…
← →
андр (2007-12-19 15:33) [18]
> Kolan © (19.12.07 15:23) [14]
:-* , ;-)))
Но всеравно бли кажется сложнее....
← →
Kolan © (2007-12-19 15:33) [19]Получается ты хочешь менять вид формы в зав от переданной настройки?
Наверно в случаее с Dll вариант с 0,1,2,3… самый верный если состояний заданое кол-во и часто меняться не будет.
А это 0,1,2,3 описывается в документации(просто в текстовом файле), так вызываются все Windows диалоги.
Когда кто-то быдет вызывать твой диалог он прочтет документацию и вызовет его с соотв числов. таких примеров полно в Windows.pas.
← →
андр (2007-12-19 15:34) [20]Впринципе я думаю есть смысл передавать, 0,1,2,3,4.... пользователь всеравно этого не видет....
← →
Kolan © (2007-12-19 15:38) [21]В случае как в моем примере посетителям надо знать о форме, следовательно тебе придется в общий моуль(как ты говоришь ShareModule) выносить и их.
Если бы у тебя были пакеты, я бы сделал посетителей…
С Dll надо, делать константы, имхо.
Пример виндовый диалог MesageBox. А вот и те самые константы:const
{ MessageBox() Flags }
{$EXTERNALSYM MB_OK}
MB_OK = $00000000;
{$EXTERNALSYM MB_OKCANCEL}
MB_OKCANCEL = $00000001;
{$EXTERNALSYM MB_ABORTRETRYIGNORE}
MB_ABORTRETRYIGNORE = $00000002;
{$EXTERNALSYM MB_YESNOCANCEL}
MB_YESNOCANCEL = $00000003;
…
← →
андр (2007-12-19 15:38) [22]
> Kolan © (19.12.07 15:33) [19]
Good!
Как самому активному в этом вопросе, еще вопрос:
Каким образом лутше выгружать плагин (dll) по окончанию в нем какихто действий:
Посылать PostMessage, илиже использовать interface ....?
← →
андр (2007-12-19 15:39) [23]
> Kolan © (19.12.07 15:38) [21]
Спас. очень помог!
Мастера ему! Мастера!!!! :-))))
← →
Kolan © (2007-12-19 15:41) [24]Посетителя удобно использовать когда в той твоей форме по клику на кнопке надо делать то, что хочет пользователь, который её вызвал. А для настройки вида самой формы так их применить неудасться.
Был неправ. Но пример все равно полезный, из серии «взять на замеку».
← →
Kolan © (2007-12-19 15:45) [25]
> Каким образом лутше выгружать плагин (dll) по окончанию
> в нем какихто действий:
> Посылать PostMessage, илиже использовать interface …?
По ситуации. И что значит «выгружать»? FreeLibrary ?
← →
андр (2007-12-19 15:48) [26]
> Kolan © (19.12.07 15:41) [24]
Держи мастера (М)
;-)
Еще раз спасибо!
← →
андр (2007-12-19 15:48) [27]
> FreeLibrary ?
угу
← →
Kolan © (2007-12-19 15:56) [28]Имхо кто загрузил библиотеку, тот и знает когда её выгружать.
Обычно диалог вешь модальная.
Напрмер TOpenDialogOpenDialog := TOpenDialog.Create
try
if OpenDialog.Execute then
…
finally
OpenDialog.Free;
end;
Так же можно и с dllLoadLibrary
try
if <экспортируемая функция> then
…
finally
FreLibrary
end;
А <экспортируемая функция> не возвращается пока все не сделает.
Ежели у тебя этот диалог в фоновом режиме работает, то надо как-то синхронизировать… Тут возможны варианты…
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2008.08.31;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.009 c