如何使用ApplicationEvents OnMessage得知 MDI Chile 被開啟了 |
尚未結案
|
egg_huang
一般會員 發表:4 回覆:5 積分:1 註冊:2003-05-23 發送簡訊給我 |
這是 wameng 大大在另一文章發表的
http://delphi.ktop.com.tw/topic.php?TOPIC_ID=64486
---------------------------------------- procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
begin
if Msg.message = 45089 then
begin
Showmessage(inttostr(Msg.hwnd));
end;
end; 可在此得知 MDI Child 要關閉了。
------------------------------------------- 想請教各位大大, 關閉是 45089 那開啟是多少呢?
|
yorkland
高階會員 發表:2 回覆:138 積分:108 註冊:2004-12-17 發送簡訊給我 |
|
Miles
尊榮會員 發表:27 回覆:662 積分:622 註冊:2002-07-12 發送簡訊給我 |
Hi egg_huang 你好:
我試圖使用wameng大大的方法去攔截ApplicationEvents的訊息, 但是無法攔到MDIChild Create的訊息, 所以換了另一種方法, 請參考
http://delphi.ktop.com.tw/topic.php?TOPIC_ID=64805 改寫如下
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); procedure FormShow(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } FClientInstance : TFarProc; FPrevClientProc : TFarProc; procedure ClientWndProc(var aMessage: TMessage); public { Public declarations } end; var Form1: TForm1; implementation Uses Unit2; {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin Form2 := TForm2.Create(Self); Form2.Show; end; procedure TForm1.ClientWndProc(var aMessage: TMessage); begin case aMessage.Msg of WM_MDICreate : begin aMessage.Result := CallWindowProc(FPrevClientProc,ClientHandle, aMessage.Msg, aMessage.wParam, aMessage.lParam); ShowMessage('Open Child'); end; WM_MDIDESTROY: begin aMessage.Result := CallWindowProc(FPrevClientProc,ClientHandle, aMessage.Msg, aMessage.wParam, aMessage.lParam); //MainForm.Tile; end; else aMessage.Result := CallWindowProc(FPrevClientProc,ClientHandle, aMessage.Msg, aMessage.wParam, aMessage.lParam); end; end; procedure TForm1.FormShow(Sender: TObject); begin FPrevClientProc := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC)); FClientInstance := MakeObjectInstance(ClientWndProc); SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(FClientInstance)); end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(FPrevClientProc)); end; end.我不是高手, 高手是正在銀幕前微笑的人.
------
我不是高手, 高手是正在銀幕前微笑的人. |
egg_huang
一般會員 發表:4 回覆:5 積分:1 註冊:2003-05-23 發送簡訊給我 |
|
egg_huang
一般會員 發表:4 回覆:5 積分:1 註冊:2003-05-23 發送簡訊給我 |
引言: Hi egg_huang 你好: 我試圖使用wameng大大的方法去攔截ApplicationEvents的訊息, 但是無法攔到MDIChild Create的訊息, 所以換了另一種方法, 請參考 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=64805 改寫如下感謝大大回應!! 此方式是不錯, 可以解決我的問題, 可是因為使用者需求有些 Child From 的 FromStyle 我改成了 fsStayOnTop, 結果就不行了.unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); procedure FormShow(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } FClientInstance : TFarProc; FPrevClientProc : TFarProc; procedure ClientWndProc(var aMessage: TMessage); public { Public declarations } end; var Form1: TForm1; implementation Uses Unit2; {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin Form2 := TForm2.Create(Self); Form2.Show; end; procedure TForm1.ClientWndProc(var aMessage: TMessage); begin case aMessage.Msg of WM_MDICreate : begin aMessage.Result := CallWindowProc(FPrevClientProc,ClientHandle, aMessage.Msg, aMessage.wParam, aMessage.lParam); ShowMessage('Open Child'); end; WM_MDIDESTROY: begin aMessage.Result := CallWindowProc(FPrevClientProc,ClientHandle, aMessage.Msg, aMessage.wParam, aMessage.lParam); //MainForm.Tile; end; else aMessage.Result := CallWindowProc(FPrevClientProc,ClientHandle, aMessage.Msg, aMessage.wParam, aMessage.lParam); end; end; procedure TForm1.FormShow(Sender: TObject); begin FPrevClientProc := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC)); FClientInstance := MakeObjectInstance(ClientWndProc); SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(FClientInstance)); end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(FPrevClientProc)); end; end.我不是高手, 高手是正在銀幕前微笑的人. |
wameng
版主 發表:31 回覆:1336 積分:1188 註冊:2004-09-16 發送簡訊給我 |
事實上,使用偵測 MDI Form 與MDI Child開啟與關閉。
本來就應按照Miles 大大為正規作法。 主要是應為MDIChild 的Parent 恰巧為
MainForm的ClientHandle 所管控。
因此介入 ClientWndProc 管理,是目前較常作的作法。 若仍堅持使用OnMessage。
當然並不是每一個訊息,均會通過 OnMessage事件。 但是 Msg.Message = 49309
似乎會是一個好的開始。
Msg.lPARAM 若是 Mainform.ClientHandle 則表示為MDIChild 動作。
Msg.lPARAM 若是 Form2.Handle 則表示為form2.FormStyle為非MDIChild。
如此作為事件來源的判斷。 但 49309 訊息,似乎並不是那麼簡單。
當 MiniMize or Restore 也會產生。
不過判斷的決定權仍在 lParam 的手上。 以上僅作為您的參考。若有錯誤,歡迎指教批評!
|
Miles
尊榮會員 發表:27 回覆:662 積分:622 註冊:2002-07-12 發送簡訊給我 |
|
egg_huang
一般會員 發表:4 回覆:5 積分:1 註冊:2003-05-23 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |