2009-04-05 7 views
2

J'essaye de créer une boîte de dialogue d'enregistrement de fichier personnalisée pour XP en utilisant C++/VS2008. Mon dialogue aura trois listes déroulantes et une zone d'édition. J'ai besoin que le contenu des listes déroulantes soit mis à jour dynamiquement lorsque des sélections sont effectuées sur d'autres listes déroulantes. Par conséquent, mon besoin d'attraper les événements CBN_.Attraper ON_CBN_SELCHANGE et d'autres événements dropdown lors de l'extension de CFileDialog

J'ai créé une classe qui étend CFileDialog et une classe qui étend CComboBox. Je peux obtenir le dialogue personnalisé (avec les combos) à afficher mais je ne peux pas piéger les événements CBN_. J'ai utilisé l'assistant VS 'Create MFC DLL' pour obtenir deux classes: La classe app et la classe de dialogue d'enregistrement de fichier personnalisé. J'ai créé une classe CComboBox dérivée afin que je puisse ajouter des messages/code de recouvrement d'événement. J'ai mis dans les cartes de message, DoDataExchange et le code de recouvrement d'événement dans la classe de dialogue.

Le code qui suit est une version abrégée de ce que je suis en train de travailler. Je me dis que je n'ai pas besoin de poster la création de trois listes déroulantes quand je ne peux pas avoir une seule liste déroulante à travailler. Je n'ai pas non plus mis de code pour la boîte d'édition, puisque je n'ai pas de problèmes avec ça.

Une partie du code: A partir de la classe app - la création d'une instance de la boîte de dialogue personnalisée, appelant 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; 
} 

Voici une partie du fichier personnalisé boîte de dialogue Enregistrer:

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) ; 
} 

Et voici la classe dérivée de 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) ; 
} 

J'ai essayé des versions où la classe de dialogue a t e messagemap/DoDataExchange, la classe ComboBox les a, les deux classes les ont.

Je suis capable d'attraper quelques événements - aucun avec le CComboBox, cependant. Je peux obtenir la boîte de dialogue pour répondre à ON_NOTIFY, ON_WM_DESTROY et la zone d'édition répond à ON_WM_KILLFOCUS. J'ai cette pensée lancinante que c'est un front-slapper, que je suis trop proche de cela et ne peux pas voir l'évidence.

Toute aide, assistance, direction serait grandement appréciée.

+0

Je dois mentionner que j'ai créé cela comme une DLL MFC afin que je puisse sous-classe CFileDialog. Lorsque j'ai essayé de créer une application, je ne pouvais pas sous-classer CFileDialog. Puis j'ai changé VS2008 linker opts pour créer un exécutable. Il fonctionne mais je ne peux pas piéger les événements déroulants. – Lou

Répondre