|
erez_me wrote:
Why isn't my MainFrame class gets the notification?
The short answer - the MainFrame is not the direct parent of the tab control. The direct parent is likely a class derived from either CMDITabOwnerImpl or CTabbedFrameImpl. You can run Spy++ to see the window hierarchy.
If you're using MDI tabs, and you want the MainFrame to receive notifications from the tab control, you could have your own CMDITabOwnerImpl derived class. This class could either forward on notifications to the MainFrame, or do the special handling right there. If you have your own CMDITabOwnerImpl derived class, you can use that in the template parameters for CTabbedMDIClient.
If you're not doing MDI tabs, and have a CTabbedFrameImpl derived class as the tab owner (such as CTabbedPopupFrame or CTabbedChildWindow ), you can call SetForwardNotifications to have notifications forwarded on to the parent of the tab owner. Or instead, you could make your own CTabbedFrameImpl derived class that did whatever special processing you needed.
I would suggest customizing your own tab owner class to do what you want. If you need some external information, you could always add different member variables and accessor functions, or even come up with your own notifications or registered messages to communicate with the window's parent.
HTH,
-Daniel
|
|
|
|
|
Thanks Daniel,
I realized that the actual parent of the tab control was really not the actual Main Frame window.
I should probably derive my own CMDITabOwnerImpl and reflect the notification back to the parent (which will be in my case the CMainFrame class).
Thanks again for keeping up with me as I am trying to grasp it all
Erez
|
|
|
|
|
i meet the same question with you. i add the below codes into "TabbedMDI.h":
LRESULT OnSelChanging(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
{
ATLASSERT(idCtrl==pnmh->idFrom);
// Be sure the notification is from the tab control
// (and not from a sibling like a list view control)
if(pnmh && (m_TabCtrl == pnmh->hwndFrom))
{
ATLTRACE("***CMDITabOwner::OnSelChanging:%d\n", m_TabCtrl.GetCurSel());
// Send notification to MainFrm Window (=::GetParent(m_hWndMDIClient))
::SendMessage(::GetParent(m_hWndMDIClient), WM_NOTIFY, idCtrl, (LPARAM)pnmh );
}
bHandled = FALSE;
return 0;
}
and:
LRESULT OnSelChange(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
{
// Be sure the notification is from the tab control
// (and not from a sibling like a list view control)
if(pnmh && (m_TabCtrl == pnmh->hwndFrom))
{
int nNewTab = m_TabCtrl.GetCurSel();
// i added:
ATLTRACE("***CMDITabOwner::OnSelChange:%d\n", nNewTab);
// Send notification to MainFrm Window (=::GetParent(m_hWndMDIClient))
::SendMessage(::GetParent(m_hWndMDIClient), WM_NOTIFY, idCtrl, (LPARAM)pnmh );
......
}
others just as yours. so you can recieve CTCN_SELCHANGING or CTCN_SELCHANGE in MainFrm.
the core is the HWND i got using ::GetParent(m_hWndMDIClient) is MainFrm's window handle.
|
|
|
|
|
Almost three years after the first post, thanks for keeping your article (and source codes) updated.
Pascal Binggeli
|
|
|
|
|
My compiler can't find the atlapp.h. Is this a standard MSVC .NET file?
|
|
|
|
|
|
Hi Daniel, I'm trying to integrate your tab solution into a custom control and I'm getting compile warnings. It compiles, but the tabs don't show up. I'm using VC7 with WTL 7.1. Any thoughts would be appreciated!
Thanks,
Dave
c:\MDI_AX_BASE\MdiControl_src\MdiControl\CUSTOMTABCTRL.H(1845) : warning C4244: 'initializing' : conversion from 'UINT_PTR' to 'UINT', possible loss of data
c:\MDI_AX_BASE\MdiControl_src\MdiControl\CUSTOMTABCTRL.H(1835) : while compiling class-template member function 'LRESULT CCustomTabCtrl<T,TItem,TBase,TWinTraits>::OnGetToolTipInfo(int,LPNMHDR,BOOL &)'
with
[
T=CDotNetTabCtrl<CTabViewTabItem>,
TItem=CTabViewTabItem,
TBase=ATL::CWindow,
TWinTraits=CCustomTabCtrlWinTraits
]
c:\MDI_AX_BASE\MdiControl_src\MdiControl\DOTNETTABCTRL.H(18) : see reference to class template instantiation 'CCustomTabCtrl<T,TItem,TBase,TWinTraits>' being compiled
with
[
T=CDotNetTabCtrl<CTabViewTabItem>,
TItem=CTabViewTabItem,
TBase=ATL::CWindow,
TWinTraits=CCustomTabCtrlWinTraits
]
c:\MDI_AX_BASE\MdiControl_src\MdiControl\DOTNETTABCTRL.H(1121) : see reference to class template instantiation 'CDotNetTabCtrlImpl<T,TItem>' being compiled
with
[
T=CDotNetTabCtrl<CTabViewTabItem>,
TItem=CTabViewTabItem
]
c:\MDI_AX_BASE\MdiControl_src\MdiControl\TABBEDFRAME.H(188) : see reference to class template instantiation 'CDotNetTabCtrl<TItem>' being compiled
with
[
TItem=CTabViewTabItem
]
c:\MDI_AX_BASE\MdiControl_src\MdiControl\TABBEDMDI.H(657) : see reference to class template instantiation 'CCustomTabOwnerImpl<T,TTabCtrl>' being compiled
with
[
T=CMDITabOwner<CDotNetTabCtrl<CTabViewTabItem>>,
TTabCtrl=CDotNetTabCtrl<CTabViewTabItem>
]
c:\MDI_AX_BASE\MdiControl_src\MdiControl\TABBEDMDI.H(1104) : see reference to class template instantiation 'CMDITabOwnerImpl<T,TTabCtrl>' being compiled
with
[
T=CMDITabOwner<CDotNetTabCtrl<CTabViewTabItem>>,
TTabCtrl=CDotNetTabCtrl<CTabViewTabItem>
]
c:\MDI_AX_BASE\MdiControl_src\MdiControl\TABBEDMDI.H(1128) : see reference to class template instantiation 'CMDITabOwner<TTabCtrl>' being compiled
with
[
TTabCtrl=CDotNetTabCtrl<CTabViewTabItem>
]
c:\MDI_AX_BASE\MdiControl_src\MdiControl\TABBEDMDI.H(372) : see reference to class template instantiation 'CTabbedMDIClient<TTabCtrl>' being compiled
with
[
TTabCtrl=CDotNetTabCtrl<CTabViewTabItem>
]
c:\MDI_AX_BASE\MdiControl_src\MdiControl\MainFrm.h(7) : see reference to class template instantiation 'CTabbedMDIFrameWindowImpl<T>' being compiled
with
[
T=CMainFrame
]
c:\MDI_AX_BASE\MdiControl_src\MdiControl\TABBEDFRAME.H(468) : warning C4267: 'argument' : conversion from 'size_t' to 'int', possible loss of data
c:\MDI_AX_BASE\MdiControl_src\MdiControl\TABBEDFRAME.H(447) : while compiling class-template member function 'int CCustomTabOwnerImpl<T,TTabCtrl>::DisplayTab(HWND,BOOL,BOOL)'
with
[
T=CMDITabOwner<CDotNetTabCtrl<CTabViewTabItem>>,
TTabCtrl=CDotNetTabCtrl<CTabViewTabItem>
]
c:\MDI_AX_BASE\MdiControl_src\MdiControl\TABBEDFRAME.H(583) : warning C4267: 'argument' : conversion from 'size_t' to 'int', possible loss of data
c:\MDI_AX_BASE\MdiControl_src\MdiControl\TABBEDFRAME.H(553) : while compiling class-template member function 'BOOL CCustomTabOwnerImpl<T,TTabCtrl>::UpdateTabText(HWND,LPCTSTR)'
with
[
T=CMDITabOwner<CDotNetTabCtrl<CTabViewTabItem>>,
TTabCtrl=CDotNetTabCtrl<CTabViewTabItem>
]
c:\MDI_AX_BASE\MdiControl_src\MdiControl\CUSTOMTABCTRL.H(2863) : warning C4267: 'return' : conversion from 'size_t' to 'int', possible loss of data
c:\MDI_AX_BASE\MdiControl_src\MdiControl\CUSTOMTABCTRL.H(2843) : while compiling class-template member function 'int CCustomTabCtrl<T,TItem,TBase,TWinTraits>::HitTest(LPCTCHITTESTINFO) const'
with
[
T=CDotNetTabCtrl<CTabViewTabItem>,
TItem=CTabViewTabItem,
TBase=ATL::CWindow,
TWinTraits=CCustomTabCtrlWinTraits
]
c:\MDI_AX_BASE\MdiControl_src\MdiControl\CUSTOMTABCTRL.H(912) : warning C4312: 'type cast' : conversion from 'DWORD' to 'HCURSOR' of greater size
c:\MDI_AX_BASE\MdiControl_src\MdiControl\CUSTOMTABCTRL.H(906) : while compiling class-template member function 'void CCustomTabCtrl<T,TItem,TBase,TWinTraits>::StopItemDrag(bool)'
with
[
T=CDotNetTabCtrl<CTabViewTabItem>,
TItem=CTabViewTabItem,
TBase=ATL::CWindow,
TWinTraits=CCustomTabCtrlWinTraits
]
c:\MDI_AX_BASE\MdiControl_src\MdiControl\CUSTOMTABCTRL.H(2067) : warning C4267: 'argument' : conversion from 'size_t' to 'UINT', possible loss of data
c:\MDI_AX_BASE\MdiControl_src\MdiControl\CUSTOMTABCTRL.H(2045) : while compiling class-template member function 'void CCustomTabCtrl<T,TItem,TBase,TWinTraits>::UpdateTabItemTooltipRects(void)'
with
[
T=CDotNetTabCtrl<CTabViewTabItem>,
TItem=CTabViewTabItem,
TBase=ATL::CWindow,
TWinTraits=CCustomTabCtrlWinTraits
]
c:\MDI_AX_BASE\MdiControl_src\MdiControl\CUSTOMTABCTRL.H(2512) : warning C4267: 'argument' : conversion from 'size_t' to 'int', possible loss of data
c:\MDI_AX_BASE\MdiControl_src\MdiControl\CUSTOMTABCTRL.H(2490) : while compiling class-template member function 'BOOL CCustomTabCtrl<T,TItem,TBase,TWinTraits>::MoveItem(size_t,size_t,bool,bool)'
with
[
T=CDotNetTabCtrl<CTabViewTabItem>,
TItem=CTabViewTabItem,
TBase=ATL::CWindow,
TWinTraits=CCustomTabCtrlWinTraits
]
c:\MDI_AX_BASE\MdiControl_src\MdiControl\CUSTOMTABCTRL.H(2518) : warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data
c:\MDI_AX_BASE\MdiControl_src\MdiControl\CUSTOMTABCTRL.H(2518) : warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data
c:\MDI_AX_BASE\MdiControl_src\MdiControl\CUSTOMTABCTRL.H(2580) : warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data
c:\MDI_AX_BASE\MdiControl_src\MdiControl\CUSTOMTABCTRL.H(2567) : while compiling class-template member function 'BOOL CCustomTabCtrl<T,TItem,TBase,TWinTraits>::DeleteItem(size_t,bool,bool)'
with
[
T=CDotNetTabCtrl<CTabViewTabItem>,
TItem=CTabViewTabItem,
TBase=ATL::CWindow,
TWinTraits=CCustomTabCtrlWinTraits
]
c:\MDI_AX_BASE\MdiControl_src\MdiControl\CUSTOMTABCTRL.H(2683) : warning C4267: 'argument' : conversion from 'size_t' to 'UINT', possible loss of data
c:\MDI_AX_BASE\MdiControl_src\MdiControl\CUSTOMTABCTRL.H(3025) : warning C4267: 'return' : conversion from 'size_t' to 'int', possible loss of data
c:\MDI_AX_BASE\MdiControl_src\MdiControl\CUSTOMTABCTRL.H(3013) : while compiling class-template member function 'int CCustomTabCtrl<T,TItem,TBase,TWinTraits>::FindItem(CCustomTabCtrl<T,TItem,TBase,TWinTraits>::TItem *,CTabViewTabItem::FieldFlags,int) const'
with
[
T=CDotNetTabCtrl<CTabViewTabItem>,
TItem=CTabViewTabItem,
TBase=ATL::CWindow,
TWinTraits=CCustomTabCtrlWinTraits
]
c:\MDI_AX_BASE\MdiControl_src\MdiControl\CUSTOMTABCTRL.H(2453) : warning C4267: '=' : conversion from 'size_t' to 'int', possible loss of data
c:\MDI_AX_BASE\MdiControl_src\MdiControl\CUSTOMTABCTRL.H(2438) : while compiling class-template member function 'int CCustomTabCtrl<T,TItem,TBase,TWinTraits>::InsertItem(int,CCustomTabCtrl<T,TItem,TBase,TWinTraits>::TItem *,bool)'
with
[
T=CDotNetTabCtrl<CTabViewTabItem>,
TItem=CTabViewTabItem,
TBase=ATL::CWindow,
TWinTraits=CCustomTabCtrlWinTraits
]
c:\MDI_AX_BASE\MdiControl_src\MdiControl\CUSTOMTABCTRL.H(2481) : warning C4267: 'argument' : conversion from 'size_t' to 'UINT', possible loss of data
c:\MDI_AX_BASE\MdiControl_src\MdiControl\DOTNETTABCTRL.H(385) : warning C4244: 'initializing' : conversion from 'DWORD_PTR' to 'int', possible loss of data
c:\MDI_AX_BASE\MdiControl_src\MdiControl\DOTNETTABCTRL.H(380) : while compiling class-template member function 'void CDotNetTabCtrlImpl<T,TItem>::DrawItem_TabInactive(DWORD,LPNMCTCCUSTOMDRAW,RECT &)'
with
[
T=CDotNetTabCtrl<CTabViewTabItem>,
TItem=CTabViewTabItem
]
c:\MDI_AX_BASE\MdiControl_src\MdiControl\DOTNETTABCTRL.H(437) : warning C4244: 'initializing' : conversion from 'DWORD_PTR' to 'int', possible loss of data
c:\MDI_AX_BASE\MdiControl_src\MdiControl\DOTNETTABCTRL.H(432) : while compiling class-template member function 'void CDotNetTabCtrlImpl<T,TItem>::DrawItem_ImageAndText(DWORD,LPNMCTCCUSTOMDRAW,int,RECT &,RECT &)'
with
[
T=CDotNetTabCtrl<CTabViewTabItem>,
TItem=CTabViewTabItem
]
|
|
|
|
|
The line numbers indicated don't match the code it refers to - have you customized these files at all? Also, are you sure you're using VC 7.0 and not 7.1?
However, I do know that there are some updates that need to be made so that it compiles 64-bit clean. These warnings suggest you are either compiling for 64-bit, or you have /Wp64 (detect 64-bit portability issues) set.
I'll be updating the article with new code that compiles 64-bit clean. There are also a couple minor updates to accomodate WTL 7.5 I'll make at the same time. I was planning on uploading these updates closer to the WTL 7.5 release, but I may do them sooner than that.
As far as why the tabs aren't showing up, it's likely that's a different problem. Have you tried doing complete rebuilds of the samples to see if they work? If you're integrating it into your own thing, pay particular attention to how you have the tab owner working (and sizing). Does the tab control show up in Spy++ as a window, but it's just set to 0 width and height?
-Daniel
|
|
|
|
|
Greetings: First of all, excellent work and better yet, excellent responses to all those with questions!
There was a recent post about this, however, I didn't see any confirmation that a working solution was arrived at. I'd like to be able to select the active tab and contents under certain criteria. I'm able to enumerate all the child windows to get the HWND of the view frame window that I want to bring to the foreground, but I have not been able to get this to work.
If you could post the code needed to do this (I'm using the dotnet tab with MDI) based on the frame HWND of the desired view, I'd be very appreciative! Everything else is working great!
Fabulous effort! Thanks Daniel!
|
|
|
|
|
Davem1 wrote:
Greetings: First of all, excellent work and better yet, excellent responses to all those with questions!
Thanks
Davem1 wrote:
I'd like to be able to select the active tab and contents under certain criteria. I'm able to enumerate all the child windows to get the HWND of the view frame window that I want to bring to the foreground, but I have not been able to get this to work.
Is this an MDI? If so, all you have to do is call MDIActivate(hWndViewFrame) on the main frame or the MDIClient window, or this->MDIActivate(m_hWnd) from within the MDI child frame (the class deriving from CTabbedMDIChildWindowImpl). If you do, the corresponding tab for the window will automatically be selected.
If you want to go from the tab side of things and have C++ knowledge of the tab owner class, call DisplayTab(hWndViewFrame).
Let me know if these ways don't work for you - there's some other ways to do this as well. Also, let me know if you need this for MDI tabs, or other tabs.
HTH,
-Daniel
|
|
|
|
|
Hi Daniel, Wow! Thanks for the quick response. This is for an out of the box WTL MDI application. In trying to use your solution (above) from a CMainFrame callback function that I use to enumerate all the child windows and MDIActive() is reported as "identifier not found".
I'm pretty new to WTL, what is the dependency that I'm missing? I get the same response ("identifier not found") trying to use DisplayTab() as well. It seems that I have some dependency issue that I haven't identified.
And yes, this is for MDI tabs. This is probably something easy in terms of dependencies and any feedback from you would be greatly appreciated!
Thanks again Daniel!
|
|
|
|
|
Correction to above, I'm using MDIActivate(), not MDIActive(). I suspect the issue is how to get MDIActivate() recognized from BOOL CALLBACK EnumChildWindowProc(HWND hWndViewFrame,LPARAM lParam) which is called from a CMainFrame function EnumChildWindows(m_hWndMDIClient, EnumChildWindowProc,1)
Thanks again! Dave
|
|
|
|
|
Hi Daniel, I got it working by sending a custom message to the desired child frame and then in the child frame message handler, using this->MDIActivate(m_hWnd) as you suggested.
Works great! Thanks so much for your response.
Dave
|
|
|
|
|
Davem1 wrote:
I got it working by sending a custom message to the desired child frame and then in the child frame message handler, using this->MDIActivate(m_hWnd) as you suggested.
If you have window-only knowledge of the child frame, and are outside of the main frame (or in a static method of the main frame), instead of sending a custom message, you could try this:
HWND hWndMDIClient = ::GetParent(hWndChildFrame);
::SendMessage(hWndMDIClient, WM_MDIACTIVATE, (WPARAM)hWndChildFrame, 0);
Or if you're calling EnumChildWindows from the main frame, you could pass m_hWndMDIClient as the LPARAM, and avoid the GetParent call in the callback.
The MDIActivate call is actually just a thin wrapper on CMDIWindow that does just this (CMDIWindow inherits from CWindow and is used by the main frame and the MDI child frames).
HTH,
-Daniel
|
|
|
|
|
Userful code! but I wanna create a multi-tabbed MDI app. Or create a tabbed MDI include a tabbed Frame, and tabbedChild display in a view of tabbed frame.
How to do it?
And excuse my bad english
|
|
|
|
|
I create a CTabbedChildWindow my CMainFrame class implement the CTabbedMDIFrameWindowImpl, then create a view as a tab of CTabbedChildWindow as following code:
<br />
m_tabbedChildWindow.Create(m_hWnd, rcDefault);<br />
<br />
m_hWndClient = m_ChildFrame.Create(m_tabbedChildWindow, rcDefault, _T("Child"),<br />
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);<br />
m_tabbedClient.SetTabOwnerParent(m_ChildFrame);<br />
BOOL bSubclass = m_tabbedClient.SubclassWindow(m_hWndMDIClient);<br />
But it's not working ...
|
|
|
|
|
Mongris wrote:
Userful code! but I wanna create a multi-tabbed MDI app. Or create a tabbed MDI include a tabbed Frame, and tabbedChild display in a view of tabbed frame.
I'm not exactly clear on what you mean. But I'll give it a guess.
Here's a couple of things to keep in mind.
Getting MDI tabs to work in a different window hierarchy might be tricky (like having the MDI Client window as a child of tab view). Instead, you might want to consider starting with an SDI application, like the TabbedSDISplitter demonstrates. The "view" of a tab can be any window - including a child window that contains another tab control and associated tab views. However, if the child window has special dependencies (like an MDI child frame expects to be a direct child of the MDI client window), it will only work if those dependencies are met. However, if you keep it to just "view" windows, you can do it without any trouble.
Try this.
- Copy the TabbedSDISplitter sample.
- In mainfrm.h, copy the declaration for m_tabbedChildWindow, and make a m_tabbedGrandChildWindow.
- After the m_tabbedChildWindow.Create call, add the lines
m_tabbedGrandChildWindow.SetReflectNotifications(true);
m_tabbedGrandChildWindow.SetTabStyles(CTCS_TOOLTIPS | CTCS_DRAGREARRANGE);
m_tabbedGrandChildWindow.Create(m_tabbedChildWindow, rcDefault);
- Change the m_view2 and m_view3 Create calls to pass m_tabbedGrandChildWindow as the parent window (instead of m_tabbedChildWindow)
- After the "m_tabbedChildWindow.AddTabWithIcon(m_view1, ..." line, add the line
m_tabbedChildWindow.AddTabWithIcon(m_tabbedGrandChildWindow, _T("Grand Children"), IDI_DOCUMENT); - After that line, change the DisplayTab calls with m_view2 and m_view3 to use m_tabbedGrandChildWindow instead of m_tabbedChildWindow
- Compile and run.
HTH,
-Daniel
|
|
|
|
|
Thank you for your help!
My original idea is:
I wanna create a application. The application is a MDI window. The tabs of MDIChildWindow in a "view" of a CTabbedChildWindow. So I can present larruping "views" in CTabbedChildWindow, but only one "view" is the MDIClient window and inherit the trait of MDIApp.
If I consider starting with an SDI application, I will implement the trait MDIApp myself as dynamic menu etc, but I am not idea yet.
Give up my original idea, I tried to manage the child views by CTabbedChildWindow as following style:
<br />
m_tabbedGrandChildWindow.SetTabStyles(CTCS_TOOLTIPS | CTCS_DRAGREARRANGE |CTCS_SCROLL | CTCS_CLOSEBUTTON );
But there no effect when hit closebutton.
More suggestions please!Thank you
|
|
|
|
|
Mongris wrote:
But there no effect when hit closebutton.
You'd need to add to the tab owner a handler for the CTCN_CLOSE notification. Here's an example class (watch for line wrap)
template <class TTabCtrl = CDotNetTabCtrl<CTabViewTabItem> >
class CTabbedChildWithCloseWindow :
public CTabbedFrameImpl<CTabbedChildWithCloseWindow, TTabCtrl, CTabbedChildWindowBase<CTabbedChildWithCloseWindow, CWindow, TabbedChildWindowWinTraits> >
{
protected:
typedef CTabbedChildWithCloseWindow<TTabCtrl> thisClass;
typedef CTabbedFrameImpl<CTabbedChildWithCloseWindow, TTabCtrl, CTabbedChildWindowBase<CTabbedChildWithCloseWindow, CWindow, TabbedChildWindowWinTraits> > baseClass;
public:
CTabbedChildWithCloseWindow(bool bReflectNotifications = false) :
baseClass(bReflectNotifications)
{
}
public:
DECLARE_FRAME_WND_CLASS_EX(_T("TabbedChildWindow"), 0, 0, COLOR_APPWORKSPACE)
BOOL PreTranslateMessage(MSG* pMsg)
{
HWND hWndFocus = ::GetFocus();
if(m_hWndActive != NULL && ::IsWindow(m_hWndActive) &&
(m_hWndActive == hWndFocus || ::IsChild(m_hWndActive, hWndFocus)))
{
if(::SendMessage(m_hWndActive, WM_FORWARDMSG, 0, (LPARAM)pMsg))
{
return TRUE;
}
}
return FALSE;
}
BEGIN_MSG_MAP(thisClass)
NOTIFY_CODE_HANDLER(CTCN_CLOSE, OnTabClose)
CHAIN_MSG_MAP(baseClass)
END_MSG_MAP()
LRESULT OnTabClose(int , LPNMHDR pnmh, BOOL& bHandled)
{
LPNMCTCITEM pnmCustomTab = (LPNMCTCITEM)pnmh;
if(pnmCustomTab)
{
if(pnmCustomTab->iItem >= 0)
{
TTabCtrl::TItem* pItem = m_TabCtrl.GetItem(pnmCustomTab->iItem);
if(pItem)
{
HWND hWndChild = pItem->GetTabView();
if(0 == ::SendMessage(hWndChild, WM_CLOSE, 0, 0L))
{
this->RemoveTab(hWndChild);
}
}
}
}
bHandled = FALSE;
return 0;
}
};
HTH,
-Daniel
|
|
|
|
|
Thank you, that's what I want.
|
|
|
|
|
Another question:
I try the DockingDemo and use CTabbedChildWindowImpl instead of CTabbedFrameImpl in CHtmlFrame class. But the view wouldn't be visible.
What happend in dockwins::CAutoHideMDIDockingFrameImpl of the "m_hWndClient"?
|
|
|
|
|
Mongris wrote:
Another question:
I try the DockingDemo and use CTabbedChildWindowImpl instead of CTabbedFrameImpl in CHtmlFrame class. But the view wouldn't be visible.
What happend in dockwins::CAutoHideMDIDockingFrameImpl of the "m_hWndClient"?
CHtmlFrame is an MDI child frame. There's one thing that you might not have noticed. CHtmlFrame inherits from CTabbedFrameImpl, but also inherits from CTabbedMDIChildWindowImpl via the 3rd template parameter. You could try passing the same CTabbedMDIChildWindowImpl declaration to CTabbedChildWindowImpl, but I haven't tried it.
What were you hoping that CTabbedChildWindowImpl would give you that CTabbedFrameImpl doesn't? CTabbedChildWindowImpl is more appropriate when you want to swap out some "view" window with a tab owner/tab control/tabbed views scenario. CTabbedFrameImpl is what you use when you need the window to act as a frame (like an MDI child frame, a top level SDI frame, etc.) in addition to a tab owner/tab control/tabbed views.
HTH,
-Daniel
|
|
|
|
|
Sorry, that's my clerical error. I should to type "CTabbedMDIChildWindowImpl" but typed "CTabbedFrameImpl".
Thank you!
|
|
|
|
|
under WTL 7.5.5002.0:
c:\TabbingFramework_demo\include\atlgdix.h(226) : error C2953: 'WTL::CIconT' : template class has already been defined
c:\TabbingFramework_demo\include\atlgdix.h(226) : see declaration of 'WTL::CIconT'
c:\TabbingFramework_demo\include\atlgdix.h(228) : error C2955: 'WTL::CIconT' : use of class template requires template argument list
c:\TabbingFramework_demo\include\atlgdix.h(226) : see declaration of 'WTL::CIconT'
c:\TabbingFramework_demo\include\atlgdix.h(228) : error C2371: 'WTL::CIcon' : redefinition; different basic types
c:\wtl75\include\atluser.h(871) : see declaration of 'WTL::CIcon'
c:\TabbingFramework_demo\include\atlgdix.h(229) : error C2955: 'WTL::CIconT' : use of class template requires template argument list
c:\TabbingFramework_demo\include\atlgdix.h(226) : see declaration of 'WTL::CIconT'
c:\TabbingFramework_demo\include\atlgdix.h(229) : error C2371: 'WTL::CIconHandle' : redefinition; different basic types
c:\wtl75\include\atluser.h(870) : see declaration of 'WTL::CIconHandle'
c:\TabbingFramework_demo\include\atlgdix.h(364) : error
C2953: 'WTL::CCursorT' : template class has already been defined
c:\TabbingFramework_demo\include\atlgdix.h(364) : see declaration of 'WTL::CCursorT'
c:\TabbingFramework_demo\include\atlgdix.h(366) : error C2955: 'WTL::CCursorT' : use of class template requires template argument list
c:\TabbingFramework_demo\include\atlgdix.h(364) : see declaration of 'WTL::CCursorT'
c:\TabbingFramework_demo\include\atlgdix.h(366) : error C2371: 'WTL::CCursor' : redefinition; different basic types
c:\wtl75\include\atluser.h(1028) : see declaration of 'WTL::CCursor'
c:\TabbingFramework_demo\include\atlgdix.h(367) : error C2955: 'WTL::CCursorT' : use of class template requires template argument list
c:\TabbingFramework_demo\include\atlgdix.h(364) : see declaration of 'WTL::CCursorT'
c:\TabbingFramework_demo\include\atlgdix.h(367) : error C2371: 'WTL::CCursorHandle' : redefinition; different basic types
c:\wtl75\include\atluser.h(1027) : see declaration of 'WTL::CCursorHandle'
c:\TabbingFramework_demo\include\atlgdix.h(456) : error C2953: 'WTL::CAcceleratorT' : template class has already been defined
c:\TabbingFramework_demo\include\atlgdix.h(456) : see declaration of 'WTL::CAcceleratorT'
c:\TabbingFramework_demo\include\atlgdix.h(458) : error C2955: 'WTL::CAcceleratorT' : use of class template requires template argument list
c:\TabbingFramework_demo\include\atlgdix.h(456) : see declaration of 'WTL::CAcceleratorT'
c:\TabbingFramework_demo\include\atlgdix.h(458) : error C2371: 'WTL::CAccelerator' : redefinition; different basic types
c:\wtl75\include\atluser.h(665) : see declaration of 'WTL::CAccelerator'
c:\TabbingFramework_demo\include\atlgdix.h(459) : error C2955: 'WTL::CAcceleratorT' : use of class template requires template argument list
c:\TabbingFramework_demo\include\atlgdix.h(456) : see declaration of 'WTL::CAcceleratorT'
c:\TabbingFramework_demo\include\atlgdix.h(459) : error C2371: 'WTL::CAcceleratorHandle' : redefinition; different basic types
c:\wtl75\include\atluser.h(664) : see declaration of 'WTL::CAcceleratorHandle'
c:\TabbingFramework_demo\include\atlgdix.h(465) : error C2011: 'WTL::CLogFont' : 'class' type redefinition
c:\wtl75\include\atlgdi.h(354) : see declaration of 'WTL::CLogFont'
|
|
|
|
|
Yes, these things are getting added to WTL proper for WTL 7.5. I'll have an updated version of atlgdix.h in my next update, but for now, add the line
#if(_WTL_VER < 0x0750) before the CIcon section, and add
#endif //(_WTL_VER < 0x0750) after CLogFont and before CMemDC.
-Daniel
|
|
|
|
|