|
I was orginally using the CTabbedChildWindow. I took it and created CTopTabbedChildWindow and overrided the WM_CREATE message then called CreateTabWindow(m_hWnd, rcDefault, CTCS_TOOLTIPS). To my dismay I got the same issue where the child views (not the tabs themselves) would draw under the Tab Control Bar. It seems that the tab control isn't shifting the view properly the first time, but it will when you change the tab then go back. That leads me to believe that there is something going wrong with the TabbedFrame because it will eventually draw the child window in the right position.
I am currently going through the code to see if I can find the bug but since the library is so big it might take some time.
After some digging, I think the problem is with
void TabbedFrameImpl::UpdateLayout(BOOL bResizeBars = TRUE)
...
if(m_hWndActive)
{
::DeferWindowPos(
hdwp,
m_hWndActive,
NULL,
rect.left, rect.top + m_nTabAreaHeight,
rect.right - rect.left,
rect.bottom - (rect.top+m_nTabAreaHeight),
SWP_NOZORDER | SWP_SHOWWINDOW);
}
...
It looks like this code should be drawing m_hWndActive just below the Tab Bar but it isn't. Now I could be way off on my prognosis here but maybe it's the issue.
|
|
|
|
|
clintsinger wrote:
After some digging, I think the problem is with ...
If you look at the entire function, you'll see the lines:
HDWP hdwp = BeginDeferWindowPos(nWindowPosCount);
DWORD dwStyle = (DWORD)m_TabCtrl.GetWindowLong(GWL_STYLE);
BOOL bHasBottomStyle = (dwStyle & CTCS_BOTTOM);
if(bHasBottomStyle)
{
...
with the part you referenced above as part of the "else".
Then after that "if" statement is
m_TabCtrl.UpdateLayout();
So if there is an issue, its somewhere else
-Daniel
|
|
|
|
|
If I call m_tabCtrl.UpdateLayout (where m_tabCtrl is a CTabbedChildWindow< CDotNetTabCtrl<CTabViewTabItem> >) from my main OnSize then the view positions correctly, even with the tabs on the top. Unfortunately it looks like it the view jumps between the wrong position and the right position. Also clicking one of the tabs resets the child view to the wrong postion (only after an OnSize), until the tab another tab is clicked then the orginal is clicked back again.
|
|
|
|
|
clintsinger wrote:
it looks like it the view jumps between the wrong position and the right position
I can't seem to reproduce this behavior. For example, if I modify CTabbedFrameImpl::OnCreate to call
CreateTabWindow(m_hWnd, rcDefault, CTCS_TOOLTIPS)
instead of
CreateTabWindow(m_hWnd, rcDefault, (CTCS_BOTTOM | CTCS_TOOLTIPS))
the tabs show up on top like they're suppose to, and the child views are positioned correctly. Switching the tabs doesn't make it "jump" at all.
If you can send me directly a sample that demonstrates the problem you're seeing, I'll look into it.
P.S. For the next update, I'm going to update CTabbedFrameImpl so that you can tell it what tabs styles to use when creating the tab control, so that you get to choose a little easier.
-Daniel
|
|
|
|
|
I'm programming in MFC and I whould like use those set of classes in my current project. Can anyone help me to use those in MFC or insert in a separated DLL?
Are there another ways?
Thank you for help me.
Massimo Germi
|
|
|
|
|
Yes, it seems a couple of people would like to use these tabs in an MFC app. If you just want to use an existing tab control (say, like CDotNetTabCtrl) similar to how you use a SysTreeView32 or SysListView32, one way is to setup a Win32 DLL that uses ATL/WTL, then expose DLL functions to access the functionality of the tab control. Another way (that I haven't tried) is to ATL/WTL "enable" your MFC app, and use the tab control class directly.
If you want to use the tab control for doing some of the tabbed MDI or tabbed frame stuff, those classes are written to work with the ATL style of windowing and ATL/WTL base classes (such as CMDIFrameWindowImpl, etc.) used in ATL/WTL apps. These would need to be ported to work in the MFC framework and style of doing windowing.
Of course, the best choice is just to dump MFC completely and come over to the ATL/WTL party
-Daniel
|
|
|
|
|
...provide some classes that let the user drag and drop tabbed views between docking windows... like in .net
That's be really handy!
|
|
|
|
|
Yes, that's on my TODO list. Sergey Klimov has already written a sample called "SDITabbedSample" that uses my tab stuff that let's you drag and drop tabbed views. It's with the demo apps for his WTLDockingWindow stuff.
-Daniel
|
|
|
|
|
I just wanted to say thanks. I really appreciate the hard work that people put into all these libraries to help us little folks out.
|
|
|
|
|
I second that, you guys are doing a great job, and my app wouldn't be anywhere near as cool as it is without you peeps doing what you do!
< < HydraIRC > > www.Hydras-World.com
|
|
|
|
|
If you use the CTabbedMDICommandBarCtrl a bug occurs when compiling with _WIN32_IE >= 0x0500 - the rebars are restored offset to the left, and each time you restart the application, they shift over some more
Edit "tabbedmdi.h", goto line 1316 and remove the "RBBIM_IDEALSIZE" flag.
e.g.
...
for(int i = 0; i < nCount; i++)
{
#if (_WIN32_IE >= 0x0500)
REBARBANDINFO rbi = { sizeof(REBARBANDINFO), RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_STYLE };
//REBARBANDINFO rbi = { sizeof(REBARBANDINFO), RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE | RBBIM_STYLE };
::SendMessage(GetParent(), RB_GETBANDINFO, i, (LPARAM)&rbi);
if(rbi.hwndChild == m_hWnd)
...
Hope this helps, and thanks for creating such a nice looking control!
I'm using it in my application, HydraIRC, grab it from - www.Hydras-World.com
|
|
|
|
|
Interesting. Thanks for the tip! That part of CTabbedMDICommandBarCtrl is a direct copy and paste from CMDICommandBarCtrlImpl::OnAllHookMessages. So, I take it that the default CMDICommandBarCtrl does the same thing to you in a plain vanilla WTL MDI app?
-Daniel
|
|
|
|
|
Well i know that my app does it, and someone else spotted a similar thing in the wtl docking windows stuff and posted a message there too..
It's weird, because for me, it was fine for ages, then all of a sudden starting doing it, then for another user, it did it straight away...
|
|
|
|
|
When you create a new MDI Child window it's always maximized. It should create the window in the same state as the current MDI window.
e.g.
if the current window is restored, new window created as restored.
if current window is maximized, create new window as maximized.
The default should be to always maximize MDI windows, but there should be a way to override this behaviour as it's most annoying for my app..
|
|
|
|
|
Hydra wrote:
When you create a new MDI Child window it's always maximized. It should create the window in the same state as the current MDI window.
You must be referring to the "DockingDemo" sample. If you run the 2 other MDI samples, you'll see that it does indeed do exactly what you would like. In fact, I go to extra lengths that an out-of-the-box WTL app doesn't go through to match the maximization of that last previously active MDI child.
You can see another codeproject article I wrote about this very topic:
http://www.codeproject.com/wtl/wtlmdichildmax.asp
In the "DockingDemo" sample, I am demonstrating how (via my CTabbedMDIChildWindowImpl) you can easily have your app always create MDI children as maximized - by simply including the "WS_MAXIMIZE" style for the child frame. To see the demo without this behavior, simply go to the DockingDemo's version of "HtmlFrame.h", and remove "WS_MAXIMIZE" from CHtmlFrameWinTraits
-Daniel
|
|
|
|
|
ahh, i missed that.. ok thanks! just what i wanted then
|
|
|
|
|
I'm using Windows XP, WTL 7.0, and Visual Studio .NET, when I try any of the demos, or when i use the TabbedMDI control in my app the application does not exit properly if an MDI window is still open.
Instead executing code after the line..:
int nRet = theLoop.Run();
.. it just goes "ding" and then drops back to the dev environment. No assertions, no nothing. I stepped through the code after it processes my CMainFrame::OnClose() and it exits while processing this bit of code from user32.dll
77D458A1 call dword ptr [eax+14h]
77D458A4 push 0
77D458A6 push 0Ch
77D458A8 pop edx
77D458A9 lea ecx,[ebp-0Ch]
77D458AC mov dword ptr [ebp-0Ch],eax
77D458AF call 77D444A7 <<< Exits here!
The callstack from my app is:
HydraIRC.exe!WTL::CMDIFrameWindowImpl<cmainframe,wtl::cmdiwindow,dockwins::cdockingframetraitst<csimplesplitterbar<5>,114229248,262400> >::DefWindowProcA(unsigned int uMsg=0x00000010, unsigned int wParam=0x00000000, long lParam=0x00000000) Line 1270 + 0x22 C++
HydraIRC.exe!WTL::CMDIFrameWindowImpl<cmainframe,wtl::cmdiwindow,dockwins::cdockingframetraitst<csimplesplitterbar<5>,114229248,262400> >::MDIFrameWindowProc(HWND__ * hWnd=0x010c7100, unsigned int uMsg=0x00000010, unsigned int wParam=0x00000000, long lParam=0x00000000) Line 1224 + 0x14 C++
HydraIRC.exe!ATL::CContainedWindowT<atl::cwindow,atl::cwintraits<1442840576,0> >::DefWindowProcA(unsigned int uMsg=0x00000010, unsigned int wParam=0x00000000, long lParam=0x00000000) Line 3779 + 0x21 C++
HydraIRC.exe!ATL::CContainedWindowT<atl::cwindow,atl::cwintraits<1442840576,0> >::WindowProc(HWND__ * hWnd=0x010c7340, unsigned int uMsg=0x00000010, unsigned int wParam=0x00000000, long lParam=0x00000000) Line 3822 + 0x14 C++
HydraIRC.exe!WTL::CMDIFrameWindowImpl<cmainframe,wtl::cmdiwindow,dockwins::cdockingframetraitst<csimplesplitterbar<5>,114229248,262400> >::DefWindowProcA(unsigned int uMsg=0x00000112, unsigned int wParam=0x0000f060, long lParam=0x006d03c6) Line 1270 + 0x22 C++
HydraIRC.exe!WTL::CMDIFrameWindowImpl<cmainframe,wtl::cmdiwindow,dockwins::cdockingframetraitst<csimplesplitterbar<5>,114229248,262400> >::MDIFrameWindowProc(HWND__ * hWnd=0x010c7100, unsigned int uMsg=0x00000112, unsigned int wParam=0x0000f060, long lParam=0x006d03c6) Line 1224 + 0x14 C++
HydraIRC.exe!ATL::CContainedWindowT<atl::cwindow,atl::cwintraits<1442840576,0> >::DefWindowProcA(unsigned int uMsg=0x00000112, unsigned int wParam=0x0000f060, long lParam=0x006d03c6) Line 3779 + 0x21 C++
HydraIRC.exe!ATL::CContainedWindowT<atl::cwindow,atl::cwintraits<1442840576,0> >::WindowProc(HWND__ * hWnd=0x010c7340, unsigned int uMsg=0x00000112, unsigned int wParam=0x0000f060, long lParam=0x006d03c6) Line 3822 + 0x14 C++
HydraIRC.exe!WTL::CMDIFrameWindowImpl<cmainframe,wtl::cmdiwindow,dockwins::cdockingframetraitst<csimplesplitterbar<5>,114229248,262400> >::DefWindowProcA(unsigned int uMsg=0x000000a1, unsigned int wParam=0x00000014, long lParam=0x006d03c6) Line 1270 + 0x22 C++
HydraIRC.exe!WTL::CMDIFrameWindowImpl<cmainframe,wtl::cmdiwindow,dockwins::cdockingframetraitst<csimplesplitterbar<5>,114229248,262400> >::MDIFrameWindowProc(HWND__ * hWnd=0x010c7100, unsigned int uMsg=0x000000a1, unsigned int wParam=0x00000014, long lParam=0x006d03c6) Line 1224 + 0x14 C++
HydraIRC.exe!ATL::CContainedWindowT<atl::cwindow,atl::cwintraits<1442840576,0> >::DefWindowProcA(unsigned int uMsg=0x000000a1, unsigned int wParam=0x00000014, long lParam=0x006d03c6) Line 3779 + 0x21 C++
HydraIRC.exe!ATL::CContainedWindowT<atl::cwindow,atl::cwintraits<1442840576,0> >::WindowProc(HWND__ * hWnd=0x010c7340, unsigned int uMsg=0x000000a1, unsigned int wParam=0x00000014, long lParam=0x006d03c6) Line 3822 + 0x14 C++
HydraIRC.exe!Run(char * __formal=0x00151f18, int nCmdShow=0x00000001) Line 533 + 0x8 C++
HydraIRC.exe!WinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * __formal=0x00000000, char * lpstrCmdLine=0x00151f18, int nCmdShow=0x00000001) Line 603 + 0xd C++
HydraIRC.exe!WinMainCRTStartup() Line 251 + 0x32 C
kernel32.dll!77e7eb69()
Hope you can fix it!
|
|
|
|
|
Hydra wrote:
when I try any of the demos, or when i use the TabbedMDI control in my app the application does not exit properly if an MDI window is still open
Thanks for reporting this! I'm still looking into this, and I'll reply back to this message when I figure out what the problem is or how to fix it (hopefully both ).
Thanks,
-Daniel
|
|
|
|
|
sure thing, and if you need any more info from me, don't hesitate to ask.
|
|
|
|
|
Ok, so I thought, bugger the MDI tabs, don't really need them anyway because I have a taskbar on a rebar toolbar that controls the windows and reorders itself according to which windows you used last:
m_MyToolBar.Movebutton(currentbuttonindex, 0) //move to first button
I wish the .net ones did that, actually, add that to your TODO list too..
anyway, I digress..
So, I #ifdef'd out the MDI tabbed stuff, and implemented two docking windows, each with two tabbed views, and again, the exit problem occurs when there are MDI windows open ?!?.
So maybe the bug is not in the TabbedMDI..Impl, but instead the bug might be in the actual custom Tab Controls or maybe not, but I thought this might be useful for you to know anyway.
|
|
|
|
|
ahh, i might have narrowed it down a bit for you..
i accidentally declared my view in my base class as well as my derived class (oops!) and initilised the ones in the derived class and added them to the tabs and that's what caused exit problem in the above example.
After i removed the declaration in the derived class it all worked normally and exited without a error, even with multiple MDI windows open.
So, maybe the problem *IS* with just the MDI tabs, as I originally thought, but maybe the solution has something to do with something similar...
here's what i had:
class TextQueueManager
{
public:
CSimpleArray<textqueueitem *=""> m_TextQueue;
int m_QueueType;
CTextQueueView *m_pTextQueueView; // <-- the tabbed view...
TextQueueManager( void );
~TextQueueManager( void );
void AddItem(char *From, char *Message, char *ServerName);
void RemoveOldItems( void );
private:
void RemoveItem( TextQueueItem *pTQI );
};
class PrivMsgQueueManager :
public TextQueueManager
{
public:
//CTextQueueView *m_pTextQueueView; // <-- oops! had it here too..
PrivMsgQueueManager( void )
{
m_QueueType = CWQUEUE_PRIVMSG;
m_pTextQueueView = new CTextQueueView(this);
}
~PrivMsgQueueManager( void )
{
delete m_pTextQueueView;
}
};
|
|
|
|
|
Hydra wrote:
when I try any of the demos, or when i use the TabbedMDI control in my app the application does not exit properly if an MDI window is still open
Sorry for taking so long to get back about this.
The fix turns out to be very simple. In DotNetTabCtrl.h, replace line 719:
m_tooltip.SetToolRect(m_hWnd, ectcToolTip_Close, &m_rcCloseButton);
with
if(m_tooltip.IsWindow())
{
m_tooltip.SetToolRect(m_hWnd, ectcToolTip_Close, &m_rcCloseButton);
}
and line 773 and 774:
m_tooltip.SetToolRect(m_hWnd, ectcToolTip_ScrollRight, &m_rcScrollRight);
m_tooltip.SetToolRect(m_hWnd, ectcToolTip_ScrollLeft, &m_rcScrollLeft);
with
if(m_tooltip.IsWindow())
{
m_tooltip.SetToolRect(m_hWnd, ectcToolTip_ScrollRight, &m_rcScrollRight);
m_tooltip.SetToolRect(m_hWnd, ectcToolTip_ScrollLeft, &m_rcScrollLeft);
}
These changes will be in my next updates.
The problem was that when all the items are deleted in DeleteAllItems (called while handling WM_DESTROY) DeleteItem is called, which calls UpdateLayout, which, when CTCS_CLOSEBUTTON and/or CTCS_SCROLL are set, tries to update their respective tooltips, but the tooltips have already been destroyed.
I'm also going to make a change to DeleteAllItems that you can make now if you like. Replace CustomTabCtrl.h line 2338:
while( GetItemCount()>0 ) DeleteItem(0U, false, true);
with
this->SendMessage(WM_SETREDRAW, FALSE, 0);
while( GetItemCount()>0 ) DeleteItem(0U, false, true);
this->SendMessage(WM_SETREDRAW, TRUE, 0);
-Daniel
|
|
|
|
|
I can't find the file "altapp.h".
|
|
|
|
|
atlapp.h is part of WTL. You can get WTL from
http://msdn.microsoft.com/downloads/?url=/downloads/sample.asp?url=/msdn-files/027/001/586/msdncompositedoc.xml&frame=true
or go to msdn.microsoft.com, go to developer downloads ->
Visual Studio, Tools and Languages -> Visual C++ -> Windows Template Library
After installing it, be sure to put WTL's include directory in your Tools->Options->Directories->Include files list.
-Daniel
|
|
|
|
|
I noticed if I change CreateTabWindow(m_hWnd, rcDefault, (CTCS_BOTTOM | CTCS_TOOLTIPS)); to CreateTabWindow(m_hWnd, rcDefault, (CTCS_BOTTOM | CTCS_TOOLTIPS | CTCS_SCROLL | CTCS_CLOSEBUTTON)); I get the associate controls but when I close the application a whole pile of memory and resource leaks show up in BoundsChecker. I noticed that these same leaks appear in the other samples where the scroll and closebutton are used. Therefore I can only assume that it is do to these features.
Just a heads up.
Cheers,
Clint
|
|
|
|
|