図のようにCHILDウィンドウを最大化すると
ステータスバーやツールバーの領域まで拡大
されてしまって困っています。
この問題はどのように解決すればいいのでしょうか。
よろしくお願いします。
以下コードです
#include <windows.h>
#include "resource.h"
#include <CommCtrl.h>
LRESULT CALLBACK FrameProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ChildProc(HWND, UINT, WPARAM, LPARAM);
char szClassNme[/url] = "ウィンドウクラス・ネーム";
HWND hwCl;
HWND hwFm;
HINSTANCE hInstFm;
HMENU hmFm;
HWND hwSb;
void myError(LPCSTR msg){MessageBox(NULL,msg,"",0);}
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPreInst,
LPSTR lpszCmdLine, int nCmdShow)
{
hInstFm=hInst;
MSG msg;
WNDCLASS wc;
if (!hPreInst) {
wc.style =CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc =FrameProc;
wc.cbClsExtra =0;
wc.cbWndExtra =0;
wc.hInstance =hInst;
wc.hIcon =NULL;
wc.hCursor =LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground =(HBRUSH)(COLOR_APPWORKSPACE+1);
wc.lpszMenuName =NULL;
wc.lpszClassName =szClassNme;
if (!RegisterClass(&wc)){
myError("1");
return FALSE;
}
}
hmFm=LoadMenu(hInst,MAKEINTRESOURCE(IDR_MENU1));
hwFm = CreateWindow(szClassNme,"FRAME",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
NULL,hmFm,hInst,NULL);
wc.lpszClassName="CCN";
wc.lpfnWndProc=ChildProc;
wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
if (!RegisterClass(&wc)){
myError("1");
return FALSE;
}
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (msg.wParam);
}
LRESULT CALLBACK FrameProc(HWND hw, UINT msg, WPARAM wp, LPARAM lp)
{
switch (msg) {
case WM_CREATE:
//Create Client
CLIENTCREATESTRUCT ccs;
ccs.hWindowMenu=GetSubMenu(hmFm,1);
ccs.idFirstChild=1;
hwCl= CreateWindow( "MDICLIENT",NULL,
WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL | WS_VISIBLE,
0, 0, 0, 0, hw, (HMENU)1, hInstFm, (LPSTR) &ccs);
//Create Statusbar
InitCommonControls();
hwSb=CreateWindowEx(0,STATUSCLASSNAME,NULL,
WS_CHILD | SBARS_SIZEGRIP | CCS_BOTTOM | WS_VISIBLE,
0,0,0,0,hw,(HMENU)2,hInstFm,NULL);
break;
case WM_COMMAND:
switch(wp){
case IDM_NEW1:
HWND hwCh;
MDICREATESTRUCT mcs;
mcs.x=CW_USEDEFAULT;
mcs.y=CW_USEDEFAULT;
mcs.cx=CW_USEDEFAULT;
mcs.cy=CW_USEDEFAULT;
mcs.szClass="CCN";
mcs.szTitle="child";
mcs.hOwner=hInstFm;
mcs.SSS=WS_CHILD;//SSS→style
mcs.lParam=0;
hwCh=(HWND)SendMessage(hwCl,WM_MDICREATE,0,(LPARAM)&mcs);
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefFrameProc(hw, hwCl,msg, wp, lp);
}
LRESULT CALLBACK ChildProc(HWND hw, UINT msg, WPARAM wp, LPARAM lp){
return DefMDIChildProc(hw,msg,wp, lp);
}
MDIでステータスバー等の領域を残すには
Re:MDIでステータスバー等の領域を残すには
ChildProc関数でWM_GETMINMAXINFOを処理してください。
switch (msg) { case WM_GETMINMAXINFO: MINMAXINFO *pi = (MINMAXINFO*)lp; pi->ptMaxPosition.x = (最大化時の左上X座標); pi->ptMaxPosition.y = (最大化時の左上Y座標); pi->ptMaxSize.x = (最大化時の幅); pi->ptMaxSize.y = (最大化時の高さ); return 0; }
Re:MDIでステータスバー等の領域を残すには
ありがとうございます。
そんなデータをセットするメッセージがあったんですね。
しかし相変わらずウィンドウを動かした時等には画像のように
ステータスバー領域が侵略されてしまいます・・・。
この問題を解決する方法もご存知でしょうか?
よろしくお願いいたします。
そんなデータをセットするメッセージがあったんですね。
しかし相変わらずウィンドウを動かした時等には画像のように
ステータスバー領域が侵略されてしまいます・・・。
この問題を解決する方法もご存知でしょうか?
よろしくお願いいたします。
Re:MDIでステータスバー等の領域を残すには
私もWin32APIでMDI+ステータスバーのアプリを作りましたが、そんな現象に出くわしたことはなく、
WM_GETMINMAXINFOメッセージも知らなかったので、不思議に思っていろいろ試してみたところ、
・MDIクライアントがステータスバーの上にかぶってしまっている
ことが原因と思われます。
WinXPで試しましたが、以下でどうでしょうか。
(1)MDIクライアントとステータスバーを作る順番を逆にする。
※先にステータスバーを作った後、MDIクライアントを作る。
(2)MDIクライアントのウィンドウスタイルに WS_CLIPSIBLINGS を追加する。
※兄弟ウィンドウ(ステータスバー)の領域を侵食しない。
追記訂正:
「MDIクライアントがステータスバーの上にかぶって」という表現は正しくないような・・
「MDIクライアントがステータスバーの領域にまで広がってしまっている」が適切かな・・
WM_GETMINMAXINFOメッセージも知らなかったので、不思議に思っていろいろ試してみたところ、
・MDIクライアントがステータスバーの上にかぶってしまっている
ことが原因と思われます。
WinXPで試しましたが、以下でどうでしょうか。
(1)MDIクライアントとステータスバーを作る順番を逆にする。
※先にステータスバーを作った後、MDIクライアントを作る。
(2)MDIクライアントのウィンドウスタイルに WS_CLIPSIBLINGS を追加する。
※兄弟ウィンドウ(ステータスバー)の領域を侵食しない。
追記訂正:
「MDIクライアントがステータスバーの上にかぶって」という表現は正しくないような・・
「MDIクライアントがステータスバーの領域にまで広がってしまっている」が適切かな・・

Re:MDIでステータスバー等の領域を残すには
無事できました。ありがとうございます!
WS_CLIPSIBLINGSなんてものがあったんですね。目から鱗です。
まだまだ初心者なものでwindow stylesのことなんて
全然わからずに数時間(十数時間?)彷徨っていました。
ISLeさん、たろさん、本当にありがとうございました。
WS_CLIPSIBLINGSなんてものがあったんですね。目から鱗です。
まだまだ初心者なものでwindow stylesのことなんて
全然わからずに数時間(十数時間?)彷徨っていました。
ISLeさん、たろさん、本当にありがとうございました。
Re:MDIでステータスバー等の領域を残すには
フレームウインドウのリサイズに対応できていないのではないでしょうか。
#WM_GETMINMAXINFOは見当違いでした。すみません。
case WM_SIZE: { RECT rc; SendMessage(hwSb, WM_SIZE, wp, lp); GetWindowRect(hwSb, &rc); MoveWindow(hwCl,0,0,LOWORD(lp),HIWORD(lp)-(rc.bottom-rc.top),TRUE); } return 0; // 必須!!FrameProc関数のメッセージ処理に上記のコードを追加してみてください。
#WM_GETMINMAXINFOは見当違いでした。すみません。
Re:MDIでステータスバー等の領域を残すには
ISLeさん
ありがとうございます。
どうやらそちらの方法の方が優れていそうですね。
チャイルドウィンドウが動くときにもWM_SIZEメッセージは送られるんですね。
まだまだ細かい理屈はわかりませんが
大変勉強になりました。これからもっと精進します。ありがとうございます。
ありがとうございます。
どうやらそちらの方法の方が優れていそうですね。
チャイルドウィンドウが動くときにもWM_SIZEメッセージは送られるんですね。
まだまだ細かい理屈はわかりませんが
大変勉強になりました。これからもっと精進します。ありがとうございます。