Delphi Tips
>> Index
● 09/15 Win98 でタイトルバーのグラデーション色を得る
● 09/13 TFontDialog で標準以外のサイズを選択肢に表示したい
● 09/09 Metafile が Draw で1ピクセル小さく描画される
● 08/31 全角文字が半角文字の2倍幅になるフォントの選び方
● 08/13 TColor 値を文字列に変換する
● 05/14 システムカラーを得る、設定する
● 02/11 API を使って縦書きなどのフォントを指定する
● 02/08 SetWindowsExt/SetViewportExtを使うときの注意点
最終更新: 9200 日前
0260 D1D2 D3 D4 D5 D6 D7 3.195 98 作成: 1999/09/15 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3NT4 2K XP 更新: 1999/09/15 osamu 編集
Win98 でタイトルバーのグラデーション色を得る
const
COLOR_GRADIENTACTIVECAPTION = 27;
COLOR_GRADIENTINACTIVECAPTION = 28;
という前提で、GetSysColor() API を使用してください。
DWORD の色がかえります。( TColor に代入できます )
どーせやるなら、
const
COLOR_GRADIENTACTIVECAPTION = 27;
COLOR_GRADIENTINACTIVECAPTION = 28;
clGradientActiveCaption = $80000000 + COLOR_GRADIENTACTIVECAPTION;
clGradientInactiveCaption = $80000000 + COLOR_GRADIENTINACTIVECAPTION;
としておくと便利かもしれません。
この状態で、 Delphi4 の ColorToRGB のソースを見るかぎりでは
ColorToRGB(clGradientActiveCaption)
は正常に動作します。
ところで…この定数ですが、、、、Delphi4 にも定義されていないようです。
# たんに、私が未確認なだけでしょうか?
勝手に Graphic.pas (Desktop 版では Graphic.int)に書き足しておいても問題はないと思うのですが…。。。
参照: [Delphi-ML:34285]
0253 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/09/13 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/09/13 osamu 編集
TFontDialog で標準以外のサイズを選択肢に表示したい
> ルビをうつフォントを指定しようと思い、TFontDialogで
> 片付けようと思いましたが、TFontDialogで、MSゴシック
> など8Pt以下のポイントが出てきません。指定できるように
> する方法をどなたかご存知でしょうか。
思いっきり強引ですけど
unit FontDialogEx;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, Dialogs;
type
TFontDialogEx = class(TFontDialog)
protected
function TaskModalDialog(DialogFunc: Pointer;
var DialogData): Bool; override;
end;
procedure Register;
implementation
uses Dlgs, CommDlg;
const
WM_FONTDIALOGEX = WM_USER + 256;
str1: string = '4';
str2: string = '5';
str3: string = '6';
str4: string = '7';
var
OldHook: function(Wnd: HWnd; Msg: UINT; WParam: WPARAM;
LParam: LPARAM): UINT; stdcall;
function FontDialogHookEx(Wnd: HWnd; Msg: UINT; WParam: WPARAM;
LParam: LPARAM): UINT; stdcall;
begin
if (Msg = WM_COMMAND) and (LOWORD(WParam) = cmb1) then begin
PostMessage(Wnd, WM_FONTDIALOGEX, 0, 0);
end;
if Msg = WM_FONTDIALOGEX then begin
SendDlgItemMessage(Wnd, cmb3, CB_RESETCONTENT, 0, 0);
SendDlgItemMessage(Wnd, cmb3, CB_ADDSTRING, 0, LongInt(PCHAR(str1)));
SendDlgItemMessage(Wnd, cmb3, CB_ADDSTRING, 0, LongInt(PCHAR(str2)));
SendDlgItemMessage(Wnd, cmb3, CB_ADDSTRING, 0, LongInt(PCHAR(str3)));
SendDlgItemMessage(Wnd, cmb3, CB_ADDSTRING, 0, LongInt(PCHAR(str4)));
Result := 1;
exit;
end;
Result := OldHook(Wnd, Msg, WParam, LParam);
end;
function TFOntDialogEx.TaskModalDialog(DialogFunc: Pointer; var DialogData): Bool;
begin
OldHook := TChooseFont(DialogData).lpfnHook;
TChooseFont(DialogData).lpfnHook := FontDialogHookEx;
inherited TaskModalDialog(DialogFunc, DialogData);
end;
procedure Register;
begin
RegisterComponents('NkCtrls', [TFontDialogEx]);
end;
end.
一応動いてます(^^ フォント名毎に表示するサイズリストを変えたい場合は、cmb1 に選択されているフォント名を確認するコードが必要になるでしょう。
一瞬元のポイントサイズがコンボボックスに表示されてしまいますが今のところ他に良い手を思いつきません(^^;
参照: [Delphi-ML:42562] <ダイアログ> <Dialogs> <コンポーネント >
0248 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/09/09 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/09/09 osamu 編集
Metafile が Draw で1ピクセル小さく描画される
>拡張メタファイルを作成するツールを作ろうとしています。
>そこで、メタファイルに編集を加えるたびに以前編集した像が
>1ドット(?)ずつ縮小してしまう問題があるのです。
TMetafile.Draw を見ると
R := Rect;
Dec(R.Right); // Metafile rect includes right and bottom coords
Dec(R.Bottom);
PlayEnhMetaFile(ACanvas.Handle, FImage.FHandle, R);
となっていて、描画先矩形を 1ドット分縮小しているのが原因のようです。
Win32 Programmer's Ref. で PlayEnhMetafile を見ると、
Points along the edges of the rectangle are included in the picture.
なんて微妙なことが書いてあるのですが、実際には Win98 で試してみた限り矩形領域を小さくするのは正しくないようです。Dec をコメントにすると完全に同じ大きさの図形が得られます。
対処としては graphics.pas を修正するか、Right, Bottom を一つ大きめに指定して StretchDraw するしかないようです。
ただ、ディスプレイデバイスとメタファイルの参照デバイスが異なると多少の誤差は避けられないようです。この辺を考慮して高精度のメタファイルを作るにはメタファイルを直接編集するしかないと思います。
参照: [Delphi-ML:33593] <画像> <バグ>
0230 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/08/31 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/08/31 osamu 編集
全角文字が半角文字の2倍幅になるフォントの選び方
等幅フォントを使っても、全角文字と半角文字を混ぜて使うと、桁の位置がずれて見づらくなってしまう場合があります。これは、特定のフォントサイズ以外では、全角文字が半角文字の2倍の幅にならないことに起因しています。
ピクセル単位とポイント単位の変換は以下のようになっています。
Point = 72 * ( Pixels / GetDeviceCaps(hDC, LOGPIXELS_) )
Pixels = Point / 72 * GetDeviceCaps(hDC, LOGPIXELS_)
ここで、LOGPIXELS_ は LOGPIXELSX または LOGPIXELSY ですが、幅を問題にする場合には、LOGPIXELSX を使います。
Pixels が整数になるような Point 数の等幅フォントを使えば、全角文字がちょうど半角文字二つ分の幅になり、エディタのように使った場合に、「ずれ」が生じません。
たとえば、画面の設定が 96dpi の時、第2式は
Pixels = 4 * Point / 3
となりますので、適するサイズは、3の倍数ポイントのフォントということになります。
参照:
0203 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/08/13 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/08/13 osamu 編集
TColor 値を文字列に変換する
レジストリに TColor 型の値を格納したいような場合、ColorToString 関数を使えば TColor から AnsiString に変換できるので、あとは TRegistry の WriteString で書き出してやればいいと思います。
反対に AnsiString から TColor に戻すのは StringToColor 関数を使えばいいです。
詳しくはヘルプを見てください。
参照: [builder:17839] <文字列> <PASCAL>
0187 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/05/14 おばQ rev 1.3 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/05/14 おばQ 編集
システムカラーを得る、設定する
ひきさんのページ『日本Delphi振興会』にも載っていますが
更に情報を加えておきます。
WindowsAPIでWindowsのシステムカラーを得たり設定したりする事が出来ます。それぞれGetSysColor、SetSysColorというAPI関数です。
サンプルとしてButton1を押すと色の設定情報を読込み
Button2を押すと読込んだ情報を設定するというものを作りました。
Button1を押して
その後にコントロールパネルでWindowsの色設定を変更しても
Button2を押す事で変更前の色設定になります。
const
SysColorMaxNumber=28;
type
TForm1 = class(TForm)
…省略…
private
FList: array[0..SysColorMaxNumber] of Integer;
FColorList: array[0..SysColorMaxNumber] of TColor;
FRGBList: array[0..SysColorMaxNumber] of Longint;
end;
…省略…
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
for i:=0 to SysColorMaxNumber do
begin
FList[i] := i;
FColorList[i] := TColor(GetSysColor(i));
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
i: Integer;
begin
for i:=0 to SysColorMaxNumber do
FRGBList[i] := ColorToRGB(FColorList[i]);
SetSysColors(SysColorMaxNumber,FList,FRGBList);
end;
GetSysColor(COLOR_ACTIVECAPTION)という定数も指定出来ます。この定数はwindows.pasに定義されています。
Delphiで定義されている色のclBtnFaceやclActiveCaptionとAPIでのGetSysColor(COLOR_ACTIVECAPTION)との違いは以下のようなコードで理解できるでしょう。
ShowMessage(IntToHex((clRed),8));
ShowMessage(IntToHex((clBtnFace),8));
ShowMessage(IntToHex(GetSysColor(COLOR_BTNFACE),8));
ShowMessage(IntToHex(ColorToRGB(clRed),8));
ShowMessage(IntToHex(ColorToRGB(clBtnFace),8));
ShowMessage(IntToHex(ColorToRGB(GetSysColor(COLOR_BTNFACE)),8));
参照:
0137 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/11 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/11 osamu 編集
API を使って縦書きなどのフォントを指定する
var
lbl :TLogFont;
begin
// ここをいろいろ変えれば縦横比を変えることができる
// (日本語の場合、幅:高さ=1:2で横倍率が100%)
lbl.lfWidth := 10;
lbl.lfHeight := 20;
// 文字の太さ(0〜1000)
// 「標準」の太さは400、「太字」の太さは700
lbl.lfWeight := 400;
// 反時計回りの角度(単位は1/10度)
lbl.lfEscapement := 2700;
// 下線なし(デフォルトでは「あり」)
lbl.lfUnderline := 0;
// 打ち消し線なし(デフォルトでは「あり」)
lbl.lfStrikeOut := 0;
// 斜体無効(デフォルトでは有効)
lbl.lfItalic := 0;
// 縦書き用の「@」がつくフォントを使用する
lbl.lfFaceName := '@MS ゴシック';
// フォントを作成
Canvas.Font.Handle := CreateFontIndirect(lbl);
// キャンバスのブラシスタイルを変えることで
// 背景を透明にして描画します
Canvas.Brush.Style := bsClear;
// 文字列を描画
Canvas.TextOut(300, 300, '縦書き文字');
end;
参照: [Delphi-ML:24027] <その他コンポーネント関連> <コンポーネント >
0064 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/08 osamu 編集
SetWindowsExt/SetViewportExtを使うときの注意点
TCanvas.Handle に対してこれらの関数を呼んで使う際の注意点。
(1) Font.Height と Font.Size の関係はマッピングモードが MM_TEXT
で有ることを仮定しているので SetMapMode API でマッピングモードを
変えた場合は Font.Height のみを使った方が良いでしょう。
(2) API の効果の寿命はイベントハンドラ毎です。
引き継がれません。
参照: [Delphi-ML:19671] <Windows>
[新規作成] [最新の情報に更新]
How To
Lounge
KeyWords
Osamu Takeuchi osamu@big.or.jp
Tips
Delphi
Home