Win7 + XE3 starter
お世話になります。 D6 personalからXE3に移植中でいろいろと苦戦しています。 D6では下記のようなコードでpnlst上にCheckBoxをCreateして着色し、白抜き文字で名前を書いて問題なく動いていました。それがXE3では指定の色に着色されず(透明)また文字色も白抜きにはならず黒になってしまいます。
for i := 1 to nst do begin
chk_st[i] := Tcheckbox.Create(form1);
with chk_st[i] do
begin
height:=12;
width:=120;
Color:=st_color[i];
caption:=st_nam[i];
font.Color:=rgb(255,255,255);
left:=5;
top:=225 +i*14;
Parent :=form1.pnlst;
Tag:=i;
onMouseMove:=form1.st_MouseMove;
onmousedown:=form1.st_mousedown;
end; // with
end; //for
そのようにしたらD6のように表現できるのか? ご教示ください。
とりあえず、以下を見てもらうとして... (^-^;A
[【C++ Builder XE2】TCheckBoxのフォント色の変更について (Embarcadero Discussion Forums)]
https://forums.embarcadero.com/thread.jspa?threadID=81986&tstart=0
"リンク先のリンク先" のコードではフォント色しか変更されません。
背景色を変更できるようにするには、
"リンク先のリンク先" のコードの
SetBkMode(canv.Handle, Ord(TRANSPARENT));
の上に、
if not Self.ParentColor then
begin
canv.Brush.Color := Self.Color;
canv.FloodFill(BtnWidth + 1, 0, canv.Pixels[BtnWidth + 1, 0], fsSurface);
end;
を記述すれば文字色/背景色を変更できます。
DEKO様 ご教示をありがとうございます。
リンク先のコードを眺めておりましたが残念ながら当方の理解のレベルを超えたものでした。現状のコードをベースに具体的にどのように追加変更をしたら良いか教えてください。
今回の質問とは別にTCheckBoxを貼り付けて背景色、文字色の指定を試しましたがやはりこれも指定色を反映できませんでしたが、この場合も同様な対策が必要なのでしょうか?
>今回の質問とは別にTCheckBoxを貼り付けて背景色、文字色の指定を試しましたがしましたがやはりこれも指定色を反映できませんでした
Formに貼り付けたTCheckBoxの背景色、文字色を変えたいなら、
type
TCheckBox = class({Vcl.}StdCtrls.TCheckBox)
private
FOriginalCaption: string;
_MySetCap: Boolean;
procedure WMPaint(var msg: TWMPaint); message WM_PAINT;
procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
end;
type
TForm1 = class(TForm)
CheckBox1: TCheckBox;
...........................
Form1: TForm1;
implementation
{$R *.dfm}
procedure TCheckbox.CMTextChanged(var Message: TMessage);
begin
inherited;
if _MySetCap then Exit;
FOriginalCaption := Caption;
end;
procedure TCheckbox.WMPaint(var msg: TWMPaint);
var
BtnWidth: Integer;
canv: TControlCanvas;
begin
BtnWidth := GetSystemMetrics(SM_CXMENUCHECK);
_MySetCap := True;
if not (csDesigning in ComponentState) then
Caption := '';
_MySetCap := False;
inherited;
canv := TControlCanvas.Create;
try
canv.Control := Self;
canv.Font := Font;
if not Self.ParentColor then // デフォルトでは、Self.ParentColor は True?
begin
// SetBkMode(canv.Handle, Ord(OPAQUE));
canv.Brush.Color := clBlue; //Self.Color; // とりあえず背景は青色
canv.FloodFill(BtnWidth + 1, 0, canv.Pixels[BtnWidth + 1, 0], fsSurface);
end;
SetBkMode(canv.Handle, Ord(TRANSPARENT));
canv.Font.Color := clYellow; //Self.Font.Color; // とりあえずCaption文字は黄色
canv.TextOut(BtnWidth + 1, 2, FOriginalCaption);
finally
canv.Free;
end;
end;
DEKO様 とりあえず様 ご教示をありがとうございます。
コードの内容は理解できないまま早速FormにCheckBox1を貼り付けてテストを開始してみました。 でもまだエラーだらけで進んでいません。 動いてしまえば何とか理解も進むかと思ったのですが。
とにかくテストを進めるしかないようです。ありがとうございました。
定義部 (interface の下) で、フォームの定義より前 (interface の type の下) に、
TCheckBox = class(StdCtrls.TCheckBox) // XE2 以降なら class(Vcl.StdCtrls.TCheckBox)
private
FOriginalCaption: string;
_MySetCap: Boolean;
procedure WMPaint(var msg: TWMPaint); message WM_PAINT;
procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
end;
これを記述して、
procedure TCheckbox.CMTextChanged(var Message: TMessage);
...
procedure TCheckbox.WMPaint(var msg: TWMPaint);
...
これらを実装部 (implementation の下) に記述するだけですよ。
TCheckBox の ParentColor が False なら、Color の値が背景色になり Font.Color が文字色となります。
[TCheckBox の文字色と背景色を変えたい (Delphi)]
http://ht-deko.minim.ne.jp/ft1301.html#130122_01
DEKO様 大変ありがとうございました。ご指摘のリンクのサンプルにはUses節に何を書き込むかなどが具体的に出ていましたので確実に再現できました。テストしたところ貼り付けたCheckBox(静的)もCreateしたものも着色に成功しましたので本体のプログラムに実装して着色が確認できました。
しかしCheckBoxの上に他のアプリを表示したり本ソフトを最小化から復元したりした際には色が消えてしまう(VBのAutoRedraw=falseのような)現象に直面しました。(静的、動的とも)しかし消えた枠の上にマウスを移動すると着色が再現されます。
何度も恐縮ですがこれを消えないようにする方法などありましたらご教示ください。よろしくお願いします。
> 他のアプリを表示したり
当方の XE3 では再現できませんでした。
> 本ソフトを最小化から復元したり
これも再現できませんでしたが、
フォームの OnResize イベントハンドラに
CheckBox1.Invalidate;
...
と書いてやればばいいと思います。
DEKO様 何度もすみません。
色が消えてしまう現象についての記述が間違っていました。見られる現象は
1.着色済みのCheckBoxのあるForm全体をドラッグしてScreen右端に隠し、それをまた中央に戻したときに一度隠された部分の色が消えている。
2.Momo1を配置して(例えば)
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
Memo1.left:=x;
Memo1.top:=y+20;
end;
のようにしてMemo1をCheckBox上に移動すると色が消える。
3.消えたCheckBoxにマウスを移動すると色が再現される。
というようなものです。よろしくお願いします。
ちょっと見た目が変わりますが、
if not Self.ParentColor then
begin
canv.Brush.Color := Self.Color;
canv.FloodFill(BtnWidth + 1, 0, canv.Pixels[BtnWidth + 2, 0], fsSurface);
end;
これをコメントアウトして、
SetBkMode(canv.Handle, Ord(TRANSPARENT));
↓
SetBkMode(canv.Handle, Ord(OPAQUE));
にすれば、文字列の背景色は変わります (TCheckBox の背景色ではありません)。
# 本格的にやりたければ、自前でオーナードローして下さい。
SetBkMode(canv.Handle, Ord(TRANSPARENT));
↓
SetBkMode(canv.Handle, Ord(OPAQUE));
canv.Brush.Color := Self.Color;
です。
DEKO様 これで所期の目的を達成することができました。解決に至るまでお付き合いいただき大変感謝しております。 最終的にこんなコードでやったとご報告しようと思いましたがほとんどDEKO様のサイト
http://ht-deko.minim.ne.jp/ft1301.html#130122_01
のコピペですので割愛させていただきました。 ありがとうございました。
[続・TCheckBox の文字色と背景色を変えたい (Delphi)]
http://ht-deko.minim.ne.jp/ft1301.html#130124
また変えちゃいましたけどね (^-^;A
(この文は先ほど送ったものが掲載されなかったので再送しました)
DEKO様 再度ありがとうございます。 早速最新のものを実装して動作を確認しました。 しかし文の最後に「 TCheckbox だけでなく、TRadioButton にも同様の処理が必要になります。また、無理矢理テーマを外しているので、予測できないような問題が起こるかもしれません...ご利用は計画的に」などと警告が出ていて不安になってしまいました。 そこでまた1つ前のバージョン(FillRectしないもの)に戻しました。各種のOS、バージョンなどで汎用性を脅かすような何か不安が考えられるような問題があるのでしょうか?
> 無理矢理テーマを外しているので(中略)ご利用は計画的に
この一文は、"SetWindowTheme() でテーマを外した場合" に掛かっています。
FillRect() しようがしまいが、やっている事は同じですので、
2013/01/24 版の方がいいのではないかと思います。
# 2013/01/22 改定版は TAB キーを押して TCheckBox にフォーカス矩形を表示
# させた時、その矩形が背景色の矩形と異なる問題があり、
# "WordWrap = True" に対処できなかったり、TCheckBox.Height をいじった時に
# 垂直方向にセンタリングされないという問題もあります。
DEKO様 「テーマ」とは何かを理解していませんのでどのような不安があるのか判断できませんでした。 とにかく最新版に戻してみましたのでこれで進めてみます。
このコードを実装した結果では文字の右端が欠ける場合がいくつか見られましたので FOriginalCaption := Caption + ' '; のようにして文末を足してみました。 本当にありがとうございました。
ツイート | ![]() |