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

自定元件使用外部單元(非系統)

答題得分者是:careychen
stacker_liew
中階會員


發表:59
回覆:168
積分:65
註冊:2004-05-17

發送簡訊給我
#1 引用回覆 回覆 發表時間:2008-08-12 12:46:27 IP:60.51.xxx.xxx 訂閱
我想建立一個自定元件(Custom Component),但該元件裡面有個procedure有用到外部單元的變數,請問如何做到?

[code delphi]
unit TrayAnimation;

interface

uses
SysUtils, Classes, Math, ShellApi, Messages, Graphics, Windows, Forms;

type
TTrayAnimation = class(TComponent)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure FloatingRectangles(Minimizing, OverrideUserSettings: Boolean;);

published
{ Published declarations }
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('Samples', [TTrayAnimation]);
end;

{ TTrayAnimation }

constructor TTrayAnimation.Create(AOwner: TComponent);
begin
inherited Create(AOwner);

end;

destructor TTrayAnimation.Destroy;
begin

inherited Destroy;
end;

procedure TTrayAnimation.FloatingRectangles(Minimizing,
OverrideUserSettings: Boolean;);
var
RectFrom, RectTo: TRect;
GotRectTo: Boolean;
abd: TAppBarData;
HTaskbar, HTrayWnd: HWND;
ResetRegistry: Boolean;
ai: TAnimationInfo;

procedure SetAnimation(Animation: Boolean);
begin
FillChar(ai, SizeOf(ai), 0);
ai.cbSize := SizeOf(ai);
if Animation then
ai.iMinAnimate := 1
else
ai.iMinAnimate := 0;
SystemParametersInfo(SPI_SETANIMATION, 0, @ai, SPIF_SENDCHANGE);
end;

begin
// Check if user wants window animation
ResetRegistry := False;
if OverrideUserSettings then
begin
FillChar(ai, SizeOf(ai), 0);
ai.cbSize := SizeOf(ai);
SystemParametersInfo(SPI_GETANIMATION, 0, @ai, SPIF_SENDCHANGE);
if ai.iMinAnimate = 0 then
begin
// Temporarily enable window animation
ResetRegistry := True;
SetAnimation(True);
end;
end;

RectFrom := MainForm.BoundsRect;
GotRectTo := False;

// Get the traybar's bounding rectangle
HTaskbar := FindWindow('Shell_TrayWnd', nil);
if HTaskbar <> 0 then
begin
HTrayWnd := FindWindowEx(HTaskbar, 0, 'TrayNotifyWnd', nil);
if HTrayWnd <> 0 then
if GetWindowRect(HTrayWnd, RectTo) then
GotRectTo := True;
end;

// If that fails, invent a rectangle in the corner where the traybar is
if not GotRectTo then
begin
FillChar(abd, SizeOf(abd), 0);
abd.cbSize := SizeOf(abd);
if SHAppBarMessage(ABM_GETTASKBARPOS, abd) = 0 then Exit;
with Screen, abd.rc do
if (Top > 0) or (Left > 0) then
RectTo := Rect(Width-32, Height-32, Width, Height)
else if (Bottom < Height) then
RectTo := Rect(Width-32, 0, Width, 32)
else if (Right < Width) then
RectTo := Rect(0, Height-32, 32, Height);
end;

if Minimizing then
DrawAnimatedRects(MainForm.Handle, IDANI_CAPTION, RectFrom, RectTo)
else
DrawAnimatedRects(MainForm.Handle, IDANI_CAPTION, RectTo, RectFrom);

if ResetRegistry then
SetAnimation(False); // Disable window animation
end;

end.

[/code]

MainForm 就是參照到外部單元,我想使用元件放在那個Form就指到那個Form,請問要如何做?
careychen
尊榮會員


發表:41
回覆:580
積分:959
註冊:2004-03-03

發送簡訊給我
#2 引用回覆 回覆 發表時間:2008-08-12 14:05:22 IP:218.210.xxx.xxx 訂閱
試試這樣


[code delphi]
RectFrom := TWinControl(Owner).BoundsRect;

if Minimizing then
DrawAnimatedRects(TWinControl(Owner).Handle, IDANI_CAPTION, RectFrom, RectTo)
else
DrawAnimatedRects(TWinControl(Owner).Handle, IDANI_CAPTION, RectTo, RectFrom);
[/code]
------
價值的展現,來自於你用哪一個角度來看待它!!
編輯記錄
careychen 重新編輯於 2008-08-12 14:07:27, 註解 無‧
careychen 重新編輯於 2008-08-12 15:30:13, 註解 顏色出不來 =_=‧
pedro
尊榮會員


發表:152
回覆:1187
積分:892
註冊:2002-06-12

發送簡訊給我
#3 引用回覆 回覆 發表時間:2008-08-12 14:11:39 IP:60.248.xxx.xxx 未訂閱
繼承至TComponent,其建構式Create,有參數owner
元件被放置在form上,其owner即被設置,
由owner去處理所屬的form

如果是MDI式應用程式,可在Application.MainForm取得

procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(TForm(Button1.Owner).Caption);
ShowMessage(Application.MainForm.Caption);
end;
stacker_liew
中階會員


發表:59
回覆:168
積分:65
註冊:2004-05-17

發送簡訊給我
#4 引用回覆 回覆 發表時間:2008-08-13 11:21:39 IP:219.95.xxx.xxx 訂閱
感謝大大,我照上面的例子改了,也可以用,但奇怪的是我把元件裝在面板上後,在拖拉到程式上,會發生找不到元件的問題,請問上面那元件應該改成怎樣才不會有問題?
careychen
尊榮會員


發表:41
回覆:580
積分:959
註冊:2004-03-03

發送簡訊給我
#5 引用回覆 回覆 發表時間:2008-08-13 11:36:07 IP:218.210.xxx.xxx 訂閱
我試過了,是可以的,所以有可能是你元件路徑的關係,請看一下下面這篇
最底下是我昨天的 Po 文

http://delphi.ktop.com.tw/board.php?cid=169&fid=1369&tid=94818

------
價值的展現,來自於你用哪一個角度來看待它!!
stacker_liew
中階會員


發表:59
回覆:168
積分:65
註冊:2004-05-17

發送簡訊給我
#6 引用回覆 回覆 發表時間:2008-08-13 11:41:09 IP:219.95.xxx.xxx 訂閱

===================引 用 stacker_liew 文 章===================
感謝大大,我照上面的例子改了,也可以用,但奇怪的是我把元件裝在面板上後,在拖拉到程式上,會發生找不到元件的問題,請問上面那元件應該改成怎樣才不會有問題?

實際情形是在編譯時會編譯不過,說找不到元件TrayAnimation,請問是什麼原因呢?

註:我的環境是Delphi 7,Windows XP SP3,我的文件是存在 我的文件/My Delphi Projects/TrayAnimations下。

我試過另存在Tray.dpk檔編譯安裝,還有另一種加入到Borland User Components的方法都一樣。

應該不是路徑的問題。
編輯記錄
stacker_liew 重新編輯於 2008-08-13 11:51:44, 註解 無‧
stacker_liew 重新編輯於 2008-08-13 11:55:24, 註解 無‧
careychen
尊榮會員


發表:41
回覆:580
積分:959
註冊:2004-03-03

發送簡訊給我
#7 引用回覆 回覆 發表時間:2008-08-13 11:58:57 IP:218.210.xxx.xxx 訂閱

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

===================引 用 stacker_liew 文 章===================
感謝大大,我照上面的例子改了,也可以用,但奇怪的是我把元件裝在面板上後,在拖拉到程式上,會發生找不到元件的問題,請問上面那元件應該改成怎樣才不會有問題?

實際情形是在編譯時會編譯不過,說找不到元件TrayAnimation,請問是什麼原因呢?
那請確定一下 TrayAnimation 的 dcu 有指定正確嗎?
------
價值的展現,來自於你用哪一個角度來看待它!!
stacker_liew
中階會員


發表:59
回覆:168
積分:65
註冊:2004-05-17

發送簡訊給我
#8 引用回覆 回覆 發表時間:2008-08-13 12:04:53 IP:219.95.xxx.xxx 訂閱

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

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

===================引 用 stacker_liew 文 章===================
感謝大大,我照上面的例子改了,也可以用,但奇怪的是我把元件裝在面板上後,在拖拉到程式上,會發生找不到元件的問題,請問上面那元件應該改成怎樣才不會有問題?

實際情形是在編譯時會編譯不過,說找不到元件TrayAnimation,請問是什麼原因呢?
那請確定一下 TrayAnimation 的 dcu 有指定正確嗎?

喔喔…可以了,原來是dcu的問題,感恩喔…
stacker_liew
中階會員


發表:59
回覆:168
積分:65
註冊:2004-05-17

發送簡訊給我
#9 引用回覆 回覆 發表時間:2008-08-13 12:10:31 IP:219.95.xxx.xxx 訂閱
還是一樣,我把dcu都放在bpl目錄裡了,重新啟動Delphi 7,編譯時出現[Error] main.pas(26): Undeclared identifier: 'TTrayAnimation',[Error] main.pas(26): Published field 'MyTrayAnimation' not a class nor interface type,…
careychen
尊榮會員


發表:41
回覆:580
積分:959
註冊:2004-03-03

發送簡訊給我
#10 引用回覆 回覆 發表時間:2008-08-13 12:28:36 IP:218.210.xxx.xxx 訂閱
嗯~~這個,如果問題還沒解決,可以不用急著結案
因為我用的是你一開始 po 出來的程式碼,但你現在似乎是新的程式碼造成的問題
你要不要傳上來,我再幫你重看一次?

===================引 用 stacker_liew 文 章===================
還是一樣,我把dcu都放在bpl目錄裡了,重新啟動Delphi 7,編譯時出現[Error] main.pas(26): Undeclared identifier: 'TTrayAnimation',[Error] main.pas(26): Published field 'MyTrayAnimation' not a class nor interface type,…
------
價值的展現,來自於你用哪一個角度來看待它!!
stacker_liew
中階會員


發表:59
回覆:168
積分:65
註冊:2004-05-17

發送簡訊給我
#11 引用回覆 回覆 發表時間:2008-08-13 12:37:14 IP:219.95.xxx.xxx 訂閱
這是新的程式碼。感恩喔…
[code delphi]
unit TrayAnimation;

interface

uses
SysUtils, Classes, Math, ShellApi, Messages, Graphics, Windows, Forms, Controls;

type
TTrayAnimation = class(TComponent)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure FloatingRectangles(Minimizing, OverrideUserSettings: Boolean);
published
{ Published declarations }
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('Samples', [TTrayAnimation]);
end;

{ TTrayAnimation }

constructor TTrayAnimation.Create(AOwner: TComponent);
begin
inherited Create(AOwner);

end;

destructor TTrayAnimation.Destroy;
begin

inherited Destroy;
end;

procedure TTrayAnimation.FloatingRectangles(Minimizing,
OverrideUserSettings: Boolean);
var
RectFrom, RectTo: TRect;
GotRectTo: Boolean;
abd: TAppBarData;
HTaskbar, HTrayWnd: HWND;
ResetRegistry: Boolean;
ai: TAnimationInfo;

procedure SetAnimation(Animation: Boolean);
begin
FillChar(ai, SizeOf(ai), 0);
ai.cbSize := SizeOf(ai);
if Animation then
ai.iMinAnimate := 1
else
ai.iMinAnimate := 0;
SystemParametersInfo(SPI_SETANIMATION, 0, @ai, SPIF_SENDCHANGE);
end;

begin
// Check if user wants window animation
ResetRegistry := False;
if OverrideUserSettings then
begin
FillChar(ai, SizeOf(ai), 0);
ai.cbSize := SizeOf(ai);
SystemParametersInfo(SPI_GETANIMATION, 0, @ai, SPIF_SENDCHANGE);
if ai.iMinAnimate = 0 then
begin
// Temporarily enable window animation
ResetRegistry := True;
SetAnimation(True);
end;
end;

RectFrom := TWinControl(Owner).BoundsRect;
GotRectTo := False;

// Get the traybar's bounding rectangle
HTaskbar := FindWindow('Shell_TrayWnd', nil);
if HTaskbar <> 0 then
begin
HTrayWnd := FindWindowEx(HTaskbar, 0, 'TrayNotifyWnd', nil);
if HTrayWnd <> 0 then
if GetWindowRect(HTrayWnd, RectTo) then
GotRectTo := True;
end;

// If that fails, invent a rectangle in the corner where the traybar is
if not GotRectTo then
begin
FillChar(abd, SizeOf(abd), 0);
abd.cbSize := SizeOf(abd);
if SHAppBarMessage(ABM_GETTASKBARPOS, abd) = 0 then Exit;
with Screen, abd.rc do
if (Top > 0) or (Left > 0) then
RectTo := Rect(Width-32, Height-32, Width, Height)
else if (Bottom < Height) then
RectTo := Rect(Width-32, 0, Width, 32)
else if (Right < Width) then
RectTo := Rect(0, Height-32, 32, Height);
end;

if Minimizing then
DrawAnimatedRects(TWinControl(Owner).Handle, IDANI_CAPTION, RectFrom, RectTo)
else
DrawAnimatedRects(TWinControl(Owner).Handle, IDANI_CAPTION, RectTo, RectFrom);

if ResetRegistry then
SetAnimation(False); // Disable window animation
end;

end.

[/code]
careychen
尊榮會員


發表:41
回覆:580
積分:959
註冊:2004-03-03

發送簡訊給我
#12 引用回覆 回覆 發表時間:2008-08-13 12:46:14 IP:218.210.xxx.xxx 訂閱

===================引 用 careychen 文 章===================
嗯~~這個,如果問題還沒解決,可以不用急著結案
因為我用的是你一開始 po 出來的程式碼,但你現在似乎是新的程式碼造成的問題
你要不要傳上來,我再幫你重看一次?

===================引 用 stacker_liew 文 章===================
還是一樣,我把dcu都放在bpl目錄裡了,重新啟動Delphi 7,編譯時出現[Error] main.pas(26): Undeclared identifier: 'TTrayAnimation',[Error] main.pas(26): Published field 'MyTrayAnimation' not a class nor interface type,…

那再問一下,你上面有 uses TrayAnimation 這個 unit 嗎? 最上面的地方,不是 implementation 下面的哦
------
價值的展現,來自於你用哪一個角度來看待它!!
stacker_liew
中階會員


發表:59
回覆:168
積分:65
註冊:2004-05-17

發送簡訊給我
#13 引用回覆 回覆 發表時間:2008-08-13 12:55:16 IP:219.95.xxx.xxx 訂閱

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

===================引 用 careychen 文 章===================
嗯~~這個,如果問題還沒解決,可以不用急著結案
因為我用的是你一開始 po 出來的程式碼,但你現在似乎是新的程式碼造成的問題
你要不要傳上來,我再幫你重看一次?

===================引 用 stacker_liew 文 章===================
還是一樣,我把dcu都放在bpl目錄裡了,重新啟動Delphi 7,編譯時出現[Error] main.pas(26): Undeclared identifier: 'TTrayAnimation',[Error] main.pas(26): Published field 'MyTrayAnimation' not a class nor interface type,…

那再問一下,你上面有 uses TrayAnimation 這個 unit 嗎? 最上面的地方,不是 implementation 下面的哦

有啊,我用拖拉的方式的,所以系統會自動幫我加上去。
careychen
尊榮會員


發表:41
回覆:580
積分:959
註冊:2004-03-03

發送簡訊給我
#14 引用回覆 回覆 發表時間:2008-08-13 13:00:34 IP:218.210.xxx.xxx 訂閱

還是一樣,我把dcu都放在bpl目錄裡了,重新啟動Delphi 7,編譯時出現[Error] main.pas(26): Undeclared identifier: 'TTrayAnimation',[Error] main.pas(26): Published field 'MyTrayAnimation' not a class nor interface type,…

剛看到你打了一句話 我把dcu都放在bpl目錄裡了 但你應該是放在 LibraryPath 抓的到的地方才對
建議你把這些 dcu 放到 C:\Test 然後在 libraryPath 這個地方加上這個路徑試試

------
價值的展現,來自於你用哪一個角度來看待它!!
stacker_liew
中階會員


發表:59
回覆:168
積分:65
註冊:2004-05-17

發送簡訊給我
#15 引用回覆 回覆 發表時間:2008-08-13 13:05:55 IP:219.95.xxx.xxx 訂閱

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

還是一樣,我把dcu都放在bpl目錄裡了,重新啟動Delphi 7,編譯時出現[Error] main.pas(26): Undeclared identifier: 'TTrayAnimation',[Error] main.pas(26): Published field 'MyTrayAnimation' not a class nor interface type,…

剛看到你打了一句話 我把dcu都放在bpl目錄裡了 但你應該是放在 LibraryPath 抓的到的地方才對
建議你把這些 dcu 放到 C:\Test 然後在 libraryPath 這個地方加上這個路徑試試

我的BPL和DCU都是放在C:\Program Files\Borland\Delphi7\Projects\Bpl,這是軟體安裝時的預設目錄,應該沒問題吧。

我其它的元件都正常運做,例如:CoolTrayIcon,DCPxxx,TntXXX,ZeosDBO,都沒問題。

stacker_liew
中階會員


發表:59
回覆:168
積分:65
註冊:2004-05-17

發送簡訊給我
#16 引用回覆 回覆 發表時間:2008-08-14 11:25:58 IP:218.208.xxx.xxx 訂閱
找到原因了,原來在程式目錄下有一個相同名稱的單元,所以編譯不過,現在沒問題了,感謝大大的幫忙…
careychen
尊榮會員


發表:41
回覆:580
積分:959
註冊:2004-03-03

發送簡訊給我
#17 引用回覆 回覆 發表時間:2008-08-14 11:48:19 IP:218.210.xxx.xxx 訂閱
恭禧~~ 恭禧~~ 

不過,這種問題....... 我看也只有你自己能解~~
------
價值的展現,來自於你用哪一個角度來看待它!!
系統時間:2024-04-18 10:31:34
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!