クライアント領域の大きさを指定 – プログラミング – Home

クライアント領域の大きさを指定
 
通知
すべてクリア

[解決済] クライアント領域の大きさを指定


にゃー
 にゃー
(@にゃー)
ゲスト
結合: 11年前
投稿: 4
Topic starter  

Win7で VC++2012の MFC(シングルドキュメント)を使用している者です。

クライアント領域の大きさを指定しようと思い、PreCreateWindowの中身を

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)

{

if( !CFrameWnd::PreCreateWindow(cs) )

return FALSE;

// TODO: この位置で CREATESTRUCT cs を修正して Window クラスまたはスタ
イルを

// 修正してください。

//変更点 ここから

cs.style = WS_MINIMIZEBOX |WS_POPUPWINDOW |WS_CAPTION

;

// 指定したクライアントサイズ

int cxClient =800;

int cyClient = 600;

int cx = cxClient

+GetSystemMetrics(SM_CXEDGE )*2

+GetSystemMetrics(SM_CXBORDER )*2;

int cy = cyClient

+GetSystemMetrics( SM_CYEDGE )*2

+GetSystemMetrics(SM_CYBORDER )*2

+GetSystemMetrics( SM_CYCAPTION )

+GetSystemMetrics( SM_CYMENU );

cs.cx=cx;

cs.cy=cy;

//変更点 ここまで

cs.dwExStyle &= ~WS_EX_CLIENTEDGE;

cs.lpszClass = AfxRegisterWndClass(0);

return TRUE;

}

としたのですが、実測してみると、どうも縦横共に12ピクセルほど足りません。

どうすればクライアント領域を800×600丁度にできますでしょうか。


引用未解決
トピックタグ
瀬戸っぷ
 瀬戸っぷ
(@瀬戸っぷ)
ゲスト
結合: 18年前
投稿: 178
 

ナニが足りないのか…は未確認ですが……
>クライアント領域の大きさを指定しようと思い
であれば、AdjustWindowRect()、またはAdjustWindowRectEx()が使えませんか?
CREATESTRUCT構造体にstyleとdwExStyleもあるようですから、算出する際に利用できるかと。
# 算出前にRECT構造体にはよろしく値を設定する必要がありますけどね。


返信引用
にゃー
 にゃー
(@にゃー)
ゲスト
結合: 11年前
投稿: 4
Topic starter  

ご返答、ありがとうございます。

言葉足らずで申し訳ありません。

実行結果のウインドウのクライアント領域が、指定よりも縦横共に12ピクセル足りない、
という意味です。

また、AdjustWindowRectEx及びAdjustWindowRectEを、PreCreateWindow内に

RECT rect={0,0,800,600};

AdjustWindowRectEx(&rect,cs.style,true,cs.dwExStyle);

の様に置いて実行しましたが、指定した大きさのクライアント領域を持つウインドウには
なりませんでした。


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

フレーム(NC)を持つウインドウの、クライアント領域の大きさを
指定通りにしようとする試みは、失敗するか、将来破綻します。

原理的にクライアント領域は、フレームのサイズから、
フレームのスタイルや、クライアントのスタイルで使用されるピクセル数の
減算で算定される、いわば「残りの領域」であるからですね。
これらの中には動的に変化するスクロールバーなども含まれてしまいます。

また、これらのピクセル数は、適用されるテーマや、デフォルトのフォント、
ユーザー補助の適用、最近はモニタの高解像度化の影響で、デフォルトの
倍率が設定される、などによっても動的に変更されますので、
これらの全ての影響を事前に検知して算定に組み入れることは不可能です。

以上の通り不毛な作業となるばかりか、その仕様自体が瑕疵あつかいされると
考えられますので、その仕様の検討は中止すべきだと思います。


返信引用
ロマ
 ロマ
(@ロマ)
ゲスト
結合: 18年前
投稿: 170
 

Spy++でフレームの大きさと、フレームのクライアント領域の大きさを比較してみてくだ
さい(Viewのウィンドウでは無く)。
ついでに、スタイル指定の結果も見てください。
(ひょっとしたら、SM_CXFIXEDFRAME,SM_CYFIXEDFRAMEかもしれません)


返信引用
tea
 tea
(@tea)
ゲスト
結合: 11年前
投稿: 2
 

ゲームを作る場合など、クライアント領域のサイズを指定する場面は稀にありますね。
AdjustWindowRectExは実行後、クライアント領域の左上の原点を0として、
そこからウィンドウの左上・右下までの差分がRECTの中に入ります。
(フレームやメニューがあるとleft及びtopはマイナス値になる)

よって、ウインドウ全体の大きさは

RECT rect={0,0,800,600};
AdjustWindowRectEx(&rect,cs.style,true,cs.dwExStyle);
cs.cx=abs(rect.left)+rect.right;
cs.cy=abs(rect.top)+rect.bottom;

でOKなはずです。


返信引用
にゃー
 にゃー
(@にゃー)
ゲスト
結合: 11年前
投稿: 4
Topic starter  

多くのご意見、ありがとうございます。

teaさんのコードを試しましたが、クライアント領域が指定に対し縦横3ピクセル足りませ
んでした。

ほかにも、色々試しましたが、上手くいかず、仲澤@失業者さんのおっしゃるとおり、仕
様の検討を中止することを考えております。


返信引用
tea
 tea
(@tea)
ゲスト
結合: 11年前
投稿: 2
 

大変失礼しました。こちらでも確認してみましたが、
確かにうまくいかないですね…。

どうやらView側のWS_EX_CLIENTEDGEがズレの原因のようで、View側から取り除て、
代わりにウィンドウ幅を算出するFrame側に付加することでうまくいきました。

ドッキングツールバーとステータスバーが無いことが条件になりますが、
念のため下記にコードを示しておきます。

MainFrm.cppのCMainFrame::PreCreateWindow内にて、
cs.dwExStyle |= WS_EX_CLIENTEDGE; // WS_EX_CLIENTEDGEを追加
RECT rect={0,0,800,600};
AdjustWindowRectEx(&rect,cs.style,true,cs.dwExStyle);
cs.cx=abs(rect.left)+rect.right;
cs.cy=abs(rect.top)+rect.bottom;

XXXView.cppのXXXView::PreCreateWindow内にて、元のreturn行をコメントアウトして

if (!CView::PreCreateWindow(cs))
return FALSE;
cs.dwExStyle &= ~WS_EX_CLIENTEDGE; // WS_EX_CLIENTEDGEを取り除く
return TRUE;

これでクライアント領域のサイズ指定はうまくいくと思いますが、
ツールバーやステータスバーが必要な場合はこの方法ではうまくいきません。


返信引用
にゃー
 にゃー
(@にゃー)
ゲスト
結合: 11年前
投稿: 4
Topic starter  

teaさん

再びのご返答、ありがとうございます。

MainFrameのPreCreateWindowにて

cs.style &= ~WS_MAXIMIZEBOX ;

cs.style &= ~WS_THICKFRAME;

cs.dwExStyle |= WS_EX_CLIENTEDGE;

RECT rect={0,0,800,600};

AdjustWindowRectEx(&rect,cs.style,true,cs.dwExStyle);

cs.cx=abs(rect.left)+rect.right;

cs.cy=abs(rect.top)+rect.bottom;

とし、ViewのPreCreateWindowにて

if (!CView::PreCreateWindow(cs))

return FALSE;

cs.dwExStyle &= ~WS_EX_CLIENTEDGE; // WS_EX_CLIENTEDGEを取り除く

return TRUE;

としたところ、800×600のクライアント領域を持つウインドウができました。

他の方々からも、多くのご助言に感謝いたします。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

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