Сообщений 3 Оценка 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); } |
Сообщений 3 Оценка 103 [+2/-0] Оценить |