Шаг 44.
Библиотека OWL.
Добавление строки состояния

    На этом шаге мы рассмотрим пример программы со строкой состояния.

    Строка сообщения устанавливает отдельную область (обычно в нижней части вашего основного окна) для текста подсказки или других сообщений, которые вы захотите передать пользователю. Строка состояния представляет собой строку сообщения, которая обеспечивает не только возможность отображения сообщения, но и возможность отслеживать статус различных клавиш, включая Num Lock, Caps Lock, Insert. В ряде приложений пользователю очень удобно одним взглядом охватить состояние этих клавиш, поэтому OWL имеет класс TStatusBar, который автоматически выдает эту информацию.

    Как видно из примера, создание строки состояния не многим отличается от создания строки сообщения.

#include <owl\applicat.h>
#include <owl\decframe.h>
#include <owl\controlb.h>
#include <owl\buttonga.h>
#include <owl\statusba.h>
#include <owl\editfile.rh>
#include "pr44_1.rc"

//Класс приложения
class TApp: public TApplication
{
  public:
	 TApp():TApplication(){}
	 void InitMainWindow();
};

//Класс основного окна
class TWndw : public TDecoratedFrame
{
  public:
            TWndw(TWindow *parent, const char far *title, 
            TWindow *client, BOOL trackMenuSelection);
  protected:
	  void CmFileNew();
	  void CmFileOpen();
	  void CmFileSave();
	  void CmMax();
	  void CmRestore();
	  // Переключатели доступности команд.
	  void CmEnableMax (TCommandEnabler &commandEnabler);
	  void CmEnableRestore (TCommandEnabler &commandEnabler);

	  DECLARE_RESPONSE_TABLE(TWndw);
};

DEFINE_RESPONSE_TABLE1 (TWndw, TDecoratedFrame)
	EV_COMMAND(CM_FILENEW, CmFileNew),
	EV_COMMAND(CM_FILEOPEN, CmFileOpen),
	EV_COMMAND(CM_FILESAVE, CmFileSave),
	EV_COMMAND(CM_MAX, CmMax),
	EV_COMMAND(CM_RESTORE, CmRestore),
	EV_COMMAND_ENABLE(CM_MAX, CmEnableMax),
	EV_COMMAND_ENABLE(CM_RESTORE, CmEnableRestore),
END_RESPONSE_TABLE;

TWndw::TWndw(TWindow *parent, const char far *title, 
       TWindow *clientWnd, BOOL trackMenuSelection):
       TDecoratedFrame(parent,title, clientWnd, trackMenuSelection)
{
  TButtonGadget *b;
  TSeparatorGadget *s;
  // Добавить меню к главному окну.
  AssignMenu("MENU_1");
  // Создать новый объект панели инструментов.
  TControlBar *cntrlBar = new TControlBar(this);
  // Добавить приспособления к панели инструментов.
  b = new TButtonGadget(BMP_NEW, CM_FILENEW);
  cntrlBar->Insert(*b);
  b = new TButtonGadget(BMP_OPEN, CM_FILEOPEN);
  cntrlBar->Insert(*b);
  b = new TButtonGadget (BMP_SAVE, CM_FILESAVE);
  cntrlBar->Insert(*b);
  s = new TSeparatorGadget(10);
  cntrlBar->Insert(*s);
  b = new TButtonGadget(BMP_MAX, CM_MAX);
  cntrlBar->Insert(*b);
  b = new TButtonGadget(BMP_RESTORE, CM_RESTORE);
  cntrlBar->Insert(*b);
  s = new TSeparatorGadget(10);
  cntrlBar->Insert (*s);
  b = new TButtonGadget(BMP_EXIT, CM_EXIT);
  cntrlBar->Insert(*b);
  // Установить режим подсказки для команды.
  cntrlBar->SetHintMode(TControlBar::EnterHints);
  // Вставить панель инструментов в окно.
  Insert(*cntrlBar, TDecoratedFrame::Top);
  // Создать новую строку состояния.
  TStatusBar *statBar = new TStatusBar(this, TGadget::Embossed, 
       TStatusBar::CapsLock | TStatusBar::NumLock | TStatusBar::Overtype);
  // Изобразить метку в строке состояния. 
  statBar->SetText("Status");
  // Вставить строку состояния в нижнюю часть окна. 
  Insert(*statBar, TDecoratedFrame::Bottom);
  // Определить расположение и размеры окна.
  Attr.X = 50;
  Attr.Y = 50;
  Attr.W = GetSystemMetrics(SM_CXSCREEN) / 3;
  Attr.H = GetSystemMetrics(SM_CYSCREEN) / 4;
}

// TWndw::CmFileNew()
// Эта функция реагирует на сообщение CM_FILENEW,
// которое генерируется командой New из файлового
// меню или кнопкой NEW.
void TWndw::CmFileNew()
{
  MessageBox ("Выбран пункт FILENEW", "Сообщение",MB_OK);
}

// TWndw::CmFileOpen()
// Эта функция реагирует на сообщение CM_FILEOPEN,
// которое генерируется командой Open из файлового
// меню или кнопкой OPEN.
void TWndw::CmFileOpen()
{
  MessageBox ("Выбран пункт FILEOPEN", "Сообщение",MB_OK);
}

// TWndw::CmFileSave()
// Эта функция реагирует на сообщение CM_FILESAVE,
// которое генерируется командой Save из файлового
// меню или кнопкой SAVE.
void TWndw::CmFileSave()
{
  MessageBox ("Выбран пункт FILESAVE", "Сообщение",MB_OK);
}

//TWndw::CmRestore()
// Эта функция реагирует на сообщение СМ_RESTORE, которое
// генерируется кнопкой RES панели управления.
void TWndw::CmRestore()
{
  // Послать системное сообщение для восстановления размеров окна.
  SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0);
}


//TWndw::CmMax()
// Эта функция реагирует на сообщение СМ_МAХ, которое
// генерируется кнопкой МАХ панели управления.
void TWndw::CmMax()
{
  // Послать системное сообщение для максимизации окна.
  SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0);
}

//TWndw::CmEnableMax()
// Эта функция является переключателем доступности
// кнопки MAX панели управления.
void TWndw::CmEnableMax (TCommandEnabler &commandEnabler)
{
  // Разблокировать кнопку MAX, если окно не
  // максимизировано; в противном случае
  // заблокировать кнопку MAX.
  commandEnabler.Enable(!IsZoomed());
}

//TWndw::CmEnableRestore()
// Эта функция является переключателем доступности
// кнопки RES панели управления.
void TWndw::CmEnableRestore(TCommandEnabler &commandEnabler)
{
  // Разблокировать кнопку RES, если окно
  // максимизировано; в противном случае
  // заблокировать кнопку RES.
  commandEnabler.Enable(IsZoomed());
}

void TApp::InitMainWindow()
{
  // Окно TDecoratedFrame должно иметь окно-клиент.
  TWindow *client = new TWindow (0,0,0);
  // Сконструировать главное окно.
  TDecoratedFrame *wndw= new TWndw(0,"Создание строки состояния",client,TRUE);
  // Установить значение указателя MainWindow приложения.
  SetMainWindow(wndw);
}

int OwlMain(int,char *[])
{
  return TApp().Run();
}

    Файл ресурсов:

#ifndef WORKSHOP_INVOKED
#include "windows.h"
#endif

#include <owl\editfile.rh>

#define BMP_NEW       1
#define BMP_OPEN      2
#define BMP_SAVE      3
#define BMP_MAX       4
#define BMP_RESTORE   5
#define BMP_EXIT      6
#define CM_FILESAVE   24333
#define CM_EXIT       24310
#define CM_FILEOPEN   24332
#define CM_FILENEW    24331
#define CM_MAX        201
#define CM_RESTORE    202

#ifdef RC_INVOKED

MENU_1 MENU
{
  POPUP "&File"
  {
	  MENUITEM "&New...",  CM_FILENEW
	  MENUITEM "&Open...", CM_FILEOPEN
	  MENUITEM "&Save...", CM_FILESAVE
	  MENUITEM SEPARATOR
	  MENUITEM "E&xit",    CM_EXIT
  }
}


BMP_NEW  BITMAP  "100131.bmp"
BMP_OPEN BITMAP "100143.bmp"
BMP_SAVE BITMAP "100144.bmp"
BMP_MAX BITMAP "100156.bmp"
BMP_RESTORE BITMAP "100130.bmp"
BMP_EXIT BITMAP "100139.bmp"

STRINGTABLE
{
  CM_MAX, "Развернуть окно на весь экран"
  CM_RESTORE, "Вернуть окно к нормальному размеру"
}

#endif
Текст этого приложения вместе с файлами рисунков можно взять здесь.

    Результат работы приложения:


Рис.1. Результат работы приложения

    При запуске этой программы вы увидите окно, показанное на рисунке 1. Теперь главное окно приложения содержит строку состояния, а не строку сообщения, поэтому оно может не только отобразить текст подсказки, но и показать статус различных клавиш клавиатуры, в данном случае Caps Lock, Num Lock и Insert. Если пользователь переключит режим любой ио этих клавиш, строка состояния изменится, чтобы показать новый статус клавиши. Если клавиша отключена, строка состояния ничего не покажет. Если клавиша включена, строка состояния отображает индикатор клавиши в соответствующем окне строки состояния.

    Кроме замены строки сообщения на строку состояния, в этой версии программа показывает подсказку для команды только тогда, когда кнопка нажата. Это различие обеспечивается установкой значения PressHints режима подсказки инструментальной линейки:

    cntrlBar->SetHintMode(TGadgetWindow::PressHints);

    Программа создает строку состояния при обращении к конструктору класса TStatusBar:

  TStatusBar *statBar = new TStatusBar(this, TGadget::Embossed, 
       TStatusBar::CapsLock | TStatusBar::NumLock | TStatusBar::Overtype);

    Очевидно, этот конструктор более сложный по сравнению с конструктором строки сообщения, он имеет пять аргументов, а не три, как показано в предыдущем фрагменте программы. Первый аргумент - это указатель на родительское окно строки состояния. Второй аргумент - это тип обрамления строки состояния, который может принимать значения:

    Третий аргумент определяет, для какой клавиши или режима строка состояния будет отображать информацию. Он может иметь значения:

    Вы логически складываете эти величины, чтобы получить одно беззнаковое целое число, содержащее битовые флаги для индикаторов режима, который вы хотите отобразить в строке состояния.

    Четвертый и пятый аргументы являются указателями на TGadgetWindowFont и TLibId. Все пять аргументов имеют заданные по умолчанию значения, поэтому вам совсем не нужно устанавливать их. В предыдущем примере требовались только три первых аргумента.

    После конструирования строки состояния программа устанавливает заглавие строки состояния:

    statBar->SetText("Status");

    Наконец, программа добавляет строку состояния к главному окну, вызывая функцию Insert() окна:

    Insert(*statBar, TDecoratedFrame::Bottom);

    Со следующего шага мы начнем знакомиться с созданием MDI-приложений.




Предыдущий шаг Содержание Следующий шаг