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

如何做subclass?

答題得分者是:change.jian
jck11
一般會員


發表:6
回覆:3
積分:1
註冊:2006-09-16

發送簡訊給我
#1 引用回覆 回覆 發表時間:2006-09-16 23:42:02 IP:125.232.xxx.xxx 訂閱

網路上看到的一個範例

提到做完這個subclass動作後,將無法結束程式

但試不出來,不知何處出了問題

unit Unit1;

interface

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

type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
OldWndProc: Pointer;

implementation

{$R *.DFM}

function NewWndProc(hHwnd, Msg, wParam, lParam: LongWORD): Longint; stdcall;
begin
if Msg=WM_CLOSE then exit;
Result := CallWindowProc(OldWndProc, hHwnd, Msg, wParam, lParam);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
close;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
OldWndProc:= Pointer(GetWindowLong(Self.Handle, GWL_WNDPROC));
SetWindowLong(Self.Handle, GWL_WNDPROC, Longint(@NewWndProc));
end;

end.

aftcast
站務副站長


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

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

你好,
你hook了原來的WndProc,然後又自行處理WM_CLOSE 這個訊息,但是…你就簡單一句話 exit,那樣子是無法幫你結束你的程式的。單純 exit是指結束NewWndProc,但非你的主程式結束。

試著then Application.Terminate; 試看看也許ok,因為我沒自行處理過WM_CLOSE

------


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

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
jck11
一般會員


發表:6
回覆:3
積分:1
註冊:2006-09-16

發送簡訊給我
#3 引用回覆 回覆 發表時間:2006-09-17 11:43:24 IP:125.232.xxx.xxx 訂閱

aftcast兄可能誤會我的意思了

那個範例是說,原本我按button1可以是常結束程式的

但只要我加了那個subclass之後

程式就會不結束

但我試了一下,程式還是會close的

所以我才會覺得是不是我哪裡搞錯呢

aftcast
站務副站長


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

發送簡訊給我
#4 引用回覆 回覆 發表時間:2006-09-17 14:08:43 IP:61.229.xxx.xxx 未訂閱
SORRY, 我沒看清楚!
嗯,造程式看來應該是無法正程結束。但你為何照常結束呢?
可以請問一下你button1裡的onlick是怎樣的結束程式? 下Application.Terminate?
------


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

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


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

發送簡訊給我
#5 引用回覆 回覆 發表時間:2006-09-17 14:09:16 IP:61.229.xxx.xxx 未訂閱
SORRY, 我沒看清楚!
嗯,照程式看來應該是無法正程結束。但你為何照常結束呢?
可以請問一下你button1裡的onlick是如何的結束程式? 下Application.Terminate?

可以試著把
SetWindowLong(Self.Handle, GWL_WNDPROC, Longint(@NewWndProc));
改成
SetWindowLong(Application.Handle, GWL_WNDPROC, Longint(@NewWndProc));

試看看是否還是會結束?
或者把button1的事件貼一下。
謝謝。

------


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

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
jck11
一般會員


發表:6
回覆:3
積分:1
註冊:2006-09-16

發送簡訊給我
#6 引用回覆 回覆 發表時間:2006-09-18 08:13:16 IP:61.60.xxx.xxx 訂閱

試了一下還是不行
我的button1的程式就只有close而以

procedure TForm1.Button1Click(Sender: TObject);
begin
close;
end;


aftcast
站務副站長


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

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

對不起,實在看不出來問題在哪兒,又加上我手中沒有delphi可以試。所以只能猜了。
最後一個猜的地方是改了紅色的地方。

function NewWndProc(hHwnd, Msg, wParam, lParam: LongWORD): Longint; stdcall;
begin
if Msg=WM_CLOSE or Msg=WM_QUERYENDSESSION then exit;
Result := CallWindowProc(OldWndProc, hHwnd, Msg, wParam, lParam);
end;

再不行就要請手中用delphi的人來實測幫你了…

------


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

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
jck11
一般會員


發表:6
回覆:3
積分:1
註冊:2006-09-16

發送簡訊給我
#8 引用回覆 回覆 發表時間:2006-09-18 21:01:25 IP:125.232.xxx.xxx 訂閱

測了一下 還是沒成功

感謝大大的幫忙 :)

change.jian
版主


發表:29
回覆:620
積分:439
註冊:2003-06-02

發送簡訊給我
#9 引用回覆 回覆 發表時間:2006-09-28 13:39:49 IP:211.23.xxx.xxx 未訂閱

hi,

function NewWndProc(hHwnd, Msg, wParam, lParam: LongWORD): Longint; stdcall;
begin
if Msg=WM_CLOSE then exit; //<-- 碰到 WM_CLOSE 就離開(沒有任何處理),所以當然不會關閉
Result := CallWindowProc(OldWndProc, hHwnd, Msg, wParam, lParam);
end;

waterful0
一般會員


發表:7
回覆:12
積分:3
註冊:2006-07-12

發送簡訊給我
#10 引用回覆 回覆 發表時間:2006-10-04 10:22:55 IP:220.134.xxx.xxx 未訂閱

NewWndPro的確是可以subclass掉原有的WndProc,
所以你可以發覺當你按下Form右上角的X並無法將視窗關閉。
因為你已經將WM_CLOSE這個訊息處理掉了(if Msg=WM_CLOSE then exit;)

但為何按下button1還是會將視窗關閉呢?那是因為Close這個由VCL幫我們封裝好的procedure
是在接受到WM_CLOSE這個訊息才作用的,他的作用當然就是把視窗關閉,呵。
而當你按下button1直接呼叫close時,此時又沒有發出WM_CLOSE所以NewWndProc當然沒有作用。

如果要在按下button1時不將視窗關閉,建議可以在CloseQuery這個事件中編寫你的程式碼來阻止視窗的關閉。

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