
VC++6.0のwin32sdkで、MFCのSDI標準テンプレートのようにメニューでツールバー,ステータスバーを切り替えるアプリケーションにしたいと思います。
以下のようなコードにしていますが、このままでは表示非表示を切り替えた場合、中央ウインドウのサイズが変更されません。
ドラッグして全体のサイズを変更すると中央メインウインドウも正常な表示になりますが、なにか中央のウインドウを再描画する処理が必要と思われます。その再描画処理についてご教示くださいますようお願いします。
1)ステータスバーの高さ,ツールバーの高さをグローバル変数にする
2)メニューからのメッセージでこのグローバル変数を表示(夫々のバーの高さ)、非表示(夫々のバーの高さ=0)を切り替える。
3)WndProcのWM_SIZEで中央メインウインドウをMoveMindowする
[グローバル変数]
----------------------------------------------
static int bShow = 16;//ステータスバーの高さ(非表示は0)
static int tbShow = 25;//ツールバーの高さ(非表示は0)
----------------------------------------------
[LRESULT CALLBACK WndProcの一部]
-----------------------------------------------
case WM_SIZE:
......
MoveWindow(中央のハンドル, 0, tbShow, LOWORD(lp), HIWORD(lp)-tbShow-bShow, TRUE);
break;
-----------------------------------------------
No.4ベストアンサー
- 回答日時:
こんにちは。
補足頂きました。本格的に試してみた所、すんません、計算ミスです。
×MoveWindow(hTree, 0, tbShow, rc.right, rc.bottom - (tbShow - bShow), TRUE);
○MoveWindow(hTree, 0, tbShow, rc.right, rc.bottom - (tbShow + bShow), TRUE);
で表示されています。
::に関しては以下URLの「グローバルスコープ」が参考になるでしょう。
http://wisdom.sakura.ne.jp/programming/cpp/cpp7. …
簡単に言えば、C++のキーワードの一つで
::Function()
と書けば、グローバル関数を意味します。此れは書かなくても構わない物です。
別の意味で言うと、当方の使用しているモノがVC++であるため、::と入力した瞬間、APIや自作したグローバル関数等が、一瞬にしてリスト表示される機能がある為に、書いているという事実も有ります。
この回答への補足
ありがとうございました。二週間が過ぎましたので締め切ります。
あとで調べてみると以下のように強制的にWM_SIZEを発生させて再描画する方法もありそうです。
GetClientRect(hWnd, &rc);
SendMessage(hWnd, WM_SIZE, (WPARAM)SIZE_RESTORED, MAKELPARAM(rc.right, rc.bottom));
UpdateWindow(hWnd);
ありがとうございました。出来ました!全て解決しました。
SDKの勉強中はちょっと自分の知識や技量を逸脱すると迷路に入って解決できなくなります。サポート感謝しています。
MFCのSDI標準テンプレートで自動的にやってくれることですが、MFCはブラックボックスが多すぎて好きになれません。その点SDKは最初とっつきにくいものの中身が見えるので好きです。RECTの使い方が勉強になりました。
::の使い方もよくわかりました。クラスで同じ名のメンバー関数が有る場合意味がありますね。
どうもありがとうございました。
No.3
- 回答日時:
こんばんは。
補足頂きました。メインのウィンドウ(場合によってはhTreeの親ウィンドウ)からウィンドウサイズを取り出し、其れを利用して計算した位置に、hTreeを動かさないといけないのではないでしょうか。
・MoveWindow(hTree, 0, tbShow,LOWORD(lp),HIWORD(lp)-tbShow-bShow,TRUE);
・LOWORD(lp),HIWORD(lp)
上記のLPARAM分析で得られた値は、少なくともこのメッセージ内(case ID_VIEW_STATUS_BAR, case ID_VIEW_TOOLBAR)においては、ウィンドウのサイズを示している物では無いので、使用出来ないのです。
RECT rc = {0};
::GetClientRect(hWnd/*外側のウィンドウ又はhTreeの親ウィンドウ*/, &rc);
::MoveWindow(hTree, 0, tbShow, rc.right, rc.bottom - (tbShow - bShow), TRUE);
と言った具合だと思います。
後、InValidRect()というのは再描画を強制するAPIであり、ウィンドウの移動やサイズ変更とは基本的に関係のない代物です。
取り敢えず以上で試されて下さい。もし無理であれば、其の時改めて補足して頂ければ、時間の折り合いが付き次第、此方からある程度のサンプルは提示出来るかもしれません。
この回答への補足
ありがとうございます。何分sdkを勉強中でこの辺の仕組みがよく理解できてないのです。
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp){
RECT rc = {0};
GetClientRect(hWnd, &rc);
と、先頭に追加し、
case ID_VIEW_STATUS_BAR:
....
SetMenuItemInfo(hMenu , ID_VIEW_STATUS_BAR , FALSE , &mi);
MoveWindow(hTree, 0, tbShow, rc.right, rc.bottom - (tbShow - bShow), TRUE);
break;
....
case ID_VIEW_TOOLBAR:
....
SetMenuItemInfo(hMenu , ID_VIEW_TOOLBAR , FALSE , &mi);
MoveWindow(hTree, 0, tbShow, rc.right, rc.bottom - (tbShow - bShow), TRUE);
break;
と、二つのバーの処理に同じMoveWindowを入れたところ、ツールバーの表示切替でhTreeは正常に動きましたが、今度は表示切替によってステータスバーが表示されなくなりました。
全ウインドウの最小化復元で3つの子ウインドウが正常に再表示されるのは前と同じです。よろしくお願いします。
それともう一つ.....
MoveWindow(hTree, 0, tbShow, rc.right, rc.bottom - (tbShow - bShow), TRUE);
の先頭に::が有るのと無いのとで何か違いがあるのでしょうか? 語頭の::の意味についても参考までに教えてください。
No.2
- 回答日時:
こんばんは。
チラッと見た限りでは、case ID_VIEW_STATUS_BAR:
memset(&mi, 0, sizeof(MENUITEMINFO));
mi.cbSize = sizeof(MENUITEMINFO);
mi.fMask = MIIM_STATE;
if (bShow) {
ShowWindow(hStatus, SW_HIDE);
mi.fState = MFS_UNCHECKED;
bShow = 0;
} else {
ShowWindow(hStatus, SW_SHOW);
mi.fState = MFS_CHECKED;
bShow = 16;
}
SetMenuItemInfo(hMenu , ID_VIEW_STATUS_BAR , FALSE , &mi);
//此処で論点のウィンドウをMoveWindow()やSetWindowPos()でサイズ調整する
break;
// ツールバーの表示非表示切り替え(メニューから)
case ID_VIEW_TOOLBAR:
memset(&mi, 0, sizeof(MENUITEMINFO));
mi.cbSize = sizeof(MENUITEMINFO);
mi.fMask = MIIM_STATE;
if (tbShow) {
ShowWindow(hToolBar, SW_HIDE);
mi.fState = MFS_UNCHECKED;
tbShow = 0;
} else {
ShowWindow(hToolBar, SW_SHOW);
mi.fState = MFS_CHECKED;
tbShow = 26;
}
SetMenuItemInfo(hMenu , ID_VIEW_TOOLBAR , FALSE , &mi);
//此処で論点のウィンドウをMoveWindow()やSetWindowPos()でサイズ調整する
break;
}
では無いでしょうか。
この回答への補足
ありがとうございます。
ご指摘の位置に
MoveWindow(hTree, 0, tbShow,LOWORD(lp),HIWORD(lp)-tbShow-bShow,TRUE);
を入れた場合、メニューの表示非表示切替をクリックすると中央のツリービューウインドウが消えてしまいます。
ところがこの消えた状態で、ウインドウを最小化復元するかメインウインドウの境界をドラッグしてサイズを変更すると(多分WM_SIZEが発生して)中央ウインドウが正常な位置に再描画されます。InValidRectを入れても変わりませんでした。
MFCのSDIテンプレートではこのような不具合は発生せず、クリックと同時に中央ウインドウのサイズが変更されますがどこがおかしいのでしょうか??
No.1
- 回答日時:
ちょっとプログラムが部分的すぎてよく分からんが、強制的に再描画させるならInvaliDateRect(HWND, RECT*, BOOL) Win32APIを使ってみてはどうだろう。
第二引数にNULLを食わせればHWND全体を再描画してくれるはずですぜ。第三引数がFALSEだと再描画されない(風に見える)場合があるのでその時はTRUEをセットしましょう。
この回答への補足
当方のウィンドウプロシージャは以下の通りです。
InvalidateRect(hWnd, NULL, TRUE);
をどのイベントで発生させたらよいか、よくわかりません。
よろしくお願いします。
//ウィンドウプロシージャ
---------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
static HMENU hMenu;
MENUITEMINFO mi;
static HWND hStatus;
static HWND hTree;
static TCHAR strMsg[80];
static int bShow = 16;
static int tbShow = 25;
switch (msg) {
case WM_COMMAND:
switch (LOWORD(wp)) {
case IDM_END:
SendMessage(hWnd, WM_CLOSE, 0, 0);
break;
// ステータスバーの表示非表示切り替え(メニューから)
case ID_VIEW_STATUS_BAR:
memset(&mi, 0, sizeof(MENUITEMINFO));
mi.cbSize = sizeof(MENUITEMINFO);
mi.fMask = MIIM_STATE;
if (bShow) {
ShowWindow(hStatus, SW_HIDE);
mi.fState = MFS_UNCHECKED;
bShow = 0;
} else {
ShowWindow(hStatus, SW_SHOW);
mi.fState = MFS_CHECKED;
bShow = 16;
}
SetMenuItemInfo(hMenu , ID_VIEW_STATUS_BAR , FALSE , &mi);
break;
// ツールバーの表示非表示切り替え(メニューから)
case ID_VIEW_TOOLBAR:
memset(&mi, 0, sizeof(MENUITEMINFO));
mi.cbSize = sizeof(MENUITEMINFO);
mi.fMask = MIIM_STATE;
if (tbShow) {
ShowWindow(hToolBar, SW_HIDE);
mi.fState = MFS_UNCHECKED;
tbShow = 0;
} else {
ShowWindow(hToolBar, SW_SHOW);
mi.fState = MFS_CHECKED;
tbShow = 26;
}
SetMenuItemInfo(hMenu , ID_VIEW_TOOLBAR , FALSE , &mi);
break;
}
break;
case WM_CREATE:
InitCommonControls();
// ステータスバー作成
hStatus = MyCreateStatusbar(hWnd);
wsprintf(strMsg , TEXT("Ready"));
SendMessage(hStatus, SB_SETTEXT, (WPARAM)0 | 0, (LPARAM)strMsg);
// ツールバーウインドウ作成
hToolBar = CreateToolbarEx(hWnd, WS_CHILD | WS_VISIBLE,ID_TOOLBAR,
4, hInst,IDB_TOOLBAR,tbb, 8, 0, 0, 16, 15, sizeof(TBBUTTON));
SendMessage(hToolBar, TB_INSERTBUTTON,7, (LPARAM)&tb);
// ツリービューウインドウの作成
hTree = CreateWindowEx(0, WC_TREEVIEW, "",
WS_CHILD | WS_BORDER | WS_VISIBLE | TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT,
0, 0, 0, 0,hWnd, (HMENU)ID_MYTREE, hInst, NULL);
break;
case WM_PAINT:
break;
case WM_SIZE:
SendMessage(hToolBar, WM_SIZE, wp, lp);
SendMessage(hStatus, msg, wp, lp);
// ツリービューウインドウの再配置(中央に配置)
MoveWindow(hTree, 0, tbShow,LOWORD(lp),HIWORD(lp)-tbShow-bShow,TRUE);
break;
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, msg, wp, lp));
}
return 0;
}
-------------------------------------------------------------------------------
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) 【マクロ】リボン、行列、数式・ステータスバを非表示に 4 2022/12/12 07:32
- フリーソフト libreoffice drawのツールバーのチェックが外れてしまう 1 2022/10/04 22:02
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- その他(ソフトウェア) Ghosteryのプライバシー 広告ブロッカーのトラブルについて質問です。 1 2023/05/03 21:09
- Excel(エクセル) 【エクセルマクロ】既に開いているIEの、サイズや表示位置を変更するには 4 2022/12/01 22:57
- Windows Me・NT・2000 IMEオプションが開かない 2 2023/04/07 18:04
- Illustrator(イラストレーター) クリップスタジオペイントについて。 1 2022/11/15 11:38
- HTML・CSS HTMLの条件によって表示方向が切り替わる実装のコードを教えて下さい。 (コードは下記リンクを参照) 1 2022/09/25 14:35
- Visual Basic(VBA) ExcelのVBAコードについて教えてください。 4 2023/05/26 10:43
- Android(アンドロイド) ステータスバーのバッテリー残量表示が0%のまま変わらない 2 2022/08/01 20:07
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Minecraft 統合版(PC)の描画距...
-
TextBoxに文字を書いても表示さ...
-
MFCで株価チャートソフトを作り...
-
塗りつぶしモード ALTERNATEと...
-
google Colabでmatplotlibの描...
-
MFCでOnPaintのタイミング
-
VB6,リストボックスの特定行の...
-
ClistBoxでオーナードローがよ...
-
[VB.net] DataGridViewの列ヘッ...
-
矢印を描画するには
-
VBAにGDI+を参照させる方法
-
iPhoneSDK 楕円の描画およびグ...
-
DirectX9.0での四角形の描画に...
-
テクスチャに半透明ポリゴンを...
-
ちらつきを何とかしたい
-
CScrollViewの使用方法について
-
VC++でカーソルを固定する
-
N88BASICのcircle 命令をDXlib ...
-
UpdateData( FALSE); による文...
-
C++のソースをコンパイルしてで...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Minecraft 統合版(PC)の描画距...
-
[VB.net] DataGridViewの列ヘッ...
-
word
-
TextBoxに文字を書いても表示さ...
-
VB6,リストボックスの特定行の...
-
NVIDIAのシェーダーキャッシュ
-
panelのスクロール表示について
-
VC++プログラムをつかったBMP画...
-
VBAにGDI+を参照させる方法
-
google Colabでmatplotlibの描...
-
MFCでOnPaintのタイミング
-
MFCのタイマーのつかい方を教え...
-
UpdateData( FALSE); による文...
-
CStaticコントロールの静的イメ...
-
Form1 Load で実行されない。
-
InvalidateRectの使い方について
-
win32api 画面のちらつき
-
c++ ダブルバッファリング、以...
-
CDC(LineTo)で描画した線を透過...
-
BitBltでの表示での問題です。
おすすめ情報