I've would like to have 2 sets of tabs on my CScrollView -derived class, so I put 2 CMFCTabCtrs side by side. The tab controls are filled with dialogs (currently same class, but different objects for test purpose, later different dialogs for each tab control).
The problem is while the controls themselves are placed besides each other as desired. the tabs or dialogs from the second tab control appear in area of the first tab controls, thus overlapping with it.
on the picture above the dialog on the left (currently minimalistic for testing) actually belongs to the control on the right. the dialogs inside of tab are childs of the view.
Resource of the dialog:
IDD_COMBATANTDLG DIALOGEX 0, 0, 320, 331
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
GROUPBOX "Flotte",IDC_STATIC,19,18,192,175,BS_FLAT
LTEXT "Static",IDC_STATIC,91,94,19,8
EDITTEXT IDC_EDIT1,136,118,40,14,ES_AUTOHSCROLL
END
declarations:
class SimDataInput : public CScrollView
{
protected: // create from serialization only
SimDataInput();
DECLARE_DYNCREATE(SimDataInput)
// Attributes
private:
CMFCTabCtrl combatant_tabs[2];//tabs
std::vector<CombatantDlg*> p2combatdlg[2];//stores pointers to dialog
const CStringW attdef[2] = { L"Angreifer ", L"Verteidiger " };//standard labels for respective tab controls
............
from OnInitialUpdate():
void SimDataInput::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
for (auto i = 0; i < 2;i++)
{
CStringW label ( attdef[i]);
RECT pos = RECT{ i * 400, 0, 400 + i * 400, 500 };
combatant_tabs[i].Create(CMFCTabCtrl::STYLE_3D, pos, this,10000+i, CMFCTabCtrl::LOCATION_TOP,TRUE);//create tab
combatant_tabs[i].EnableTabSwap(FALSE);
combatant_tabs[i].EnableActiveTabCloseButton();
//combatant_tabs[sim::ATT].EnableTabDocumentsMenu(TRUE);
p2combatdlg[i].reserve(16);
p2combatdlg[i].emplace_back();//create pointer
p2combatdlg[i].back() = new CombatantDlg(this);//initialize pointer to the new dialog
p2combatdlg[i].back()->Create(IDD_COMBATANTDLG, this);//create dialog
//p2combatdlg[i].back()->SetWindowPos(&combatant_tabs[i], 400, 0, 0, 0, SWP_NOZORDER | SWP_SHOWWINDOW);//tried this -doesn't help
label.AppendFormat(L"%d",1);
combatant_tabs[i].InsertTab(p2combatdlg[i].back(),label , 0, -1, FALSE);//insert the first tab
}
....... next function inserts new tabs after pushing respective button
void SimDataInput::OnCombatant(UINT nID)//used by ON_COMMAND_RANGE for both tab controls
{
nID -= ID_ATTACKER;
if (combatant_tabs[nID].GetTabsNum() == 16)
return;
CStringW label ( attdef[nID]);
p2combatdlg[nID].emplace_back();
label.AppendFormat(L"%d", p2combatdlg[nID].size());
p2combatdlg[nID].back() = new CombatantDlg(this);
p2combatdlg[nID].back()->Create(IDD_COMBATANTDLG, this);
combatant_tabs[nID].InsertTab(p2combatdlg[nID].back(), label , combatant_tabs[nID].GetTabsNum(), -1, FALSE);
combatant_tabs[nID].SetActiveTab(combatant_tabs[nID].GetTabsNum() - 1);
// TODO: Add your command handler code here
}
After all, making the CMFCTabCtrls parents to the contained dialog corrected the behaviour. I had to store the pointer to the former parentsd insidethe dialogs to make the access easier