Last Updated 2004/10/22
Programming Tips Visual C++ MFC ウィンドウ  索 引 
フルスクリーンなウィンドウ(その2)
2004/10/22

WindowsNT3.51 の頃にフルスクリーンを実現させるには,

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    cs.style = WS_POPUP | WS_VISIBLE;
    cs.hMenu = NULL;

    return CFrameWnd::PreCreateWindow(cs);
}

とすればよかったが,Windows95/NT4.0 では無理である.
周囲に細い枠がついてしまう.


それでは,以下のようにしてみよう.
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    cs.dwExStyle &= ~WS_EX_WINDOWEDGE;
    cs.dwExStyle &= ~WS_EX_CLIENTEDGE;

    return CFrameWnd::PreCreateWindow(cs);
}

これだけでは無理である.
MFC のソースを見てみると,

BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT& cs)
{
    if (cs.lpszClass == NULL)
    {
        if (!AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG))
            return FALSE;

        cs.lpszClass = _afxWndFrameOrView;  // COLOR_WINDOW background
    }

    if ((cs.style & FWS_ADDTOTITLE) && afxData.bWin4)
        cs.style |= FWS_PREFIXTITLE;

    if (afxData.bWin4)
        cs.dwExStyle |= WS_EX_CLIENTEDGE;

    return TRUE;
}

となっており,強制的に WS_EX_CLIENTEDGE がついてしまう.
(これが細い枠がついてしまう原因である)

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    CFrameWnd::PreCreateWindow(cs);

    cs.style = WS_POPUP | WS_VISIBLE;
    cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
    cs.hMenu = NULL;

    return TRUE;
}

こうして,CFrameWnd::PreCreateWindows() を先に呼ぶとフルスクリーンウィンドウを作成できる.
CView もデフォルトでは WS_BORDER が付いているので,こちらも修正する必要がある.

BOOL CTestView::PreCreateWindow(CREATESTRUCT& cs)
{
    cs.style &= ~WS_BORDER;

    return CView::PreCreateWindow(cs);
}

しかし,これは現状の MFC の仕組みを利用したのであり,将来的に安全である保障はどこにもない.

MSJ日本語版 No.40 にタイトルバーを付けたままフルスクリーンにする方法が書かれている.(フルスクリーン化と共にタイトルバー上でのダブルクリックによるウィンドウサイズのリストアを防ぐ方法など)
(No.40 と No.42 をあわせて読むとためになる)


以下の様にすると真っ白の画面を覆うことができる.


BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    cs.x = 0;
    cs.y = 0;
    cs.cx = GetSystemMetrics(SM_CXSCREEN);
    cs.cy = GetSystemMetrics(SM_CYSCREEN);
    if( cs.hMenu ) {
        ::DestroyMenu(cs.hMenu);
    }
    cs.hMenu = NULL;
    if( cs.style & WS_THICKFRAME ) {
        cs.style &= ~WS_THICKFRAME;
    }

    return CFrameWnd::PreCreateWindow(cs);
}


int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;

    // キャプションを消す
    DWORD dwStyle = GetWindowLong(this->m_hWnd, GWL_STYLE);
    if( dwStyle & WS_CAPTION ) {
        dwStyle &= ~WS_CAPTION;
    }
    SetWindowLong(this->m_hWnd, GWL_STYLE, dwStyle);

    // エッジを無くす
    DWORD dwExStyle = GetWindowLong(this->m_hWnd, GWL_EXSTYLE);
    dwExStyle &= ~WS_EX_WINDOWEDGE;
    dwExStyle &= ~WS_EX_CLIENTEDGE;
    SetWindowLong(this->m_hWnd, GWL_EXSTYLE, dwExStyle);

    // 以下の6番目の引数の組み合わせは任意
    SetWindowPos( NULL,
                  0,
                  0,
                  0,
                  0,
                  SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED
                  );
    return 0;
}


int CMyView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    if (CView::OnCreate(lpCreateStruct) == -1)
        return -1;

    // ここでもエッジを消す
    DWORD dwExStyle = GetWindowLong(this->m_hWnd, GWL_EXSTYLE);
    dwExStyle &= ~WS_EX_WINDOWEDGE;
    dwExStyle &= ~WS_EX_CLIENTEDGE;
    SetWindowLong(this->m_hWnd, GWL_EXSTYLE, dwExStyle);

    return 0;
}


参照
フルスクリーンなウィンドウ
前後のTips
フルスクリーンなウィンドウ(その2)

DSS ProgrammingTipsCGI Ver2.02