|
Hello Dan,
How about support for the new Office 2003 tab style?
Thanks for the great work.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Paul Selormey wrote:
How about support for the new Office 2003 tab style?
Good idea. I'll put it on my TODO list
If you want to take a shot at doing it, make a new file, and make a new class for it. You can follow how the classes in DotNetTabCtrl.h inherit from CCustomTabCtrl and do their thing. Send it to me, and I'll include it in future updates
-Daniel
|
|
|
|
|
Daniel Bowen wrote:
If you want to take a shot at doing it, make a new file, and make a new class for it. You can follow how the classes in DotNetTabCtrl.h inherit from CCustomTabCtrl and do their thing. Send it to me, and I'll include it in future updates
I am planning a WTL project similar to the BCGSoft/CodeJock libraries and will use your codes. So I thought if I could get my request honored, I will save some time
The WTL docking library is not being updated and I plan to seek the author's permission to use it as part of the library. For now, I am trying to find time to study that. If you could spare a bit of time and knock it for me, I will be glad. Otherwise, I will surely have to work on it.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Hello
At first thanks for this framework! It looks really useful.
I'm beginner in Win32(MDI related) programming.
I've downloaded MDISplit demo http://www.codeproject.com/wtl/mdisplit.asp
and have tried to append tabbed MDI UI.
I've changed CMDIFrameWindowImpl to CTabbedMDIFrameWindowImpl,
CMDIChildWindowImpl to CTabbedMDIChildWindowImpl in all files.
But I can't see the tab bar - just empty non-drawn (with artefacts from other windows/controls) space. If you may please help - what should I do for fixing it?
There is a code that create splitter window - I tried to sligtly modify it:
HWND CMainFrame::CreateClient()
{
// Get the Client RECT for the entire window as a starting size
RECT rcClient;
GetClientRect(&rcClient);
// Create the vertical splitter. This is the main window
m_splitter.Create(m_hWnd, rcClient, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
// Create the About dialog in the left pane
m_about.Create(m_splitter.m_hWnd);
m_splitter.SetSplitterPane(SPLIT_PANE_LEFT, m_about.m_hWnd);
// Create the MDI client in the right pane
m_hWndMDIClient = CreateMDIClient();
m_splitter.SetSplitterPane(SPLIT_PANE_RIGHT, m_hWndMDIClient);
// IMPORTANT! Make the splitter the parent of the MDI client
::SetParent(m_hWndMDIClient, m_splitter.m_hWnd);
//NEW CODE
m_tabbedClient.SetParent(m_splitter.m_hWnd); //am I right?
m_tabbedClient.SetTabOwnerParent(m_splitter.m_hWnd);
m_splitter.SetSplitterPos(132); // from left
// Splitter is ultimately the client of Main Frame (m_hWndClient)
return m_splitter.m_hWnd;
}
|
|
|
|
|
Vladimir Vunukov wrote:
I'm beginner in Win32(MDI related) programming.
I've downloaded MDISplit demo http://www.codeproject.com/wtl/mdisplit.asp
and have tried to append tabbed MDI UI.
I've changed CMDIFrameWindowImpl to CTabbedMDIFrameWindowImpl,
CMDIChildWindowImpl to CTabbedMDIChildWindowImpl in all files.
But I can't see the tab bar - just empty non-drawn (with artefacts from other windows/controls) space. If you may please help - what should I do for fixing it?
Sorry for not getting back sooner. I took a look at the MDISplit code. I was able to get it to work with my TabbedMDI stuff by doing the following:
- Add the necessary includes to get TabbedMDI.h to compile.
- Do not change CMDIFrameWindowImpl to CTabbedMDIFrameWindowImpl like you'd normally do.
- Declare
CTabbedMDIClient< CDotNetTabCtrl<CTabViewTabItem> > m_tabbedClient; as a member of CMainFrame. - In the
CreateClient function you quoted, add the line
m_tabbedClient.SubclassWindow(m_hWndMDIClient); after the line
::SetParent(m_hWndMDIClient, m_splitter.m_hWnd); - Find all instances of
CMDIChildWindowImpl and replace with CTabbedMDIChildWindowImpl (should be in ChildFrm.h). - You can also probably replace
CMDICommandBarCtrl in CMainFrame with CTabbedMDICommandBarCtrl (although I didn't test this much).
You might also want to consider using Sergey Klimov's docking window framework with my tabbing classes. See the DockingDemo from the samples with this article.
HTH,
-Daniel
|
|
|
|
|
|
Hi,
First of all thank you very much for writing such a fabulous control.
I found something wierd in your docking tab demo app,
To replay the bug:
First drag the docked tab window to make it float, and then drag a docked tab out of the tab window and make it float. Then double click the floating tab or drag it back to tab window. The tab will dock again but it is not correctly sized. One more funny thing is that the sizing problem only happens if the docking window is small enough. And once a tab is re-docked and sized together with the tab window, it will dock correctly from then on, no matter how small the tab window is.
I guess there must be something wrong with the initial coordinates of some rectangle.;)
Best Regards
Lei
|
|
|
|
|
jiang-lei wrote:
Hi,
First of all thank you very much for writing such a fabulous control.
You're welcome!
jiang-lei wrote:
To replay the bug:
First drag the docked tab window to make it float, and then drag a docked tab out of the tab window and make it float. Then double click the floating tab or drag it back to tab window. The tab will dock again but it is not correctly sized. One more funny thing is that the sizing problem only happens if the docking window is small enough. And once a tab is re-docked and sized together with the tab window, it will dock correctly from then on, no matter how small the tab window is.
I guess there must be something wrong with the initial coordinates of some rectangle.
Best Regards
Lei
Not to pass the buck , but this sounds like a bug with Sergey Klimov's docking window code. I've noticed several quirks along the same lines, and have sent him several suggestions. Be sure and read the replies on his article at http://www.codeproject.com/wtl/wtldockingwindows.asp.
Also take a look at this message I posted earlier to see if it helps: http://www.codeproject.com/wtl/TabbingFramework.asp?msg=429425&searchkw=docking&sd=4%2F11%2F2001&ed=7%2F10%2F2003#xx429425xx
Thanks,
-Daniel
|
|
|
|
|
Daniel (or anyone),
Beginning with the DockingDemo MDI sample app as the basis for my work, I am constructing a utility app that currently maintains two CTabbedFrameImpl derived Frame windows; Each frame window hosts multiple views embedded in the CTabbedFrameImpl frame using dotnet flat buttons. The frames are hosted in a CTabbedMDICommandBarCtrl object to provide frame switching via tabs;
In one of the Child Frame Windows I am using the opensource CodeMax (2.1) sytnax highlighting code editor in multiple views to allow simultaneous editing of configuration files (ala sysedit). These views are created dynamically in the ChildFrame OnCreate() and also even more dynamically via ID_FILE_OPEN handling. ID_FILE_OPEN is handled in the Child Frame and causes a new View to be created and added to the CTabbedFrameImpl tab bar.
This all works fine and is just background info to set the stage.
The problem I have is related to handling messages in the views associated with the Child Frame window.
In the Child Frame, my message map looks like this:
<br />
BEGIN_MSG_MAP_EX ( CFrameCodeMax )<br />
MSG_WM_CREATE ( OnCreate ) <br />
MSG_WM_SETFOCUS ( OnSetFocus )<br />
MSG_WM_FORWARDMSG ( OnForwardMsg )<br />
MSG_WM_CLOSE( OnClose )<br />
<br />
COMMAND_ID_HANDLER( ID_FILE_OPEN, OnFileOpen )<br />
<br />
CHAIN_CLIENT_COMMANDS ()<br />
CHAIN_MSG_MAP ( baseClass ) <br />
<br />
REFLECT_NOTIFICATIONS ()<br />
END_MSG_MAP ()<br />
baseClass (i.e., the Child Frame) is declared as:
<br />
typedef CTabbedFrameImpl< CFrameCodeMax, CDotNetButtonTabCtrl< CTabViewTabItem >, CTabbedMDIChildWindowImpl< CFrameCodeMax, CMDIWindow, CFrameCodeMaxWinTraits > > baseClass;<br />
and my winTraits are:
<br />
typedef CWinTraits< WS_OVERLAPPEDWINDOW | WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_MAXIMIZE, WS_EX_MDICHILD > CFrameCodeMaxWinTraits;<br />
In my Views, I have the following message map; reduced for clarity...
<br />
BEGIN_MSG_MAP_EX ( CViewCodeMax ) <br />
<br />
MSG_WM_CREATE ( OnCreate ) <br />
<br />
<br />
COMMAND_ID_HANDLER_EX ( ID_FILE_RELOAD, OnFileReload )<br />
COMMAND_ID_HANDLER_EX ( ID_FILE_SAVE, OnFileSave )<br />
COMMAND_ID_HANDLER_EX ( ID_FILE_SAVE_AS, OnFileSaveAs )<br />
<br />
...<br />
... lines removed for brevity ...<br />
... <br />
<br />
CHAIN_MSG_MAP_ALT ( CodeMaxControlNotifications < CViewCodeMax >, CMAX_REFLECTED_NOTIFY_CODE_HANDLERS )<br />
CHAIN_MSG_MAP_ALT ( CodeMaxControlCommands < CViewCodeMax >, CMAX_BASIC_COMMAND_ID_HANDLERS ) <br />
<br />
END_MSG_MAP () <br />
Okay, now let's see if I can explain my problem clearly...
In several of the COMMAND_ID_HANDLER_EX() macros you can see that I am handling messages that originate from the main menu, like ID_FILE_SAVE and others. In addition there are several notification messages that originate via the CodeMax
The problem behavior is that, depending on which tab in the dotnet button bar I have clicked on to activate a particular edit view, I would expect that View to process the messages from the UI - i.e., the Active view should handle the messages; But this is not the case; instead, the first view that I add to the Child Frame seems to handle the messages that originate in the UI, like Save File, while the last view that I add to the Child Frame seems to handle the control notifications from the CodeMax edit control. Both situations are not ideal; Instead I would prefer that the active view handle the messages;
One solution I have thought of would have me handling the message in the Child Frame, identifying the active view and then specifically calling public methods in the active view; i.e.,
int nActiveTab = this->GetTabCtrl().GetCurSel();
for( unsigned int i=0; i < m_vTabs.size(); i++ ) {
if( m_vTabs[i].nTab = nActiveTab )
m_vTabs[i].pView->SomeMethodCall();
}
While I can certainly do this, I tend to think that I am missing some aspect of ATL / WTL message maps that would allow this dynamic message handling to function properly.
It appears that the CHAIN_CLIENT_COMMANDS() in my Child Frame is not aware of the active view - do I have to set a the m_hWndClient variable somewhere when a Tab click causes a different view to become 'active'? If so, is there a message generated by the dotnet tab control that I can add to my message map in the Child Frame to enable this behaviour? I supposed I could do it during Idle processing somehow.
Apologies if I have not included enough code - I can provide more if that would help.
Thanks in advance for any tips / pointers.
Regards,
Scott Burkhalter
Principal Consultant
SoulTech Solutions
w: www.soulsolu.com e: scott@soulsolu.com
|
|
|
|
|
soultech wrote:
The problem behavior is that, depending on which tab in the dotnet button bar I have clicked on to activate a particular edit view, I would expect that View to process the messages from the UI - i.e., the Active view should handle the messages
If I understand correctly, there's a small bit of code that currently isn't there that needs to be added.
If you invoke a menu item from the main frame's menu, then there's a WM_COMMAND message sent to your main frame window. In WTL, you usually have the entry
CHAIN_MDI_CHILD_COMMANDS() in your main frame's message map. This asks for the active MDI child, and re-sends (or "forwards") the message on to that window. The MDI child is the "Child Frame". For an out of the box WTL MDI application, the child frame has a "client" or "view" window as a child. So when the frame gets a WM_COMMAND, it then forwards the message onto the view (a child of the frame). This is usually done with CHAIN_CLIENT_COMMANDS() in the frame window's message map.
soultech wrote:
It appears that the CHAIN_CLIENT_COMMANDS() in my Child Frame is not aware of the active view - do I have to set a the m_hWndClient variable somewhere when a Tab click causes a different view to become 'active'?
Close. CHAIN_CLIENT_COMMANDS comes from WTL, so it wouldn't know about the tabbing classes. Its meant for CFrameWindowImpl which has a member variable m_hWndClient for the one and only active view. With a CTabbedFrameImpl derived class, what you have instead of a single child as the view, you have one view (of possibly several) as the "active" one.
In your CTabbedFrameImpl derived class, you have access to all the base methods and properties. CTabbedFrameImpl tracks its active view with the member variable m_hWndActive . What you could do is have your own version that looked something like:
#define CHAIN_ACTIVETABVIEW_COMMANDS() \
if(uMsg == WM_COMMAND && m_hWndActive != NULL) \
::SendMessage(m_hWndActive, uMsg, wParam, lParam);
Also, if you look in the message map for CTabbedFrameImpl , you'll see that I already pass keyboard messages down to the active view (if they are sent to the frame). If there are other messages that need to make it down to the active view, you could do something similar. You don't want to just forward everything to the active view, because that would make a lot of things not work right (for example, you wouldn't want to forward WM_CREATE sent to the frame forwarded to the active view). That means, be very careful whenever you're using CHAIN_MSG_MAP, CHAIN_MSG_MAP_ALT, etc. - it's usually what you want when chaining to the message map of a base class, but often wrong if you use it to forward all messages meant for one window to go to another window.
I'll add the CHAIN_ACTIVETABVIEW_COMMANDS() macro to my next update, and have CTabbedFrameImpl use it. Forwarding WM_COMMAND messages on to the active view seems like it should always be OK (I'll add it just before the REFLECT_NOTIFICATIONS).
Also note that if you want the HWND corresponding to a tab, you can call GetItem(index) , and then GetTabView (assuming that the tab item type is CTabViewTabItem).
All this window messaging stuff can be made to work quite well with the tabbing stuff, but with an extra window in between, sometimes you have to think a little more about what's really going on Spy++ can help debug where messages are really going. Having the "PreTranslateMessage" / WM_FORWARDMSG stuff also takes special consideration, but it can work correctly.
If I missed something that you're still having a problem with, let me know.
-Daniel
|
|
|
|
|
Well, I'm glad I asked the question! I'll give the macro a try and see if that does the trick.
Thanks for your tip and once again, thanks for your efforts with the WTL community.
Care to share your thoughts on the features and fun you're adding to the next release? Inquiring minds want to know
Regards
Scott Burkhalter
Principal Consultant
SoulTech Solutions
w: www.soulsolu.com e: scott@soulsolu.com
|
|
|
|
|
FYI for anyone following this thread in the future: Dan's suggestion works - I added the CHAIN_ACTIVETABVIEW_COMMANDS() macro to the CTabbedFrameImpl base class implementation and then inserted it into the message map just above REFLECT_NOTIFICATIONS(). i.e.,
BEGIN_MSG_MAP(thisClass)
.
.
.
CHAIN_ACTIVETABVIEW_COMMANDS()
if(m_bReflectNotifications)
{
REFLECT_NOTIFICATIONS()
}
END_MSG_MAP()
The only caveat is that I did have to remove the CHAIN_CLIENT_COMMANDS() entry from the view's parent MDI Child Frame window mesage map. Otherwise, in addition to the now correct processing due to the suggested macro highlighted above, the CHAIN_CLIENT_COMMANDS() handler ends up sending the WM_COMMAND messages to the view it 'thinks' is active (whatever HWND m_hWndActive contains) which tends to be wrong most of the time.
I.e., if you have both macros in your implementation the command messages are processed two times:
1) by the child frame CFrameWindowImpl implementation, which passes it to the wrong active view via CHAIN_CLIENT_COMMANDS() in your Child Frame message map
2) by the tabbed frame CTabbedFrameImpl implementation, which properly passes to the current active view via CHAIN_ACTIVETABVIEW_COMMANDS() in the Child Frame's Tab base implementation
So, if you need to enable this functionality, and you start to see double message processing and odd behaviour, be sure to check that you have commented out the CHAIN_CLIENT_COMMANDS() handler in the views parent frame window.
Ciao,
Scott Burkhalter
Principal Consultant
SoulTech Solutions
w: www.soulsolu.com e: scott@soulsolu.com
|
|
|
|
|
soultech wrote:
.e., if you have both macros in your implementation the command messages are processed two times:
1) by the child frame CFrameWindowImpl implementation, which passes it to the wrong active view via CHAIN_CLIENT_COMMANDS() in your Child Frame message map
...
Just a small point of clarification. CFrameWindowImpl and its base class CFrameWindowImplBase don't do CHAIN_CLIENT_COMMANDS() , but often the class that derives from CFrameWindowImpl does. I'm assuming that its from the derived class where you pulled out CHAIN_CLIENT_COMMANDS - which is the correct thing to do
Also, I should have mentioned this before, but for an example of an MDI child window that is also a tabbed frame, see the "TabDemo", and the CHtmlFrame class. The current implementation of CHtmlFrame handles a couple WM_COMMAND messages itself, but with the new CHAIN_ACTIVETABVIEW_COMMANDS() in CTabbedFrameImpl, commands will make it down to the active view auto-magically
Thanks,
-Daniel
|
|
|
|
|
soultech wrote:
Care to share your thoughts on the features and fun you're adding to the next release? Inquiring minds want to know
I've meant to have an update much earlier than now, but I've been quite busy with deadlines and such. I have a list of outstanding issues brought up by comments to the article. I've also had my own TODO list since releasing the article.
Hopefully within a couple weeks I'll have an update. There are a number of things that will be included, and a couple that I would like to have, but won't this time around.
When I post the updates, I'll have history at the top of each file with what has changed. I'd give a list of what I'm hoping to get in, but for now, I hope you'll forgive me if I don't give that list
If you have suggestions, please e-mail then to me, or post them to the article.
-Daniel
|
|
|
|
|
Hi Daniel
Thanx for your good work
I wanna use CTabbedFrameImpl but without a tab control , I want to programmatically switch between views ( really with other controls )
good luck
sdsf
|
|
|
|
|
Sahbi wrote:
... without a tab control , I want to programmatically switch between views ...
I'd start out with a "frame" type window (which might just be a child window of another window). I'd then have other windows that are children of this frame window, and track which one is the "active" one. Essentially, you show the "active" view, and hide the other views. You fill the client area of the frame window with the active view. (BTW, if the frame window has no border, etc., you won't ever even see any part of the frame window).
CFrameWindowImpl (from WTL) does part of this, but it only has one window as the "client" window. It does the "fill the client area of the frame" with its UpdateLayout method, which gets called when handling WM_SIZE . UpdateLayout could also be called at other times (i.e., when switching active views).
Try examining the code for CTabbedFrameImpl, and debug through it (set breakpoints, etc.) to see how I do this with the tabs. Also run Spy++ to see the window hierarchy. The way I have it work with the tabs is that the tabs are drawn in a child window (sibling to the tab views) that is at the top or bottom of the "frame", and the active view is resized to the remaining client area of the frame. You could probably copy CTabbedFrameImpl, name your new class something else, remove the inheritance from CCustomTabOwnerImpl, remove all the other tab related stuff, and be pretty close to what you need
HTH,
-Daniel
|
|
|
|
|
Ok lot of thanx Daniel for interest..
I finally realized that I should write my own class that is more simple and do perfectly the job
In fact, I've made a simple CWindowImpl<...> that holds an array of CWindow(s) just like any TabbedFrame control , with methods like :
AddTab(..)
RemoveTab(..) &
SetActiveTab(..)
etc...
AddTab(HWND,...) is given handles of child windows, and will turn them not WS_VISIBLE
SetActiveTab(int ) will be given the index of the view to be activated so that it turns it WS_VISIBLE , EnableWindow( TRUE );ShowWindow( SW_SHOW );SetFocus( );Invalidate( TRUE );
My problem was shaming, because in child view, I can't catch any WM_NOTIFY message
the trick was as simple as putting FORWARD_NOTIFICATIONS() in my message loop.
Ok, now it works fine , may be I'll get some improvement from your code.
sdsf
|
|
|
|
|
This is just an FYI;
In the DockingDemo sample application the following code resides in mainfrm.h;
#ifdef _DEMO_TABBEDAUTOHIDEDOCKINGWINDOW_
if(uMsg == WM_COMMAND && (LOWORD(wParam) >= ID_VIEW_PANEFIRST || LOWORD(wParam) <= ID_VIEW_PANELAST))
{
ATLASSERT(m_PaneWindows.size() >= (ID_VIEW_PANELAST-ID_VIEW_PANEFIRST));
m_PaneWindows[LOWORD(wParam) - ID_VIEW_PANEFIRST]->Toggle();
}
#else
COMMAND_TOGGLE_MEMBER_HANDLER(ID_VIEW_OUTPUT,m_OutputFrame)
#endif
I believe the '||' in the initial 'if(uMsg...' should be an '&&'; otherwise the ATLASSERT() asserts for when you try to handle other messages by passing them off to the child MDI windows. For example, once I add a COMMAND_ID_HANDLER for ID_FILE_OPEN to the CChildFrame class in ChildFrm.h I recieve the ATLASSERT(). It is fixed by changing the above mentioned '||' to an '&&'.
Danial, please straighten me out if I'm missing something here - I am quite new to WTL and it wouldn't surprise me if that was the case!
Regards,
Scott H. Burkhalter
Principal Consultant, Soultech Solutions
w: www.soulsolu.com e: softeng@soulsolu.com
|
|
|
|
|
Scott Burkhalter wrote:
I believe the '||' in the initial 'if(uMsg...' should be an '&&';
You're right I'll fix that for the next update.
Thanks!
-Daniel
|
|
|
|
|
Dear Daniel!
First of all, thanks for your great job!
I'm using CTabbedChildWindow<CDotNetTabCtrl<CTabViewTabItem> > in my application to switch between several list-views. Unfortunately, when I resize the application window, the active list-view flickers badly. This is because the TabbedChildWindow class has CS_HREDRAW | CS_VREDRAW style. After I replaced
DECLARE_WND_CLASS(_T("TabbedChildWindow"))
with
DECLARE_WND_CLASS_EX(_T("TabbedChildWindow"), CS_DBLCLKS, COLOR_WINDOW)
the effect disappeared.
I wonder if CS_HREDRAW | CS_VREDRAW class style was used intentionally?
-----
Mike Bru
|
|
|
|
|
Mike Bru wrote:
I'm using CTabbedChildWindow<cdotnettabctrl<ctabviewtabitem> > in my application to switch between several list-views. Unfortunately, when I resize the application window, the active list-view flickers badly. This is because the TabbedChildWindow class has CS_HREDRAW | CS_VREDRAW style. After I replaced
DECLARE_WND_CLASS(_T("TabbedChildWindow"))
with
DECLARE_WND_CLASS_EX(_T("TabbedChildWindow"), CS_DBLCLKS, COLOR_WINDOW)
the effect disappeared.
I wonder if CS_HREDRAW | CS_VREDRAW class style was used intentionally?
No, CS_HREDRAW and CS_VREDRAW weren't used intentionally. Thanks for the suggested DECLARE_WND_CLASS_EX - its a good idea. CTabbedChildWindow is suppose to act more like a frame, so I suppose it doesn't even need CS_DBLCLKS (which would make it look almost like DECLARE_FRAME_WND_CLASS). With the window implemented by CTabbedChildWindow, you won't actually be seeing the client area as long as there is at least one tab view, but will be seeing the tab window and the active view (which are both child windows).
In regards to eliminating flicker on a list view, try some code like this:
typedef CWinTraits<WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER,
WS_EX_CLIENTEDGE> CMyFlickerFreeListViewWinTraits;
class CMyFlickerFreeListView :
public CWindowImpl<CMyFlickerFreeListView, CListViewCtrl, CMyFlickerFreeListViewWinTraits>
{
protected:
typedef CMyFlickerFreeListView thisClass;
typedef CWindowImpl<CMyFlickerFreeListView, CListViewCtrl, CMyFlickerFreeListViewWinTraits> baseClass;
...
public:
CMyFlickerFreeListView() :
m_HeaderCtrl(this, 1)
{
...
}
...
public:
DECLARE_WND_SUPERCLASS(_T("MyFlickerFreeListView"), CListViewCtrl::GetWndClassName())
BEGIN_MSG_MAP(thisClass)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
...
DEFAULT_REFLECTION_HANDLER()
ALT_MSG_MAP(1)
MESSAGE_HANDLER(WM_PAINT, OnHeaderPaint)
MESSAGE_HANDLER(WM_PRINTCLIENT, OnHeaderPaint)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
END_MSG_MAP()
LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);
... (initialize other stuff)
CHeaderCtrl ctrlHeader = this->GetHeader();
m_HeaderCtrl.SubclassWindow(ctrlHeader);
...
bHandled = TRUE;
return lRet;
}
LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if(m_HeaderCtrl.IsWindow())
{
m_HeaderCtrl.UnsubclassWindow();
}
...
bHandled=FALSE;
return 0;
}
LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
{
if( wParam != NULL )
{
CMemDC memdc((HDC)wParam, NULL);
memdc.FillSolidRect(&memdc.m_rc, ::GetSysColor(COLOR_WINDOW));
this->DefWindowProc( uMsg, (WPARAM)memdc.m_hDC, 0);
}
else
{
CPaintDC dc(m_hWnd);
CMemDC memdc(dc.m_hDC, &dc.m_ps.rcPaint);
memdc.FillSolidRect(&dc.m_ps.rcPaint, ::GetSysColor(COLOR_WINDOW));
this->DefWindowProc( uMsg, (WPARAM)memdc.m_hDC, 0);
}
return 0;
}
LRESULT OnHeaderPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
{
if( wParam != NULL )
{
CMemDC memdc((HDC)wParam, NULL);
memdc.FillSolidRect(&memdc.m_rc, ::GetSysColor(COLOR_BTNFACE));
m_HeaderCtrl.DefWindowProc( uMsg, (WPARAM)memdc.m_hDC, 0);
}
else
{
CPaintDC dc(m_HeaderCtrl);
CMemDC memdc(dc.m_hDC, &dc.m_ps.rcPaint);
memdc.FillSolidRect(&dc.m_ps.rcPaint, ::GetSysColor(COLOR_BTNFACE));
m_HeaderCtrl.DefWindowProc( uMsg, (WPARAM)memdc.m_hDC, 0);
}
return 0;
}
LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
{
return 1;
}
...
protected:
CContainedWindow m_HeaderCtrl;
...
};
Thanks,
-Daniel
|
|
|
|
|
When using the docking code from Sergies codeproject area along with this Bowen code, I receive the compile error above...
It can be fixed by editing TabbedDockingWindow.h and changing
#ifndef __WTL_DW__EXTDOCKINGWINDOW_H__
to
#ifndef AFX_EXTDOCKINGWINDOW_H__0CD64AFC_8687_4B20_8B8F_EE149C8C0E94__INCLUDED_
Apparently Sergie has updated his method of enforcing include singularities vai GUIDs.
Great Code Daniel! Thanks so much for contributing this effort to the WTL group.
Regards,
Scott Burkhalter
Principal Consultant
SoulTech Solutions
w: www.soulsolu.com e: scott@soulsolu.com
|
|
|
|
|
soultech wrote:
Great Code Daniel! Thanks so much for contributing this effort to the WTL group.
You're welcome!
soultech wrote:
Apparently Sergie has updated his method of enforcing include singularities vai GUIDs.
Actually, the __WTL_DW__EXTDOCKINGWINDOW_H__ is a suggestion (among some others) that I sent to Sergey that hasn't been released in his updates. I have it in my code because I had thought that he would release an update a little sooner than he has.
In my next update I'll probably change
#ifndef __WTL_DW__EXTDOCKINGWINDOW_H__ to
#if !defined(__WTL_DW__EXTDOCKINGWINDOW_H__) && !defined(AFX_EXTDOCKINGWINDOW_H__0CD64AFC_8687_4B20_8B8F_EE149C8C0E94__INCLUDED_) to handle both the current release and a future release
Thanks,
-Daniel
|
|
|
|
|
Well, I guess I should have expected that you would already have thought of it, but I don't think it would have crossed my mind that you suggested it!
touche`
Regards
Scott Burkhalter
Principal Consultant, SoulTech Solutions
|
|
|
|
|
First I would like to thank you again for writing a wonderful set of tabbing classes. I have been really impressed with the outcome.
I would like to know how to move the tab order around. (tab order being the order of the tabs in the tab strip not keyboard tab order)
I would like to dynamically change the order of the tabs with the ability to remove and insert diff. tabs. I suppose it would be ok to store off the HWND's of the tabs, remove them, then add them back in the correct order. However, I can't seem to find where the actual tabs are to remove and add.
Is there a better way to accomplish this?
Thanks again,
--David Horner
|
|
|
|
|