Глава 6. Обзор классов окон библиотеки MFC
- Создание и уничтожение Windows-окон
- Методы инициализации
- Методы управления состоянием окна
- Методы управления размером и положением окна
- Методы взаимодействия Windows-окон
- Методы управления текстом окна
- Панель выбора цвета (класс CColorDialog)
- Панель выбора файлов (класс CFileDialog)
- Панель выбора шрифта (класс CFontDialog)
- Панель для вывода документов на печать (класс CPrintDialog)
- Панель для выполнения поиска и замены (класс CFindReplaceDialog)
Очень много объектов, рассматриваемых в предыдущих главах, связаны с Windows-окнами. К ним прежде всего относятся облики и диалоги - объекты классов
CView и CDialog и их производные. Элементы управления (окна редактирования, списки, кнопки и др.) - тоже связаны с окнами, изображающими их на экране. Существующий практически в каждом приложении объект главное окно-рамка тоже представлен на экране Windows-окном - главным окном приложения . Классы всех этих объектов являются производными от класса CWnd . Он-то и обеспечивает отображение окна на экране и работу с ним.Объекты класса CWnd и Windows-окна
Рассмотрим взаимоотношения объектов класса
CWnd с Windows-окнами. Хотя объекты класса CWnd и производных от него классов (оконные объекты) не тождественны Windows-окнам, они связаны настолько тесно, что такое отождествление вполне оправдано. Windows-окно - объект операционной системы Windows - это внутренняя структура данных операционной системы, с которой связано изображение на экране в виде окна-прямоугольника со специальными элементами и областями. Эта структура обеспечивает управление окном на экране и реакцию на воздействие пользователя на окно . В смысле объектно-ориентированного программирования она во многом подобна классу и имеет метод - функцию окна . Однако эта структура не является, конечно же, структурой какого-либо языка программирования, поэтому Windows-окно не является объектом в смысле языка C++. Дескриптор (handle) Windows-окна просто идентифицирует его при вызове функций API, предназначенных для работы с Windows-окнами.Оконный объект
- это объект в смысле языка C++, который служит для работы с Windows-окном. Его переменная m_hWnd задает определитель (handle) Windows-окна, прикрепленного (attached) к данному оконному объекту. Создание оконного объекта состоит из двух этапов: создания самого объекта и создания и прикрепления Windows-окна к оконному объекту или прикрепление к оконному объекту уже существующего Windows-окна. Оконный объект может использоваться приложением для управления экранным образом (окном на экране) прикрепленного Windows-окна . При этом само Windows-окно становится "прозрачным", т.е. не фигурирует при вызове соответствующих методов.Оконный объект использует большое количество функций API, предназначенных для работы с окнами. Например, метод
MoveWindow передвигает и изменяет размер окна на экране:wnd.MoveWindow(x, y, width, height, rep);
При вызове этого метода его реализация на самом деле использует API-функцию
BOOL MoveWindow( HWND hWnd, // дескриптор Windows-окна int X, // позиция по горизонтали int Y, // позиция по вертикали int nWidth, // ширина int nHeight, // высота BOOL bRepaint); // признак перерисовки
Функция API вызываетcя со значением первого параметра, равным дескриптору Windows-окна, прикрепленного к оконному объекту.
Таким образом, оконный объект как бы содержит в себе Windows-окно и предоставляет для работы с ним методы в смысле языка C++. О классе CWnd оконных объектов говорят, что он является классом-оболочкой для Windows-окон.
Ранее уже упоминалось об оконном объекте - облике (класс CView ). Прикрепленное к облику Windows-окно служит для отображения документа на экране. Однако окно облика никогда не появляется на экране без окна другого объекта - окна- рамки . Окно-рамка (класс CFrameWnd ) - объект производного от CWnd класса - координирует взаимодействие приложения с документом и его обликом. Прикрепленное к нему Windows-окно представлено в виде рамки, внутри которого находится окно облика. На экране они выглядят как одно целое, но на самом деле они прикреплены к разным объектам. Рамка имеет нестандартные элементы управления окна: полосу заголовка, меню, кнопки минимизации и максимизации, элементы управления размерами окна. Рамка также может иметь строку статуса и панель инструментов. Окно облика, наоборот, не имея элементов управления (они сосредоточены у рамки), является рабочей областью, в которой облик строит приложение.
Любое Windows-окно имеет две области: клиентскую область , изображение в которой задается приложением, и системную область , состоящую из управляющих элементов. Таким образом, окно-рамка задает Windows-окно, использующее только свою системную область, а облик задает Windows-окно, использующее только свою клиентскую область. Windows-окно, прикрепленное к облику, является дочерним (child) по отношению к Windows-окну, прикрепленному к соответствующему объекту окно-рамка. Это, в частности, означает, что дочернее окно нельзя передвинуть за пределы клиентской области родительского окна.
Число методов класса CWnd очень велико, с ними можно ознакомится при помощи справочной системы Visual C++. Остановимся подробнее только на некоторых из них.
Некоторые методы класса CWnd
Создание и уничтожение Windows-окон
CWnd();
Создает объект класса CWnd, обеспечивающий доступ к Windows-окну. При этом само Windows-окно не создается. Далее можно либо создать новое Windows-окно и закрепить его за данным оконным объектом, либо закрепить уже имеющееся Windows-окно. Первое достигается методами
CreateEx и Create , второе - методом Attach .virtual BOOL DestroyWindow();
Уничтожает Windows-окно, закрепленное за объектом класса
CWnd . Если окно уничтожено успешно, возвращается ненулевое значение, в противном случае - 0. После выполнения этого метода оконный объект уже не имеет закрепленного за ним Windows-окна. Сам оконный объект при этом не уничтожается. Метод DestroyWindow посылает соответствующие сообщения, чтобы уничтожить окно и связанные с ним ресурсы. Оно также уничтожает дочерние окна и, если требуется, информирует родительское окно.Методы иниц иализации
Методы создания Windows-окон обсуждаться не будут, так как при работе со многими классами окна (к которым относятся и элементы управления) создаются каркасом прилржения. Рассмотрим только методы для прикрепления и открепления Windows-окон.
BOOL Attach(HWND hWndNew);
Закрепляет Windows-окно, заданное определителем hWndNew за оконным объектом. При успешном выполнении возвращает ненулевое значение, в противном случае
- 0.HWND Detach();
Открепляет Windows-окно, закрепленное за данным оконным объектом, и возвращает определитель открепленного окна.
Методы управления состоя нием окна
Сначала рассмотрим четыре типа состояний:
- Активное/неактивное. Активным является окно, с которым пользователь работает в текущий момент. Оно находится поверх всех окон и выделено цветом заголовка. Окно активизируется после щелчка мыши в любой его точке.
- В фокусе/не в фокусе клавиатуры. Окну в фокусе клавиатуры направляются сообщения, вызванные нажатием клавиш на клавиатуре. Как правило, активное окно как раз и находится в фокусе клавиатуры. Исключения составляют дочерние окна, которые сами по себе не могут быть активными или неактивными, но при этом могут быть в фокусе клавиатуры. В этом случае активным должно быть родительское окно.
- Мышь захвачена/не захвачена . Все сообщения от мыши, захваченной окном, направляются этому окну независимо от позиции курсора на экране.Только одно окно может захватить мышь в текущий момент.
- Включенное/выключенное (доступное/недоступное) . Если окно во выключенном состоянии, пользователь не может сделать его активным или передать ему фокус. Операционная система игнорирует любые сообщения окну от клавиатуры и мыши.
Перечислим некоторые методы управления состоянием окна.
BOOL IsWindowEnabled() const;
Если окно в выключенном состоянии, возвращает нулевое значение, в противном случае - 0.
BOOL EnableWindow(BOOL bEnable=TRUE);
Если значение параметра TRUE, окно переводится в включенное состояние, FALSE - в выключенное. Метод возвращает ненулевое значение, если в момент вызова окно находилось в выключенном состоянии. Если окно было во включенном состоянии или произошла ошибка, возвращается 0.
CWnd* SetActiveWindow();
Переводит окно в активное состояние. Возвращает указатель на оконный объект, обеспечивающий доступ к окну, активному в момент вызова этого метода (указатель может быть временным и не должен запоминаться для дальнейшего использования).
static CWnd* PASCAL GetActiveWindow();
Возвращает указатель на оконный объект, обеспечивающий доступ к окну, активному в момент вызова этого метода. Если в момент вызова активных окон нет, возвращается NULL. Этот указатель может быть временным и не должен запоминаться для дальнейшего использования.
CWnd* SetCapture();
Переводит окно в состояние захвата мыши. Возвращает указатель на оконный объект, обеспечивающий доступ к окну, которым мышь была захвачена в момент вызова этого метода. Если в момент вызова мышь не захвачена, возвращает NULL. Этот указатель может быть временным и не должен запоминаться для дальнейшего использования. Чтобы освободить мышь, используется API-функция ReleaseCapture (параметров не имеет). При успешном ее выполнении возвращается TRUE, иначе - FALSE.
static CWnd* PASCAL GetCapture();
Возвращает указатель, задающий окно, захватившее мышь. Если такого окна нет, возвращает NULL.
BOOL ModifyStyle(DWORD dwRemove, DWORD dwAdd, UINT nFlags=0);
Изменяет стиль окна. Параметр dwRemove задает набор элементов стиля, которые должны быть изъяты из стиля окна. Параметр dwAdd - набор элементов стиля, которые должны быть добавлены к стилю окна. Возвращает ненулевое значение, если стиль был успешно изменен, в противном случае - 0.
Если параметр nFlags не равен 0, то после изменения стиля вызывается API-функция SetWindowPos, которая перерисовывает окно, используя набор флагов, полученный комбинацией значения:
- SWP_NOSIZE - сохранять текущий размер;
- SWP_NOMOVE - сохранять текущую позицию;
- SWP_NOZORDER - сохранять текущий Z-порядок;
- SWP_NOACTIVE - не делать окно активным.
Метод ы управления размером и положением окна
void MoveWindow(int x, int y, int nWidth, int nHeight, BOOL bRepaint=TRUE);
void MoveWindow(LPCRECT lpRect, BOOL bRepaint=TRUE);
Эти методы изменяют положение и размеры окна. Положение левого верхнего угла окна задантся координатами x,y, а размеры шириной nWidth и высотой nHeight. Параметр bRepaint определяет, будет ли инициироваться перерисовка. Если он равен TRUE, окну будет послано сообщение WM_PAINT, в противном случае сообщение не посылается, и перерисовка не производится. Эти действия применяются как к клиентской, так и неклиентской области окна, а также к частям родительского окна, открывшимся при перемещении.
Новое положение и размеры окна можно задать и с помощью структуры типа RECT или объекта класса CRect, передав в качестве параметра ссылку на структуру или объект класса.
Для окна, у которого нет родителя, координаты указываются относительно левого верхнего угла экрана, а для имеющего такового - относительно верхнего левого угла родительского окна.
BOOL SetWindowPos(const CWnd* pWndInsertAfter, int x, int y, int cx, int cy, UINT nFgags);
Изменяет положение, размеры и место окна в Z-упорядочении (порядке изображения окон в слоях изображения). Параметры x, y, cx, cy задают новое положение левой стороны, новое положение верхней стороны, новую длину и новую высоту соответственно.
Параметр pWndInsertAfter определяет окно, за которым нужно поместить исходное окно в Z-упорядочении. Этот параметр может быть либо указателем на объект класса CWnd, либо одним из следующих значений:
- wndBottom поместить окно в конец Z-упорядочения, т.е. позади всех окон на экране;
- wndTop поместить окно в начало Z-упорядочения, т.е. впереди всех окон на экране;
- wndTopMost поместить окно на ближайшее место, делающее окно неперекрытым. Окно перемещается на неперекрытое место, даже если оно неактивно;
- wndNoTopMost поместить окно на ближайшее место позади всех неперекрытых окон. Окно, перекрытое в момент вызова этого метода, не перемещается.
Параметр nFlags задает режим изменения размера и положения окна и может быть следующей комбинацией флагов:
- SWP_DRAWFRAME изображать вокруг окна рамку (определенную при его создании);
- SWP_HIDEWINDOW скрыть окно;
- SWP_NOACTIVE не делать окно активным. Если этот флаг не установлен, окно делается активным и помещается впереди, либо на место в Z-упорядочении, определяемое параметром pWndInsertAfter;
- SWP_NOMOVE сохранить текущее положение окна, проигнорировав параметры x и y;
- SWP_NOREDRAW не перерисовывать измененное окно. Если этот флаг установлен, то после выполнения функции окно с новыми установками на экране не появится, а старое изображение окна не будет стерто с родительского окна;
- SWP_NOSIZE сохранить текущий размер окна, проигнорировав параметры cx и cy;
- SWP_NOZORDER сохранить текущее Z-упорядочение, проигнорировав параметр pWndInsertAfter;
- SWP_SHOWWINDOW показать окно (сделать окно видимым и перерисовать).
Если окно не является дочерним, координаты указываются относительно левого верхнего угла экрана, иначе координаты указываются относительно верхнего левого угла клиентской области родительского окна. Приложение не может активизировать неактивное окно, не поместив его в начало Z-упорядочения. Приложение не может изменить место активного окна в Z-упорядочении произвольным образом. Перекрытые окна могут быть родительскими по отношению к неперекрытым, но не наоборот.
void GetWindowRect(LPRECT lpRect) const;
Копирует параметры прямоугольника, ограничивающего окно, в структуру типа RECT или объект класса CRect, заданные параметром lpRect. Этот прямоугольник включает все - и клиентскую и системную часть окна. Параметры даются относительно левого верхнего угла экрана. При вызове метода значением фактического параметра может быть либо ссылка на (не константную) структуру типа RECT либо объект класса CRect.
void GetClientRect(LPRECT lpRect) const);
Копирует параметры прямоугольника, ограничивающего клиентскую часть окна, в структуру типа RECT или объект класса CRect, определенные параметром lpRect. Параметры даются относительно левого верхнего угла клиентской области окна, поэтому левая и верхняя составляющие будут равны нулю, а правая и нижняя - ширине и длине клиентской области. При вызове метода параметр lpRect может быть либо указателем на структуру типа RECT, либо переменной класса CRect.
Методы взаимодействия Windows-окон
BOOL UpdateData(BOOL bSaveAndValidate=TRUE);
Выполняет обмен данными между объектом класса, производного от CWnd, и частным случаем Windows-окна - диалоговым окном. Если параметр равен FALSE, данные будут пересылаться от объекта и обновлять содержимое элементов управления диалогового окна. В противном случае данные будут считываться из элементов управления диалогового окна и обновлять переменные оконного объекта. При выполнении этого метода происходит вызов виртуального метода DoDataExchange класса CWnd. Эту функция нужно переопределить, чтобы она выполнила весь необходимый обмен. Как правило, в качестве объектов, обменивающихся данными с диалоговым окном, выступают объекты пользовательских классов, производных от CDialog или CFormView. Для них имеется возможность создания переменных, связанных с элементом управления. В этом случае работу по созданию переопределенной функции DoDataExchange выполняет ClassWizard.
Методы управления текстом окна
void SetWindowText(LPCTSTR lpszString);
Устанавливает текст заголовка окна. Если окно - элемент управления, устанавливает текст в этом элементе. При вызове функции параметр должен быть либо указателем на строку символов, оканчивающуюся нулевым символом, либо переменной типа CString.
int GetWindowText(LPSTR lpszStringBuf, int nMaxCount) const;
void GetWindowText(CString& rString) const;
Копирует текст из заголовка окна. Если окно - элемент управления, копирует текст из этого элемента. При вызове первого варианта функции параметр lpszStringBuf должен быть указателем на буфер, в который будет скопирован текст, а параметр nMaxCount - выражением, задающим размер буфера (максимальное число символов, которое разрешается скопировать
в буфер). Функция возвращает число скопированных символов, не включающее нуль-символ. При вызове второго варианта параметр rString должен быть переменной типа CString.int GetWindowTextLength() const;
Возвращает длину текста заголовка окна, а если окно является элементом управления - длину текста этого элемента. Длина не учитывает нуль-символ.
CFont* GetFont() const;
Получает текущий шрифт данного окна.
void SetFont(CFont* pFont, BOOL bRedraw=TRUE);
Устанавливает текущий шрифт окна. Параметр pFont должен задавать новое значение для текущего шрифта. Если параметр bRedraw равен TRUE, окно после установки нового шрифта перерисовывается.
Некоторые методы класса CButton
UINT GetState() const;
Возвращает описание набора текущих состояний кнопки. Чтобы выделить из этого описания значения конкретных типов состояния, можно использовать маски:
- 0х0003 - выделяет собственное состояние кнопки. Применимо только к флажку или переключателю. Если результат побитового умножения дает 0, значит кнопка находится в невыбранном состоянии, 1 - в выбранном, 2 - в неопределенном.
- 0х0004 - выделяет состояние первого типа. Ненулевой вариант означает, что кнопка "нажата", нулевой - кнопка свободна.
- 0х0008 - выделяет положение фокуса. Ненулевой вариант - кнопка в фокусе клавиатуры.
int GetCheck() const;
Возвращает собственное состояние флажка или переключателя. Возвращаемое значение может принимать одно из значений: 0 - кнопка не выбрана; 1 - кнопка выбрана; 2 - кнопка в неопределенном состоянии. Если кнопка не является ни переключателем, ни флажком, возвращается 0.
void SetCheck(int nCheck);
Устанавливает собственное состояние флажка или переключателя. Значения задаются из набора: 0 - невыбранное; 1 - выбранное; 2 - неопределенное. Значение 2 применимо только к флажку со свойством 3State.
UINT GetButtonStyle() const;
Возвращает стиль кнопки.
void SetButtonStyle(UINT nStyle, BOOL bRedraw=TRUE);
Устанавливает стиль кнопки. Если параметр bRedraw равен TRUE, кнопка перерисовывается.
HICON GetIcon() const;
Возвращает дескриптор пиктограммы, сопоставленной кнопке. Если у кнопки нет сопоставленной пиктограммы, возвращает NULL.
HICON SetIcon(HICON hIcon);
Сопоставляет кнопке пиктограмму. Значением параметра при вызове должен быть дескриптор пиктограммы.
Пиктограмма автоматически помешается на поверхность кнопки и сдвигается в ее центр. Если поверхность кнопки меньше пиктограммы, она обрезается со всех сторон до размеров кнопки. Положение пиктограммы может быть выровнено и не по центру. Для этого нужно, чтобы кнопка имела одно из следующих свойств: BS_LEFT, BS_RIGHT, BS_CENTER, BS_TOP, BS_BOTTOM, BS_VCENTER
Данный метод устанавливает для кнопки только одну пиктограмму, которая будет наравне с текстом присутствовать при любом ее состоянии. Не надо путать ее с растровым изображением у растровой кнопки.
HBITMAP GetBitmap() const;
Возвращает дескриптор растрового изображения, сопоставленного кнопке. Если такового не существует, то возвращается NULL.
HBITMAP SetBitmap(HBITMAP hBitmap);
Сопоставляет кнопке растровое изображение. Значением параметра должен быть дескриптор растрового изображения. Правила размещения растрового изображения такие же, как и у значка.
HCURSOR GetCursor();
Возвращает дескриптор курсора, сопоставленного кнопке методом SetCursor. Если у кнопки нет сопоставленного курсора, то возвращается NULL.
HCURSOR SetCursor(HCURSOR hCursot);
Сопоставляет кнопке курсор, изображение которого будет помещено на поверхность кнопки аналогично значку и растровому изображению.
Некоторые методы класса CEdit
Окна редактирования могут работать в режимах однострочного и многострочного редакторов. Приведем сначала методы, общие для обоих режимов, а затем методы для многострочного редактора.
Общие методы
DWORD GetSel() const;
void GetSel(int& nStartChar, int& nEndChar) const;
Получает первую и последнюю позиции выделенного текста. Для значения типа DWORD младшее слово содержит позицию первого, старшее - последнего символа.
void SetSel(DWORD dwSelection, BOOL bNoScroll=FALSE);
void SetSel(int nStartChar, int nEndChar, BOOL bNoScroll=FALSE);
Устанавливает новое выделение текста, задавая первый и последний выделенный символ. Значение FALSE параметра bNoScroll должно отключать перемещение курсора в область видимости.
void ReplaceSel(LPCTSTR lpszNewText);
Заменяет выделенный текст на строку, передаваемую в параметре lpszNewText.
void Clear();
Удаляет выделенный текст.
void Copy();
Копирует выделенный текст в буфер.
void Cut();
Переносит (копирует и удаляет) выделенный текст в буфер обмена.
void Paste();
Вставляет текст из буфера обмена, начиная с позиции, в которой находится курсор.
BOOL Undo();
Отмена последней операции, выполненной редактором. Если редактор однострочный, возвращается всегда неотрицательное значение, иначе неотрицательное значение возвращается лишь в случае успешной замены.
BOOL CanUndo() const;
Определяет, можно ли отменить последнюю операцию редактора.
void EmptyUndoBuffer();
Сбрасывает флаг undo, сигнализирующий о возможности отмены последней операции редактора, и тем самым делает невозможным отмену. Этот флаг сбрасывается автоматически при выполнении методов SetWindowText и SetHandle.
BOOL GetModify() const;
Возвращает неотрицательное значение, если содержимое окна редактирования не модифицировалось. Информация о модификации поддерживается в специальном флаге, обнуляемом при создании окна редактирования и при вызове метода:
void SetModify(BOOL bModified=TRUE);
Устанавливает или сбрасывает флаг модификации (см. предыдущий метод). Флаг сбрасывается при вызове метода с параметром FALSE и устанавливается при модификации содержимого окна редактирования или при вызове SetModify с параметром TRUE.
BOOL SetReadOnly(BOOL bReadOnly=TRUE);
Устанавливает режим просмотра (bReadOnly=TRUE) или редактирования (bReadOnly=FALSE).
TCHAR GetPasswordChar() const;
Возвращает символ, который при выводе пароля будет появляться на экране вместо символов, набираемых пользователем. Если такой символ не определен, возвращается 0. Устанавливается этот символ методом (по умолчанию используется "*"):
void SetPasswordChar(TCHAR ch);
void LimitText(int nChars=0);
Устанавливает максимальную длину в байтах текста, который может ввести пользователь. Если значение параметра равно 0, длина текста устанавливается равной UINT_MAX.
Методы работы с многострочным редактором
void LineScroll(int nLines, int nChars=0);
Прокручивает текст в области редактирования. Параметр nLimes задает число строк для вертикальной прокрутки. Окно редактирования не прокручивает текст дальше последней строки. При положительном значении параметра область редактирования сдвигается вдоль текста к последней строке, при отрицательной - к первой.
Параметр nChars задает число символов для горизонтальной прокрутки. Окно редактирования прокручивает текст вправо, даже если строки закончились. В этом случае в области редактирования появляются пробелы. При положительном значении параметра область редактирования сдвигается вдоль к концу строки, при отрицательном - к началу.
int GetFirstVisibleLine() const;
Возвращает номер первой видимой строки.
int GetLineCount() const;
Возвращает число строк текста, находящегося в буфере редактирования. Если текст не вводился, возвращает 1.
int GetLine(int nIndex, LPTSTR lpszBuffer) const;
int GetLine(int nIndex, LPTSTR lpszBuffer, int nMaxLength) const;
Копирует строку с номером, равным значению параметра nIndex, в буфер, заданный параметром lpszBuffer. Первое слово в буфере должно задавать его размер. При вызове второго варианта метода значение параметра nMaxLength копируется в первое слово буфера.
Метод возвращает число в действительности скопированных байтов. Если номер строки больше или равен числу строк в буфере окна редактирования, возвращает 0. Текст копируется без каких-либо изменений, нуль-символ не добавляется.
int LineIndex(int nLine=-1) const;
Возвращает номер первого символа в строке. Неотрицательное значение параметра принимается в качестве номера строки. Значение -1 задает текущую строку. Если номер строки больше или равен числу строк в буфере окна редактирования (строки нумеруются с 0), возвращается 0.
Некоторые методы класса CListBox
void ResetContent();
Очищает содержимое списка, делая его пустым.
int AddString( LPCSTR lpszItem);
Добавляет строку lpszItem в список и сортирует его, если при создании включено свойство Sort. В противном случае элемент добавляется в конец списка.
int DeleteString( UINT nIndex);
Удаляет из списка элемент с индексом nIndex. Индексация элементов начинается с 0.
int GetCurSel() const;
Получает индекс элемента, выбранного пользователем.
int SetCurSel( int nSelect);
Отмечает элемент с индексом nSelect как выбранный элемент списка. Если значение параметра равно -1, список не будет содержать отмеченных элементов.
int GetText( int nIndex, LPSTR lpszBuffer) const;
void GetText( int nIndex, CString& rString) const;
Копирует элемент с индексом nIndex в буфер.
int SetTopIndex( int nIndex);
Организует прокрутку списка в окне так, чтобы элемент с индексом nIndex был видимым.
int FindString( int nStartAfter, LPCSTR lpszItem) const;
Организует поиск в списке и возвращает в качестве результата индекс элемента списка, префикс которого совпадает со строкой lpszItem. Результат не зависит от регистра, в котором набирались символы сравниваемых строк. Параметр nStartAfter задает начало поиска, но поиск идет по всему списку. Он начинается от элемента, следующего за nStartAfter, до конца списка и затем продолжается от начала списка до элемента с индексом nStartAfter. В качестве результата выдается первый найденный элемент, удовлетворяющий условиям поиска. Если такого нет, результат получает значение LB_ERR.
int FindStringExact( int nIndexStart, LPCSTR lpszFind) const;
Этот метод отличается от предыдущего тем, что теперь не префикс элемента должен совпадать со строкой lpszFind, а сам элемент. Поиск по-прежнему не чувствителен к регистру, в котором набираются символы.
Стандартные диалоговые панели
В состав библиотеки MFC входит ряд классов, представляющих стандартные диалоговые панели. Эти классы позволяют легко реализовать такие часто используемые операции, как открытие и сохранение файла, выбор цвета, выбор шрифта и т.д. Все эти классы наследуются от класса
CCommonDialog, который в свою очередь является производным по отношению к базовому классу CDialog.Приведем классы стандартных диалоговых панелей и их назначение:
- CColorDialog - Панель для выбора цвета
- CFileDialog - Панель выбора файлов для открытия и сохранения на диске
- CFindReplaceDialog - Панель для выполнения операции поиска и замены
- CFontDialog - Панель для выбора шрифта
- CPrintDialog - Панель для вывода документа на печать
- CPageSetupDialog - Панель выбора формата документа
Классы, управляющие стандартными диалоговыми панелями, определены в файле afxdlgs.h. Поэтому при использовании этих классов в приложении необходимо включить этот файл в исходный текст при помощи директивы #i nclude.
Панель выбора цвета (класс CColorDialog)
Чтобы отобразить на экране стандартную диалоговую панель выбора цвета, надо создать объект класса
CColorDialog , а затем вызвать метод DoModal . При создании объекта класса СColorDialog используется следующий конструктор:CColorDialog(COLORREF clrInit=0,DWORD dwFlags=0,CWnd* pParentWnd=NULL);
Все параметры конструктора необязательны, однако в некоторых случаях использование этих параметров может помочь.
Первый параметр clrInit позволяет указать цвет, выбранный по умолчанию сразу после открытия диалоговой панели. Если параметр не будет указан, в качестве цвета, выбранного по умолчанию, будет использоваться черный цвет.
Параметр dwFlags содержит набор флагов, управляющих диалоговой панелью выбора цвета. При помощи него блокировать или разрешать работу некоторых элементов управления диалоговой панели выбора цвета. Если при создании объекта класса
CColorDialog не указать параметр dwFlags, тем не менее можно выполнить настройку диалоговой панели, обратившись непосредственно к элементу m_cc данного класса. Параметр dwFlags, указанный в конструкторе, используется для инициализации m_cc. Изменения в элемент m_cc должны быть внесены до того, как панель будет отображаться на экране.Последний параметр pParentWnd можно использовать, чтобы указать родительское окно диалоговой панели.
Методы класса CСolorDialog
Чтобы вывести диалоговую панель выбора цвета на экран, необходимо использовать метод
DoModal . После отображения панели на экране пользователь может выбрать из нее цвет и нажать кнопки OK или Cancel для подтверждения выбора цвета или отказа от него. Когда диалоговая панель закрывается, метод DoModal возвращается значения IDOK и IDCANCEL, в зависимости от того, какую кнопку нажал пользователь:CColorDialog dlgColor; int iResult=dlgColor.DoModal();
На экране появится стандартная диалоговая панель выбора цвета Color. В верхней половине диалоговой панели расположены 48 прямоугольников, имеющих различные цвета. Они представляют так называемые основные цвета (Basic colors). Можно выбрать один из этих цветов и нажать кнопку OK. После того, как диалоговая панель закрыта (метод
DoModal завершил свою работу), можно воспользоваться методами класса CColorDialog , чтобы узнать цвета, выбранные пользователем.Для определения цвета, выбранного пользователем, можно обратиться к методу
GetColor класса CColorDialog . Данный метод возвращает значение COLORREF, соответствующее выбранному цвету.Если пользователю недостаточно основных цветов, представленных в диалоговой панели Color, он может выбрать до 16 дополнительных цветов. Для этого он должен нажать кнопку DefineCustom Colors. Диалоговая панель изменит свой внешний вид - появятся дополнительные органы управления, позволяющие выбрать любой из 16 777 216 цветов. Когда цвет выбран, нужно нажать кнопку Add Custom Colors. Выбранный цвет будет добавлен к дополнительным цветам (Custom colors) - один из свободных прямоугольников окрасится соответствующим цветом.
При помощи метода GetSavedCustomColors класса CColorDialog можно определить дополнительные цвета, выбранные пользователем в диалоговой панели Color. Этот метод возвращает указатель на массив из 16 элементов типа COLORREF. Каждый элемент массива описывает один дополнительный цвет.
Когда диалоговая панель Color отображается приложением первый раз, все прямоугольники, отображающие дополнительные цвета, имеют белый цвет. Дополнительные цвета, выбранные пользователем, сохраняются во время работы приложения. После перезапуска приложения дополнительные цвета сбрасываются.
Панель выбора файлов (класс CFileDialog)
Среди стандартных диалоговых панелей, для которых в библиотеке MFC создан специальный класс, есть панели для работы с файловой системой - Open и Save As. Диалоговая панель Open позволяет выбрать один или несколько файлов и открыть их для дальнейшего использования. Диалоговая панель Save As позволяет выбрать имя файла для записи в него документа.
Для управления диалоговыми панелями Open и Save As предназначен один класс
CFileDialog . Рассмотрим конструктор класса CFileDialog более подробно:CFileDialog(BOOL bOpenFileDialog, LPCTSTR lpszDefExt=NULL,LPCTSTR lpszFileName=NULL, DWORD dwFlags=OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter=NULL,CWnd* pParentWnd=NULL);
Объекты класса
CFileDialog представляют диалоговые панели Open или Save As в зависимости от параметра bOpenFileDialog. Если параметр bOpenFileDialog содержит значение TRUE, то создается объект, управляющий диалоговой панелью Open, а если FALSE - диалоговой панелью Save As.Параметр bOpenFileDialog является единственным обязательным параметром, который необходимо указать. Остальные параметры конструктора класса
CFileDialog задают различные режимы работы панели и могут не указываться.Чтобы создать объект класса
CFileDialog , представляющий диалоговую панель для открытия файлов (mFileOpen), и объект, представляющий диалоговую панель для сохранения файлов (mFileSaveAs), можно воспользоваться следующими вызовами конструктора класса:CFileDialog mFileOpen(TRUE); // для панели открытия файловCFileDialog mFileSaveAs(FALSE); // для панели сохранения файла
Во многих случаях имена файлов, которые нужно открыть или закрыть, имеют определенное расширение. Параметр lpszDefExt позволяет задать расширение файлов, используемое по умолчанию. То есть, если пользователь при определении имени файла не укажет расширение, имени файла автоматически присваивается расширение, принятое по умолчанию. Если при определении свойств диалоговой панели программист присвоит параметру lpszDefExt значение NULL, то расширение файлов должно задаваться пользователем явно.
В некоторых случаях требуется, чтобы диалоговые панели отображались с уже выбранным именем файла. Чтобы указать имя файла, используемое по умолчанию, применяется параметр lpszFileName. Если параметр lpszFileName имеет значение NULL, данная возможность не реализуется.
С помощью флага dwFlags можно изменить внешний вид и некоторые другие характеристики стандартных диалоговых панелей класса
CFileDialog . В него можно записать комбинацию флагов, управляющих различными характеристиками этих панелей. Например, флаг OFN_HIDEREADONLY означает, что из диалоговой панели удаляется переключатель "Read Only", а флаг OFN_OVERWRITEPROMPT (используемый для панели Save As) - что необходимо выводить диалоговую панель с предупреждением, если пользователь выбирает для сохранения имя уже существующего файла.Диалоговые панели выбора файлов обычно имеют список так называемых фильтров, включающих названия типов файлов и расширения имен файлов данного типа. Выбрав фильтр, пользователь указывает, что он желает работать только с файлами определенного типа, имеющими соответствующее расширение. Файлы с другими расширениями в диалоговых панелях не отображаются.
Список фильтров можно указать через параметр lpszFilter. Одновременно можно указать несколько фильтров. Каждый фильтр задается двумя строками - строкой, содержащей имя фильтра, и строкой, в которой перечислены соответствующие ему расширения имен файлов. Если одному типу соответствует несколько расширений, они разделяются символом ;. Строка, содержащая имя фильтра, отделяется от строки с расширениями файлов символом |. Если используется несколько фильтров, то они также отделяются друг от друга символом |. Например, в качестве строки, задающей фильтры, можно использовать строку вида:
char szFilters[] = " Data (*.dat) |*.dat| Packed Data (*.pac;*.wav) | *.pac; *.wav| All Files (*.*)| *.* ||";
Диалоговые панели, представленные объектами класса
CFileDialog , могут иметь или не иметь родительского окна. Чтобы указать родительское окно, нужно передать конструктору CFileDialog указатель на него через параметр pParentWnd.Методы класса CFileDialog
Создание объекта класса
CFileDialog еще не вызывает отображения соответствующей диалоговой панели. Для этого необходимо воспользоваться методом DoModal класса CFileDialog.При вызове метода DoModal для ранее созданного объекта класса CFileDialog на экране открывается соответствующая диалоговая панель. После того, как пользователь завершает работу с диалоговой панелью, метод DoModal вернет значение IDOK или IDCANCEL в случае успешного завершения и нуль - в случае возникновения ошибок:CFileDialog dlgOpen(TRUE); int iResult=dlgOpen.DoModal();
После того, как пользователь закроет диалоговую панель и метод
DoModal вернет управление, можно воспользоваться другими методами класса CFileDialog , чтобы определить имена выбранных файлов:- GetPathName - Определяет полный путь файла
- GetFileName - Определяет имя выбранного файла
- GetFileExt - Определяет расширение имени выбранного файла
- GetFileTitle - Позволяет определить заголовок выбранного файла
- GetNextPathName - Если диалоговая панель позволяет выбрать сразу несколько файлов, то этот метод можно использовать для определения полного пути следующего из выбранных файлов
- GetReadOnlyPref - Позволяет узнать состояние атрибута "только для чтения" (read-only) выбранного файла
- GetStartPosition - Возвращает положение первого элемента из списка имен файлов
Наиболее важный метод -
GetPathName. Он получает полный путь файла, выбранного из диалоговых панелей Open или Save As. Если диалоговая панель позволяет выбрать сразу несколько файлов, тогда метод GetPathName возвращает массив строк, состоящий из нескольких строк, заканчивающихся двоичным нулем. Первая из данных строк содержит путь к каталогу, в котором расположены выбранные файлы, остальные строки содержат имена выбранных файлов. Выделение строки, содержащей путь к каталогу, проблем не вызывает, а чтобы получить имена выбранных файлов, необходимо воспользоваться методами GetStartPosition и GetNextPathName.Метод
GetStartPosition возвращает значение типа POSITION. Оно предназначено для передачи методу GetNextPathName и получения очередного имени выбранного файла. Если пользователь не выбрал ни одного файла, метод GetStartPosition возвращает значение NULL. Значение, полученное этим методом, следует записать во временную переменную типа POSITION и передать ссылку на нее методу GetNextPathName . Метод GetNextPathName вернет полный путь первого из выбранных в диалоговой панели файлов и изменит значение переменной pos, переданной методу по ссылке. Новое значение pos можно использовать для последующих вызовов метода GetNextPathName и получения путей всех остальных выбранных файлов. Когда метод GetNextPathName вернет имена всех выбранных файлов, в переменную pos записывается значение NULL.В панелях Open и Save As имеется переключатель "ReadOnly". По умолчанию этот преключатель не отображается. Если есть необходимость воспользоваться этим переключателем, то нужно отказаться от использования флага OFN_HIDEREADONLY.
Метод
GetReadOnlyPref позволяет определить положение переключателя "ReadOnly". Если переключатель включен, то метод GetReadOnlyPref возвращает ненулевое значение. В противном случае GetReadOnlyPref возвращает нуль.Панель выбора шрифта (класс CFontDialog)
Стандартная диалоговая панель Font предназначена для выбора шрифта. Эта панель отображает список шрифтов, установленных в системе, и позволяет выбрать название шрифта, его начертание и другие параметры.
Для управления диалоговой панелью Font в библиотеку классов MFC включен класс
CFontDialog . Методы этого класса можно использовать для отображения панели Font и определения характеристик шрифта, выбранного пользователем. Конструктор класса CFontDialog:CFontDialog(LPLOGFONT lplfInitial=NULL, DWORD dwFlags=CF_EFFECTS | CF_SCREENFONTS, CDC* pdcPrinter,CWnd* pParentWnd=NULL);
Все параметры конструктора являются необязательными. Настройка стандартной панели выбора шрифта, которая выполняется конструктором класса
CFontDialog по умолчанию, удовлетворяет большинству пользователей.Параметр lplfInitial является указателем на структуру LOGFONT, описывающую логический шрифт. Если этот параметр используется, то в диалоговой панели по умолчанию будет выбран шрифт, наиболее соответствующий шрифту, описанному в структуре LOGFONT.
Параметр dwFlags задает набор флагов, управляющий различными режимами работы панели. Например, флаг CF_EFFECTS позволяет пользователю создавать подчеркнутые и перечеркнутые буквы, определять цвет букв, а флаг CF_SCREENFONTS - разрешает выбирать только экранные шрифты.
Через параметр pdcPrinter можно передать конструктору контекст отображения принтера, шрифты которого будут представлены в диалоговой панели Font. Данный параметр используется только в том случае, если в параметре dwFlags указаны флаги CF_PRINTERFONTS или CF_BOTH.
Через параметр pParentWnd можно указать родительское окно для диалоговой панели Font.
Методы класса CFontDialog
Для отображения диалоговой панели Font предназначен виртуальный метод
DoModal . Если пользователь выбрал шрифт и нажал кнопку OK, метод DoModal возвращает идентификатор IDOK, если пользователь отменил выбор шрифта, метод DoModal возвращает идентификатор IDCANCEL:CFontDialog dlgFont(); int iResult=dlgFont.DoModal();
Остальные методы класса предназначены для определения характеристик выбранного пользователем шрифта.
Метод
GetCurrentFont позволяет сразу определить все характеристики выбранного шрифта, записав их в структуру LOGFONT.Остальные методы класса позволяют определить только отдельные характеристики выбранного шрифта:
Панель для вывода документов на печать (класс CPrintDialog)
Класс
CPrintDialog можно использовать для создания двух видов диалоговых панелей, предназначенных для печати документов и выбора форматов документов. Кроме класса CPrintDialog можно также использовать класс CPageSetupDialog . Он позволяет создать диалоговую панель для выбора формата документа, имеющую несколько иной вид.В приложениях, подготовленных с использованием средств MFC AppWizard и построенные по модели документ-облик, по умолчанию встроена возможность вывода редактируемого документа на печать.
В меню File такого приложения находятся три строки (Print, Print Preview и Print Setup), которые управляют процессом печати документов, подготовленных в приложении. Чтобы распечатать документ, достаточно выбрать из меню File строку Print. На экране появится диалоговая панель Print. В ней можно выбрать печатающее устройство для печати документов (группа Name), указать, будет печататься весь документ либо его часть (группа Print range), а также сколько копий документа будет напечатано (группа Copies). Также можно настроить различные характеристики печатающего устройства, если нажать кнопку Properties в группе Printer.
Если требуется определить только печатающее устройство и формат документа, из меню File следует выбрать строку Printer Setup. В группе Printer можно указать печатающее устройство и настроить его соответствующим образом. Группа Paper задает формат бумаги и режим подачи бумаги в печатающее устройство. Группа Orientation включает только один переключатель, определяющий ориентацию бумаги. Он принимает положение Portrait для вертикальной ориентации изображения на бумаге (режим "портрет") или Landscape для горизонтальной ориентации изоборажения на бумаге (режим "ландшафт").
Строка Print Preview меню File выбирается для предварительного просмотра документа перед печатью. При этом главное окно приложения изменит свой внешний вид и можно будет просмотреть, как будет выглядеть документ после печати.
Если не требуется выполнять специфическую обработку документа перед печатью, то вряд ли понадобится самостоятельное добавление программного кода, отвечающего за процесс печати. Просто следует отметить, что процедура создания панелей, связанных с печатью документа, практически ничем не отличается от создания выше описанных стандартных диалоговых панелей.
Панель для выполнения поиска и замены (класс CFindReplaceDialog)
Класс
CFindReplaceDialog предназначен для управления диалоговыми окнами Find и Replace. Диалоговая панель Find используется для поиска известных строк в документе приложения, а панель Replace позволяет замену одной строки на другую.Важным отличием диалоговых панелей Find и Replace от других стандартных диалоговых панелей является то, что они представляют собой немодальные диалоговые панели. Поэтому процесс создания этих панелей значительно отличается от процесса создания стандартных панелей для выбора цвета, шрифта и имен файла.