CTabCtrl not working properly
Hello,
I have a Dialog with an CTabCtrl. Each tab is a single dialog template with a underlying class.
Now the behaviour is as following:
Switching from tab 1 to tab 2 to tab 3, everything is fine
Switching from tab 1 to tab 3 the dialog from tab 2 is displayed and when I hover over the screen with my mouse the edit controls appear. So something must be wrong with the order I guess or something...
here is my class, I hope this helps:
Code:
// SettingsDialog.cpp: Implementierungsdatei
//
#include "stdafx.h"
#include "BasicSettingsForm.h"
#include "4PEPConnectDI.h"
#include "SettingsDialog.h"
#include "afxdialogex.h"
#include "SAPSettingsForm.h"
#include "AboutForm.h"
#include "TestDialog.h"
#include "SettingsHandler.h"
#include <string>
#include "4PEPUtils.h"
// CSettingsDialog-Dialogfeld
IMPLEMENT_DYNAMIC(CSettingsDialog, CDialogEx)
CSettingsDialog::CSettingsDialog(CWnd* pParent /*=NULL*/) : CDialogEx(CSettingsDialog::IDD, pParent)
{
m_tabs[0] = TEXT("SAP Konfiguration");
m_formIDs[0] = IDD_SAPSETTINGS_FORMVIEW;
m_tabs[1] = TEXT("SAP Konfiguration 2");
m_formIDs[1] = IDD_TEST_FORMVIEW;
m_tabs[2] = TEXT("Über");
m_formIDs[2] = IDD_ABOUT_FORMVIEW;
}
CSettingsDialog::~CSettingsDialog(){
for(UINT i = 0; i < m_tabCount; i++) delete m_dialogs[i];
}
void CSettingsDialog::DoDataExchange(CDataExchange* pDX){
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_SETTINGS_TAB, m_settingsTab);
}
BOOL CSettingsDialog::OnInitDialog () {
CDialogEx::OnInitDialog ();
// necessary to realize tabbing between dialog and subform
DWORD dwStyle = m_settingsTab.GetStyle();
m_settingsTab.ModifyStyle(0, dwStyle | WS_TABSTOP | WS_CHILD | DS_CONTROL );
m_settingsTab.ModifyStyleEx(0, WS_EX_CONTROLPARENT);
// create the tab controls
for(UINT i = 0; i < m_tabCount; i++){
TCITEM tcItem;
tcItem.mask = TCIF_TEXT;
tcItem.pszText = m_tabs[i];
m_settingsTab.InsertItem(i, &tcItem);
// CDialog can not be used due to access to dialog fields
//m_dialogs[i] = new CDialog;
if(i==0) m_dialogs[0] = new CSAPSettingsForm;
if(i==2) m_dialogs[2] = new CAboutForm;
if(i==1) m_dialogs[1] = new CTestDialog;
m_dialogs[i]->Create(m_formIDs[i], &m_settingsTab);
// necessary to realize tabbing between dialog and subform
dwStyle = m_dialogs[i]->GetStyle();
m_dialogs[i]->ModifyStyle(0, dwStyle | WS_TABSTOP | WS_CHILD | DS_CONTROL );
m_dialogs[i]->ModifyStyleEx(0, WS_EX_CONTROLPARENT);
//initially display first tab
if(i == 0){
m_dialogs[i]->EnableWindow(TRUE);
m_dialogs[i]->ShowWindow(SW_SHOW);
}else{
m_dialogs[i]->EnableWindow(FALSE);
m_dialogs[i]->ShowWindow(SW_HIDE);
}
this->setDialogPos(&m_settingsTab, m_dialogs[i]);
}
return TRUE; // return TRUE unless you set the focus to a control
}
void CSettingsDialog::setDialogPos(CTabCtrl* tabCtrl, CDialog* dialog){
CRect tabRect, itemRect;
int nX, nY, nXc, nYc;
tabCtrl->GetClientRect(&tabRect);
tabCtrl->GetItemRect(0, &itemRect);
nX=itemRect.left;
nY=itemRect.bottom+1;
nXc=tabRect.right-itemRect.left-4;
nYc=tabRect.bottom-nY-4;
dialog->SetWindowPos(&(m_settingsTab.wndTop), nX, nY, nXc, nYc, SWP_SHOWWINDOW);
}
BEGIN_MESSAGE_MAP(CSettingsDialog, CDialogEx)
ON_NOTIFY(TCN_SELCHANGING, IDC_SETTINGS_TAB, &CSettingsDialog::tabctrl_before_selchange)
ON_NOTIFY(TCN_SELCHANGE, IDC_SETTINGS_TAB, &CSettingsDialog::tabctrl_after_selchange)
ON_BN_CLICKED(IDOK, &CSettingsDialog::ok_clicked)
ON_BN_CLICKED(IDCANCEL, &CSettingsDialog::cancel_clicked)
END_MESSAGE_MAP()
// CSettingsDialog-Meldungshandler
void CSettingsDialog::tabctrl_before_selchange(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: Fügen Sie hier Ihren Kontrollbehandlungscode für die Benachrichtigung ein.
UINT curTab = TabCtrl_GetCurFocus(m_settingsTab);
m_dialogs[curTab]->EnableWindow(FALSE);
m_dialogs[curTab]->ShowWindow(SW_HIDE);
*pResult = 0;
}
void CSettingsDialog::tabctrl_after_selchange(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: Fügen Sie hier Ihren Kontrollbehandlungscode für die Benachrichtigung ein.
UINT curTab = TabCtrl_GetCurFocus(m_settingsTab);
m_dialogs[curTab]->EnableWindow(TRUE);
m_dialogs[curTab]->ShowWindow(SW_SHOW);
*pResult = 0;
}
void CSettingsDialog::ok_clicked()
{
// TODO: Fügen Sie hier Ihren Kontrollbehandlungscode für die Benachrichtigung ein.
// Idee: die forms implementieren ein Interface welches eine Methode Save zur Verfügung stellt
// diese wird hier dann gerufen und alle Form klassen kümmern sich dann selbstständig um das Speichern
// ihrer Daten.
int result = MessageBoxEx(this->m_hWnd, TEXT("Alle bereits geladenen Daten werden hiermit zurückgesetzt!"), TEXT("4PEP Connect Desktop Integration"), MB_ICONWARNING | MB_YESNO, GetUserDefaultLangID()); // MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
if(result == IDYES){
// call check for all tab forms, if any check fails quit processing
// the check method of each tab must display the messages itself
for(UINT i = 0; i < m_tabCount; i++) if(!m_dialogs[i]->Check()) return;
// call save for all its tab forms
for(UINT i = 0; i < m_tabCount; i++) m_dialogs[i]->Save();
CSettingsHandler* sHndl = CSettingsHandler::GetInstance();
sHndl->storeSettings();
/// IMMER LP(C)TSTR, TCHAR benutzten und TEXT
CTreeCtrl* tree = (CTreeCtrl*)C4PEPUtils::ILCFindWindowEx(this->GetParent(), WC_TREEVIEW);
C4PEPUtils::ClearDataAndResetWinExplorer(tree);
CDialogEx::OnOK();
}
}
void CSettingsDialog::cancel_clicked()
{
// TODO: Fügen Sie hier Ihren Kontrollbehandlungscode für die Benachrichtigung ein.
CDialogEx::OnCancel();
}
Re: CTabCtrl not working properly
I"d recommend you to get rid of your current design and move to use CPropertySheet with CPropertyPage classes instead.