Перехват ON_CBN_SELCHANGE и других выпадающих событий при расширении CFileDialog - PullRequest
2 голосов
/ 05 апреля 2009

Я пытаюсь создать собственный диалог сохранения файла для XP, используя C ++ / VS2008. Мой диалог будет иметь три выпадающих списка и поле для редактирования. Мне нужно, чтобы содержимое раскрывающихся списков динамически обновлялось при выборе других раскрывающихся списков. Следовательно, мне нужно ловить события CBN_.

Я создал класс, расширяющий CFileDialog, и класс, расширяющий CComboBox. Я могу отобразить пользовательский диалог (с комбо), но не могу перехватить события CBN_.

Я использовал мастер VS 'Create MFC DLL', чтобы получить два класса: класс приложения и класс диалогового окна сохранения файла. Я создал производный класс CComboBox, чтобы добавить код перехвата сообщений / событий. Я вставил карты сообщений, DoDataExchange и код перехвата событий в класс диалога.

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

Некоторый код: из класса приложения - создание экземпляра пользовательского диалога с вызовом DoModal:

BOOL CSaveAsApp::InitInstance() 
{
CWinApp::InitInstance();
//  Parse the command line to get the defaultExtension and the file filter 
CString cmdLineAsString =   CString( theApp.m_lpCmdLine );

int curPos  =   0 ;
CString fileExtension   = cmdLineAsString.Tokenize(" ", curPos ) ;
CString fileFilter  = cmdLineAsString.Tokenize(" ", curPos ) ; ;


MyFileDialog    dlg( FALSE, fileExtension.GetBuffer(), "Enter File Name Here",
                    OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
                    fileFilter.GetBuffer(), m_pMainWnd) ;


m_pMainWnd = &dlg;

int nResponse = dlg.DoModal();

if (nResponse == IDOK)
{
   ...  
}
else if (nResponse == IDCANCEL)
       ...

return FALSE;
}

Вот некоторый код из диалогового окна сохранения файла:

IMPLEMENT_DYNAMIC(MyFileDialog, CFileDialog ) 
//  LJM Put in last two parms: DWORD dwSize, BOOL bVistaStyle (0, 0 )
//      bVistaStyle = 0 ==> XP-Style dialog

MyFileDialog::MyFileDialog(BOOL bOpenFileDialog, LPCTSTR lpszDefExt, 
            LPCTSTR    lpszFileName, DWORD dwFlags, LPCTSTR lpszFilter, 
            CWnd* pParentWnd) :
    CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags,
            lpszFilter, pParentWnd, 0, 0) 
{ }

MyFileDialog::~MyFileDialog() { }

void MyFileDialog::DoDataExchange(CDataExchange* pDX)
{
   CFileDialog::DoDataExchange(pDX);
   //{{AFX_DATA_MAP(MyFileDialog)
   //DDX_Control(pDX, IDC_CONTEXT_COMBO, m_ComboContext);
   //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(MyFileDialog, CFileDialog)
ON_CBN_SELCHANGE(IDC_CONTEXT_COMBO, &MyFileDialog::OnCbnSelchangeUniqueNumber)
ON_CBN_SELENDOK(IDC_CONTEXT_COMBO, &MyFileDialog::OnCbnSelchangeUniqueNumber)
END_MESSAGE_MAP()

BOOL MyFileDialog::OnInitDialog() 
{
CFileDialog::OnInitDialog();

//AfxEnableControlContainer();

const UINT iExtraSize = 300;
// Get a pointer to the original dialog box.
CWnd *wndDlg = GetParent();
RECT Rect;


wndDlg->GetWindowRect(&Rect);
// Change the size of FileOpen dialog
wndDlg->SetWindowPos(NULL, 0, 0, 
                    Rect.right - Rect.left, 
                    Rect.bottom - Rect.top + iExtraSize,  
                    SWP_NOMOVE);

CWnd *wndComboCtrl = wndDlg->GetDlgItem(cmb1);   
wndComboCtrl->GetWindowRect(&Rect);
wndDlg->ScreenToClient(&Rect); // Remember it is child controls

Rect.top += 60;
Rect.bottom += 120;
Rect.left += 50;

m_ComboContext.Create(WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP, Rect, wndDlg, IDC_CONTEXT_COMBO);      


    m_ComboContext.SetFont(wndComboCtrl->GetFont(), TRUE);

        m_ComboContext.AddString(_T("Lou1") );
    m_ComboContext.AddString(_T("L432") );
    m_ComboContext.AddString(_T("Lou2") );
    m_ComboContext.AddString(_T("Lou3") );



return true ;
}

void MyFileDialog::OnCbnSelchangeUniqueNumber()
{
AfxMessageBox( _T("OnCbnSelchangeUniqueNumber"), 0, 0 ) ;
}

А вот производный класс от CComboBox:

   IMPLEMENT_DYNAMIC(LouComboBox, CComboBox)

   LouComboBox::LouComboBox() {  }

   LouComboBox::~LouComboBox() {  }

BEGIN_MESSAGE_MAP(LouComboBox, CComboBox)
ON_CONTROL_REFLECT(CBN_SELCHANGE, &LouComboBox::OnCbnSelchange)
ON_CONTROL_REFLECT(CBN_KILLFOCUS, &LouComboBox::OnCbnKillfocus)
ON_CONTROL_REFLECT(CBN_SELENDCANCEL, &LouComboBox::OnCbnSelendcancel)

ON_CBN_SELCHANGE(IDC_CONTEXT_COMBO, &LouComboBox::OnCbnSelchangeUniqueNumber)
END_MESSAGE_MAP()

void LouComboBox::OnCbnSelchange()
{
// TODO: Add your control notification handler code here
AfxMessageBox( _T("Menu selected"), 0, 0 ) ;
}

void LouComboBox::OnCbnKillfocus()
{
// TODO: Add your control notification handler code here
AfxMessageBox( _T("Lost focus"), 0, 0 ) ;
}

void LouComboBox::OnCbnSelendcancel()
{
AfxMessageBox( _T("OnCbnSelendcancel"), 0, 0 ) ;
}

void LouComboBox::OnCbnSelchangeUniqueNumber()
{
// TODO: Add your control notification handler code here    
AfxMessageBox( _T("OnCbnSelchangeUniqueNumber"), 0, 0 ) ;
}

Я пробовал версии, в которых у класса диалога есть карта сообщений / DoDataExchange, у класса ComboBox они есть, у обоих классов они есть.

Я могу отлавливать некоторые события, но не с помощью CComboBox. Я могу получить диалоговое окно для ответа на ON_NOTIFY, ON_WM_DESTROY, а поле редактирования отвечает на ON_WM_KILLFOCUS.

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

Любая помощь, помощь, направление будет принята с благодарностью.

1 Ответ

1 голос
/ 07 октября 2011

Вы должны предоставить процедуру подключения к диалогу для захвата сообщений. Подробности здесь: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646931%28v=vs.85%29.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...