最大化(最小化)で終了時のウィンドウ位置の保存

[戻る]
ナオーバ 2002/11/15(金) 11:07:26
CMainFrame::DestroyWindow()時にGetWindowPlacementで取得する
WINDOWPLACEMENT構造体のlength以外ををレジストリに保存します
CMainFrame::OnCreate()時にレジストリを読み込み
WINDOWPLACEMENT構造体を構築し(lengthは設定しています)
SetWindowPlacementを実行します

問題は最大化 or 最小化で終了した時に元のサイズに戻りません
これ以外の動作は問題ないのです。
終了時のレジストリの値は最大化(最小化)時のサイズではなく、元のサイズです

WINDOWPLACEMENT構造体のflagsで制御すると思うのですが、
どうしていいかわかりません

SetWindowPlacement、GetWindowPlacementだけで制御しているサンプルが
見つけられませんでした、
SetWindowPlacement、GetWindowPlacementだけでは制御できないのでしょうか?

よろしくお願いします
WIN2000 SP2/VC6.0 SP5/MFC使用

dairygoods 2002/11/15(金) 13:22:14
> 問題は最大化 or 最小化で終了した時に元のサイズに戻りません

最大化 or 最小化で終了した場合は、
次の起動時に元のサイズに戻したいということでしょうか?

ナオーバ 2002/11/15(金) 14:15:29
伝わりにくい文章ですみません。

終了時のウィンドウサイズ、位置で起動します。

 最大化(最小化)で終了した場合は最大化(最小化)で起動します。
 ですが起動後「元のサイズに戻す」を行うと元のサイズに戻らないのです。

少し進展しまして、
CMainFrame::OnCreate()内で設定したWINDOWPLACEMENT構造体が
起動後にWINDOWPLACEMENT構造体を取得すると、
OnCreate()内で設定した値と違いました。

まだここまでなので、

よろしくお願いします

くたくた 2002/11/15(金) 14:43:47
[保存]
CMainFrame::OnClose()でやってみて下さい。
(もしかしたらこれは不要かもしれませんが、その時はご了承下さい)

[復元]
C?App::InitInstance()の末端部分でやってみて下さい。
最大化の問題に関しては解決されると思います。
最小化に関しては、SetWindowPlacement()前までに、下記コードを追加してみて下さい。

if( wp.showCmd == SW_MINIMIZE   ||   wp.showCmd == SW_SHOWMINIMIZED ){
   if( wp.flags == WPF_RESTORETOMAXIMIZED ){
       wp.showCmd = SW_SHOWMAXIMIZED;
   }else{
       wp.showCmd = SW_RESTORE;
   }
}
※ wp:WINDOWPLACEMENT型変数

この問題を自己解決するには、相当の時間と運が必要だと思います。
このような対処は不要であるのが当然であり、
尚かつ これに関する記載がドキュメントには無いからです。

EIJI 2002/11/15(金) 15:41:27
保存するとき(OnClose)に以下のようにしてみてください。

WINDOWPLACEMENT wp;
if(GetWindowPlacement(&wp))
{
    if(IsZoomed())
        wp.flags |= WPF_RESTORETOMAXIMIZED;
    保存する関数(&wp);
}

ナオーバ 2002/11/15(金) 15:51:28
ありがとうございます
[復元]部分をC?App::InitInstance()の
 m_pMainWnd->ShowWindow(SW_SHOW)のまえにしました。

最大化・最小化の問題は解決したんですが、
起動時にデフォルトのウィンドウが一瞬表示されてから、
指定サイズのウィンドウが表示されます。

でも何故、CMainFrame::OnCreate()内では駄目で
C?App::InitInstance()ではできるのでしょうか?

CMainFrame::OnCreate()内ではCMainFrameのthisとAfxGetMainWnd()が
同じではないようです。これが原因?

よろしくおねがいします

ナオーバ 2002/11/15(金) 15:59:50
EIJIさんかぶってしまいました

最大化終了時にGetWindowPlacementで取得 flags は 2 でした 
 #define WPF_RESTORETOMAXIMIZED  0x0002
なのであえて行わなくても良いのではないでしょうか?

dairygoods 2002/11/15(金) 16:31:47
OnCreate()の後で、lpCreateStructの値に応じてウィンドウの初期化が行われます。

つまり、OnCreate()中はまだウィンドウを作っている最中であり、
そこでウィンドウの状態を変更してしまうと、
おかしくなってしまうのではないでしょうか?

くたくた 2002/11/15(金) 16:51:56
>起動時にデフォルトのウィンドウが一瞬表示されてから、
>指定サイズのウィンドウが表示されます。
失礼しました、説明不足です。InitInstance()に下記コードを挿入して下さい。

WINDOWPLACEMENT wp;
レジストリからwpを取得;
if( 取得できた? ){
    // 以前にソフトを起動した事がある時はここを通る
    SetWindowPlacement()でwpを設定
}else{
    // インストール後、初めてソフトを起動時
    m_pMainWnd->ShowWindow( SW_SHOW );
    m_pMainWnd->UpdateWindow();
}

>でも何故、CMainFrame::OnCreate()内では駄目で
>C?App::InitInstance()ではできるのでしょうか?
分かりません。当時、「こうすれば何とか動く」事を突き詰めた時点で疲れ果てた為、
諦めました。
又、原因を究明する(技術的な習得)価値が無いと判断したのも理由の一つです。

どうしても追求する必要があるなら、挑戦してみて下さい。

ナオーバ 2002/11/15(金) 17:37:40
何度もありがとうございます。
InitInstance()に提示されたコードを追加しましたがうまくいきません。

起動時にデフォルトのウィンドウが一瞬表示されます

想像ですが、MFC内部でCMainFrame::OnCreate()後に表示していると思います。
これの後すぐにSetWindowPlacementをする為"一瞬表示"されるのでしょう。

もう少し挑戦してみます。

くたくた 2002/11/15(金) 17:57:30
>InitInstance()に提示されたコードを追加しましたがうまくいきません。
またまた失礼しました!
InitInstance()内のProcessShellCommand()前に下記を追加して下さい。

m_nCmdShow = SW_HIDE;

ProcessShellCommand()の前にやるのは、
この関数を呼び出した時にメインウィンドウの表示が行われる為です。

これで大丈夫でしょう!駄目なら言って下さい。

ナオーバ 2002/11/15(金) 18:17:04
[[解決]]
成功しました!!

>ProcessShellCommand()の前にやるのは、
>この関数を呼び出した時にメインウィンドウの表示が行われる為です。
ここで表示しているのを m_nCmdShow = SW_HIDE で表示しないようにしているのですね

ありがとうございました。

古いスレッドには追加発言できません。