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

調用Windows的API函數製作桌面寵物

 
conundrum
尊榮會員


發表:893
回覆:1272
積分:643
註冊:2004-01-06

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-01-01 22:39:27 IP:220.143.xxx.xxx 未訂閱
 調用Windows的API函數製作桌面寵物
http://www.ccw.com.cn/applic/prog/htm2003/20031113_10AST.asp    一、引言    相信大家都見過一些桌面上的小寵物,如Office中的小助手等,小寵物們活潑可愛,還可幫助主人完成一定的事件,為應用程式添色不少,那我們自己也能否製作出這樣的小寵物表單呢?答案是肯定的。說到底其實就是對表單顯示區域的操作,使得表單具有多種多樣的外形,然後在表單上繪製相應的圖案。    二、支援區域操作的編程介面    在Windows的API函數中有一組用於區域操作的函數,可以用來生成區域、合併區域、獲取區域資料、根據資料生成區域、把區域和表單聯繫等,其中常用的幾個函數有:生成矩形區域的CreateRectRgn函數,生成橢圓區域的CreateEllipticRgn函數,合併兩個區域的CombinetRgn函數,從記憶體區域資料生成區域的ExCreateRegion函數,獲得區域資料的GetRegionData函數,把區域和表單聯繫的SetWindowRgn函數。    在Delphi中,這些常用的區域函數都被封裝到了Windows單元中,在實際應用中,只須在單元檔中引用Windows單元(默認),即可直接使用這些函數。    三、多態表單的生成原理    1、不規則表單的生成    在實際操作過程中,可以直接利用CreateEllipticRgn函數直接生成圓形表單,也可以利用CreatePolygonRgn函數生成任意非矩形表單。如果目標區域過於複雜,可以把目標劃分成規則的多個小區域分別建立,再把各區域合併,即可得到目標區域。    對於要生成基於點陣圖圖案的表單,可以首先將點陣圖背景色設為單一色,再按點陣圖圖案上的色彩進行行掃描,每掃描到非背景色,則產生一個圖元寬的矩形區域,併入已形成的區域。這樣當整個圖案掃描完畢,以點陣圖輪廓構成的區域形成,然後把點陣圖圖案繪入表單,可以得到一個圖形表單。    2、動畫的生成    在表單創建時,建立起相對於每個點陣圖圖案的區域資料,在程式運行時,通過線程輪換調用資料產生區域,並在表單上顯示相應的點陣圖圖案,以達到動畫效果。    四、點陣圖圖案表單的創建    1、點陣圖圖案區域資料的生成函數GetRgnData    procedure GetRgnData (Bmp: TBitmap; var nCount: Cardinal; var lpRgnData: PRgnData);    var    h, w, i, j: Integer;    tc: TColor;    hrgn1, hrgn2: HRGN;    begin    h := Bmp.Height;    w := Bmp.Width;    //獲取點陣圖第一象素點的顏色值,背景顏色    tc := Bmp.Canvas.Pixels[0, 0];    //生成矩形區域    hrgn1 := CreateRectRgn (0, 0, w, h);    try    for i := 0 to h-1 do    begin    for j := 0 to w-1 do    begin    //判斷當前象素點的顏色值是否與背景色相同    if Bmp.Canvas.Pixels[j, i] = tc then     begin    hrgn2 := CreateRectRgn (j, i, j 1, i 1);    if hrgn2 <> 0 then    //摳去hrgn2資料區域    CombineRgn (hrgn1, hrgn1, hrgn2, RGN_DIFF);     DeleteObject (hrgn2);    end;    end;    end;    //獲取hrgn1資料區域大小    nCount := GetRegionData (hrgn1, 0, nil);     //分配記憶體空間給臨時區域指標lpRgnData    GetMem (lpRgnData, nCount * sizeof(TRgnData));    //獲取資料    GetRegionData (hrgn1, nCount, lpRgnData);    except    ShowMessage ('區域資料生成出錯');    end;    DeleteObject (hrgn1);    end;    2、動畫線程的實現    ⑴ 線程的定義    TAnimThread = class (TThread)    private    FIndex: Integer;    OwnerForm: TForm;    procedure DrawAnimPic;    protected    procedure Execute; override;    public    constructor Create (Form: TForm); {override;}    end;    說明:①FIndex所要顯示的點陣圖索引值,OwnerForm指定當前表單;    ②DrawAnimPic線程中動畫繪製表單過程。    ⑵ 線程的實現    constructor TAnimThread.Create (Form: TForm);    begin    OwnerForm := Form;    FIndex := 0;    inherited Create (False);    end;    procedure TAnimThread.DrawAnimPic;    var    Bmp: TBitmap;    w, h: Integer;    rgn: HRGN;    begin    Bmp := AnimBmp[FIndex];    w := Bmp.Width;    h := Bmp.Height;    //重新設置表單的尺寸    OwnerForm.Width := w;     OwnerForm.Height := h;    //從記憶體區域資料生成區域    rgn := ExtCreateRegion (nil, nCount[FIndex], TRData[FIndex]^);     //把區域和表單聯繫起來    SetWindowRgn (OwnerForm.Handle, rgn, True);     DeleteObject (rgn);    //在表單畫布上繪製點陣圖圖案    BitBlt (OwnerForm.Canvas.Handle, 0, 0, w, h, Bmp.Canvas.Handle, 0, 0, SRCCOPY);    end;    procedure TAnimThread.Execute;    begin    inherited;    //反復執行,直至線程終止    repeat    FIndex := FIndex mod 6;    //同步繪製過程DrawAnimPic    Synchronize (DrawAnimPic);    Sleep (300);    Inc (FIndex);    until Terminated;    end;     說明:① 在繪製過程DrawAnimPic所使用到的變數定義在單元檔內,其定義:    AnimBmp: array[0..5] of TBitmap;    nCount: array[0..5] of Cardinal;    TRData: array[0..5] of PRgnData;    以上變數均在表單創建過程中賦值,在表單銷毀前釋放。    ②線上程的執行(Execute)過程中,不能直接調用DrawAnimPic過程,以免產生VCL元件讀寫衝突,所以必須使用同步函數Synchronize進行協調。    五、結束語    通過本次學習,讓讀者初步瞭解Delphi編程中線程的創建及使用,同時掌握如何在Delphi編程過程中調用Windows 的API函數,來建立個性化的應用程式。本文簡述了一個動畫表單的實現過程,當然要真正作為一個寵物,它必須有自己的“思想”,會隨機地做出一些動作,這就需要在程式中可以隨機地調取一些動作序列,其程式過程讀者可根據自己的 興趣進一步完善。
系統時間:2024-06-27 15:39:09
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!