前の記事では、ヒントの簡単なアプリケーションを紹介します。この記事では、ヒントウィンドウをカスタマイズする例を示します。このカスタムヒントウィンドウには、ガラスが境界線であり、影の効果があり、良い効果があります。
ただし、この前に、Controlsユニットで定義されているヒントの親クラスをカスタマイズする方法を紹介する必要があります。いくつかの仮想方法を見てみましょう。CreateParamsはウィンドウのスタイルを設定します。境界がないように上書きしたいと思います。 ncpaintは窓の境界を描きます。また、境界線は必要ないため、カバーする必要があります。ペイントはより重要であるため、ヒントウィンドウクライアントエリアのコンテンツで覆う必要があります。しかし、最も重要なことはActivateHintで、ウィンドウのサイズを設定して表示します。このクラスの実装を以下に示します。
ユニットwdhintwnd;
インタフェース
用途
窓、クラス、コントロール、グラフィック、フォーム、sysutils、extctrls;
タイプ
twdhintwnd = class(thintwindow)
プライベート
fwndbmp:tbitmap; //ウィンドウビットマップ
fhintbmp:tbitmap; //プロンプト情報ビットマップ
保護されています
手順Createparams(var params:tcreateparams);
手順ペイント;
手順NCPaint(DC:HDC);
{画像プロンプトを描く}
手順Drawhintimg(bmp:tbitmap; ahint:string);
{プロンプトウィンドウに対応するデスクトップ領域の画像を取得}
手順getDeskTopimg(bmp:tbitmap; r:trect);
{デスクトップ領域の画像を扱って、小さな影のあるガラスのように見える}
手順EffectHandle(wndbmp、hintbmp:tbitmap);
公共
Constructor Create(aowner:tomponent);
破壊者はオーバーライドします。
手順ActivateHint(rect:trect; const ahint:string);
終わり;
実装
{twdhintwnd}
手順twdhintwnd.activatehint(rect:trect; const ahint:string);
var
P:tpoint;
始める
//ここにテキストを表示するための適切なサイズを取得します
fhintbmp.width:= rect.right -rect.left;
fhintbmp.height:= rect.bottom -rect.top + 4;
drawhintimg(fhintbmp、ahint);
fwndbmp.width:= rect.right -rect.left + 23;
fwndbmp.height:= rect.bottom -rect.top + 27;
Inc(rect.right、23);
Inc(rect.bottom、27);
BoundSrect:= rect;
残っている場合<screen.desktopleft
左:= screen.desktopleft;
top <screen.desktoptopの場合
TOP:= screen.desktoptop;
左 + width> screen.desktopwidthの場合
左:= screen.desktopwidth -width;
Top + height> screen.desktopheightの場合
TOP:= screen.desktopheight -height;
getdesktopimg(fwndbmp、boundsrect);
EffectHandle(fwndbmp、fhintbmp);
p:= clientToscreen(ポイント(0、0));
setWindowpos(ハンドル、hwnd_topmist、px、py、0、0、
swp_showwindowまたはswp_noactivateまたはswp_nosize);
終わり;
Constructor Twdhintwnd.create(aowner:tcomponent);
始める
継承;
fwndbmp:= tbitmap.create;
fwndbmp.pixelformat:= pf24bit;
fhintbmp:= tbitmap.create;
終わり;
手順twdhintwnd.createparams(var params:tcreateparams);
始める
継承;
//ウィンドウの境界を削除します
params.style:= ws_borderではなくparams.style;
終わり;
Destructor twdhintwnd.destroy;
始める
fwndbmp.free;
fhintbmp.free;
継承;
終わり;
手順twdhintwnd.getdesktopimg(bmp:tbitmap; r:trect);
var
C:Tcanvas;
始める
c:= tcanvas.create;
試す
c.handle:= getDc(0);
bmp.canvas.copyrect(rect(0、0、bmp.width、bmp.height)、c、r);
ついに
C.Free;
終わり;
終わり;
手順twdhintwnd.effecthandle(wndbmp、hintbmp:tbitmap);
var
R:トレクト;
I、J:整数;
P:pbytearray;
トランススト、トランスステングル:整数;
始める
r:= rect(0、0、wndbmp.width -4、wndbmp.height -4);
frame3d(wndbmp.canvas、r、clmedgray、clbtnshadow、1);
//ウィンドウの下の影の効果になります
トランススト:= 60;
J:= wndbmp.height -4からwndbmp.height -1 do
始める
p:= wndbmp.scanline [j];
transstangle:= transst;
i:= 3からwndbmp.width -1 do
始める
//右下隅にある場合
i> wndbmp.width -5の場合
始める
p [3*i]:= p [3*i]*transstangle div 100;
p [3*i + 1]:= p [3*i + 1]*transstangle div 100;
p [3*i + 2]:= p [3*i + 2]*transstangle div 100;
トランススタング:=トランススタング + 10;
Transstangle> 90の場合、transstangle:= 90;
終わり
それ以外の場合は始まります
p [3*i]:= p [3*i]*transst div 100;
p [3*i + 1]:= p [3*i + 1]*transst div 100;
p [3*i + 2]:= p [3*i + 2]*transst div 100;
終わり;
終わり;
トランススト:= transst + 10;
終わり;
//ウィンドウの右側に影の効果になります
j:= 3からwndbmp.height -5 do
始める
p:= wndbmp.scanline [j];
トランススト:= 60;
i:= wndbmp.width -4 to wndbmp.width -1 do
始める
p [3*i]:= p [3*i]*transst div 100;
p [3*i + 1]:= p [3*i + 1]*transst div 100;
p [3*i + 2]:= p [3*i + 2]*transst div 100;
トランススト:= transst + 10;
終わり;
終わり;
wndbmp.canvas.draw(10、10、hintbmp);
終わり;
手順twdhintwnd.ncpaint;
始める
//ボーダー図面を許可しないリロード
終わり;
手順twdhintwnd.paint;
始める
canvas.copyrect(clientRect、fwndbmp.canvas、clientRect);
終わり;
手順twdhintwnd.drawhintimg(bmp:tbitmap; ahint:string);
var
R:トレクト;
始める
bmp.canvas.brush.color:= application.hintcolor;
bmp.canvas.pen.color:= application.hintcolor;
bmp.canvas.rectangle(0、0、bmp.width、bmp.height);
bmp.canvas.font.color:= screen.hintfont.color;
r:= rect(0、0、bmp.width、bmp.height);
Inc(R.Left、2);
Inc(R.Top、2);
drawText(bmp.canvas.handle、pchar(ahint)、-1、r、dt_leftまたはdt_noprefixまたは
dt_wordbreakまたはdrawtextbidimodeflagsreadingonly);
終わり;
初期化
application.showhint:= false;
hintwindowclass:= twdhintwnd;
application.showhint:= true;
終わり。
プロジェクトにユニットを追加して、効果を確認してください。
プログラムの重要な部分がコメントされており、ここにいくつかの重要なポイントがあります。
一部、ここでは、アプリケーションのshowhintをfalseに設定し、VCLソースコードを見て、アプリケーションがヒントウィンドウを破壊したことを知っています。Hintwindowclassの定義は次のとおりです。
ThintWindowClass = ThintWindowのクラス。
hintwindowclass:thintwindowclass = thintwindow;
ここでは、最終的にTrueを使用して、この時点でカスタマイズされたクラスを作成します。
ActivateHintメソッドでは、効果を処理します。原則は、デスクトップのプロンプトウィンドウの位置に対応するビットマップを取得し、プロンプトウィンドウに描画し、プロンプト情報の位置を中央にコピーすることです。プロンプトウィンドウの透明性があるように、効果は今です。第二に、ガラスの端を描き、最後に窓の右と下部に影の効果を上げます。
Shadow Effectsの実装については、Alphaテクノロジーがオンラインで使用できます。
dst.red = src.red * alpha +(1-alpha) * dst.red;
dst.green = src.green * alpha +(1-alpha) * dst.green;
dst.blue = src.blue * alpha +(1-alpha) * dst.blue;
アルファの値は0〜1の間です。つまり、1の場合は完全に不透明ですが、混合に使用する色は黒です。つまり、0なので、上記のコードが見るものは次のとおりです。
p [3*i]:= p [3*i]*transstangle div 100;
ガラスのプロンプトウィンドウの原理は、もちろんこのようなものです。しかし、迅速なウィンドウとして、それで十分だと思います。