15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Как убрать системное меню из приложения свёрнутого в иконку

Существуют два метода, которые позволяют убрать системное меню, которое появляется при клике пользователем по приложению, свёрнутому в иконку:

  1. Переопределить функцию основного фрейма окна PreCreateWindow, чтобы удалить WS_SYSMENU из оконных стилей. Однако, данный метод убирает системное меню когда приложение находится в нормальном состоянии.

  2. Переопределить метод основного фрейма окна OnSize и включить или исключить стиль WS_SYSMENU окна основного фрейма в зависимости от действий пользователя. Данный способ позволяет убрать системное меню когда приложение свёрнуто в иконку и добавить системное меню, когда приложение восстановлено.

Первый метод

Чтобы полностью убрать системное меню из приложения, переопределяем метод основного фрейма окна PreCreateWindow как показано ниже:

   BOOL CMainFrame::PreCreateWindow(CREATESTRUCT & cs)
   {
           // Вызываем PreCreateWindow из базового класса, и в следующей
           // строке заменяем CMDIFrameWnd на CFrameWnd для SDI приложения

           if (!CMDIFrameWnd::PreCreateWindow(cs))
                return FALSE;

          // Убираем бит стиля системного меню из окна

           cs.style &= ~WS_SYSMENU;
           return TRUE;
   } 

Второй метод

Следующие шаги и фрагменты кода показывают, как убрать системное меню когда приложение свёрнуто в иконку и вернуть системное меню, когда приложение восстановлено.

  1. В объявлении класса CMainFrame объявляем public переменную типа BOOLEAN. Эта переменная определяет, разрешено системное меню или нет:
          // В SDI приложении CMainFrame наследуется от CFrameWnd
    
          class CMainFrame : public CMDIFrameWnd
          {
          public:
             BOOL sys_menu_enabled;
                 .
                 .  // Остальные объявления класса
                 .
          } 



  2. Изменяем конструктор CMainFrame, чтобы инициализировать переменную sys_menu_enabled в TRUE:
          CMainFrame::CMainFrame()
          {
            //поумолчанию системное меню разрешено
            sys_menu_enabled = TRUE;
                 .
                 .  // обычный код конструктора, если он есть
                 .
          } 



  3. Воспользуемся визардом (Class Wizard), чтобы создать обработчик сообщения WM_SIZE для класса CMainFrame и добавим следующий код в обработчик сообщения CMainFrame::OnSize:
          void CMainFrame::OnSize(UINT nType, int cx, int cy)
          {
            // объявляем локальную переменную для хранения стиля окна
    
               long window_style;
    
            //вызываем функцию OnSize базового класса,
            //если SDI приложение вызывает CFrameWnd::OnSize()
    
            CMDIFrameWnd::OnSize(nType, cx, cy);
    
            //если пользователь минимизирует приложение
    
            if (nType == SIZE_MINIMIZED)
            {
                 // Получаем стиль основного фрейма окна
                  window_style = GetWindowLong(m_hWnd, GWL_STYLE);
    
                 //Убираем системное меню из оконного стиля
                  window_style &= ~WS_SYSMENU;
    
                 //переключаем булевую переменную, чтобы запретить системное меню
                  sys_menu_enabled = FALSE;
    
                 //Устанавливаем атрибуты стиля для основного фрейма окна
                 SetWindowLong(m_hWnd, GWL_STYLE, window_style);
            }
            else
            {
                 //если пользователь восстанавливает приложение
                 //и его системное меню запрещено,
                 if ((nType == SIZE_RESTORED) || nType == SIZE_MAXIMIZED) &&
                    (!sys_menu_enabled))
                 {
                     window_style = GetWindowLong(m_hWnd, GWL_STYLE);
    
                   //Добавляем системное меню к стилю окна
                     window_style |= WS_SYSMENU;
    
                  //переключаем булевую переменную, чтобы разрешить системное меню
                    sys_menu_enabled = TRUE;
    
                    SetWindowLong(m_hWnd, GWL_STYLE, window_style);
                    SendMessage(WM_NCACTIVATE,TRUE);
                 }
             }
          }