16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル
"RE:グラデーション文字"
この発言は #00473 Fermion さんのRE^3:グラデーション文字 に対するコメントです
#434 から Fermion さんが紹介されている「グラデーション文字」の
サンプルコードを DrawText(Ex) APIと置き換えて使う場合を想定し
て再構成してみました。
やっていることの本質は Fermion さんのコードと‘全く同じ’です。
有用なコードを紹介していただいた Fermion さんに感謝します。
//【サンプル関数です】
function GradationDrawText(DC: HDC; Text: string; nCount: Integer;
var R: TRect; uFormat: UINT;
//pParams: PDrawTextParams;
// 〜 ここからグラデーション用の引数です 〜 //
cl1, cl2: TColor; // グラデーションの第1色と第2色
bHorz: Boolean // グラデーションの方向(縦 or 横)
): Integer;
var
rgnNew: HRGN;
SaveIndex, i, i1, i2: Integer;
hbrNew: HBRUSH;
R1, G1, B1, R2, G2, B2: BYTE;
begin
if (DT_CALCRECT and uFormat) <> 0 then
// 描画領域を計算するだけ
Result := DrawText(DC, PChar(Text), nCount, R, uFormat)
//Result := DrawTextEx(DC, PChar(Text), nCount, R, uFormat, pParams)
else
begin
// コンディションの保存
SaveIndex := SaveDC(DC);
// 背景の塗りつぶし
if GetBkMode(DC) = OPAQUE then
begin
hbrNew := CreateSolidBrush(GetBkColor(DC));
FillRect(DC, R, hbrNew);
DeleteObject(hbrNew);
end;
// パスで文字の外枠を作る
BeginPath(DC);
SetBkMode(DC, TRANSPARENT);
Result := DrawText(DC, PChar(Text), nCount, R, uFormat);
//Result := DrawTextEx(DC, PChar(Text), nCount, R, uFormat, pParams);
EndPath(DC);
// パスをリージョンに変換して、描画のクリッピング領域にする
rgnNew := PathToRegion(DC);
if rgnNew <> HRGN(0) then
begin
ExtSelectClipRgn(DC, rgnNew, RGN_AND);
DeleteObject(rgnNew);
// グラデーションに使う色要素を取り出しておく
R1 := GetRValue(ColorToRGB(cl1));
G1 := GetGValue(ColorToRGB(cl1));
B1 := GetBValue(ColorToRGB(cl1));
R2 := GetRValue(ColorToRGB(cl2));
G2 := GetGValue(ColorToRGB(cl2));
B2 := GetBValue(ColorToRGB(cl2));
if bHorz then
// 水平方向のグラデーション
for i := R.Left to R.Right - 1 do
begin
i1 := i - R.Left;
i2 := R.Right - 1 - i;
// 中間色のブラシを作成する
hbrNew := CreateSolidBrush(RGB(
(R1 * i1 + R2 * i2) div (i1 + i2),
(G1 * i1 + G2 * i2) div (i1 + i2),
(B1 * i1 + B2 * i2) div (i1 + i2)
));
FillRect(DC, RECT(i, R.Top, i + 1, R.Bottom), hbrNew);
DeleteObject(hbrNew);
end
else
// 垂直方向のグラデーション
for i := R.Top to R.Bottom - 1 do
begin
i1 := i - R.Top;
i2 := R.Bottom - 1 - i;
// 中間色のブラシを作成する
hbrNew := CreateSolidBrush(RGB(
(R1 * i1 + R2 * i2) div (i1 + i2),
(G1 * i1 + G2 * i2) div (i1 + i2),
(B1 * i1 + B2 * i2) div (i1 + i2)
));
FillRect(DC, RECT(R.Left, i, R.Right, i + 1), hbrNew);
DeleteObject(hbrNew);
end;
end
else
begin
//raise Exception.Create('ERROR: PathToRegion in GradationDrawText');
ShowMessage('ERROR: PathToRegion in GradationDrawText');
end;
// コンディションの復元
RestoreDC(DC, SaveIndex);
end;
end;
//【Edit1.OnKeyDown イベントハンドラでの使用例です】
procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
var
R: TRect;
uFormat: UINT;
//DTParams: TDrawTextParams;
begin
if Key = VK_RETURN then
begin
Key := 0;
// 文字を大き目にした方がグラデーションがわかりやすいので...
Canvas.Font.Size := 48;
R := Rect(0,10,300,100);
uFormat := DT_SINGLELINE or DT_VCENTER or DT_CENTER;
GradationDrawText(
Canvas.Handle, // 描画先のデバイスコンテキスト
Edit1.Text, // 描画する文字
-1, // 描画する文字数(-1 で全ての文字)
R, // 描画する領域
uFormat, // フォーマット(DrawText 参照)
//@DTParams,
// 〜 ここからグラデーション用の引数です 〜 //
clFuchsia, // グラデーションの第1色
clLime, // グラデーションの第2色
CheckBox1.Checked // グラデーションの方向(縦 or 横)
);
end;
end;
1999/05/27、河邦 正(GCC02240@nifty.ne.jp)
(http://member.nifty.ne.jp/kht0000/ 自作ComponentのNifty外へ公開用)
Original document by 河邦 正 氏 ID:(GCC02240)
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。
Copyright 1996-2002 Delphi Users' Forum
|