全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:4933
推到 Plurk!
推到 Facebook!

如何讓主Form只能放大/縮小/移動/不能關閉

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


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

發送簡訊給我
#1 引用回覆 回覆 發表時間:2006-09-17 10:51:34 IP:220.134.xxx.xxx 訂閱

各位前輩:

我希望我能控制主視窗只能放大/縮小/移動/不能關閉,但一直找不到相關屬性,
BorderIcons := [biMinimize,biMaximize];也無法達成,希望使用者都只能透過我的關閉按鈕或者選單
離開不知道要怎麼達成?

我用於關閉ACCESS視窗的程式碼

Function SystemMenu_DeleteClose()
'關閉Access主視窗 關閉X不能用
Dim iRet As Long
hWnd = Application.hWndAccessApp
hMenu = GetSystemMenu(hWnd, 0)
iRet = DeleteMenu(hMenu, SC_CLOSE, 0)
iRet = DrawMenuBar(hWnd)
End Function

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


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#2 引用回覆 回覆 發表時間:2006-09-17 14:25:52 IP:61.229.xxx.xxx 未訂閱

應該有二種方法可以達成,
1 subclassing
2 hook form dispatch msg

我覺得用第2種方法比較單純。實作如下:(我試著把我bcb的用法轉換成你的用法,你視情形自己可能需要修正)

1/ 在form的onqueryclose的事件上加
CanClose := false;
ShowMessage('請使用選單結束');
2/在form1的宣告中加入
private
procedure OnWMQueryEndSession(var Msg: TMessage); message wm_queryendsession
3/ 在實作的地方
procedure TForm1.OnWMQueryEndSession(var Msg: TMessage);
begin
Msg.Result=1;
end

試看看吧

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

各位前輩:

我希望我能控制主視窗只能放大/縮小/移動/不能關閉,但一直找不到相關屬性,
BorderIcons := [biMinimize,biMaximize];也無法達成,希望使用者都只能透過我的關閉按鈕或者選單
離開不知道要怎麼達成?

我用於關閉ACCESS視窗的程式碼

Function SystemMenu_DeleteClose()
'關閉Access主視窗 關閉X不能用
Dim iRet As Long
hWnd = Application.hWndAccessApp
hMenu = GetSystemMenu(hWnd, 0)
iRet = DeleteMenu(hMenu, SC_CLOSE, 0)
iRet = DrawMenuBar(hWnd)
End Function

------


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

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#3 引用回覆 回覆 發表時間:2006-09-17 14:41:48 IP:61.229.xxx.xxx 未訂閱
正想要寫一個用subclassing來完成的方式時,突然想到可以用override createparams( )的方式來處理。這是我曾研究vcl源代碼時發現的。也很簡單,而且可能更貼近你要的。你可能連右上角的x都不想要看到,這就使用者就沒輒了。
你可以先試下面的方式,也可以順便學習了解為何…雖然我沒講,但網路上查一下應該可以知道。

晚點沒人回,或是有時間再回你!

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

應該有二種方法可以達成,
1 subclassing
2 hook form dispatch msg

我覺得用第2種方法比較單純。實作如下:(我試著把我bcb的用法轉換成你的用法,你視情形自己可能需要修正)

1/ 在form的onqueryclose的事件上加
CanClose := false;
ShowMessage('請使用選單結束');
2/在form1的宣告中加入
private
procedure OnWMQueryEndSession(var Msg: TMessage); message wm_queryendsession
3/ 在實作的地方
procedure TForm1.OnWMQueryEndSession(var Msg: TMessage);
begin
Msg.Result=1;
end

試看看吧

------


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

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
g9221712
高階會員


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

發送簡訊給我
#4 引用回覆 回覆 發表時間:2006-09-18 02:23:55 IP:220.134.xxx.xxx 訂閱

aftcast前輩:

感謝您不斷的給予回覆和指導,真不知道要怎麼感謝您!

我發現您講的方法,都讓我有更多的體會、促使我不斷的更深入的搜索,有些議題看起來簡單,
其實隱含的應用都是很龐大的議題!尤其您講的override createparams( )的方式,我找了網路上
的討論,vcl override只能說無所不能啊! 讓我又見識到另外一個物件的使用方式! 不過雖然
最後我的解決方案,不是createparams,但也確實的解決我的問題,而且是一個印度的網站上,所找到的,
不過有aftcast的回應,我會更努力的,一天找一個議題,我想我這個菜菜鳥也可以長出毛來!


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
procedure CreateParams(var Params: TCreateParams); override;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
SysMenu: HMenu;
begin
SysMenu := GetSystemMenu(Handle, False);
Windows.EnableMenuItem(SysMenu, SC_CLOSE, MF_DISABLED or MF_GRAYED);
end;

end.

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


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#5 引用回覆 回覆 發表時間:2006-09-18 02:40:55 IP:61.229.xxx.xxx 未訂閱
剛才有一點空要回你的問題,結果你就先找到答案了! 而我要告訴你的答案和你是類似的,真是太巧了!

RemoveMenu(GetSystemMenu(Handle, false), SC_CLOSE, MF_BYCOMMAND);

就上面那句話! 和你是否很像? 有什麼不同呢? 我一回兒也試一下你的方式,比較一下!

教學相長,教的時候也是考驗自己是否很了解的時候,並也可以觸發更多的想法。

createparams的方法我其實也稍有試了一下,但無法解決這個close (x)的問題。只能用我上面的removemenu或你的EnableMenuItem吧。

但是,最上面的那個方法應該也是有用的。我通常用在icon tray時,就是當user 按下 x 時,我就下縮小至icon,但不會造成ap 結束。是另一類相關的應用。有機會也可以試看看!

也謝謝你分享喔!

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

aftcast前輩:

感謝您不斷的給予回覆和指導,真不知道要怎麼感謝您!

我發現您講的方法,都讓我有更多的體會、促使我不斷的更深入的搜索,有些議題看起來簡單,
其實隱含的應用都是很龐大的議題!尤其您講的override createparams( )的方式,我找了網路上
的討論,vcl override只能說無所不能啊! 讓我又見識到另外一個物件的使用方式! 不過雖然
最後我的解決方案,不是createparams,但也確實的解決我的問題,而且是一個印度的網站上,所找到的,
不過有aftcast的回應,我會更努力的,一天找一個議題,我想我這個菜菜鳥也可以長出毛來!

procedure TForm1.FormCreate(Sender: TObject);
var
SysMenu: HMenu;
begin
SysMenu := GetSystemMenu(Handle, False);
Windows.EnableMenuItem(SysMenu, SC_CLOSE, MF_DISABLED or MF_GRAYED);
end;

------


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

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#6 引用回覆 回覆 發表時間:2006-09-18 02:47:00 IP:61.229.xxx.xxx 未訂閱

剛比較了一下,大概只有差在當你在window的左上角click一下後,會出現menu,若是你的方式則會出現「X關閉 ALT F4] 但是是灰的。若我的則會整個把menu item 移除,即沒出現那句話!

不過,無論哪一種若用 ALT F4 都是會結束程式。所以…我想若不要讓user知道用這個hotkey,就remove了。若還是想讓user知道,就disable囉! 你說是不?

------


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

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
g9221712
高階會員


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

發送簡訊給我
#7 引用回覆 回覆 發表時間:2006-09-18 03:26:42 IP:220.134.xxx.xxx 訂閱

aftcast前輩:

這麼晚您還沒休息!我發現您的方法比較好,比較符合人機介面理論,減少不良的提示、減少使用者誤觸的錯誤,

只能說您真是太強了! 不過程式設計師的命運,好像都勢必變成熬夜一族!

------
「人們所以覺得寂寞,是因為他們會築牆,卻不會搭橋。」
程式寫的越久,卻發現自己越來越不會寫程式!
系統時間:2024-04-26 19:13:30
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!