アークピットのホームページに戻る

WinAPIトピックのトップページに戻る

APIトピックの各章に移動する

ダウンロードのページに移動する
ダウンロードができ
ない場合の対処法
 

ページ移動

2-2-8. ウィンドウの位置とサイズの記憶

 アプリケーションでは、終了時にウィンドウを位置とサイズを覚えておき、次ぎに起動した時に、その位置に表示することは良くあります。普通は記憶はレジストリに書き込みます。そして、SetWindowPlacement,GetWindowPlacement 関数でウィンドウ状態の設定や取得を行ないます。

レジストリとは

 Windows 3.1 の頃は、アプリケーションごとに、INIファイルをユーザが用意します。そしてそれに必要な情報を書き込むことで、電源を落としても再現できます。WIN32からレジストリと言う、システムが用意したデータベースに書き込むのが普通の方法です。レジストリは、ツリー状の構造になっており、キーに色々な形式のデータを格納できます。格納する場所はほぼ決まっています。

/HKEY_CURRENT_USER/Software/メーカ名/ソフト名/

 HKEY_CURRENT_USERの下のSoftwareのさらに下に、メーカ名(例えばMicrosoft)のキーを作ります。そして、さらにその下にソフトウェア名のキーを作り、そこをホームホジションにします。例えば以下の様にします。

/HKEY_CURRENT_USER/Software/Arcpit/ApMake/

 この下の構造はソフトごとに決定します。少なければ、直下に作っても良いですし、数が多いようならさらにもう一段キーを作ります。下記の例では以下のパスにデータを設定します。

/HKEY_CURRENT_USER/Software/Arcpit/ApMake/Spec/Position

ウィンドウの位置とサイズの記憶と復帰のコード例


int  APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                      LPTSTR lpCmdLine, int nCmdShow)
{
               : (他のコード)
    if (!RegisterClassEx(&wc)) return FALSE;
    ReadRegistry();
    hAccel = LoadAccelerators(hInstance,S.szAppName);
    S.hWndMain = CreateWindow(pClassName,NULL,
                             WS_OVERLAPPEDWINDOW,
                             S.rcWin.left, S.rcWin.top,
                             S.rcWin.right,S.rcWin.bottom,
                             NULL,NULL,hInstance,NULL);
               : (他のコード)
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg
                                  ,WPARAM wParam,LPARAM lParam)
{
    switch (uMsg)
    {
               : (他のコード)
        case WM_CLOSE:
        {
            WriteRegistry();
            break;
        }
               : (他のコード)
    }
    return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

//
// レジストリ関係の処理
//

static TCHAR szAppKey[] = "Software\\Arcpit\\ApMake";
static LPSTR KeyName[] = {
    "Position",   // Binary RECT   rcWin  sizeof(RECT)
};

static HKEY OpenRegistry(LPSTR lpszSubKey)
{
    TCHAR szBuf[128];
    HKEY  hKey;

    // /HKEY_CURRENT_USER/Software/Arcpit/ApMake/
    if (lpszSubKey)
        wsprintf(szBuf,"%s\\%s",szAppKey,lpszSubKey);
    else
        lstrcpy(szBuf,szAppKey);
    RegCreateKey(HKEY_CURRENT_USER,szBuf,&hKey);
    return hKey;
}

static VOID ReadRegistry(VOID)
{
    DWORD dwType,cbData;
    HKEY  hKey;
    INT   f = 0;

    hKey = OpenRegistry("Spec");
    cbData = sizeof(RECT);
    if (f || !hKey || RegQueryValueEx(hKey,KeyName[0],NULL,&dwType,
                        (LPVOID)&S.rcWin,&cbData) != ERROR_SUCCESS)
    {
        S.rcWin.left   = CW_USEDEFAULT;
        S.rcWin.top    = CW_USEDEFAULT;
        S.rcWin.right  = 320;
        S.rcWin.bottom = 280;
    }
    RegCloseKey(hKey);
}

static VOID WriteRegistry(VOID)
{
    HKEY  hKey;
    WINDOWPLACEMENT wp;

    hKey = OpenRegistry("Spec");
    if (!hKey) return;
    wp.length = sizeof(WINDOWPLACEMENT);
    if (GetWindowPlacement(S.hWndMain,&wp))
    {
        CopyMemory(&S.rcWin,&wp.rcNormalPosition,sizeof(RECT));
        S.rcWin.right  = S.rcWin.right  - S.rcWin.left;
        S.rcWin.bottom = S.rcWin.bottom - S.rcWin.top;
        S.rcWin.left += 2;  // なぜか2ドット左に寄る 98/12/30
        RegSetValueEx(hKey,KeyName[1],0
                     ,REG_BINARY,(LPBYTE)&S.rcWin,sizeof(RECT));
    }
    RegCloseKey(hKey);
}

ページ移動