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

多張圖依序顯示(使用ImageList和image物件)?

答題得分者是:jow
nlj859
資深會員


發表:139
回覆:375
積分:322
註冊:2004-03-20

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-10-31 23:57:43 IP:219.81.xxx.xxx 訂閱
我有15張圖,想一張張的秀出,但是為什麼只秀一張就停住了,哪裡有錯嗎?
請幫忙看一下,謝謝.

底下為程式碼:

[code cpp]
void __fastcall TForm1::FormCreate(TObject *Sender)
{
n=0;
Timer1->Enabled=true;
}
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
ImageList1->Draw(Image1->Canvas,0,0,n,true);
n ;
}

[/code]
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-11-01 10:11:33 IP:122.124.xxx.xxx 未訂閱
ImageList它是一個不可視的元件


jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-11-01 13:35:37 IP:210.66.xxx.xxx 訂閱
如果只是想畫出圖片, 就畫在TForm上吧

不然你的問題, 就是要去研究TImage的Canvas,
為什麼會不一樣???

(HINT)

TImage
TImage->Picture
TImage->Picture->Bitmap

TImage->Picture->Bitmap->Width
TImage->Picture->Bitmap->Height
TImage->Picture->Bitmap->Canvas

......^_^

[code cpp]
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Repaint();
Label1->Repaint();
for(int i=0;iCount;i ){
int c=i;
int r=i/10;
ImageList1->Draw(Canvas,20*c,20*r,i,true);
ImageList1->Draw(Canvas,100,100,i,true);
ImageList1->Draw(Label1->Canvas,20*c,20*r,i,true);
ImageList1->Draw(Label1->Canvas,100,100,i,true);
Sleep(50);
}
//畫在TPanel上
Panel1->Repaint();
HDC dc = GetDC(Panel1->Handle);
try{
TCanvas *canvas=new TCanvas();
try{
canvas->Handle=dc;
for(int i=0;iCount;i ){
int c=i;
int r=i/10;
ImageList1->Draw(canvas,20*c,20*r,i,true);
ImageList1->Draw(canvas,100,100,i,true);
Sleep(50);
}
}
__finally{
delete canvas;
}
}
__finally{
ReleaseDC(Panel1->Handle, dc);
}
}
//---------------------------------------------------------------------------
[/code]

上述程式碼執行結果


編輯記錄
jow 重新編輯於 2007-11-01 13:37:34, 註解 無‧
jow 重新編輯於 2007-11-01 13:45:41, 註解 無‧
jow 重新編輯於 2007-11-02 00:18:33, 註解 無‧
nlj859
資深會員


發表:139
回覆:375
積分:322
註冊:2004-03-20

發送簡訊給我
#4 引用回覆 回覆 發表時間:2007-11-01 22:49:52 IP:219.80.xxx.xxx 訂閱
Thanks.再請問一下,如何畫一張清除一張啊~
我現在試的情況都無法清除,圖片都會重疊再一起.
請幫忙解惑一下.
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#5 引用回覆 回覆 發表時間:2007-11-02 00:00:28 IP:123.193.xxx.xxx 訂閱
(1)建議你選用別的元件來作畫, 因為TImage的動作比較不同,
TImage適用來顯示圖檔的元件,它的底層使用一個TPicture的物件
而TPicture內部則包含一個TBitmap, 這個TBitmap的大小(Width, Height)
在載入圖檔前是未被指定的. 上述物件在TImage中有其相互作用的邏輯考量.

(2)前篇所示程式碼, 只要稍加運用, 你可以自TCustomControl 或
TGraphicControl繼承, 將你的需求寫一個專用的元件, 當然如果需要的
話也可以將一個TImageList包含在這個元件裡.

(3)至於如何清除先前繪製的畫面, 建議你去參考 VCL source code 中
一些改寫" procedure Paint; override; " 的程式碼, 像 TLabel之類的,
或者搜尋一下有哪些有顯示畫面的元件, 看看它們如何回應 WM_PAINT訊息.


個人建議, 僅供參考..........^_^
nlj859
資深會員


發表:139
回覆:375
積分:322
註冊:2004-03-20

發送簡訊給我
#6 引用回覆 回覆 發表時間:2007-11-02 22:29:39 IP:219.86.xxx.xxx 訂閱
不知道有沒有比較簡單的做法,我會把所有圖放至ImageList裡,由TImage去顯示.
例:當需要顯示圖檔時,則new一個TImage新物件(如底下程式碼),不用時再清除.
另外,為什麼TImage無法直接清除呢?
請幫忙~Thanks.

[code cpp]
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Image1=new TImage(this);
Image1->Parent=Form1;
Image1->Height=130;
Image1->Width=130;
Image1->Top=280;
Image1->Left=170;
Image1->Transparent=true;
Image1->Visible=true;
ImageList1->Draw(Image1->Canvas,0,0,0,true);

}
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
delete Image1;
}
[/code]
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#7 引用回覆 回覆 發表時間:2007-11-02 23:23:24 IP:123.193.xxx.xxx 訂閱
(1)將15張圖檔放到TImageList中,除非圖檔都是固定大小, 且大小相同的小圖,
否則以TImageList的運作方式, 被加入到TImageList中的圖檔會統一Keep在
一張大圖, 然後以Index來索引TImageList的圖檔其實是再從大圖切割出來的.
使用時應考量其記憶體耗量.

以下訊息是節錄TImageList的Help:

TImageList represents a collection of same-sized images, each of which can be referred to by its index.

All images in an image list are contained in a single, wide bitmap in screen device format.

(2)TImage繼承自TGraphicControl, 具備一個TCanvas物件, 可是你所存取到
的TImage的Canvas不是這個繼承來的TCanvas,而是TImage另外以GetCanvas
取得的, 如下程式碼所示:

[code delphi]
function TImage.GetCanvas: TCanvas;
var
Bitmap: TBitmap;
begin
if Picture.Graphic = nil then
begin
Bitmap := TBitmap.Create;
try
Bitmap.Width := Width;
Bitmap.Height := Height;
Picture.Graphic := Bitmap;
finally
Bitmap.Free;
end;
end;
if Picture.Graphic is TBitmap then
Result := TBitmap(Picture.Graphic).Canvas
else
raise EInvalidOperation.Create(SImageCanvasNeedsBitmap);
end;
[/code]

是動態產生一個TBitmap, 再Assign給TPicture.Graphic.你所使用的
Canvas就是這個,

(3)TImage在重繪時所做的動作,是將TPicture.Graphic繪製到
TImage繼承自TGraphicControl的Canvas上, 如下所示:
[code delphi]
procedure TImage.Paint;
var
Save: Boolean;
begin
if csDesigning in ComponentState then
with inherited Canvas do
begin
Pen.Style := psDash;
Brush.Style := bsClear;
Rectangle(0, 0, Width, Height);
end;
Save := FDrawing;
FDrawing := True;
try
with inherited Canvas do
StretchDraw(DestRect, Picture.Graphic);
finally
FDrawing := Save;
end;
end;
[/code]

所以建議你選擇其他較單純的元件來使用

(4)不然以TImage->Picture->LoadFromFile("圖檔檔名")來做也很單純.
而我個人則比較傾向自TGraphicControl或TCustomControl繼承, 寫個
小元件, 內部以TBitmap 載入圖檔來作畫...


個人建議, 僅供參考...........^_^

將圖檔畫到一個TCanvas上

[code delphi]
//------------------------------------------------------------------------------
procedure _draw_(c: TCanvas; r: TRect; fn: string);
var
b: TBitmap;
begin
if FileExists(fn) then
begin
b := TBitmap.Create;
try
b.LoadFromFile(fn);
c.Lock;
try
c.StretchDraw(r,b);
finally
c.Unlock;
end;
finally
_free_(b);
end;
end;
end;
//------------------------------------------------------------------------------
[/code]

===================引 用 nlj859 文 章===================
不知道有沒有比較簡單的做法,我會把所有圖放至ImageList裡,由TImage去顯示.
例:當需要顯示圖檔時,則new一個TImage新物件(如底下程式碼),不用時再清除.
另外,為什麼TImage無法直接清除呢?
請幫忙~Thanks.
編輯記錄
jow 重新編輯於 2007-11-02 23:30:08, 註解 無‧
jow 重新編輯於 2007-11-02 23:48:46, 註解 無‧
系統時間:2024-05-05 12:30:00
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!