|
First of all, create an CTabbedView derived from CTabView.
class CTabbedView : public CTabView
{
protected: CTabbedView();
DECLARE_DYNCREATE(CTabbedView)
...
};
Then, in OnCreate:
int CTabbedView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CTabView::OnCreate(lpCreateStruct) == -1)
return -1;
m_wndTabs.DestroyWindow();
if (! m_wndTabs.Create(CMFCTabCtrl::STYLE_3D, CRect(0, 0, 0, 0), this, 1, CMFCTabCtrl::LOCATION_BOTTOM))
{
TRACE(_T("Failed to create output tab window\n"));
return -1;
}
m_wndTabs.SetFlatFrame();
m_wndTabs.SetTabBorderSize(0);
m_wndTabs.AutoDestroyWindow(TRUE);
AddView(RUNTIME_CLASS(CYourView1), _T("Title 1"));
AddView(RUNTIME_CLASS(CYourView2), _T("Title 2"));
return 0;
}
and in your childframe, where you create the view inside your splitter, you can put this CTabbedView as any CView:
if(! m_wndSplitterTab.CreateView(1, 0, RUNTIME_CLASS(CTabbedView), CSize(0, 0), pContext))
{
m_wndSplitterTab.DestroyWindow();
return FALSE;
}
Tell me if is not clear.
|
|
|
|
|
Thank you very much.
It does not work even i followed the same code which you posted now and earlier. You can find the attached image which shows how i created the 5 views in my application using csplitterwnd class. In view 5 i need to add some tabs. I written a class CMyTabClass which derives from CTabView. i given this class as a RUNTIME_CLASS to view 5 as follows:
bStatus = SpliterObj()->CreateView
(
1,
1,
RUNTIME_CLASS(CMyTabClass),
sizeView,
pContext
);
In CMyTabClass i created the tab as follows:
if (!tab.Create(CMFCTabCtrl::STYLE_FLAT, CRect(150, 524, 250, 366), GetSplitter0()->GetPane(0, 0), 1))
{
TRACE0("Failed to create output tab window\n");
return -1; // fail to create
}
Some times i feel the coordinates may be wrong(150,524,250,366) and hence the tab is located out side the view. I changed many times but still the tab is not visible in view 5.
Click below for image Link:
[^]
|
|
|
|
|
Could you reproduce more accurate my example in your code ? For instance, in my example CRect has 0 value ... and there is more.
|
|
|
|
|
I created a sample MFC application with single document template and added the Class which derived from CTabView and created another class which derives from CView.
class MyTabClass : public CTabView
{
//this class created a window with tab control below. But not tab exactly.
//Now i added below piece of code to create a tab.
int OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CTabView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
AddView(RUNTIME_CLASS(CView1), _T("View1"));
return 0;
}
}
The above code created a single tab on window as shown in below image.
[^]
But all i need to know is how to create this same tab on Splitter Window which is shown in my first image.
A great thanks for you in quick response and support. Please let me know what wrong i did in adding the tab on csplitter window.
modified 6-Mar-18 6:33am.
|
|
|
|
|
My sample code was for splitter case ... do you want to add tab views inside an frame, or inside an splitter ?
|
|
|
|
|
Message Closed
modified 7-Mar-18 2:10am.
|
|
|
|
|
Dear member, in order to read easily, please format your code (use "code" button from above edit area).
And, yes, m_tab.Create(...) return TRUE, but further more, you do nothing ...
|
|
|
|
|
Hey sorry for the wrong indentation. Its working absolutely fine with same piece of code. The problem is what i mentioned earlier i.e., the coordinates what i provided does not show the tab control in my split window. I changed the values with hit and trail and some portion of tab control is visible on split window.
if (!m_tab.Create(CMFCTabCtrl::STYLE_3D, CRect(500, -500, 900, 300), this, 1, CMFCTabCtrl::LOCATION_BOTTOM))
{
TRACE(_T("Failed to create output tab window\n"));
return -1;
}
The values 500,-500,900,300 shown the control on my window. I need to write logic to show this control at the bottom of split window.
Thanks for your support. Now, i will tweak this and try to add tabs to it. In case of any block i will post it back.
|
|
|
|
|
Sure. In my code I give it an empty CRect, and it work fine.
|
|
|
|
|
Please correct me if i am wrong. While creating a Split window using below statement.
bStatus = GetSplitterObj()->CreateView
(
1,
1,
RUNTIME_CLASS(CMyTabClass),
sizeView,
pContext
);
Above call create Split Window. CMyTabClass is derived from CTabView. So, by default the split window should contain tab splitter at the bottom of the window. Am i right?
Because this is how it working in my sample application. In sample i created a Class which derives from CTabView and the window is created with tab splitter in the bottom by default. Later i started adding view using addview().
Then why in my application, splitter is not visible in bottom of the splitter window? why should i explicitly create it using Create()..?
|
|
|
|
|
The code:
bStatus = GetSplitterObj()->CreateView
(
1,
1,
RUNTIME_CLASS(CMyTabClass),
sizeView,
pContext
);
it is only put CMyTabClass view into your splitter window. The creation of the tabs inside this CMyTabClass should be done in CMyTabClass::OnCreate, where AddView(...) calling is mandatory.
So, you should add at least one tab in order to see something inside your splitter window
|
|
|
|
|
Then how come in sample application, below code itself creating a tab bar (horizontal with arrow buttons) in window?
if (CTabView::OnCreate(lpCreateStruct) == -1)
return -1;
The same above piece of code in my application not creating that horizontal tab bar unless i create
MFCTabCtl tab;
tab.create()....
|
|
|
|
|
If i call AddView() and run my program, it working absolutely fine with a window and a view(tab).
But instead of calling AddView() initially, at runtime i based on user input, i called addview() which leads to a crash. What could be the reason.
class View : public CScrollView
{
}
class MyTabClass : public CTabView
{
void OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CTabView::OnCreate(lpCreateStruct) == -1)
return -1;
AddView(RUNTIME_CLASS(View),_T("Sheet1"));
}
void RunTimeBasedOnUserInput()
{
for(int i = 0 ; i < userinput; i++)
{
AddView(RUNTIME_CLASS(View),_T("sheet %d",i));
}
}
}
After investigation, what i found is, During creation of window itself, OnInitUpdate function in class View is getting called each time when AddView() is called.
But if i create the views dynamically, then AddView() wont call OnInitUpdate of my View class and hence the crash occurs.
Exception as follows:
---------------------------
Microsoft Visual C++ Runtime Library
---------------------------
Debug Assertion Failed!
Program: C:\Windows\SYSTEM32\mfc140d.dll
File: f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\afxtabview.cpp
Line: 102
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
---------------------------
Abort Retry Ignore
---------------------------
Can you let me know how to get rid of this problem?
modified 13-Mar-18 1:03am.
|
|
|
|
|
If i call AddView() and run my program, its working absolutely fine with a window and a view(tab).
But instead of calling AddView() initially, at runtime based on user input, i called addview() which leads to a crash. What could be the reason.
<pre>class View : public CScrollView
{
}
class MyTabClass : public CTabView
{
void OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CTabView::OnCreate(lpCreateStruct) == -1)
return -1;
AddView(RUNTIME_CLASS(View),_T("Sheet1"));
}
void RunTimeBasedOnUserInput()
{
for(int i = 0 ; i < userinput; i++)
{
AddView(RUNTIME_CLASS(View),_T("sheet %d",i));
}
}
}
|
|
|
|
|
And what did exactly didn't work when you had applied my example ?
|
|
|
|
|
On splitter window tab control not added. tab.Create() function returns true but tab control is not visible on splitter window.
|
|
|
|
|
In above provided sample code, i have some doubts.
When i created a class CTabbedView which is inherited from CTabView, in OnCreate(), the below call it self created a tab control (horizontal splitter) without any tabs.
if (CTabView::OnCreate(lpCreateStruct) == -1)
return -1;
Then what is the use of below call?
if (!m_tab.Create(CMFCTabCtrl::STYLE_3D, CRect(0, 0, 500, 100), this, 1, CMFCTabCtrl::LOCATION_BOTTOM))
{
TRACE(_T("Failed to create output tab window\n"));
return -1;
}
What is the exact difference between AddTab and AddView.?
|
|
|
|
|
AddTab call is creating the tab area:
"Call this method to add a pane as a new tab on a tabbed pane"
CBaseTabbedPane Class[^]
and AddView call is creating the view which are hosted by CTabView:
"Call this function to add a view to the tab control that is embedded in a frame"
CTabView Class[^]
|
|
|
|
|
In my case, i need to create tabs dynamically. Lets say. When my application starts user will input a value between 1 to 10. Based on user input i need to create the tabs (no. of tabs).
later in each tab in need to display different images.
In this case, should i create my class which is inheriting from CTabView or CTabPane?
|
|
|
|
|
" should i create my class which is inheriting from CTabView or CTabPane?" Definitely from CTabView.
And this CMyTabClass, should include at least one tab, with one view.
|
|
|
|
|
If i call AddView(), this itself is creating a tab. Is this not enough? No need to call AddTab() right?
|
|
|
|
|
Yes, AddView() is creating a tab, so, it is enough.
|
|
|
|
|
If i call AddView() and run my program, its working absolutely fine with a window and a view(tab).
But instead of calling AddView() initially, at runtime based on user input, i called addview() which leads to a crash. What could be the reason.
class View : public CScrollView
{
}
class MyTabClass : public CTabView
{
void OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CTabView::OnCreate(lpCreateStruct) == -1)
return -1;
AddView(RUNTIME_CLASS(View),_T("Sheet1"));
}
void RunTimeBasedOnUserInput()
{
for(int i = 0 ; i < userinput; i++)
{
AddView(RUNTIME_CLASS(View),_T("sheet %d",i));
}
}
}
|
|
|
|
|
Hi. Have you solved this ?
|
|
|
|
|
I am serializing CMapStringToPtr object without any problem, key by key, pointer to pointer.
For this case, the key order it is matter.
So, if I archive this CMapStringToPtr object, and de-archive on the same machine, the key order are fine. But, if I de-archive this object on other machine, the key order are not the same, and this is a PROBLEM. How can avoid this issue ?
Yes, I could serialize another CStringArray with the CMapStringToPtr keys, but I don't know if this a good idea ... can you tell me how to overcome this problem ?
Thank you.
|
|
|
|
|