Russian Qt Forum
Май 03, 2024, 11:51 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: SRC Обработка Windows messages WM_SYSCOMMAND  (Прочитано 3847 раз)
soho
Гость
« : Февраль 19, 2006, 12:04 »

Может кому пригодится:
Фрагмент кода, добавляющего в системное меню окна пункт "Always On Top" ("Поверх остальных окон"). Может быть переделан под обработку любых других сообщений.

Вывод системного меню собровождается сообщением WM_SYSCOMMAND. Перехват этого сообщения и организуем.

В первую очередь, необходимо определить Qt'шный фильтр сообщений (он не определен ни в одном заголовочнике Qt (по крайней мере в Qt 3.3), поэтому сделаем это ручками):
Код:
typedef int ( *QWinEventFilter )( MSG* );
extern Q_EXPORT QWinEventFilter qt_set_win_event_filter( QWinEventFilter );

Код:
  const UINT      MENU_PINUP_ID     = 433973;
  bool            MENU_PINUP_STATE  = false;
  HWND            _hWnd             = NULL;
  HMENU           _hSysMenu         = NULL;
  QWinEventFilter _EventFilter      = NULL;

Устанавливаем наш фильтр:
Код:
  void init( HWND winId, const WCHAR* swzMenuText ) {
   
    _EventFilter = qt_set_win_event_filter( wlogWindowEventFilter );
    _hWnd = winId;

    _hSysMenu = ::GetSystemMenu( _hWnd, FALSE );
    ::RemoveMenu( _hSysMenu, SC_CLOSE, MF_BYCOMMAND );
    ::AppendMenuW( _hSysMenu, MF_STRING | MF_UNCHECKED, MENU_PINUP_ID, swzMenuText );
  }

Код нашего фильтра:
Код:
  int wlogWindowEventFilter( MSG *pMsg ) {
   
    switch( pMsg->message ) {
      case WM_SYSCOMMAND: {
        switch( pMsg->wParam ) {
          case MENU_PINUP_ID:
            onAlwaysOnTop();
            break;
        }
      }
    }

    return _EventFilter ? _EventFilter( pMsg ) : false;
  }

Собственно функция, устанавливающая наше окно поверх остальных:
Код:
  void onAlwaysOnTop() {

    UINT  uCheck    = MF_UNCHECKED;
    HWND  hWndInsertAfter = HWND_NOTOPMOST;

    if( MENU_PINUP_STATE = !MENU_PINUP_STATE ) {
      uCheck    = MF_CHECKED;
      hWndInsertAfter = HWND_TOPMOST;
    }
    ::SetWindowPos( _hWnd, hWndInsertAfter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
    ::CheckMenuItem( _hSysMenu, MENU_PINUP_ID, uCheck );
  }

Как это вызывать:
Код:
  WSysMenu::init( parent->winId(), tr( "Always On Top" ).ucs2());

А это результат:
Обратите внимание, что за счет того, что мы убрали пункт меню "Закрыть" (::RemoveMenu( _hSysMenu, SC_CLOSE, MF_BYCOMMAND )) кнопка закрытия окна тоже стала недоступной.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.046 секунд. Запросов: 20.