線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:4761
推到 Plurk!
推到 Facebook!

求問,如何透過設定,去指定物件的事件

答題得分者是:GrandRURU
g9221712
高階會員


發表:144
回覆:344
積分:162
註冊:2006-07-06

發送簡訊給我
#1 引用回覆 回覆 發表時間:2015-01-04 21:57:09 IP:122.117.xxx.xxx 訂閱
求問,如何透過設定,去指定物件的事件

各為前輩好:

我想寫一個procedure 去指定如下的TitleClick事件,但是一直提示沒有Column這個物件,不知道如何著手,請大家建議。

[code delphi]
procedure SetSMDBGRID(RunSMDBGrid: TSMDBGrid);
begin
with RunSMDBGrid do
begin
OnTitleClick := NewSMDBGridOnTitleClick(Column);
end;
end;

procedure TFRM_Main.SMDBGrid01TitleClick(Column: TColumn);
begin
(Column.Grid as TSMDBGrid).ClearSort;
if RightStr(TADODataSet(Column.Grid.DataSource.DataSet).Sort, 3) = 'ESC' THEN
begin
TADODataSet(Column.Grid.DataSource.DataSet).Sort := Column.FieldName ' ASC';
TSMDBColumn(Column).SortType := stAscending;
end
ELSE
begin
TADODataSet(Column.Grid.DataSource.DataSet).Sort := Column.FieldName ' DESC';
TSMDBColumn(Column).SortType := stDescending;
end;
end;

[/code]

------
「人們所以覺得寂寞,是因為他們會築牆,卻不會搭橋。」
程式寫的越久,卻發現自己越來越不會寫程式!
aftcast
站務副站長


發表:81
回覆:1482
積分:1762
註冊:2002-11-21

發送簡訊給我
#2 引用回覆 回覆 發表時間:2015-01-05 02:07:22 IP:114.32.xxx.xxx 訂閱
請問
NewSMDBGridOnTitleClick(Column);
裡的 Column 是什麼變數? class的欄位?

鳴~~ 靠北了(發語詞),我剛眼花,沒發現你用了 邪惡的

with RunSMDBGrid do

可不可不要那樣用啊, with xxxxx do 是 delphi 資深人員都幹x的 語法。

是不是以下才是正確的啊?

RunSMDBGrid.OnTitleClick := TFRM_Main.SMDBGrid01TitleClick;


題外話補充我為什麼會靠北了一下,有興趣的可以看下面的連結: 最好由上而下通通看一次,因為回的人很多,也都很有道理。

stackoverflow.com/questions/71419/why-should-i-not-use-with-in-delphi


------



蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
編輯記錄
aftcast 重新編輯於 2015-01-05 02:16:12, 註解 無‧
aftcast 重新編輯於 2015-01-05 02:20:30, 註解 無‧
aftcast 重新編輯於 2015-01-05 02:30:27, 註解 無‧
g9221712
高階會員


發表:144
回覆:344
積分:162
註冊:2006-07-06

發送簡訊給我
#3 引用回覆 回覆 發表時間:2015-01-05 07:01:08 IP:122.117.xxx.xxx 訂閱
我的 SetSMDBGRID如下,應該與with do 語法無關

procedure SetSMDBGRID(RunSMDBGrid: TSMDBGrid);
begin
with RunSMDBGrid do
begin
ShowHint := True;
Font.name := '新細明體';
Font.Size := 12;
Font.Color := Clblack; // Clblack ,clBlu
TitleFont.Size := 12;
ScrollBars := ssBoth;
OnTitleClick := NewSMDBGridOnTitleClick(Column);
end;
end;
------
「人們所以覺得寂寞,是因為他們會築牆,卻不會搭橋。」
程式寫的越久,卻發現自己越來越不會寫程式!
aftcast
站務副站長


發表:81
回覆:1482
積分:1762
註冊:2002-11-21

發送簡訊給我
#4 引用回覆 回覆 發表時間:2015-01-05 10:50:55 IP:49.219.xxx.xxx 訂閱
 焦點被我的題外話模糊了!不是說 do with 一定有問題,而是建議少用或不用。

一下這行才是重點:

RunSMDBGrid.OnTitleClick := TFRM_Main.SMDBGrid01TitleClick;

delphi語法我是不夠熟,但理當如上寫法。

ruru,還是其他熟delphi的出來幫一下唷!

PS. 我po完後發現,自己又豬頭了… delphi語法還是請別人回,我弱了,我自己需要服藥。sorry。

self.OnTitleClick := ?

RunSMDBGrid.OnTitleClick := ?
------



蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
編輯記錄
aftcast 重新編輯於 2015-01-05 10:59:47, 註解 無‧
aftcast 重新編輯於 2015-01-05 11:01:02, 註解 修正 我自己又搞錯 @@‧
GrandRURU
站務副站長


發表:234
回覆:1654
積分:1752
註冊:2005-06-21

發送簡訊給我
#5 引用回覆 回覆 發表時間:2015-01-05 11:00:30 IP:59.120.xxx.xxx 訂閱
蕭大的解就對了!
RunSMDBGrid.OnTitleClick := TFRM_Main.SMDBGrid01TitleClick;
就是這一行,至於 NewSMDBGrid01TitleClick 我不知道這從哪裡來的。



===================引 用 aftcast 文 章===================
焦點被我的題外話迷糊了!不是說 do with 一定有問題,而是建議少用或不用。

一下這行才是重點:

RunSMDBGrid.OnTitleClick := TFRM_Main.SMDBGrid01TitleClick;

delphi語法我是不夠熟,但理當如上寫法。

ruru,還是其他熟delphi的出來幫一下唷!

Coffee
版主


發表:31
回覆:878
積分:561
註冊:2006-11-15

發送簡訊給我
#6 引用回覆 回覆 發表時間:2015-01-05 18:32:51 IP:220.130.xxx.xxx 訂閱
with do still good if you operate ONLY ONE OBJECT at single block.

And, your new method is not a valid delphi event(check NotifyEvent if you want) so you need to call it in a normal method way instead of specify it to a new event, but first....
man you dont tell us which line of "Column" is invalid because WE ARE NOT COMPILER.
You have to make sure your object or property in the right scope, debug yourself plz.

And, prevent from specify event just right before you need to call it, because you wont never know if the internal message will be passed at the time. Specify your event and right after the object is contructed.
------
不論是否我發的文,在能力範圍皆很樂意為大家回答問題。
為了補我的能力不足之處,以及讓答案可以被重複的使用,希望大家能儘量以公開的方式問問題。
在引述到我的文時自然會儘量替各位想辦法,謝謝大家!
g9221712
高階會員


發表:144
回覆:344
積分:162
註冊:2006-07-06

發送簡訊給我
#7 引用回覆 回覆 發表時間:2015-01-06 17:51:00 IP:125.230.xxx.xxx 訂閱
各位好:

目前若在同一個UNIT下,是OK的!

SMDBGrid01.OnTitleClick := NewSMDBGridOnTitleClick;
SMDBGrid02.OnTitleClick := NewSMDBGridOnTitleClick;

procedure TFRM_Main.NewSMDBGridOnTitleClick(Column: TColumn);
begin
(Column.Grid as TSMDBGrid).ClearSort;
if RightStr(TADODataSet(Column.Grid.DataSource.DataSet).Sort, 3) = 'ESC' THEN
begin
TADODataSet(Column.Grid.DataSource.DataSet).Sort := Column.FieldName ' ASC';
TSMDBColumn(Column).SortType := stAscending;
end
ELSE
begin
TADODataSet(Column.Grid.DataSource.DataSet).Sort := Column.FieldName ' DESC';
TSMDBColumn(Column).SortType := stDescending;
end;
end;

但若獨立到另外一個UNIT下就會出現,不認得Column這個物件。
------
「人們所以覺得寂寞,是因為他們會築牆,卻不會搭橋。」
程式寫的越久,卻發現自己越來越不會寫程式!
GrandRURU
站務副站長


發表:234
回覆:1654
積分:1752
註冊:2005-06-21

發送簡訊給我
#8 引用回覆 回覆 發表時間:2015-01-06 21:00:55 IP:223.137.xxx.xxx 訂閱
我想你可能誤會了
這並不是因為在同一個 Unit 的關係,而是在一個具象化物件中,故能在同一個 Unit 裡被使用。

如果是兩個不同 Unit 要共用一個事件,必須要像底下的寫法:

var frmMaim: TFRM_Main; // Global Variable
begin
frmMain := TFRM_Main.Create();
SMDBGrid01.OnTitileClick := frmMain.NewSMDBGridOnTitleClick;
SMDBGrid02.OnTitileClick := frmMain.NewSMDBGridOnTitleClick;

===================引 用 g9221712 文 章===================
各位好:

目前若在同一個UNIT下,是OK的!

SMDBGrid01.OnTitleClick := NewSMDBGridOnTitleClick;
SMDBGrid02.OnTitleClick := NewSMDBGridOnTitleClick;

procedure TFRM_Main.NewSMDBGridOnTitleClick(Column: TColumn);
begin
(Column.Grid as TSMDBGrid).ClearSort;
if RightStr(TADODataSet(Column.Grid.DataSource.DataSet).Sort, 3) = 'ESC' THEN
begin
TADODataSet(Column.Grid.DataSource.DataSet).Sort := Column.FieldName ' ASC';
TSMDBColumn(Column).SortType := stAscending;
end
ELSE
begin
TADODataSet(Column.Grid.DataSource.DataSet).Sort := Column.FieldName ' DESC';
TSMDBColumn(Column).SortType := stDescending;
end;
end;

但若獨立到另外一個UNIT下就會出現,不認得Column這個物件。
g9221712
高階會員


發表:144
回覆:344
積分:162
註冊:2006-07-06

發送簡訊給我
#9 引用回覆 回覆 發表時間:2015-01-06 23:48:52 IP:122.117.xxx.xxx 訂閱
OnTitileClick

GrandRURU 版大:
果然功力深厚,我想應該舊這個關係。
不過若如您所說,使用frmMain := TFRM_Main.Create();
這樣會使整個Main Form 建立一個執行實例,耗用記憶體很大。

其實我源頭的想法很單純,就是當我拉一個DBGRID (or SMDBGRID) 元件時,
能快速的設定其屬性和事件,讓開發速度加快,想不到卻踢到大鐵板。

雖然您提的方法是解法,但我另想,難道不行獨立一個UNIT 去設定Main Form 的
DBGRID (or SMDBGRID) 元件嗎?
------
「人們所以覺得寂寞,是因為他們會築牆,卻不會搭橋。」
程式寫的越久,卻發現自己越來越不會寫程式!
GrandRURU
站務副站長


發表:234
回覆:1654
積分:1752
註冊:2005-06-21

發送簡訊給我
#10 引用回覆 回覆 發表時間:2015-01-07 06:31:27 IP:223.137.xxx.xxx 訂閱
自己做一個小物件吧
myComponent = class(TComponent)
public
procedure NewSMDBGridOnTitleClick;
end;

var myComponent;

===================引 用 g9221712 文 章===================
OnTitileClick

GrandRURU 版大:
果然功力深厚,我想應該舊這個關係。
不過若如您所說,使用frmMain := TFRM_Main.Create();
這樣會使整個Main Form 建立一個執行實例,耗用記憶體很大。

其實我源頭的想法很單純,就是當我拉一個DBGRID (or SMDBGRID) 元件時,
能快速的設定其屬性和事件,讓開發速度加快,想不到卻踢到大鐵板。

雖然您提的方法是解法,但我另想,難道不行獨立一個UNIT 去設定Main Form 的
DBGRID (or SMDBGRID) 元件嗎?
編輯記錄
GrandRURU 重新編輯於 2015-01-07 06:32:00, 註解 無‧
sryang
尊榮會員


發表:38
回覆:742
積分:876
註冊:2002-06-27

發送簡訊給我
#11 引用回覆 回覆 發表時間:2015-01-07 08:00:02 IP:59.127.xxx.xxx 訂閱
要把事件的處理常式集中在一個 unit 上,這個想法很好的
正如 GrandRuru 的作法,事件處理常式「必須」依附在物件之上,不可以獨立存在

我們來看看事件最簡單的定義:
TNotifyEvent = procedure(Sender: TObject) of object;
最後面的 of object 就表示必須依附在物件之上

不過呢,要使用時就得建立一個物件,這個物件又沒幹啥事,只是當成事件處理常式的載體,感覺有些浪費
不如這樣吧,用 initialization 跟 finalization 區段來建立與消滅一個共用的物件
這個物件的參考就放在 interface 區段,用 var 來宣告
------
歡迎參訪 "腦殘賤貓的備忘錄" http://maolaoda.blogspot.com/
編輯記錄
sryang 重新編輯於 2015-01-07 08:06:24, 註解 無‧
aftcast
站務副站長


發表:81
回覆:1482
積分:1762
註冊:2002-11-21

發送簡訊給我
#12 引用回覆 回覆 發表時間:2015-01-07 08:38:51 IP:114.32.xxx.xxx 訂閱
sryang都出來插花了,那我就忍不住再講一下個人的淺見:   ;-)

由於他的 procedure裡引入許多的型別,如 ado 的東西,什麼column的,若單獨寫 class,可能稍又複雜一點…

我提供另一個想法: 拉一個 datamodule,把 ado,什麼相依的東西 拉進去,就不用自己去use太多相依的units。 接著在 datamodule裡寫那些 procedure…

第二步,把 datamodule的創建順序拉到比 main form 高 (也就是第一順位建立),這點最好是這樣,不是這樣也不能說不行…但一如 coffee 版主也有提到這樣的情形。

在需main form 或需要的地方 use 這個datamodule,一如平常使用 datamodule一樣, onTitileClick : = DataModule1.newXXXXX

===================引 用 sryang 文 章===================
要把事件的處理常式集中在一個 unit 上,這個想法很好的
正如 GrandRuru 的作法,事件處理常式「必須」依附在物件之上,不可以獨立存在

我們來看看事件最簡單的定義:
TNotifyEvent = procedure(Sender: TObject) of object;
最後面的 of object 就表示必須依附在物件之上

不過呢,要使用時就得建立一個物件,這個物件又沒幹啥事,只是當成事件處理常式的載體,感覺有些浪費
不如這樣吧,用 initialization 跟 finalization 區段來建立與消滅一個共用的物件
這個物件的參考就放在 interface 區段,用 var 來宣告
------



蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
leveon
資深會員


發表:30
回覆:386
積分:303
註冊:2012-02-12

發送簡訊給我
#13 引用回覆 回覆 發表時間:2015-01-12 17:27:47 IP:1.161.xxx.xxx 訂閱

使用時並 ,物件不一定" 要建立( Create)


myComponent := TmyComponent.create(nil);
SMDBGrid01.OnTitileClick := TmyComponent(SMDBGrid01.Owner).NewSMDBGridOnTitleClick


甚至不需要物件

http://delphi.ktop.com.tw/board.php?cid=31&fid=79&tid=30573



===================引 用 sryang 文 章===================
要把事件的處理常式集中在一個 unit 上,這個想法很好的
正如 GrandRuru 的作法,事件處理常式「必須」依附在物件之上,不可以獨立存在

我們來看看事件最簡單的定義:
TNotifyEvent = procedure(Sender: TObject) of object;
最後面的 of object 就表示必須依附在物件之上

不過呢,要使用時就得建立一個物件,這個物件又沒幹啥事,只是當成事件處理常式的載體,感覺有些浪費
不如這樣吧,用 initialization 跟 finalization 區段來建立與消滅一個共用的物件
這個物件的參考就放在 interface 區段,用 var 來宣告
GrandRURU
站務副站長


發表:234
回覆:1654
積分:1752
註冊:2005-06-21

發送簡訊給我
#14 引用回覆 回覆 發表時間:2015-01-12 18:23:05 IP:221.120.xxx.xxx 訂閱
又上了一課

好物,謝謝分享!

===================引 用 leveon 文 章===================

使用時並 ,物件不一定" 要建立( Create)


myComponent := TmyComponent.create(nil);
SMDBGrid01.OnTitileClick := TmyComponent(SMDBGrid01.Owner).NewSMDBGridOnTitleClick


甚至不需要物件

http://delphi.ktop.com.tw/board.php?cid=31&fid=79&tid=30573



===================引 用 sryang 文 章===================
要把事件的處理常式集中在一個 unit 上,這個想法很好的
正如 GrandRuru 的作法,事件處理常式「必須」依附在物件之上,不可以獨立存在

我們來看看事件最簡單的定義:
TNotifyEvent = procedure(Sender: TObject) of object;
最後面的 of object 就表示必須依附在物件之上

不過呢,要使用時就得建立一個物件,這個物件又沒幹啥事,只是當成事件處理常式的載體,感覺有些浪費
不如這樣吧,用 initialization 跟 finalization 區段來建立與消滅一個共用的物件
這個物件的參考就放在 interface 區段,用 var 來宣告
aftcast
站務副站長


發表:81
回覆:1482
積分:1762
註冊:2002-11-21

發送簡訊給我
#15 引用回覆 回覆 發表時間:2015-01-12 18:48:42 IP:114.32.xxx.xxx 訂閱
leveon, 有時間的話解說一下,忙的話就算了,我再找時間去理解。 ^ ^

>> TmyComponent(SMDBGrid01.Owner).NewSMDBGridOnTitleClick

上面那行是啥? 至於method pointer (double pointer的結構),把self 換成nil或是有實值的object instance這我早理解。

我一眼看不懂上面那話就是。 我初初的看一眼,似 meta class叫用方法? 但總覺得怪怪的…

謝囉!

===================引 用 leveon 文 章===================
使用時並 ,物件不一定" 要建立( Create)
SMDBGrid01.OnTitileClick := TmyComponent(SMDBGrid01.Owner).NewSMDBGridOnTitleClick


甚至不需要物件

http://delphi.ktop.com.tw/board.php?cid=31&fid=79&tid=30573



------



蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
Coffee
版主


發表:31
回覆:878
積分:561
註冊:2006-11-15

發送簡訊給我
#16 引用回覆 回覆 發表時間:2015-01-12 19:01:42 IP:220.130.xxx.xxx 訂閱
Finally someone answer what I said. And this will be best due to thread safe and you internal object mechanism, so make a independent event will be more flexible.


===================引 用 leveon 文 章===================

使用時並 ,物件不一定" 要建立( Create)


myComponent := TmyComponent.create(nil);
SMDBGrid01.OnTitileClick := TmyComponent(SMDBGrid01.Owner).NewSMDBGridOnTitleClick


甚至不需要物件

http://delphi.ktop.com.tw/board.php?cid=31&fid=79&tid=30573



===================引 用 sryang 文 章===================
要把事件的處理常式集中在一個 unit 上,這個想法很好的
正如 GrandRuru 的作法,事件處理常式「必須」依附在物件之上,不可以獨立存在

我們來看看事件最簡單的定義:
TNotifyEvent = procedure(Sender: TObject) of object;
最後面的 of object 就表示必須依附在物件之上

不過呢,要使用時就得建立一個物件,這個物件又沒幹啥事,只是當成事件處理常式的載體,感覺有些浪費
不如這樣吧,用 initialization 跟 finalization 區段來建立與消滅一個共用的物件
這個物件的參考就放在 interface 區段,用 var 來宣告
------
不論是否我發的文,在能力範圍皆很樂意為大家回答問題。
為了補我的能力不足之處,以及讓答案可以被重複的使用,希望大家能儘量以公開的方式問問題。
在引述到我的文時自然會儘量替各位想辦法,謝謝大家!
aftcast
站務副站長


發表:81
回覆:1482
積分:1762
註冊:2002-11-21

發送簡訊給我
#17 引用回覆 回覆 發表時間:2015-01-12 19:28:23 IP:114.32.xxx.xxx 訂閱
你們二人一搭一唱好了…  哈哈。

如果這句話可以過(應該是可以,不然你們二人可能不會再那裡哈啦),我真的很配服delphi。拿一個任意的instance,然後強轉型別,接著就會被塞入 TMethod 結構中的data,而 "procedure"的部份卻同時可以依強轉型別後的那個NewSMDBGridOnTitleClick方法入帶入code部位。 這種compiler真的…要說強還是說弱?

well, however, it's a nice hack!

若我的推論錯誤,出來指正我喔!

===================引 用 Coffee 文 章===================
Finally someone answer what I said. And this will be best due to thread safe and you internal object mechanism, so make a independent event will be more flexible.


===================引 用 leveon 文 章===================

使用時並 ,物件不一定" 要建立( Create)


myComponent := TmyComponent.create(nil);
‚ SMDBGrid01.OnTitileClick := TmyComponent(SMDBGrid01.Owner).NewSMDBGridOnTitleClick



------



蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
系統時間:2017-11-24 21:11:56
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!