Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > MFC диалоговое окно + меню


Автор: fear 16.4.2006, 01:10
Появилась необходимость сделать в MFC диалоговое приложение, но при этом чтобы в нем присутсвовало меню и панель инструментов.

С Single Document и Multiple Document проблем не возникает, т.к. можно встроить и меню, и панель инструментов в конструкторе в процессе создания приложения, поставив всего лишь галочку. Но как быть с диалоговым приложением?

Может кто-нибуть сталкивался с такой проблемой или попадалась документация по теме?

Автор: Earnest 16.4.2006, 10:04
1) Создай ресурс меню.
2) В свойствах диалога есть пункт "Меню". Поставь туда ид-р ресурса.

Добавлено @ 10:05 
Панель инструментов создавай в OnCreate, точно так же, как SDI\MDI-приложениях. 

Автор: fear 16.4.2006, 12:41
C меню всё понятно, оказалось проше чем я мог представить.
А вот с панелью инструментов несовсем. В SDI\MDI-приложениях галку ставишь и все готово. В диалоговом галки не поставишь, а что за код для инициализации панели инструментов писать я понятия не имею. 

Автор: OverBug 16.4.2006, 12:45
А если нужно его динамически изменить?
Можно ли так сделать?
Код

CMenu menu;
menu.LoadMenu(IDR_DLGMENU);
SetMenu(&menu);
menu.Detach();
 
просто надо этот код поместить на сообщение WM_CREATE

Добавлено @ 12:54 
Код

m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC)
m_wndToolBar.LoadToolBar(IDR_MAINFRAME);//IDR твоего тулбар ресурса

m_wndStatusBar.Create(this);
m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));

//это позволит тулбар перетаскивать
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
 

Автор: fear 17.4.2006, 17:41
Что то не прикручивается панель инструментов.

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

int CTestDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
  if (CDialog::OnCreate(lpCreateStruct) == -1)
    return -1;

  CToolBar m_wndToolBar;
  CStatusBar m_wndStatusBar;
  m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY |CBRS_SIZE_DYNAMIC);
  m_wndToolBar.LoadToolBar(IDR_TOOLBAR);

  m_wndStatusBar.Create(this);
  m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));

  //это позволит тулбар перетаскивать
  m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
  EnableDocking(CBRS_ALIGN_ANY);
  DockControlBar(&m_wndToolBar);

  return 0;
}


d:\lang\myprojects\c++\work\test\test\testdlg.cpp(171) : error C2065: 'indicators' : undeclared identifier
d:\lang\myprojects\c++\work\test\test\testdlg.cpp(171) : error C2070: ''unknown-type'': illegal sizeof operand
d:\lang\myprojects\c++\work\test\test\testdlg.cpp(175) : error C3861: 'EnableDocking': identifier not found
d:\lang\myprojects\c++\work\test\test\testdlg.cpp(176) : error C3861: 'DockControlBar': identifier not found

Попробовал убрать всё лишнее, оставить только инициализацию панели инструментов, в итоге компилятор не ругается и результата ни какого не видно.

Код

int CTestDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
  if (CDialog::OnCreate(lpCreateStruct) == -1)
    return -1;

  CToolBar m_wndToolBar;
  CStatusBar m_wndStatusBar;
  m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
  m_wndToolBar.LoadToolBar(IDR_TOOLBAR);

  return 0;
}


Пробовал копировать рабочий код инициализации из SDI/MDI приложений и вставлять его в диалоговое приложение, результата ни какого не добился. Может быть для диалоговых приложений есть свои ньюансы? У кого-нибуть получалось прикрутить панель инструментов к диалоговому приложению? 

Автор: Earnest 17.4.2006, 18:01
Что касается индикаторов, то ты просто ссылаешься на неизвесную переменную.
OverBug пропустил при копировании, а ты содрал не думая... Это должен быть массив, причем соответствующие ид-ры обязательно должны присутствовать в строковом ресурсе, иначе при создании будет ругань. 

С панелями умеет работать только фрейм... В смысле пристыковки и т.д. Поэтому компилятор и ругается на неизвестные функции.

Наверно, как-то подкрутить можно (если требуется фиксированная панель). Например, самостоятельно определи вертикальный размер панели (у ToolBar есть функция CalcFixedLayout) и руками перемести панель (SetWindowPos)... НО не уверена, что это все.

Второй вариант: думаю, будет проще унаследовать свое главное окно от CFrameWnd, внутри сделать CFormView. Вместо CDialog::DoModal вызывать RunModalLoop. Или просто сделать нормальное SDI приложение, но без документов.  

Автор: OverBug 18.4.2006, 23:45
Посмоти в FAQ/C++/MFC/Общие вопросы. Там есть код. Сам не пробовал, но если он там, значит он того стоит.

Цитата

d:\lang\myprojects\c++\work\test\test\testdlg.cpp(175) : error C3861: 'EnableDocking': identifier not found
d:\lang\myprojects\c++\work\test\test\testdlg.cpp(176) : error C3861: 'DockControlBar': identifier not found

в stdafx.h добавь #include <afxext.h>. В ней эти функции объявлены. 

Автор: Earnest 19.4.2006, 07:25
Цитата(OverBug @  19.4.2006,  00:45 Найти цитируемый пост)
в stdafx.h добавь #include <afxext.h>. В ней эти функции объявлены.  

Ерунду говоришь. Эти функции есть у фрейма и панелей, их нет в диалоге.
 

Автор: OverBug 23.4.2006, 23:23
Да...   Они в afxwin.h объявлены. 
Тогда почему такие ошибки?  afxwin.h, помоему, по умолчанию визард ее включает?

Вообще визард, при создании диалога вкл. и afxwin.h, и afxext.h!!!!? Думаю, что если бы 
fear, пользовался визардом, то таких ошибок не было-бы. 

Автор: Earnest 24.4.2006, 07:55
OverBug, это не глобальные функции, а класса CFrameWnd. Ну откуда они у диалога возьмутся? И при чем тут визард? 
Ну что вы все за визард цепляетесь, как за костыль! В результате, как только чего-то визард не умеет, поднимается паника: как, да что! А все-то делов - включить нужные файлы, да добавить нужные обработчики. Ну, еще в MSDN заглянуть.

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

Автор: POV 26.4.2006, 19:30
Полностью согласен с предыдущим оратором. Однако очумелый волшебник, несомненно, полезен особенно в тех случаях, когда надо быстро настрогать всяких прототипчиков с последующим их заполнением и редактированием ручками. А ручки надо развивать, особенно, когда речь идет о простых правилах синтаксиса и семантики. Видишь класс - читай откель он и ставь заголовчики куда надо... это же так просто... Извините... 

Автор: КУБ 13.8.2006, 18:51
Вставь после кода создания Тулбара (т.е. в конце) эту функцию: 
Код

RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);

Она отвечает где и как отображать Тулбар. 




Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)