Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > CDialogBar в SDI приложении


Автор: Nastya 2.2.2004, 21:16
VC++6.0. SDI - приложение
Такая проблема:
Создаю DialogBar, на нем к примеру EDIT. Обработать сообщение от него не проблема, как и найти его CWnd*. Но как организовать DDX_ и DDV_ ?

Свой класс от диалога создать не получается. Ручками вставлла в CMainFrame - не работатет.

Хэлп !!!!!!!!!

Автор: mr.DUDA 2.2.2004, 22:20
Как это так - не получается создать производный класс !
Надо бы научиться обходиться без помощи ClassWizard-а... Создаём производный класс, переопределяем DoDataExchange - вот и всё, что нужно для DDX_ и DDV_ ...

Автор: Nastya 3.2.2004, 11:19
Я видносильно торможу smile.gif
Произвольный класс идет от СDialog, где в качестве идентификатора шаблона диалога указывается шаблон моего DialogBar`а ?

В чем у меня возникла проблема, ведь, элементы (например кнопки) на диалог баре не активны, пока их не обработаешь в CMainFrame или С...View или в документе.
Т.е. каким боком идет обраотка сообщений и связь всей этой каши в идиное целое?

Моежт есть дока какая-нибудь поприличнее?
Или поясни, плиз, на пальцах smile.gif

Автор: mr.DUDA 3.2.2004, 14:49
Для примера можно посмотреть MSDN 2001, пример Vc98/Mfc/general/ctrlbars - там всё это есть, только без DDX/DDV.

Вообще, в MSDN черным-по-белому написано, что все сообщения от CDialogBar-а обрабатывает окно-владелец бара, т.е. собственно класс CDialogBar - это обычный тулбар, только с "натянутым" на него шаблоном диалога.

Но можно и обойти это тупое ограничение!
Что мы и сделаем.

Итак, создаём обычный диалог с кнопкой, чекбоксом и Edit-ом, и класс для него (производный от CDialog !) - пусть это будет класс CDialogBarEx. Далее заходим в DialogBarEx.h/.cpp и вносим изменения:
Цитата
class CDialogBarEx : public CDialogBar     // меняем базовый класс
{


Цитата
CDialogBarEx::CDialogBarEx(CWnd* pParent /*=NULL*/)
: CDialogBar()  // вызов конструктора базового класса

   ........

BEGIN_MESSAGE_MAP(CDialogBarEx, CDialogBar)

   ........



Добавляем в CDialogBarEx переменную для Edit-а, и создаём обработчик нажатия на кнопку - например:
Цитата
void CDialogBarEx::OnButton1()
{
     UpdateData(TRUE);
     MessageBox(m_csValue);
}


Создаём диалог бар в CMainFrame::OnCreate
Цитата
MainFrm.h
#include "DialogBarEx.h"

class CMainFrame : public CMDIFrameWnd
{
public:
     CDialogBarEx  m_wndDlgBar;

MainFrm.cpp
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    .........

   m_wndDlgBar.Create(this, IDD_DIALOG1, CBRS_RIGHT|CBRS_TOOLTIPS|CBRS_FLYBY, IDD_DIALOG1);
   m_wndDlgBar.EnableDocking(CBRS_ALIGN_RIGHT);
   DockControlBar(&m_wndDlgBar);
}


Теперь - самое главное: как сделать кнопку доступной (она после создания серая).
Наш любимый MSDN говорит, что сообщения от диалог бара, приходящие в класс-контейнер (CMainFrame) аналогичны сообщениям от тулбара - т.е. это будут обработчики OnXXXX и OnUpdateXXXX. Значит, каким-то образом нужно создать обновление состояния "кнопки тулбара" для каждого контрола в CDialogBarEx (для Edit-а необязательно). Например, у меня есть кнопка IDC_BUTTON1. Тогда я добавляю в MainFrm.h/.cpp:
Цитата
========= MainFrm.h =================

class CMainFrame : public CMDIFrameWnd
{
   .......

// Generated message map functions
protected:
    //{{AFX_MSG(CMainFrame)
       .......
    afx_msg void OnUpdateMyControls(CCmdUI* pCmdUI);
    //}}AFX_MSG


========= MainFrm.cpp ====================

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
    //{{AFX_MSG_MAP(CMainFrame)
           ...........
    ON_UPDATE_COMMAND_UI(IDC_BUTTON1, OnUpdateMyControls)
    ON_UPDATE_COMMAND_UI(IDC_CHECK1, OnUpdateMyControls)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

........

void CMainFrame::OnUpdateMyControls(CCmdUI* pCmdUI)
{
    pCmdUI->Enable(TRUE);
}


Всё !

Теперь для каждого нового контрола нужно не забывать добавлять строку:
ON_UPDATE_COMMAND_UI(идентификатор_контрола, OnUpdateMyControls)


Что мы получили:
Путём не очень хитрых манипуляций мы имеем возможность работать с диалогом CDialogBarEx обычным, привычным для нас способом, хоть это и не класс производный от CDialog. В то же время, диалог отображается как тулбар, его можно перетягивать и приаттачивать к любому краю фрейма.

Автор: Madest 21.10.2004, 10:27
Давно хотел такое сотворить, но не получалось. А сейчас просто необходимо. В общем у меня вылетает при добавлении в
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
Код
m_wndDlgBar.Create(this, IDD_DIALOG1, CBRS_RIGHT|CBRS_TOOLTIPS|CBRS_FLYBY, IDD_DIALOG1);

с руганью
Цитата
Debug Assertion Failed!
File: bardlg.cpp
Line: 48

Все делаю как написано, плюс изменил в
void CDialogBarEx::DoDataExchange(CDataExchange* pDX)
вместо
CDialog::DoDataExchange(pDX);
написал
CDialogBar::DoDataExchange(pDX);
т.к. доступа к ЦДиалоговому DDX нету.

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