在完全自建TForm下的button onclick指向 |
答題得分者是:wameng
|
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
請問各位! 我建立一個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 發送簡訊給我 |
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 發送簡訊給我 |
|
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
謝謝! 我按上述修正後, 可以編譯通行, 但有一個很奇怪的現象, 就是如果我選擇[繼續]讓程式往下開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 發送簡訊給我 |
引言: 為何不用ModalResult 來做,簡單明瞭。感謝 wameng指點, 我沒有過這樣的寫法, 所以壓根想不到 另外也感謝allenchan讓我了解另一種做法! 剛剛上篇提到按結束就會當機的問題, 我也找到 原來Button1.ModalResult := mrCancel; Button2.ModalResult := mrOK; ... Case Form1.ShowModal of mrok :iKey:= 'Continue'; mrCancel :iKey:= 'Terminate'; end; ... 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 發送簡訊給我 |
引言: 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; |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |