ウィンドウサイズの保存・復帰 – プログラミング – Home

ウィンドウサイズの保存・復帰
 
通知
すべてクリア

[解決済] ウィンドウサイズの保存・復帰


nfs
 nfs
(@nfs)
ゲスト
結合: 16年前
投稿: 48
Topic starter  

VC2008 Express Edition, SDK, Vista SP1 です。

アプリケーションの終了時のウィンドウサイズを保存して、
アプリケーションの起動時に終了時のウィンドウサイズを復帰したいです。

現在、WM_CLOSE 時にGetWindowPlacement()で
WINDOWPLACEMENT構造体をファイルに書き込み、
WM_CREATE 時にファイルからWINDOWPLACEMENT構造体を取得し、
SetWindowPlacement()でウィンドウサイズを復帰させています。

このようなやり方だと、ウィンドウが最大化(最大化ボタンが押された状態)のときに終了
すると、次にアプリケーションを起動すると、ウィンドウサイズは最大化されるのです
が、最大化ボタンが押された状態にはなりません。

分かる方いらっしゃいましたら、よろしくお願いします。


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

最大化した状態で書き出したWINDOWPLACEMENT構造体のflagsメンバとshowCmdメンバはど
うなっているのでしょうか?

http://hp.vector.co.jp/authors/VA023539/tips/window/003.htm
によると、flagsは自分で処理する必要がある…のかも知れませんが。


返信引用
nfs
 nfs
(@nfs)
ゲスト
結合: 16年前
投稿: 48
Topic starter  

瀬戸っぷさん、回答ありがとうございます。

最大化した状態で閉じると、flags == 2(WPF_RESTORETOMAXIMIZED),
showCmd == 3(SW_SHOWMAXIMIZED) です。

ご紹介いただいたサイトのように保存時に
if (IsZoomed(in_hWnd) )
wp.flags|=WPF_RESTORETOMAXIMIZED;
としましたが、現象は変わらずでした。><

WinUser.hより
#define SW_HIDE 0
#define SW_SHOWNORMAL 1
#define SW_NORMAL 1
#define SW_SHOWMINIMIZED 2
#define SW_SHOWMAXIMIZED 3
#define SW_MAXIMIZE 3
#define SW_SHOWNOACTIVATE 4
#define SW_SHOW 5
#define SW_MINIMIZE 6
#define SW_SHOWMINNOACTIVE 7
#define SW_SHOWNA 8
#define SW_RESTORE 9
#define SW_SHOWDEFAULT 10
#define SW_FORCEMINIMIZE 11
#define SW_MAX 11

#define WPF_SETMINPOSITION 0x0001
#define WPF_RESTORETOMAXIMIZED 0x0002
#if(_WIN32_WINNT >= 0x0500)
#define WPF_ASYNCWINDOWPLACEMENT 0x0004
#endif /* _WIN32_WINNT >= 0x0500 */


返信引用
瀬戸っぷ
 瀬戸っぷ
(@瀬戸っぷ)
ゲスト
結合: 18年前
投稿: 178
 

CreateWindow()の後のコードってどうなっているんでしょうか?
メッセージループに入るまであたりのコードです。

WM_CREATEあたりでブレークポイントで停止して、Spy++などで通知されるメッセージを監
視してみてはどうでしょう?
# ExpressEditionにSpy++がついているかは…ちょっと疑問ですな。
# 英語ですが…下記のツールでもメッセージの監視とかできるようです。
# http://www.windows-spy.com/


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

VS2008を使ってるならメインフレームをCMDIFrameWndExから派生させ、
それらのめんどくさいことを全てやらないというのも、
ひとつの方法です(勝手にやってくれます)。


返信引用
瀬戸っぷ
 瀬戸っぷ
(@瀬戸っぷ)
ゲスト
結合: 18年前
投稿: 178
 

WM_CREATEでSetWindowPlacement()するとうまく行かないようです。
# 最大化状態/最小化状態の場合は復元時のサイズが上書きされてしま模様。
WM_CREATEの後にもOSから様々なメッセージが飛んできますので、その際にどこかが書き
換えられてしまうのでしょう。
ShowWindow()の位置でSetWindowPlacement()すると正しく動作しました。

http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200211/02110063.txt
過去ログにありました……。
# SetWindowPlacementで検索したら見つかった。


返信引用
nfs
 nfs
(@nfs)
ゲスト
結合: 16年前
投稿: 48
Topic starter  

瀬戸っぷさん、仲澤@失業者さん、おかげさまで解決しました!
ウィンドウサイズの保存・復帰って意外に難しいんですね。
大変勉強になりました。

ひょっとして同じことで悩んでいる人がいるかもしれないのでまとめてみました
(過去ログをまとめただけです)
[sdkでのウィンドウサイズの保存と復帰]
[保存時]
WM_CLOSEぐらいで
WINDOWPLACEMENT構造体をGetWindowPlacement()で取得したあと、以下のif文でshowCmdを
変更したあとにファイルやレジストリに保存
(このif文をいれないと、最小化で終了すると、最小化のまま起動します)
if( wp.showCmd == SW_MINIMIZE || wp.showCmd == SW_SHOWMINIMIZED ){
if( wp.flags == WPF_RESTORETOMAXIMIZED ){
wp.showCmd = SW_SHOWMAXIMIZED;
}else{
wp.showCmd = SW_RESTORE;
}
}
[復帰時]
メインウィンドウのCreateWindowEx()の直後にWINDOWPLACEMENT構造体をファイルやレジ
ストリからロードし、SetWindowPlacement()を呼ぶ。このとき、またif文が必要です。
if( WINDOWPLACEMENT構造体が取得できた? ){
// 以前にソフトを起動した事がある時はここを通る
SetWindowPlacement(hWnd, &wp);
}else{
// インストール後、初めてソフトを起動時
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
}


返信引用
nfs
 nfs
(@nfs)
ゲスト
結合: 16年前
投稿: 48
Topic starter  

チェック忘れていました。


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

解決済みですが、別法を見つけましたので記します

WinMain()
{
  HWND hWnd = CreateWindow( WS_OVERLAPPEDWINDOW );
  ShowWindow(hWnd, SW_SHOW); // nCmdShowではありません
}

case WM_CREATE:
if(LoadWp(wp)) // wp:WINDOWPLACEMENT, wpをロードできたら
{
bool maxed = wp.showCmd == SW_SHOWMAXIMIZED;
wp.showCmd = SW_HIDE;
SetWindowPlacement(hWnd, &wp);
if(maxed)
SetWindowLong(hWnd, GWL_STYLE,
GetWindowLong(hWnd, GWL_STYLE) | WS_MAXIMIZE);
}
break;


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

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