質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
Delphi

DelphiはPascalを拡張してオブジェクト指向を導入したWindows, OS X,iOS,Androidのネイティブアプリケーションを開発するための言語です。旧称はObject Pascal。開発用IDE「Delphi」にあわせ現在の名前に改称されました。

解決済

継承したFontプロパティの文字サイズを大きくしてもサイズが大きくならない

dem0nmichik0
dem0nmichik0

総合スコア37

Delphi

DelphiはPascalを拡張してオブジェクト指向を導入したWindows, OS X,iOS,Androidのネイティブアプリケーションを開発するための言語です。旧称はObject Pascal。開発用IDE「Delphi」にあわせ現在の名前に改称されました。

1回答

0グッド

0クリップ

2252閲覧

投稿2019/08/29 10:48

編集2019/10/29 14:05

###実現したいこと
四角形や円などの図形と文字列を同時に生成する自作コンポーネントを作成すること.

###困っていること
CustomControlクラスを継承したクラスを作成し,CustomControlのプロパティであるFontを継承しました.ですが,テストアプリでFontのSizeプロパティを変更しても文字列のサイズが変更せずに困っています.


図1 文字列のサイズが変わらないインスタンス


図2 Sizeプロパティを16にした時の画面

###実現方法
文字列のサイズを変更する方法はウィンドウメッセージのWM_SETFONTイベントを発生させる必要があるだろうと思っています.ですが,WM_SETFONTイベントの発生させ方が分からず困っています.どなたがご教授お願いいたします.

###ソースコード
文字数が10,000文字以上になるため,各種メソッド部分をわざと消しています.

Delphi

1unit Door; 2// Delphi 3interface 4 5uses 6 Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes, 7 Vcl.Controls, Vcl.Graphics, Vcl.Forms, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.Dialogs; 8 9type 10 TDoor = class(TCustomControl) 11 private 12 { Private 宣言 } 13 FCaption: UnicodeString; 14 FShape: TShapeType; 15 FShapeColor: TColor; 16 FWidth_C: Integer; 17 FHeight_C: Integer; 18 19 procedure SetShape(Value: TShapeType); 20 procedure SetShapeColor(Value: TColor); 21 procedure SetCaption(Value: UnicodeString); 22 procedure SetWidth_C(Value: Integer); 23 procedure SetHeight_C(Value: Integer); 24 protected 25 { Protected 宣言 } 26 public 27 { Public 宣言 } 28 left: Integer; 29 top: Integer; 30 31 // コンストラクタ(オーバーライド) 32 constructor Create( AOwner: TComponent ); override; 33 procedure Paint; override; 34 published 35 { Published 宣言 } 36 // プロパティにdefaultを付けるとデフォルト値にできる 37 property Shape: TShapeType read FShape write SetShape default stRectangle; 38 property ShapeColor: TColor read FShapeColor write SetShapeColor; 39 property Caption: UnicodeString read FCaption write SetCaption; 40 property Width_C: Integer read FWidth_C write SetWidth_C; 41 property Height_C: Integer read FHeight_C write SetHeight_C; 42 // 継承プロパティ(再宣言するとオブジェクトインスペクタに表示できるようになる) 43 property Anchors; 44 property Color; 45 property Enabled; 46 property Font; 47 property Name; 48 property ParentColor; 49 property Visible; 50 property OnClick; 51 property OnDblClick; 52 end; 53 54procedure Register; 55 56//--------------------------------------------------------------------------- 57implementation 58 59const 60 DelphiWindows: array [1 .. 1] of PWideChar = ('TAppBuilder'); 61 62procedure Register; 63begin 64 // 「Samples」パレットにドアを登録 65 RegisterComponents('Samples', [TDoor]); 66end; 67 68// WM_PAINTメッセージで起動 69// クライアントエリアに更新領域が存在するときにコール 70procedure TDoor.Paint; 71var 72 x1, y1: Integer; 73 x2, y2: Integer; 74 x_space, y_space: Integer; 75 76begin 77 // 四角形の場合 78 if FShape = stRectangle then 79 begin 80 with Canvas do begin 81 // FSahpeColor色で塗りつぶし 82 Brush.Color:= FShapeColor; 83 Brush.Style:= bsSolid; 84 FillRect(Rect(Left, Top, (Left+Width), (Top+Height))); 85 // 黒色で太さ1で枠線描画 86 Pen.Color:= clBlack; 87 Pen.Style:= psSolid; 88 Pen.Width:= 1; 89 Rectangle(Rect(Left, Top, (Left+Width), (Top+Height))); 90 91 // 文字列の描画 92 TextOut(FWidth_C, FHeight_C, FCaption); 93 end; 94 end 95 // 円の場合 96 else if FShape = stCircle then 97 begin 98 with Canvas do begin 99 // Color色で塗りつぶし 100 Brush.Color:= Color; 101 Brush.Style:= bsSolid; 102 FillRect(Rect(Left, Top, (Left+Width), (Top+Height))); 103 104 if Width > Height then 105 begin 106 x_space:= Width - Height; 107 x1:= Left + (x_space div 2); 108 y1:= Top; 109 x2:= x1 + Height; 110 y2:= y1 + Height; 111 end 112 else 113 begin 114 y_space:= Height - Width; 115 x1:= Left; 116 y1:= Top + (y_space div 2); 117 x2:= x1 + Width; 118 y2:= y1 + Width; 119 end; 120 121 // FSahpeColor色で塗りつぶし 122 Brush.Color:= FShapeColor; 123 Brush.Style:= bsSolid; 124 // 黒色で太さ1で枠線描画 125 Pen.Color:= clBlack; 126 Pen.Style:= psSolid; 127 Pen.Width:= 1; 128 Ellipse(x1, y1, x2, y2); 129 130 // 文字列の描画 131 TextOut(FWidth_C, FHeight_C, FCaption); 132 end; 133 end 134 // 楕円の場合 135 else if FShape = stEllipse then 136 begin 137 with Canvas do begin 138 // Color色で塗りつぶし 139 Brush.Color:= Color; 140 Brush.Style:= bsSolid; 141 FillRect(Rect(Left, Top, (Left+Width), (Top+Height))); 142 // FSahpeColor色で塗りつぶし 143 Brush.Color:= FShapeColor; 144 Brush.Style:= bsSolid; 145 // 黒色で太さ1で枠線描画 146 Pen.Color:= clBlack; 147 Pen.Style:= psSolid; 148 Pen.Width:= 1; 149 Ellipse(Left, Top, (Left+Width), (Top+Height)); 150 151 // 文字列の描画 152 TextOut(FWidth_C, FHeight_C, FCaption); 153 end; 154 end 155 // 角の丸い四角形の場合 156 else if FShape = stRoundRect then 157 begin 158 with Canvas do begin 159 // Color色で塗りつぶし 160 Brush.Color:= Color; 161 Brush.Style:= bsSolid; 162 FillRect(Rect(Left, Top, (Left+Width), (Top+Height))); 163 // FSahpeColor色で塗りつぶし 164 Brush.Color:= FShapeColor; 165 Brush.Style:= bsSolid; 166 // 黒色で太さ1で枠線描画 167 Pen.Color:= clBlack; 168 Pen.Style:= psSolid; 169 Pen.Width:= 1; 170 RoundRect(Left, Top, Width, Height, 10, 10); 171 172 // 文字列の描画 173 TextOut(FWidth_C, FHeight_C, FCaption); 174 end; 175 end 176 // 角の丸い正方形の場合 177 else if FShape = stRoundSquare then 178 begin 179 with Canvas do begin 180 if Width > Height then 181 begin 182 x_space:= Width - Height; 183 x1:= Left + (x_space div 2); 184 y1:= Top; 185 x2:= x1 + Height; 186 y2:= y1 + Height; 187 end 188 else 189 begin 190 y_space:= Height - Width; 191 x1:= Left; 192 y1:= Top + (y_space div 2); 193 x2:= x1 + Width; 194 y2:= y1 + Width; 195 end; 196 197 // Color色で塗りつぶし 198 Brush.Color:= Color; 199 Brush.Style:= bsSolid; 200 FillRect(Rect(Left, Top, (Left+Width), (Top+Height))); 201 // FSahpeColor色で塗りつぶし 202 Brush.Color:= FShapeColor; 203 Brush.Style:= bsSolid; 204 // 黒色で太さ1で枠線描画 205 Pen.Color:= clBlack; 206 Pen.Style:= psSolid; 207 Pen.Width:= 1; 208 RoundRect(x1, y1, x2, y2, 10, 10); 209 210 // 文字列の描画 211 TextOut(FWidth_C, FHeight_C, FCaption); 212 end; 213 end 214 // 正方形の場合 215 else if FShape = stSquare then 216 begin 217 with Canvas do begin 218 // Color色で塗りつぶし 219 Brush.Color:= Color; 220 Brush.Style:= bsSolid; 221 FillRect(Rect(Left, Top, (Left+Width), (Top+Height))); 222 223 if Width > Height then 224 begin 225 x_space:= Width - Height; 226 x1:= Left + (x_space div 2); 227 y1:= Top; 228 x2:= x1 + Height; 229 y2:= y1 + Height; 230 end 231 else 232 begin 233 y_space:= Height - Width; 234 x1:= Left; 235 y1:= Top + (y_space div 2); 236 x2:= x1 + Width; 237 y2:= y1 + Width; 238 end; 239 240 // FSahpeColor色で塗りつぶし 241 Brush.Color:= FShapeColor; 242 Brush.Style:= bsSolid; 243 // 黒色で太さ1で枠線描画 244 Pen.Color:= clBlack; 245 Pen.Style:= psSolid; 246 Pen.Width:= 1; 247 Rectangle(Rect(x1, y1, x2, y2)); 248 249 // ためしにやってみたが,フォントサイズが変更しなかった. 250 Font.Assign(Font); 251 // 文字列の描画 252 TextOut(FWidth_C, FHeight_C, FCaption); 253 end; 254 end; 255 256// FCaption. 257// Font.Size 258end; 259 260 261//Createメソッド省略 262//SetShapeメソッド省略 263//SetShapeColorメソッド省略 264//SetCaptionメソッド省略 265//SetWidth_Cメソッド省略 266//SetHeight_Cメソッド省略 267 268end.

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

y_waiwai

2019/08/30 12:48

ソースもないことには答えようがないですが。
dem0nmichik0

2019/10/24 15:12

y_waiwai様 申し訳ありませんでした.遅くなりましたが,ただ今抜粋的にソースコードを記載いたしました. よろしくお願いいたします。

回答1

2

ベストアンサー

Paintメソッドの実装がないので予想ですが、テキストの描画はPaintメソッド内で実行しているのですよね。
であれば、テキストの描画をする前に下記のようにカンバスにフォントを設定してから描画すれば設定したフォントが反映されると思います。

Delphi

1paintメソッド 2: 3Canvas.Font.Assign(Font); 4Canvas.TextOut(...); 5:

投稿2019/10/29 00:25

au2010

総合スコア37

Zuishin, dem0nmichik0👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

dem0nmichik0

2019/10/29 14:10

au2010様,回答ありがとうございます. Paintメソッド内にはFShapeプロパティによって,四角形,正方形,円,楕円などをサイズ変更して再描画しており,最後にTextOutで文字列も描画しています.なので,おしえていただいた「Font.Assign(Font)」を正方形の場合のときに,TextOutの前に設定してやってみましたが,フォントサイズが変更されませんでした. Paintメソッドの中身を実装しましたので,お時間ありましたら,ご教授お願いいたします.
au2010

2019/10/30 00:45

Withブロック内なのでCanvasのフォントとControlのフォントの区別が付かない状態になっているのではないかと思います。 Canvas.Font.Assign(Self.Font);としてみたらどうでしょう?
dem0nmichik0

2019/10/30 13:57

au2010様,回答ありがとうございます. Canvas.Font.Assign(Self.Font)でフォントサイズが変更しました.2点質問があります. 1.Assignメソッドは「プロパティのコピー」とHPに記載されていますが,なぜ,プロパティをコピーすると実現できるのでしょうか?自分自身では,フォントサイズを変更したら何かしらのウィンドウメッセージが発生し,発生したウィンドウメッセージに対してフォントサイズの再描画処理を記述すると思っていました. 2.Canvas.Font.Assign(Self.Font)とCanvas.Font.Assign(Self.Font)の違いは「Assign(Self.Font)」か「Assign(Font)」ですが,なぜ,「Assign(Font)」だとだめなのでしょうか?「Assign(Self.Font)」だとCanvasのFontで,「Assign(Font)」だとTCustomControlのFontなため,「Self」が必要なのでしょうか? 回答お願いいたします.
au2010

2019/10/31 00:20

1については、コントロールの描画を自作する場合、コントロールのFontプロパティと実際に描画を行うCanvasのFontプロパティは別で特にリンクしている訳ではないので自分で描画する時に設定する必要があるからです。これはPenとかBrushについても同じです。 2については、コントロール自身とCanvasはそれぞれ個別にFontプロパティを持っています。Withブロック内で単にFontとした場合、どちらのFontと解釈されるかは判りませんがコピー元とコピー先が同じになるからダメだったのでしょう。作成しているコントールのFontプロパティをCanvasのFontにコピーする必要があるのです。
dem0nmichik0

2019/10/31 03:27

au2010様,回答ありがとうございます。 1,2の説明により,「自作しようとしているコントロール(TCustomControl)」と「Canvas」のFontプロパティは別々なこと,オブジェクトインスペクタによって自作しようとしているコントロール(TCustomControl)のFontプロパティが変化するから,Canvas.Font.Assign(Self.Font)によって,自作しようとしているコントロール(TCustomControl)のFontプロパティをCanvasのFontプロパティにコピーする。そして,文字列の描画で反映されることが分かりました。 丁寧なご教授ありがとうございました。

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Delphi

DelphiはPascalを拡張してオブジェクト指向を導入したWindows, OS X,iOS,Androidのネイティブアプリケーションを開発するための言語です。旧称はObject Pascal。開発用IDE「Delphi」にあわせ現在の名前に改称されました。