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

如何使用ApplicationEvents OnMessage得知 MDI Chile 被開啟了

尚未結案
egg_huang
一般會員


發表:4
回覆:5
積分:1
註冊:2003-05-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-02-17 09:50:23 IP:211.20.xxx.xxx 未訂閱
這是 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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-02-17 11:05:15 IP:220.130.xxx.xxx 未訂閱
在每一個Child Window打開或關閉時, 送message給mainform是不是能解決這個問題?
Miles
尊榮會員


發表:27
回覆:662
積分:622
註冊:2002-07-12

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-02-17 11:06:13 IP:220.135.xxx.xxx 未訂閱
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

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-02-17 11:37:39 IP:211.20.xxx.xxx 未訂閱
引言: 在每一個Child Window打開或關閉時, 送message給mainform是不是能解決這個問題?
感謝您的回應!! 可是我不希望在每個Chile Windows都改(有上千支程式), 我可能會瘋狂....
egg_huang
一般會員


發表:4
回覆:5
積分:1
註冊:2003-05-23

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-02-17 11:44:17 IP:211.20.xxx.xxx 未訂閱
引言: 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.
我不是高手, 高手是正在銀幕前微笑的人.
感謝大大回應!! 此方式是不錯, 可以解決我的問題, 可是因為使用者需求有些 Child From 的 FromStyle 我改成了 fsStayOnTop, 結果就不行了.
wameng
版主


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

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-02-17 12:32:16 IP:61.222.xxx.xxx 未訂閱
事實上,使用偵測 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

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-02-17 13:26:40 IP:220.135.xxx.xxx 未訂閱
Hi egg_huang 你好: 還有一種比較另類的做法, 將Forms.Pas這個Delphi的系統檔放到自己的專案, 修改constructor TCustomForm.Create(AOwner: TComponent);裡面的程式, 送一個自訂Message給你的MainForm 我不是高手, 高手是正在銀幕前微笑的人.
------


我不是高手, 高手是正在銀幕前微笑的人.
egg_huang
一般會員


發表:4
回覆:5
積分:1
註冊:2003-05-23

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-02-17 18:17:13 IP:211.20.xxx.xxx 未訂閱
感謝大大回應!! 可是 49309 不對吔!! 我在 ApplicationEvents 的 OnMessage 中下了 if Msg.message = 49309 then ShowMessage('Open'); 可是還是沒有停下來 ShowMessage 有沒有範例啊!!
系統時間:2024-05-19 1:04:18
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!