全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2140
推到 Plurk!
推到 Facebook!

在完全自建TForm下的button onclick指向

答題得分者是:wameng
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-04-22 12:54:36 IP:61.71.xxx.xxx 未訂閱
請問各位!    我建立一個DLL FILE, 在其中一個UNIT PAS 上需要自建一個Form, 內含兩組button, 現要將該button的onclick指向到我設定的proceudre, 但編譯時會在下列程式紅色標示錯誤, 要如何修正才能完成如下的寫法 編譯的錯誤訊息Incompatible types:method pointer and regular procedure    
unit D_Pos;    interface    uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, ini;    function DLL_Pos(dAlias, diniFile, dLoginAry, dDLLpath,
                 eVar5: variant): boolean; stdcall;    var nowdate: string;
    iKey: string;    implementation    function DLL_Pos(dAlias, diniFile, dLoginAry, dDLLpath,
                 eVar5: variant): boolean;
         var sfile, dfile: string;
             Form1: TForm;
             Label1: TLabel;
             Button1, Button2: TButton;
             Panel1: TPanel;
    procedure btn1Click(Sender: TObject);
    begin
         iKey:= 'Terminate';
         if (Sender is TButton) then Form1.Close;
    end;
    procedure btn2Click(Sender: TObject);
    begin
         iKey:= 'Continue';
         if (Sender = Button2) then Form1.Close;
    end;
begin
......
為縮短版面, 不重要的我剔除了
         if.... then 
         begin
            Form1:= TForm.Create(Application);
            Form1.Caption:= '系統警告訊息';
            Panel1:= TPanel.Create(Form1);
            Panel1.Parent:= Form1;
            Label1:= TLabel.Create(Form1);
            Label1.Parent:= Form1;
            Label1.Caption:= '     ▁▂▃警告▃▂▁' #13 #13 .....
            Button1:= TButton.Create(Form1);
            Button1.Parent:= Panel1;
            Button1.Caption:= '結束';

            Button1.onClick:= btn1Click;                Button2:= TButton.Create(Form1);
            Button2.Parent:= Panel1;
            Button2.Caption:= '繼續';                Button2.onClick:= btn2Click;                try
               Form1.ShowModal;
            finally
               FreeandNil(Form1);
            end;
         end;
....
end;
如果這些程式移到一個已建好的Form pas上是沒有問題(只要把procedure btn1click移到private內, 紅色的部份就可以編譯過), 這目前這支並非一個Form, 而是一支pas程式而已 謝謝! ps:這個寫法目的是在if 判斷一個狀況後要秀出一個form的警告視窗, 但我不想用messagebox來做, 所以由form, label, panel, button 都完全自建 發表人 - P.D. 於 2005/04/22 12:57:55
allenchan
資深會員


發表:10
回覆:306
積分:283
註冊:2004-01-06

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-04-22 13:56:37 IP:192.193.xxx.xxx 未訂閱
OnClick Event Handler 被宣告為一種 TNotifyEvent:    TNotifyEvent = procedure(Sender: TObject) of object;    看來他必須是一個 procedure of object    如果您不想讓 btn1Click, btn2Click 宣告在 TForm1 裡頭,那麼我想你應該使用類似的手法,像是:
type
  MyTest = class
    procedure btn1Click(Sender: TObject);  
  end;    var 
  test: MyTest;    implementation    procedure MyTest.btn1Click(Sender: TObject);
begin
  iKey:= 'Terminate';
  if (Sender is TButton) then Form1.Close;
end;    .......
 Button1.onClick:= test.btn1Click; 
.......    initialization
  test := MyTest.Create;    
不知這樣對您來說是否可行。 發表人 - allenchan 於 2005/04/22 13:58:24
wameng
版主


發表:31
回覆:1336
積分:1188
註冊:2004-09-16

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-04-22 14:57:09 IP:61.222.xxx.xxx 未訂閱
為何不用ModalResult 來做,簡單明瞭。
Button1.ModalResult := mrCancel;
Button2.ModalResult := mrOK;
...
Case Form1.ShowModal of
  mrok :iKey:= 'Continue';
  mrCancel :iKey:= 'Terminate';
end;
...
發表人 - wameng 於 2005/04/22 15:00:09
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-04-22 15:42:18 IP:61.71.xxx.xxx 未訂閱
謝謝! 我按上述修正後, 可以編譯通行, 但有一個很奇怪的現象, 就是如果我選擇[繼續]讓程式往下開mailform再結束沒有問題, 但如果選擇[結束], 就會出現Access...錯誤, 我還抓不到問題所在
unit D_Pos;    interface    uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, ini;    type
   TBtnProc = Class
     procedure btn1Click(Sender: TObject);
     procedure btn2Click(Sender: TObject);
   end;    var nowdate: string;
   
function DLL_Pos(dAlias, diniFile, dLoginAry, dDLLpath,
                 eVar5: variant): boolean; stdcall;    implementation    uses .....    var Form1: TForm;
    Label1: TLabel;
    Button1, Button2: TButton;
    Panel1: TPanel;
    iKey: string;
    btnP: TBtnProc;
     
procedure TBtnProc.btn1Click(Sender: TObject);
begin
     iKey:= 'Terminate';
     if (Sender is TButton) then Form1.Close;
end;    procedure TBtnProc.btn2Click(Sender: TObject);
begin
     iKey:= 'Continue';
     if (Sender = Button2) then Form1.Close;
end;    function DLL_Pos(dAlias, diniFile, dLoginAry, dDLLpath,
                 eVar5: variant): boolean;
         var sfile, dfile: string;
begin
// 非重點程式我移除了
.....
     SYSUT:= TSYSUT.Create(Application);
.....
     DM_Pos:= TDM_Pos.Create(Application);
     if not U_VarDef.connecterror then begin
        iKey:= 'Continue';
        // 如果....則要提出警告
        if..... then
        begin
           Form1:= TForm.Create(Application);
           Form1.Height:= 320;
           Form1.Width:= 380;
           Form1.Caption:= '系統警告訊息';
           Form1.BorderStyle:= bsSingle;
           Form1.BorderIcons:= [];
           Form1.Position:= poScreenCenter;
           Form1.Font.Name:= '細明體';
           Form1.Font.Size:= 14;
           Panel1:= TPanel.Create(Form1);
           Panel1.Parent:= Form1;
           Panel1.Height:= 50;
           Panel1.Align:= alBottom;
           Label1:= TLabel.Create(Form1);
           Label1.Parent:= Form1;
           Label1.Color:= clBlack;
           Label1.Font.Color:= clRed;
           Label1.Font.Style:= [fsBold];
           Label1.Align:= alClient;
           Label1.Alignment:= taLeftJustify;
           Label1.Layout:= tlCenter;
           Label1.AutoSize:= True;
           Label1.Caption:= '     ▁▂▃警告▃▂▁' #13 #13 ....
           Button1:= TButton.Create(Form1);
           Button1.Parent:= Panel1;
           Button1.Font.Size:= 9;
           Button1.Caption:= '結束';
           Button1.Height:= 40;
           Button1.Width:= 80;
           Button1.Top:= 5;
           Button1.Left:= 10;
           Button1.onClick:= btnP.btn1Click;
           Button2:= TButton.Create(Form1);
           Button2.Parent:= Panel1;
           Button2.Font.Size:= 9;
           Button2.Caption:= '繼續';
           Button2.Height:= 40;
           Button2.Width:= 80;
           Button2.Top:= 5;
           Button2.Left:= 280;
           Button2.onClick:= btnP.btn2Click;
           try
              Form1.ShowModal;
           finally
              FreeandNil(Form1);
           end;
        end;            if iKey<>'Terminate' then begin
           DM_PosLock    := TDM_PosLock.Create(Application);
           DM_PartPos    := TDM_PartPos.Create(Application);
           DM_PartPosLock:= TDM_PartPosLock.Create(Application);
           DM_PartUpd    := TDM_PartUpd.Create(Application);
           DM_IOrw       := TDM_IOrw.Create(Application);
           DM_IOrws      := TDM_IOrws.Create(Application);
           DM_Phrase     := TDM_Phrase.Create(Application);
           DM_Log        := TDM_Log.Create(Application);
.....
           Form_Pos:= TForm_Pos.Create(Application);
.....
           try
              Form_Pos.ShowModal;
           finally
              DM_Pos.Free;
              Form_Pos.Free;
              DM_Log.Free;
              DM_Phrase.Free;
              DM_IOrw.Free;
              DM_IOrws.Free;
              DM_PartUpd.Free;
              DM_PartPosLock.Free;
              DM_PartPos.Free;
              DM_PosLock.Free;
              SysUt.Free;
           end;
        end
        else begin
           DM_Pos.Free;
           SysUt.Free;
           DLLver.DebugSL.Free;
        end;
     end
     else begin
        DM_Pos.Free;
        SysUt.Free;
        DLLver.DebugSL.Free;
     end;
     result:= True;
end;    initialization
   btnP:= TBtnProc.Create;    finalization
   btnP.Free;    end.    如果選擇結束, 則會在紅色部份就當出, 如果紅色部份不加進去, 也是會當出同樣的錯誤(在下列紅色的部份)
library Pos;    { Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }    uses
  ShareMem,
  SysUtils,
  Classes,
  DLLver in '..\..\..\Dll_UT\DLLver.pas',
.....
  D_Pos in 'D_Pos.pas';    exports
       DLL_Pos;    begin    end.    但很奇怪, 如果選繼續讓 Form_Pos 執行到完成show再關閉就不會當機?
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-04-22 16:39:39 IP:61.71.xxx.xxx 未訂閱
引言: 為何不用ModalResult 來做,簡單明瞭。
Button1.ModalResult := mrCancel;
Button2.ModalResult := mrOK;
...
Case Form1.ShowModal of
  mrok :iKey:= 'Continue';
  mrCancel :iKey:= 'Terminate';
end;
...
感謝 wameng指點, 我沒有過這樣的寫法, 所以壓根想不到 另外也感謝allenchan讓我了解另一種做法! 剛剛上篇提到按結束就會當機的問題, 我也找到 原來
Button2.onClick:= btnP.btn2Click;
try
   Form1.ShowModal;
finally
   FreeandNil(Form1);
end;    改成
Button1.ModalResult := mrCancel;
Button2.ModalResult := mrOK;
...
Case Form1.ShowModal of
  mrok :iKey:= 'Continue';
  mrCancel :iKey:= 'Terminate';
end;
不要下 Form1.Free或FreenadNil(Form1), 結束時就不會當機
發表人 - P.D. 於 2005/04/22 17:04:35
ebx
一般會員


發表:1
回覆:20
積分:9
註冊:2003-10-09

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-04-22 20:02:50 IP:219.93.xxx.xxx 未訂閱
引言: OnClick Event Handler 被宣告為一種 TNotifyEvent: TNotifyEvent = procedure(Sender: TObject) of object; 看來他必須是一個 procedure of object 如果您不想讓 btn1Click, btn2Click 宣告在 TForm1 裡頭,那麼我想你應該使用類似的手法,像是:
type
  MyTest = class
    procedure btn1Click(Sender: TObject);  
  end;    var 
  test: MyTest;    implementation    procedure MyTest.btn1Click(Sender: TObject);
begin
  iKey:= 'Terminate';
  if (Sender is TButton) then Form1.Close;
end;    .......
 Button1.onClick:= test.btn1Click; 
.......    initialization
  test := MyTest.Create;    
不知這樣對您來說是否可行。 發表人 - allenchan 於 2005/04/22 13:58:24
或者
Method: TMethod;    with Button1 do
begin
  Method.Data := Button1;
  Method.Code := @btn1Click;
  OnClick := TNotifyEvent(Method);
end; 
 
系統時間:2024-05-17 11:09:19
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!