Оценка 103
[+2/-0]
Оценить ![]() ![]() ![]() ![]() ![]() ![]()
|
Демонстрационное приложение FullscreenView (30kb)

Приложение FullscreenView
Многие программы умеют изменять свои размеры так, чтобы максимально увеличить размер рабочей области за счет меню, заголовка, панелей управления и строки состояния. Как правило, этот режим включается через меню View->Full Screen.
Причем разные программы делают это по-разному: Developer Studio и Internet Explorer, например, закрывают панель задач, в то время как программы пакета Microsoft Office 2000 оставляют ее на экране. Кроме того, одни MDI-программы увеличивают также и окно активного документа, другие оставляют его как есть.
Самый простой способ заключается в том, чтобы спрятать все панели управления и и изменить размеры окна таким образом, чтобы размеры рабочей области приложения совпали с размерами рабочего стола. Так устроен полноэкранный режим в Developer Studio. К сожалению, в системах с несколькими мониторами это недостаточно. Заголовок, меню и рамка окна вылезут на соседние мониторы и будут торчать там перекрывая нужную информацию.
Решение должно быть более комплексным:
Пример - приложение FullscreenView (MFC MDI) реализует все эти действия.
Запоминаем положение и размеры окна, панелей инструментов и строки состояния:
// Hide the toolbar and the statusbar
if (m_bToolBarWasVisible = m_wndToolBar.IsWindowVisible())
ShowControlBar(&m_wndToolBar, FALSE, FALSE);
if (m_bStatusBarWasVisible = m_wndStatusBar.IsWindowVisible())
ShowControlBar(&m_wndStatusBar, FALSE, FALSE);
// Save the old position and the old size of the main window
GetWindowRect(&m_mainRect);
// Save all styles affected by fullscreenview
m_dwSavedStyles = GetStyle() & (FS_AFFECTED_STYLES | WS_MAXIMIZE);
|
Убираем меню, заголовок и рамку окна:
// Save the Original Menu and set menu to NULL
ASSERT(m_OrgMenu.GetSafeHmenu() == NULL);
CMenu* pOldMenu = GetMenu();
m_OrgMenu.Attach(pOldMenu->Detach());
SetMenu((CMenu*)NULL);
// remove the caption and the frame of the main window
ModifyStyle(FS_AFFECTED_STYLES, 0);
// maximize the main window if need
if (0 == (WS_MAXIMIZE & m_dwSavedStyles))
ShowWindow(SW_MAXIMIZE);
|
Если хочется занять пространство, зарезервированное за панелью задач, следует немного подвинуть наше максимизированное окошко:
int screenx, screeny, screencx, screency;
screenx = screeny = 0;
screencx = ::GetSystemMetrics(SM_CXSCREEN);
screency = ::GetSystemMetrics(SM_CYSCREEN);
MoveWindow(screenx, screeny, screencx, screency);
|
К сожалению, в системах с несколькими мониторами мы переместим окно на основной экран, придется добавить немного кода на такой случай:
int screenx, screeny, screencx, screency;
#if(WINVER >= 0x0500)
if (::GetSystemMetrics(SM_CMONITORS) > 0)
{
typedef HMONITOR (WINAPI * FPMONITORFROMWINDOW)( HWND hwnd, DWORD dwFlags);
typedef BOOL (WINAPI * FPGETMONITORINFO)(HMONITOR hMonitor, LPMONITORINFO lpmi);
MONITORINFO mi;
HMONITOR hm;
FPMONITORFROMWINDOW fpMonitorFromWindow;
FPGETMONITORINFO fpGetMonitorInfo;
HINSTANCE h = ::GetModuleHandle(_T("user32.dll"));
ASSERT(NULL != h);
fpMonitorFromWindow = (FPMONITORFROMWINDOW)GetProcAddress(h, "MonitorFromWindow");
#ifdef _UNICODE
fpGetMonitorInfo = (FPGETMONITORINFO)GetProcAddress(h, "GetMonitorInfoW");
#else
fpGetMonitorInfo = (FPGETMONITORINFO)GetProcAddress(h, "GetMonitorInfoA");
#endif
ASSERT(NULL != fpMonitorFromWindow && NULL != fpGetMonitorInfo);
mi.cbSize = sizeof(MONITORINFO);
hm = fpMonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST);
fpGetMonitorInfo(hm, &mi);
screenx = mi.rcMonitor.left;
screeny = mi.rcMonitor.top;
screencx = mi.rcMonitor.right - screenx;
screency = mi.rcMonitor.bottom - screeny;
}
else
#endif (WINVER >= 0x0500)
{
screenx = screeny = 0;
screencx = ::GetSystemMetrics(SM_CXSCREEN);
screency = ::GetSystemMetrics(SM_CYSCREEN);
}
MoveWindow(screenx, screeny, screencx, screency);
|
И завершающий штрих - маленькая панель с кнопкой для отключения полноэкранного режима:
// this will contain the full-screen off button
// create the new toolbar
ASSERT(!m_pwndFullScreenBar);
m_pwndFullScreenBar = new CToolBar;
m_pwndFullScreenBar->Create(this);
m_pwndFullScreenBar->LoadToolBar(IDR_FULLSCREEN);
m_pwndFullScreenBar->SetBarStyle(m_pwndFullScreenBar->GetBarStyle() |
CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
// to look better:
m_pwndFullScreenBar->ModifyStyle(0, TBSTYLE_FLAT);
m_pwndFullScreenBar->EnableDocking(0);
// place the full-screen off button somewhere:
CPoint pt(screenx + screencx - 64, screeny + 16);
FloatControlBar(m_pwndFullScreenBar, pt);
|
Чтобы вернуть все в изначальный вид слуедует проделать эти действия в обратном порядке:
if (m_pwndFullScreenBar)
{
delete m_pwndFullScreenBar;
m_pwndFullScreenBar = NULL;
}
m_bFullScreenMode = false;
// Restore all affected styles
ModifyStyle(0, m_dwSavedStyles);
// Restore the main window if need
if (0 == (WS_MAXIMIZE & m_dwSavedStyles))
ShowWindow(SW_RESTORE);
MoveWindow(&m_mainRect);
ShowControlBar(&m_wndToolBar, m_bToolBarWasVisible, FALSE);
ShowControlBar(&m_wndStatusBar, m_bStatusBarWasVisible, FALSE);
ASSERT(m_OrgMenu.GetSafeHmenu() != NULL);
SetMenu(&m_OrgMenu);
m_OrgMenu.Detach();
|
Для приложений MDI кроме того необходимо убирать заголовок у дочерних окон:
void CChildFrame::OnMDIActivate(BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd) { CMainFrame* pMainFrame=(CMainFrame*)AfxGetMainWnd(); if(!pMainFrame->m_bFullScreenMode) CMDIChildWnd::OnMDIActivate(bActivate, pActivateWnd, pDeactivateWnd); else if (!bActivate && pDeactivateWnd->GetStyle() & WS_MAXIMIZE) { pDeactivateWnd->ModifyStyle(0, WS_CAPTION); pActivateWnd->ModifyStyle(WS_CAPTION, 0); } } void CChildFrame::OnSize(UINT nType, int cx, int cy) { CMainFrame* pMainFrame=(CMainFrame*)AfxGetMainWnd(); if (pMainFrame->m_bFullScreenMode) { if (SIZE_MAXIMIZED == nType) ModifyStyle(WS_CAPTION, 0, SWP_DRAWFRAME); else ModifyStyle(0, WS_CAPTION, SWP_DRAWFRAME); } CMDIChildWnd::OnSize(nType, cx, cy); } |
Оценка 103
[+2/-0]
Оценить ![]() ![]() ![]() ![]() ![]() ![]()
|