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

Фриланс
Новости
Статьи
   
Рубрики:


Современный интрефейс - первый шаг

Поиск:
Авторы: Step, mr.DUDA


Зачем это нужно

Все мы видели проводник винды....
Он состоит из меню, тоолбар-а, статусбар-а, дерева и листа
Для создания приложения подобной структуры особого ума не надо тем более что за вас все необходимое будет сделано средой. Необходимо просто при использовать Application Wizard указать все необходимы свойства, а для разбиения клиентской области на дерево и лист достаточно просто переключить свойство Project style: в позицию Windows Exploer

В большинстве случаев подобная структура удовлетворяет большинству задач, и причина этого заключается в однородности объектов и областей окна....

А теперь взгляните на окно среды разработки и обратите внимание на разнообразие окон внутри основного окна: у одних имеются закладки, у других собственные тулбары, закладки, в зависимости от необходимости.

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

Можно конечно было бы лепить производные классы от СView и в каждом из них клепать динамически все что угодно, не забывая при этом вручную вычислять размер области отображения (что приводит к необходимости постоянно контролировать размер окна "вид", а если при этом вы еще и пытаетесь сделать тулбар перетаскиваемым то это становится настоящим гемором), а можно просто под каждую область поместить свой фрейм и работать стандартными методами… Чем мы и займемся.

Начинаем.

Для начала давайте создадим приложение со следующими настройками:
делаем его SDI.
Project style: в позицию MFC standard, а потом мы рассмотрим как модернизировать приложение с опцией Windows Exploer
включаем тулбары, статусбары. Изначально SDI приложение базируется на классах производных от:
- CFrameWnd
- CDocument
- CView

Заглянем в функцию InitInstance:
Цитата

CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(C....Doc),
RUNTIME_CLASS(CMainFrame),       // main SDI frame window
RUNTIME_CLASS(C....View));


Вот он залог удобства, и он же становится проблемой. Давайте взглянем по подробнее:

Цитата
RUNTIME_CLASS(CDoc) - нет ни каких проблем документ у нас один
RUNTIME_CLASS(CMainFrame) - тоже нету ни каких проблем, но это только потому что  это рамка основного окна.....
RUNTIME_CLASS(CView)) - а вот это  проблема. Видов у нас может быть много значит и будет несколько классов производных от CView.
Почему это проблема. По причине того,  что мы собираемся под каждый вид поместить фрейм, вернее вместо вида поставить фрейм, а вот фрейм и будет уже инициализировать вид. Но любой фрейм по умолчанию инициализирует именно тот вид который указан в команде CSingleDocTemplate(....)


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

В любом случае данный код остается без изменения. Нас он вполне устраивает так как вы при работе с Application Wizard выбрали тот вид который хотя бы раз будем использовать.

Едем дальше.

Как мы и говорили наше окно будет состоять из множества окон.... а именно из двух окон «ВИД» и двух фреймов, и ввиду того, что они будут иметь разные тоолбары, нам необходимо создать производные классы от СFrameWnd (надеюсь, создавать классы с помощью ClassWizard-а вы уже умеете :)). Создаем классы:

1. СFrame1
2. СFrame2

Теперь создаем производные классы от CView (один вид у нас есть, он нас устраивает):

Делаем класс СView2 производным от любого класса вида (например: СFormView или СListView) - это уже не принципиально для нашей задачи....

Далее.

Необходимо разбить наше окно (фрейм) на части, про СSplitterWnd слышали (ну уж видели точно)... С помощью его мы и будем разбивать наше окно (фрейм), где и как нам необходимо его разбить - в основой рамке конечно - класс CMainFrame.

Для этого мы вставляем в класс CMainFrame переменную CSplitterWnd m_splitterwnd.

Задаем структуру нашего фрейма. Структура окна задается в OnCreateClient. Вот что мы в ней будем делать:

1) Разделим фрейм на две области:
Цитата
m_splitterwnd.CreateStatic(this,1,2);

один ряд, две колонки
Теперь у нас две области и для них необходимо указать содержание. Устанавливаем содержание левой области:
Цитата
m_splitterwnd.CreateView(0,0,RUNTIME_CLASS(СFrame1),CSize(100,100),pContext);

Устанавливаем содержание правую область:
Цитата
m_splitterwnd.CreateView(0,1,RUNTIME_CLASS(СFrame2),CSize(100,100),pContext);

и добавляем return true;

Вообще-то (как вы могли заметить), функция CreateView предназначена для работы с производными от CView, но ничего страшного: CSplitterWnd подхватит и фрейм:
Код
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
// TODO: Add your specialized code here and/or call the base class
m_splitterwnd.CreateStatic(this,1,2);
m_splitterwnd.CreateView(0,0,RUNTIME_CLASS(СFrame1),CSize(100,100),pContext);
m_splitterwnd.CreateView(0,1,RUNTIME_CLASS(СFrame2),CSize(100,100),pContext);
return true;
}


2) Вызов функции CreateView с классом производным от CView, не приведет к желаемому результату, конечно у вам будет два окна, с разными видами, но вот тоолбары придется клепать динамически.

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

Это происходит по тому, что на этом этапе обои наши рамки(фреймы) привязаны к одному виду.... Тут проблем не возникает, а вот при уничтожении первый фрейм всё уничтожает (и второму делать уже нечего... получаем ошибку !)

3) Что же дальше ? Первый фрейм оставляем как есть (он подхватит класс вида который был у вас изначально). Только добавьте include на класс, производный от CDocument и include на класс, производный от СView, который был создан wizard-ом.

Обратите внимание что вставлять include необходимо в том порядке, котором указал я...

4) Второй фрейм мы чуть отредактируем.
Добавьте include на класс производный от CDocument и include на класс СView2 производный от СView, который был создан wizard-ом.

Привяжем к фрейму класс СView2. Делается это следующем образом:
Код
BOOL CFrame2::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
// TODO: Add your specialized code here and/or call the base class

pContext->m_pNewViewClass=RUNTIME_CLASS(CView2);


return CFrameWnd::OnCreateClient(lpcs, pContext);
}



Ну вот пожалуй и все. Основа заложена. Теперь добавляйте что угодно куда угодно. Тулбар для основного окна у вас есть, можете добавить еще одни туда же, редактируя функцию CMainFrame::OnCreate. Тоолбар будет перетаскиваться по границам основного окна (нет ни каких проблем с пересчетом размера окна).

Хотите добавить тоолбар на левое окно -- редактируйте CFrame1::OnCreate, и можете таскать тулбар в пределах этого окна.

Хотите в правое окно -- CFrame2::OnCreate, и таскайте тоолбар в пределах этого окна...

Это не последняя статья на эту тему, продолжение будет в ближайшем будущем. Я раскажу о более оригинальных решения создания разнообразного интерфейса, хотя вы наверное уже будете в состоянии сделать чтото более оригинальное если попробуете скомбинировать MDI и SDI классы, но все делается слегка по другому.....
Автор: Step
Сайт: http://






Просмотров: 3106

 

 

Новые статьи:


Популярные:
  1. Как сделать цикличным проигрывание MIDI-файла?
  2. Создание AVI файла из рисунков
  3. Как устройство "отключить в данной конфигурации"?
  4. Kто в данный момент присоединен через Сеть?
  5. Как узнать количество доступной памяти?
  6. Как реализовать в RichEdit разноцветный текст?
  7. Как скрыть свое приложение от ProcessViewer
  8. Как программно нажать/скрыть/показ кнопку "Start"?
  9. Модуль работы с ресурсами в PE файлах
10. Функции вызова диалоговых окон выбора
11. Проверка граматики средствами Word'а из Delphi.
12. Модуль для упрощенного вызова сообщений
13. Функции для записи и чтение своих данных в, ЕХЕ- файле
14. Рекурсивный просмотр директорий
15. Network Traffic Monitor
16. Разные модули
17. Универсальная функция для обращения к любым экспортируем функциям DLL
18. Библиотека от VladS
19. Протектор для UPX'а
20. Еще об ICQ, сообщения по контакт листу?
21. Использование открытых интерфейсов
22. Теория и практика использования RTTI
23. Работа с TApplication
24. Примеры использования Drag and Drop для различных визуальных компонентов
25. Что такое порт? Правила для работы с портами
26. Симфония на клавиатуре
27. Загрузка DLL
28. Исправление автоинкремента
29. Взаимодействие с чужими окнами
30. Проверить дубляжи в столбце


 

 

 
 
На главную