Microsoft Visual C++ и MFC. Программирование для Win95 и WinNT

       

Приложение Status


Создайте новый проект под названием Status. В качестве типа приложения выберите из списка Type строку Application. Настройте проект Status, указав, что приложение будет работать с библиотекой классов MFC.

Наберите в редакторе исходный текст приложения и сохраните его в файле Status.cpp (листинг 3.13). Включите готовый файл DialogBar.cpp в проект.

Листинг 3.13. Файл Status.cpp

//============================================================

// Приложение Status

// (c) Frolov G.V., 1996

// E-mail: frolov@glas.apc.org

//============================================================

// Включаемые файлы для MFC

#include <afxwin.h>

#include <afxext.h>

#include <afxcmn.h>

// Включаемый файл для ресурсов приложения и идентификаторов

#include "resource.h"

//============================================================

// Класс CStateApp - главный класс приложения

//============================================================

class CStateApp : public CWinApp

{

public:

   // Мы будем переопределять метод InitInstance,

   // предназначенный для инициализации приложения

   virtual BOOL InitInstance();

};

 

// Создаем объект приложение класса CStateApp

CStateApp StateApp;

 

//============================================================

// Класс CStateWindow - представляет главное окно

//============================================================

class CStateWindow : public CFrameWnd

{

protected: 

   CStatusBar  m_wndStatusBar;   // Панель состояния

   BOOL  bIndicatorTEXT;         // Флаг для управления

                                 // индикатором

                                 // ID_INDICATOR_TEXT

    

protected:

   // Метод для создания окна приложения и панели состояния

   afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

public:

   // Объявляем конструктор класса CStateWindow

   CStateWindow();

   // Объявляем методы для обработки команд меню

   afx_msg BOOL OnMenuDirectADD_SUB(UINT nID);


   afx_msg void OnMenuProcessBar();

   afx_msg void OnMenuDisableADD_SUB();

   afx_msg void OnMenuSwitchTEXT();

   afx_msg void OnMenuExit();

  

   // Метод для обработки команды ON_UPDATE_COMMAND_UI

   // от индикатора ID_INDICATOR_TEXT

   afx_msg void OnUpdateTEXT(CCmdUI* pCmdUI);

  

   // Макрокоманда необходима, так как класс

   // CStateWindow обрабатывает сообщения

   DECLARE_MESSAGE_MAP()   

};

//============================================================

// Таблица сообщений класса CStateWindow

//============================================================

BEGIN_MESSAGE_MAP(CStateWindow, CFrameWnd)

  

   // Макрокоманда вызывает метод OnCreate

   ON_WM_CREATE()

   // Обработчик сообщения ON_UPDATE_COMMAND_UI

   ON_UPDATE_COMMAND_UI(ID_INDICATOR_TEXT, OnUpdateTEXT)

  

   // Обработчики команд меню Work

   ON_COMMAND(ID_WORK_PROCESS, OnMenuProcessBar)

   ON_COMMAND(ID_WORK_DISABLE_ADDSUB, OnMenuDisableADD_SUB)

   ON_COMMAND(ID_WORK_ON_SWITCH_TEXT, OnMenuSwitchTEXT)

  

   ON_COMMAND_EX(ID_WORK_DIRECT_ADD, OnMenuDirectADD_SUB)

   ON_COMMAND_EX(ID_WORK_DIRECT_SUB, OnMenuDirectADD_SUB)

   ON_COMMAND(ID_WORK_EXIT, OnMenuExit)

  

END_MESSAGE_MAP()

//============================================================

// Индикаторы панели управления. Порядок идентификаторов

// соответствует порядку индикаторов в панели состояния

// (до тех пор, пока он не изменен методом SetPaneInfo)

//============================================================

static UINT indicators[] =

{

   ID_SEPARATOR,           // Самый первый индикатор

   ID_INDICATOR_OVR,       // Индикатор OVR

   ID_INDICATOR_PROGRESS,  // Резервирование места для

                           // progress bar

   ID_INDICATOR_CAPS,      // Индикатор клавиши <Caps Lock>

   ID_INDICATOR_NUM,       // Индикатор клавиши <Num Lock>

   ID_INDICATOR_SCRL,      // Индикатор клавиши <Scroll Lock>

   ID_INDICATOR_TEXT,      // Индикатор TEXT/PIC



   ID_INDICATOR_ADD,       // Индикатор ADD/SUB (начальное

                           // состояние START)

};

//============================================================

// Метод InitInstance класса CStateApp

// Создает главное окно приложения и отображает его на экране

//============================================================

BOOL CStateApp::InitInstance()

{

   m_pMainWnd = new CStateWindow();

   m_pMainWnd -> ShowWindow(m_nCmdShow);

   m_pMainWnd -> UpdateWindow();

   return TRUE;

}

//============================================================

// Конструктор класса CStateWindow

//============================================================

CStateWindow::CStateWindow()

{

   // Создаем окно приложения, соответствующее

   // данному объекту класса CStateWindow

   Create(NULL, "Status Bar Sample", WS_OVERLAPPEDWINDOW,

      rectDefault, NULL, MAKEINTRESOURCE(IDR_MENU));

  

   // Устанавливаем значение флага bIndicatorTEXT

   bIndicatorTEXT = TRUE;

}

//============================================================

// Метод OnMenuProcessBar класса CStateWindow

//============================================================

void CStateWindow::OnMenuProcessBar()

{

    // Определяем координаты индикатора ID_INDICATOR_PROGRESS

    RECT rectProgress;

   

    m_wndStatusBar.GetItemRect(

       m_wndStatusBar.CommandToIndex(ID_INDICATOR_PROGRESS),

         &rectProgress);

   // Создаем полосу progress bar. Размещаем ее

   // на месте индикатора ID_INDICATOR_PROGRESS

   CProgressCtrl ctrlProgressBar;

   if(!ctrlProgressBar.Create(WS_CHILD | WS_VISIBLE,

                          rectProgress, &m_wndStatusBar, 1))

   {

      // Ошибка при создании progress bar

      TRACE0("Failed to create progress bar\n");

      return;

   }

   // Устанавливаем границы для progress bar

   ctrlProgressBar.SetRange(0, 100);

   // Устанавливаем шаг приращения для progress bar



   ctrlProgressBar.SetStep(1);

 

   // Плавно увеличиваем положение progress bar

   for(int i=0;i<100;i++)

   {

      // Выполняем короткую задержку

      Sleep(10);

     

      // Выполняем шаг приращения progress bar

      ctrlProgressBar.StepIt();

   }

  

   // По завершении, отображаем текст в самом первом

   // индикаторе панели состояния

   m_wndStatusBar.SetWindowText("Process completed");

}

//============================================================

// Метод OnMenuDirectADD_SUB класса CStateWindow

//============================================================

BOOL  CStateWindow::OnMenuDirectADD_SUB(UINT nID)

{

   // Определяем индекс индикатора ID_INDICATOR_ADD

   int nIndex =

          m_wndStatusBar.CommandToIndex(ID_INDICATOR_ADD);

   // Устанавливаем нормальный режим отображения индикатора

   m_wndStatusBar.SetPaneStyle(nIndex, SBPS_NORMAL);

   // Из меню Work выбрана строка Direct set ADD

   if(nID == ID_WORK_DIRECT_ADD)

   {

      // Выводим текст ADD

      m_wndStatusBar.SetPaneText(nIndex, "ADD");

   }

   // Из меню Work выбрана строка Direct set SUB

   else if(nID == ID_WORK_DIRECT_SUB)

   {

      // Изменяем внешний вид индикатора

      m_wndStatusBar.SetPaneStyle(nIndex, SBPS_POPOUT);

      // Выводим текст SUB

      m_wndStatusBar.SetPaneText(nIndex, "SUB");

   }

   return TRUE;

}  

//============================================================

// Метод OnMenuDisableADD_SUB класса OnMenuDisableADD_SUB

//============================================================

void CStateWindow::OnMenuDisableADD_SUB()

{

   // Определяем индекс индикатора ID_INDICATOR_ADD  

   int nIndex =

          m_wndStatusBar.CommandToIndex(ID_INDICATOR_ADD);

  

   // Блокируем индикатор

   m_wndStatusBar.SetPaneStyle(nIndex, SBPS_DISABLED);

}  

//============================================================

// Метод OnUpdateTEXT класса CStateWindow



//============================================================

void CStateWindow::OnMenuSwitchTEXT()

{

   // Изменяем состояние флага bIndicatorTEXT,

   // который используется методом OnUpdateTEXT

   bIndicatorTEXT = !bIndicatorTEXT;

}

//============================================================

// Метод OnMenuExit класса CStateWindow

//============================================================

void CStateWindow::OnMenuExit()

{

   // Завершаем приложение

   DestroyWindow();

   return;

}

//============================================================

// Метод OnCreate класса CStateWindow

// Вызывается во время создания окна приложения

//============================================================

int CStateWindow::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

   // Вызываем метод OnCreate базового класса

   if(CFrameWnd::OnCreate(lpCreateStruct) == -1)

      return -1;

  

   // Создаем панель состояния

   if(!m_wndStatusBar.Create(this))

   {

      // Ошибка при создании панели состояния

      TRACE0("Failed to create status bar\n");

      return -1;  

   }

   // Отображаем индикаторы панели состояния

   if(!m_wndStatusBar.SetIndicators(indicators,

                         sizeof(indicators)/sizeof(UINT)))

   {

      // Ошибка при установке индикаторов

      TRACE0("Failed to set indicators\n");

      return -1;  

   }

  

   // Устанавливаем характеристики индикатора

   // ID_INDICATOR_PROGRESS

   m_wndStatusBar.SetPaneInfo(

      m_wndStatusBar.CommandToIndex(ID_INDICATOR_PROGRESS),

      ID_INDICATOR_PROGRESS,

      SBPS_DISABLED |   // Текст не отображается

      SBPS_NOBORDERS,   // Рамка вокруг индикатора отсутствует

      150 );            // Ширина индикатора 150 пикселов

   return 0;

}

//============================================================

// Метод OnUpdateTEXT класса CStateWindow

// Обрабатывает сообщение ON_UPDATE_COMMAND_UI

// от индикатора ID_INDICATOR_TEXT



//============================================================

void CStateWindow::OnUpdateTEXT(CCmdUI* pCmdUI)

{

   // В зависимости от состояния флага bIndicatorTEXT

   // отображаем в индикаторе ID_INDICATOR_TEXT

   // строку TEXT или PIC

   if(bIndicatorTEXT)

      pCmdUI->SetText("TEXT"); // отображаем строку TEXT

   else

      pCmdUI->SetText("PIC");  // отображаем строку PIC

   // Разрешаем отображение текста в индикаторе

   pCmdUI->Enable();

}

Создайте новый файл ресурсов и включите его в проект под именем Status.rc. Включите в него меню, присвоив ему идентификатор IDR_MENU. Введите строки меню IDR_MENU в соответствии с представленным нами файлом ресурсов (листинг 3.14). Для всех строк меню введите их описания. Они будут записаны в файл ресурсов как строковые ресурсы, имеющие одинаковые идентификаторы со строками меню.

Добавьте в файл ресурсов строку Ready, выбрав для нее идентификатор AFX_IDS_IDLEMESSAGE. Эта строка будет отображаться в панели состояния во время “бездействия” приложения.

Добавьте в файл ресурсов строки, представляющие индикаторы панели состояния: ID_INDICATOR_ADD, ID_INDICATOR_PROGRESS и ID_INDICATOR_TEXT.

Листинг 3.14. Файл Status.rc

//Microsoft Developer Studio generated resource script.

//

#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS

//////////////////////////////////////////////////////////////

//

// Generated from the TEXTINCLUDE 2 resource.

//

#include "afxres.h"

//////////////////////////////////////////////////////////////

#undef APSTUDIO_READONLY_SYMBOLS

//////////////////////////////////////////////////////////////

// Russian resources

#if !defined(AFX_RESOURCE_DLL) defined(AFX_TARG_RUS)

#ifdef _WIN32

LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT

#pragma code_page(1251)

#endif //_WIN32

#ifdef APSTUDIO_INVOKED

//////////////////////////////////////////////////////////////

//

// TEXTINCLUDE



//

1 TEXTINCLUDE DISCARDABLE

BEGIN

    "resource.h\0"

END

2 TEXTINCLUDE DISCARDABLE

BEGIN

    "#include ""afxres.h""\r\n"

    "\0"

END

3 TEXTINCLUDE DISCARDABLE

BEGIN

    "\r\n"

    "\0"

END

#endif    // APSTUDIO_INVOKED

//////////////////////////////////////////////////////////////

//

// Menu

//

IDR_MENU MENU DISCARDABLE

BEGIN

    POPUP "Work"

    BEGIN

        MENUITEM "Process",          ID_WORK_PROCESS

        MENUITEM "Direct set ADD",   ID_WORK_DIRECT_ADD

        MENUITEM "Direct set SUB",   ID_WORK_DIRECT_SUB

        MENUITEM "Disable ADD SUB",  ID_WORK_DISABLE_ADDSUB

        MENUITEM "Switch TEXT",      ID_WORK_ON_SWITCH_TEXT

        MENUITEM SEPARATOR

        MENUITEM "Exit",             ID_WORK_EXIT

    END

END

//////////////////////////////////////////////////////////////

//

// String Table

//

STRINGTABLE DISCARDABLE

BEGIN

    ID_INDICATOR_ADD        "START"

END

STRINGTABLE DISCARDABLE

BEGIN

    ID_INDICATOR_PROGRESS   "neve display"

    ID_INDICATOR_TEXT       "TEXT"

END

STRINGTABLE DISCARDABLE

BEGIN

    ID_WORK_PROCESS         " Display and play progress bar"

    ID_WORK_DIRECT_ADD      "Set indicator ID_INDICATOR_ADD

                             to ADD"

    ID_WORK_ON_SWITCH_TEXT  "Switch text in indicator

                             ID_INDICATOR_TEXT"

    ID_WORK_DIRECT_SUB      "Set indicator ID_INDICATOR_ADD

                             to SUB"

    ID_WORK_DISABLE_ADDSUB  "Disable indicator

                             ID_INDICATOR_ADD"

    ID_WORK_EXIT            "Exit application"

END

STRINGTABLE DISCARDABLE

BEGIN

    AFX_IDS_IDLEMESSAGE     "Ready"

END

#endif    // Russian resources



//////////////////////////////////////////////////////////////

#ifndef APSTUDIO_INVOKED

//////////////////////////////////////////////////////////////

//

// Generated from the TEXTINCLUDE 3 resource.

//

//////////////////////////////////////////////////////////////

#endif    // not APSTUDIO_INVOKED

Идентификаторы ресурсов приложения Status определены в файле resource.h. Этот файл создается автоматически редактором ресурсов Microsoft Visual C++. Исходный текст файла resource.h представлен в листинге 3.15.

Листинг 3.15. Файл resource.h

//{{NO_DEPENDENCIES}}

// Microsoft Developer Studio generated include file.

// Used by Status.rc

//

#define ID_INDICATOR_ADD                1

#define IDR_MENU                        101

#define ID_INDICATOR_PROGRESS           102

#define ID_INDICATOR_TEXT               103

#define ID_WORK_PROCESS                 40001

#define ID_WORK_DIRECT_ADD              40006

#define ID_WORK_ON_SWITCH_TEXT          40007

#define ID_WORK_DIRECT_SUB              40008

#define ID_WORK_DISABLE_ADDSUB          40009

#define ID_WORK_EXIT                    40010

#define ID_TIMER_CHECK                  0xE001

// Next default values for new objects

//

#ifdef APSTUDIO_INVOKED

#ifndef APSTUDIO_READONLY_SYMBOLS

#define _APS_NEXT_RESOURCE_VALUE        106

#define _APS_NEXT_COMMAND_VALUE         40011

#define _APS_NEXT_CONTROL_VALUE         1000

#define _APS_NEXT_SYMED_VALUE           104

#endif

#endif

Постройте приложение Status и запустите его. На экране появится главное окно приложения, в нижней части которого отображается панель состояния (рис. 3.23).



Рис. 3.23. Приложение Status

В панели состояния расположены несколько индикаторов. Самый первый индикатор, размер которого зависит от размера окна приложения, отображает подсказку о выбранной строке меню приложения или системного меню, а если приложение “бездействует” в нем отображается строка Ready.

Следующий индикатор OVR. В нашем приложении он не действует. Вы сами можете разработать программный код для управления этим индикатором.



Вслед за идентификатором OVR следует свободное пространство, занятое индикатором. Этот индикатор не отображается на панели и предназначен только для резервирования места под линейный индикатор progress bar.

Если вы выберите из меню Work строку Process, то на этом месте появится линейный индикатор, плавно меняющий свое значение. Мы используем линейный индикатор, чтобы отображать ход какого-нибудь длительного процесса.

После того, как линейный индикатор покажет окончание процесса, он будет удален с панели состояния, а в самом первом индикаторе появится надпись Process completed.

Затем в панели состояния следуют три стандартных индикатора CAP, NUM и SCRL, которые отображают текущее состояние клавиш <Caps Lock>, <Num Lock> и <Scroll Lock>.

Следующий индикатор, который мы рассмотрим, называется TEXT. Если вы выберите из меню Work строку Switch TEXT, то надпись TEXT в индикаторе заменится на PIC. Повторный выбор данной строки меню восстановит предыдущее состояние индикатора.

Последний индикатор в панели состояния START. Этот индикатор управляет тремя строками меню Work. При выборе строки Direct set ADD в индикаторе отображается строка ADD, а при выборе строки Direct set SUB - SUB. Во втором случае также меняется оформление индикатора. Если вы выберите из меню Work строку Disable ADD SUB, то индикатор будет заблокирован.


Содержание раздела