CStaticの幅調整 – プログラミング – Home

通知
すべてクリア

[解決済] CStaticの幅調整


Pocket
 Pocket
(@Pocket)
ゲスト
結合: 19年前
投稿: 9
Topic starter  

下記環境で開発している者ですが、宜しくお願いいたします。

環境:
WinXP, Visual Studio.NET 2003
Dialogベースアプリケーション

DialogにCStaticを貼り付けて、そこにエラー内容を書いて本体プログラムからDialogを
Createをしようとしています。
この時、エラーメッセージの長さがマチマチなので、内容の長さによってCStaticの長さ
を調節し、合わせてダイアログの長さも調節したいと思っています。

尚、Dialog/CStaticのフォントに変更はありません。

ここで、このエラーのダイアログのメンバー関数で、下記の様に実装しました。

void EShellExecuteErrorDialog::ResizeStaticWindow( CString message )
{
  HDC hDC = ::GetDC( m_StcError.GetSafeHwnd() );
  CFont font;
  
  font.CreatePointFont( 8, MS UI Gothic );
  HGDIOBJ hFont_ = SelectObject(hDC, &font);
  char szBuf[ 256 ];
  strcpy( szBuf, message );
  
  SIZE sz;
  RECT rc;
  rc.left = 0;
  rc.right = 0;
  GetTextExtentPoint32( hDC, szBuf, (int)strlen( szBuf ), &sz );
  DrawText( hDC, szBuf, (int)strlen( szBuf ), &rc, DT_CALCRECT );
  
  m_StcError.GetWindowRect( &rc );
  ScreenToClient( &rc );
  rc.right = rc.left + sz.cx;
  
  m_StcError.MoveWindow( &rc );
  
  SelectObject( hDC, hFont_ );
}

すると、GetTextExtentPoint32()のszにも、DrawTextのrcにも同じ値が入るのですが、
この値が表示されているピクセルよりも3~4割長い値が帰ってくる様で、
m_StcError.MoveWindow()でMoveすると実際の表示よりかなり長いStaticWindowになって
しまっています。

文字列の表示ピクセル数を取得するのに、正しい方法をどなたかご教授頂けないでしょ
うか。

すみませんが、宜しくお願いいたします。


引用未解決
トピックタグ
Pocket
 Pocket
(@Pocket)
ゲスト
結合: 19年前
投稿: 9
Topic starter  

すみません、一点自己修正で、

> GetTextExtentPoint32()のszにも、DrawTextのrcにも同じ値が入るのですが

この部分は、sz にも rcのright/leftの差分も同じ値になります、の間違いです。
どこぞで、GetTextExtentPoint32()ではカーニング処理がされない値が返ると漏れ伝え
聞いて、DrawTextも試してみたのですが、結果は一緒だった、という感じです。


返信引用
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

>  HGDIOBJ hFont_ = SelectObject(hDC, &font);

CFont* と HGDIOBJ はまったく別物ですので、
CFont* の値を指定しても、SelectObject 側では、
「無効なフォントが指定されたぞ」と思っていることでしょう。

そして、デフォルトのフォントで計算されているのだと思います。


返信引用
sugar
 sugar
(@sugar)
ゲスト
結合: 23年前
投稿: 448
 

>  font.CreatePointFont( 8, MS UI Gothic );

8ptのフォントを作る時は、第1引数は 80 にしないといけないんじゃなかったかな。


返信引用
Pocket
 Pocket
(@Pocket)
ゲスト
結合: 19年前
投稿: 9
Topic starter  

dairygoodsさん、sugarさん有難うございます。

ちなみに、フォントに変更をかけてない場合は、SelectObjectのくだりはやはり必要無
いでしょうか?

というのも、最初は何もせずデフォルトでやっていたのですが、ダイアログデフォルト
のフォント値とCStaticのデフォルトフォントは別物でしょうか?

何も指定せず、デフォルトでやった場合はdairygoodsさんのおっしゃる様に、今と値が
変わらないのですが、そもそも今回のケースでフォント指定の必要性が有るのかも良く
分かりません (^-^;;

ちなみに、フォント系とSelectObjectのあたりをカットしても、GetTextExtentPoint32
()で帰ってくる値は同じで、DrawTextも同様です。また、フォントを指定するにして
も、何をして良いやら、良く分からない、、、という感じです。(指定の仕方が間違っ
ていたのもありますが)

ダイアログに設定されているデフォルトフォント(MS UI Gothic,8ポイント)とそのダ
イアログの中のコントロールのデフォルトフォントは別なのでしょうか?


返信引用
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

デバイスコンテキストのデフォルトと
ダイアログリソースで設定するダイアログのフォントは無関係です。

フォントを指定せずTextOut()等で出力してみれば、
どんなフォントか分かると思います。


返信引用
Pocket
 Pocket
(@Pocket)
ゲスト
結合: 19年前
投稿: 9
Topic starter  

dairygoodsさん、有難うございます。

お二人の助言を元に以下の方法で実装して、上手く動作致しました。
有難うございました!

void EShellExecuteErrorDialog::ResizeStaticWindow( CString message )
{
HDC hDC = ::GetDC( m_StcError.GetSafeHwnd() );
LOGFONT lf;
HFONT hFont;
SIZE sz;

GetFont()->GetLogFont( &lf );

hFont = CreateFont( lf.lfHeight,
lf.lfWidth,
0, //テキストの角度
0, //ベースラインとx軸との角度
lf.lfWeight,
FALSE, //イタリック体
FALSE, //アンダーライン
FALSE, //打ち消し線
lf.lfCharSet,
lf.lfOutPrecision,
lf.lfClipPrecision,
lf.lfQuality,
lf.lfPitchAndFamily,
lf.lfFaceName
);

HGDIOBJ hFont_ = SelectObject( hDC, hFont );

GetTextExtentPoint32( hDC, message, message.GetLength(), &sz );

SelectObject( hDC, hFont_ );

m_StcError.GetWindowRect( &rc );
rc.right = rc.left + sz.cx;
ScreenToClient( &rc );

m_StcError.MoveWindow( &rc );
}


返信引用
Pocket
 Pocket
(@Pocket)
ゲスト
結合: 19年前
投稿: 9
Topic starter  

あぁ、、

すみません、解決チェックを押し忘れました。


返信引用
R-Cradle
 R-Cradle
(@R-Cradle)
ゲスト
結合: 22年前
投稿: 4
 

もう解決しているようですが...
わざわざフォントを作成しなくても、スタティックコントロールのフォントを取得
して、それをDCに選択してから、GetTextExtent()すればいいのでは。
こんな感じ。(試してないです)

CClientDC dc(&m_StcError);
CFont* pPrevFont = dc.SelectObject(m_StcError.GetFont());
CSize size = dc.GetTextExtent(message);
dc.SelectObject(pPrevFont);

これで、正しいsizeが手に入ると思われます。


返信引用
Pocket
 Pocket
(@Pocket)
ゲスト
結合: 19年前
投稿: 9
Topic starter  

こんにちわ。
R-Cradleさん、有難う御座います。

今思えば、この方法で大丈夫でしたね。実験しましたが、同様に上手く行きました。
結果的にハマったポイントは、フォントをきちんと設定しないと駄目だ、という事を抜か
していた為に、あれやこれやの方法で、うにうにしてました。

冷静に考えれば、そうなのですが、お恥ずかしい・・・(^-^;;


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました