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

如何防止程式被最小化

答題得分者是:banson1716
Nelson Lo
一般會員


發表:35
回覆:87
積分:24
註冊:2003-04-04

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-07-14 09:59:49 IP:61.221.xxx.xxx 未訂閱
請教各位, 我想使用 if (Msg.Message = wm_Syscommand) and (Msg.wParam = SC_MINIMIZE) then Handled := True; 來攔截程式被最小化,不知道對不對, 可是就算攔到訊息了又該如何不最小化呢? 我是指包括按螢幕左下角的"顯示桌面"按鈕.
Nelson Lo
一般會員


發表:35
回覆:87
積分:24
註冊:2003-04-04

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-07-14 10:03:14 IP:61.221.xxx.xxx 未訂閱
補充一點 括按螢幕左下角的"顯示桌面"按鈕 好像攔截不到最小化的訊息
timhuang
尊榮會員


發表:78
回覆:1815
積分:1608
註冊:2002-07-15

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-07-14 19:04:34 IP:203.95.xxx.xxx 未訂閱
引言: 攔到訊息了又該如何不最小化呢?
procedure TForm1.WndProc(var Message: TMessage);
begin
  if (Message.Msg = wm_Syscommand) and (Message.wParam = SC_MINIMIZE) then
  begin
    abort;
  end;
  inherited WndProc(Message);
end;
Nelson Lo
一般會員


發表:35
回覆:87
積分:24
註冊:2003-04-04

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-07-15 08:55:39 IP:61.221.xxx.xxx 未訂閱
感謝您的回答 但是這樣還是攔不到所有會造成最小化的動作 例如 1.括按螢幕左下角的"顯示桌面"按鈕 2.按工作列上面程式自己的按鈕
shaofu
高階會員


發表:5
回覆:136
積分:103
註冊:2003-01-07

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-07-15 10:52:47 IP:210.243.xxx.xxx 未訂閱
應該是要很特別的方法來做..  你說的那個顯示桌面的最小化.. 等級好像很高...(OS Level?) 常常 Windows 快當要死不活時.. 或者你的程式已經當了 (Block 住), 那個顯示桌面的最小化都還能正常工作.. < > 當然, 我對這個也沒研究就是了 < > 上 google 找找看吧... PS: 如果只是要攔 task bar 上的, 要改攔 Application.OnMessage. 發表人 - shaofu 於 2003/07/15 11:00:18
Nelson Lo
一般會員


發表:35
回覆:87
積分:24
註冊:2003-04-04

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-07-15 11:46:06 IP:61.221.xxx.xxx 未訂閱
沒錯 我用Application.OnMessage可以攔到task bar 上的, 但是卻又攔不到程式右上角的最小化(當然我可以把它disable就好了), 難道沒有兩全其美的辦法嗎!! 至於螢幕左下角的"顯示桌面"按鈕的最小化...... 到現在還是找不到 還是謝謝您的回答
shaofu
高階會員


發表:5
回覆:136
積分:103
註冊:2003-01-07

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-07-15 12:47:46 IP:210.243.xxx.xxx 未訂閱
右上角的用 timhuang 兄的就好了 < > 兩個可以一起用啊... 只是顯示桌面那個.. 可能要去挖一些資料才有辦法..< >
aquarius
資深會員


發表:3
回覆:347
積分:330
註冊:2003-05-21

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-07-15 13:02:40 IP:211.23.xxx.xxx 未訂閱
引言: 沒錯 我用Application.OnMessage可以攔到task bar 上的, 但是卻又攔不到程式右上角的最小化(當然我可以把它disable就好了), 難道沒有兩全其美的辦法嗎!! 至於螢幕左下角的"顯示桌面"按鈕的最小化...... 到現在還是找不到 還是謝謝您的回答
用 TIMER 搞定!! TIMER 設 1000, 這樣最多消失一秒後又回來了. 就算用顯示桌面的那個也一樣... < class="code"> procedure TForm1.Timer1Timer(Sender: TObject); begin if not IsWindowVisible(handle) then begin WindowState:=wsNormal ; Application.Restore ; end ; end; ...Aquarius
------
水瓶男的blog: http://791909.blogspot.com
Nelson Lo
一般會員


發表:35
回覆:87
積分:24
註冊:2003-04-04

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-07-15 13:14:12 IP:61.221.xxx.xxx 未訂閱
aquarius 兄 偷吃步< >< > 這樣不行啦
Rain
資深會員


發表:31
回覆:236
積分:268
註冊:2003-02-17

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-07-15 13:43:23 IP:218.5.xxx.xxx 未訂閱
哈哈,顯示桌面的這個估計有點難度,它的原理也不是讓表單最小化,因此攔截最小化消息是不行的,不妨來看看它是怎麼實現的吧: 在那個Quick Launch目錄下找到顯示桌面.scf,用記事本打開,可以發現是調用ToggleDesktop:Command=ToggleDesktop,在MSDN library中找一下這個 ToggleDesktop的相關說明:    ToggleDesktop Method    Raises and lowers the desktop.    就是說它的做法是通過提升和降低桌面來實現所有表單的隱藏和顯示的。 更詳細的請見:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/objects/ishelldispatch4/toggledesktop.asp    至於要怎麼解決,或許用鉤子攔截點擊顯示桌面動作是一種方法,只是也比較麻煩了,不妨再等等看哪位前輩有什麼好的方法吧
aquarius
資深會員


發表:3
回覆:347
積分:330
註冊:2003-05-21

發送簡訊給我
#11 引用回覆 回覆 發表時間:2003-07-15 13:53:12 IP:211.23.xxx.xxx 未訂閱
引言: aquarius 兄 偷吃步< >< > 這樣不行啦
不愛用 TIMER 嗎? 那換個地方放就好了嘛!!
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnIdle:= MyIdleHandler;
end;    procedure TForm1.MyIdleHandler(Sender: TObject; var Done: Boolean);
begin
   if not IsWindowVisible(handle) then
    begin
    WindowState:=wsNormal ;
    Application.Restore ;
    end ;    end;    
按 <顯示桌面>, 是不會有 MESSAGE 產生的, 所以得在其他的地方檢查. 基本上就是 POLLING 就對了啦!! 只是看你把檢查的地方放在那兒比較不會礙眼罷了!! ...
------
水瓶男的blog: http://791909.blogspot.com
Nelson Lo
一般會員


發表:35
回覆:87
積分:24
註冊:2003-04-04

發送簡訊給我
#12 引用回覆 回覆 發表時間:2003-07-15 14:32:30 IP:61.221.xxx.xxx 未訂閱
引言: 按 <顯示桌面>, 是不會有 MESSAGE 產生的
按 <顯示桌面>, 真的不會有 MESSAGE 產生嗎?? 應該有吧< >< > 如果沒有它如何要每個視窗最小化呢??
aquarius
資深會員


發表:3
回覆:347
積分:330
註冊:2003-05-21

發送簡訊給我
#13 引用回覆 回覆 發表時間:2003-07-15 14:54:46 IP:211.23.xxx.xxx 未訂閱
引言:
引言: 按 <顯示桌面>, 是不會有 MESSAGE 產生的
按 <顯示桌面>, 真的不會有 MESSAGE 產生嗎?? 應該有吧< >< > 如果沒有它如何要每個視窗最小化呢??
Windows 系統中, 不是只有 Message 才能控制別人的程式呀!! 顯示桌面 的實際做法, 在 Rain 提供的那個網址有提到. 就像你要結束一個程式, 可以送 WM_QUIT, 也可以用 TerminateProcess. 後者可不會給被結束的程式任何的 MESSAGE. ...Aquarius
------
水瓶男的blog: http://791909.blogspot.com
Nelson Lo
一般會員


發表:35
回覆:87
積分:24
註冊:2003-04-04

發送簡訊給我
#14 引用回覆 回覆 發表時間:2003-07-15 15:50:00 IP:61.221.xxx.xxx 未訂閱
謝謝您的解說 那麼那些以非message方式傳達的API 是用何種機制來達成控制另一程式的目的呀 如果有個方向 或許可以找出ToggleDesktop實作的方法
aquarius
資深會員


發表:3
回覆:347
積分:330
註冊:2003-05-21

發送簡訊給我
#15 引用回覆 回覆 發表時間:2003-07-16 14:34:30 IP:211.23.xxx.xxx 未訂閱
引言: 謝謝您的解說 那麼那些以非message方式傳達的API 是用何種機制來達成控制另一程式的目的呀 如果有個方向 或許可以找出ToggleDesktop實作的方法
ToggleDesktop 的實作方法我是沒有特別去研究. 但控制 WINDOWS 系統中別的程式的方法有很多呀!! 例如用 HOOK 進入別人的行程去修改 Windows style, 或攔截 API 進行其他的處理..... 方法很多... 自己多找點書來看吧!!..... :) ...Aquarius
------
水瓶男的blog: http://791909.blogspot.com
banson1716
高階會員


發表:55
回覆:182
積分:167
註冊:2002-04-14

發送簡訊給我
#16 引用回覆 回覆 發表時間:2003-07-17 03:53:51 IP:218.175.xxx.xxx 未訂閱
try try see public procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND; { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.WMSysCommand; begin if (Msg.CmdType = SC_MINIMIZE) then MessageBeep(0) else inherited; end;
banson1716
高階會員


發表:55
回覆:182
積分:167
註冊:2002-04-14

發送簡訊給我
#17 引用回覆 回覆 發表時間:2003-07-17 04:25:27 IP:218.175.xxx.xxx 未訂閱
Form1.BorderIcons := Form1.BorderIcons - [biMinimize];
Nelson Lo
一般會員


發表:35
回覆:87
積分:24
註冊:2003-04-04

發送簡訊給我
#18 引用回覆 回覆 發表時間:2003-07-17 13:34:05 IP:61.221.xxx.xxx 未訂閱
banson1716 兄 那 WMSysCommand 要如何使用呢 例如 Application.OnMessage := AppMessage; or WindowProc := WndProc; 謝謝
banson1716
高階會員


發表:55
回覆:182
積分:167
註冊:2002-04-14

發送簡訊給我
#19 引用回覆 回覆 發表時間:2003-07-17 15:57:19 IP:218.175.xxx.xxx 未訂閱
參考 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=30391 procedure TForm1.WMSysCommand(var Message: TWMSysCommand); begin BorderIcons := BorderIcons - [biMinimize]; if (Message.CmdType = SC_MINIMIZE) then MessageBeep(0) else inherited; end; 發表人 - banson1716 於 2003/07/17 16:15:27
ko
資深會員


發表:28
回覆:785
積分:444
註冊:2002-08-14

發送簡訊給我
#20 引用回覆 回覆 發表時間:2003-07-17 16:43:01 IP:61.221.xxx.xxx 未訂閱
Nelson Lo 你好: 小弟有一個淺見,提出來大家參考.. 小弟認為抓取最小化的訊息,不如抓取hWnd改變的訊息,當hWnd改變就給他 來個程式最置前..< > 安內你共好嗯好阿...< >
------
======================
昏睡~
不昏睡~
不由昏睡~
Nelson Lo
一般會員


發表:35
回覆:87
積分:24
註冊:2003-04-04

發送簡訊給我
#21 引用回覆 回覆 發表時間:2003-07-17 16:57:51 IP:61.221.xxx.xxx 未訂閱
引言: Nelson Lo 你好: 小弟有一個淺見,提出來大家參考.. 小弟認為抓取最小化的訊息,不如抓取hWnd改變的訊息,當hWnd改變就給他 來個程式最置前..< > 安內你共好嗯好阿...< >
可是這樣會不會還是先被最小化了才又再置前呢 還有小弟我實在功力有限 不知道hWnd要如何抓ㄝ 謝謝
banson1716
高階會員


發表:55
回覆:182
積分:167
註冊:2002-04-14

發送簡訊給我
#22 引用回覆 回覆 發表時間:2003-07-20 03:46:10 IP:218.175.xxx.xxx 未訂閱
轉載 接收一個Form中的消息 六種方法: (1)使用Delphi的標準方式,響應一定的事件(如果Delphi提供 的話,最常用的,最簡單的) (2)重載窗體的WndProc虛擬對像方法,並查找相應的消息 (3)重載窗體的DefaultHandler虛擬對像方法,並查找相應的消 息 (4)為消息定義一個消息響應對像方法(如果第一種方法不行的 話,這是最常用的) (5)重載Delphi提供的對應的動態對像方法 (6)使用Application的OnMessage事件響應 五種方法的響應順序 (2)(4)(3)(5)(1)。隻要有可能就使用第(1)中方法 舉例: 以接收鼠標左鍵在屏幕上單擊這個消息為例 代碼: type TFormManyMess = class(TForm) .... procedure FormMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer); public procedure WndProc(var Message: TMessage); override; procedure DefaultHandler(var Message); override; procedure WmLButtonDown (var Message: TWMMouse);message wm_lButtonDown; procedure MouseDown(Button: TMouseButton;Shift: TShiftState; X, Y: Integer); override; end; //使用Delphi的標準方式 procedure TFormManyMess.FormMouseDown(Sender: TObject;Button: TMouseButton; Shift: TShiftState;X, Y: Integer); begin if Button = mbLeft then LBox.Items.Add (Format ('%s in (%d, %d)',['FormMouseDown', X, Y])); end; //重載窗體的WndProc虛擬對像方法,並查找相應的消息 procedure TFormManyMess.WndProc(var Message: TMessage); begin if Message.Msg = wm_LButtonDown then LBox.Items.Add (Format ('%s in (%d, %d)',['WndProc', LoWord (Message.LParam),HiWord (Message.LParam)])); inherited; end; //重載窗體的DefaultHandler虛擬對像方法,並查找相應的消息 procedure TFormManyMess.DefaultHandler(var Message); begin with TMessage (Message) do if Msg = wm_LButtonDown then LBox.Items.Add (Format ('%s in (%d, %d)',['DefaultHandler', LoWord (LParam),HiWord (LParam)])); inherited; end; //為消息定義一個消息響應對像方法 procedure TFormManyMess.WmLButtonDown (var Message: TWMMouse); begin LBox.Items.Add (Format ('%s in (%d, %d)',['WmLButtonDown', Message.XPos, Message.YPos])); inherited; end; //重載Delphi提供的對應的動態對像方法 procedure TFormManyMess.MouseDown(Button: TMouseButton;Shift: TShiftState; X, Y: Integer); begin if Button = mbLeft then LBox.Items.Add (Format ('%s in (%d, %d)',['MouseDown', X, Y])); inherited; end; //使用Application的OnMessage事件響應 procedure TFormManyMess.ApplicationMessage (var Msg: TMsg;var Handled: Boolean); begin if (Msg.Message = wm_LButtonDown) and (Msg.hWnd = Handle) then LBox.Items.Add (Format ('%s in (%d, %d)',['ApplicationMessage', LoWord (Msg.LParam),HiWord (Msg.LParam)])); Handled := False; end; procedure TFormManyMess.FormCreate(Sender: TObject); begin Application.OnMessage := ApplicationMessage; end; 發表人 - banson1716 於 2003/07/20 03:47:28
系統時間:2024-05-02 10:18:46
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!