|
ON_WM_NCHITTEST ,
无法从"UINT (__thiscall CSizingControlBar::* )(CPoint)"转换为"LRESULT (__thiscall CWnd::* )(CPoint)
|
|
|
|
|
I am getting the following problem using CSizingTabCtrlBar.
Sequence:
1. Right click in any one of the tabs view when it is docked(Ex: Tab1).
2. Now float the control bar and change the tab(Ex: Tab2).
3. Again click on the other tab.(Ex: Tab1)
4. Now observe mainframe menu, toolbar events gets disabled. Even application cannot be closed.
But mainframe events gets enabled when it is docked again.
Please let me know the solution for this problem. Thanks in advance
Deepthi
|
|
|
|
|
Sorry for that, but since I developed the code in early 2000, several frameworks came up including similar extensions. So, please try these frameworks and keep "my" code as a simple example only.
Kind regards,
Dirk Clemens
|
|
|
|
|
.... I'm figuring out how to make this damm code work., I found out that some of the base class original code created by Cristi Posea was modified by you and that's the reason why its not working on me...
|
|
|
|
|
I like this dock window but it seems to give me some trouble. I need two tabs with different treeview. I've learned a lot from here but need some corrections. Thanks to Mark Conway from CodeGuru (Dock demo/docktest).But I did not use those dlls, I have combine from there and here, based on CSizingControlBar. I did not create any special class to support the treeview like the sample "MY Bar", but I lost something, here:
This is cpp: I define the ID tab here.
#define IDC_TREEBAR_TAB 1001
///////////////////////////////////////////////////////////////////////////// I use workspace instead My Bar.
// CWorkspaceBar
CWorkspaceBar::CWorkspaceBar()
{
}
CWorkspaceBar::~CWorkspaceBar()
{
}
BEGIN_MESSAGE_MAP(CWorkspaceBar, CSuperControlBarG)
//{{AFX_MSG_MAP(CWorkspaceBar)
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_DESTROY()
ON_NOTIFY(TCN_SELCHANGE, IDC_TREEBAR_TAB, OnTabChange)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CWorkspaceBar message handlers
int CWorkspaceBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CSuperControlBarG::OnCreate(lpCreateStruct) == -1)
return -1;
// Create tab control
CRect rect(0, 0, 0, 0);
rect.SetRectEmpty();
// Create Tab window
if (!m_TabCtrl.Create(WS_VISIBLE | WS_CHILD | TCS_BOTTOM | TCS_MULTILINE,
rect, this,IDC_TREEBAR_TAB))
{
TRACE0("Failed to create workspace tab window\n");
return -1;
}
m_TabCtrl.SetFont(CFont::FromHandle((HFONT)GetStockObject(DEFAULT_GUI_FONT)));
m_Images.Create(IDB_TABIMAGES, 16, 1, RGB (255, 0, 255));
m_TabCtrl.SetImageList(&m_Images);
// create tree window here
//Populate tab
LPCTSTR szTabName[] = { _T("400 Series"), _T("Xpres") };
for (int i = 0; i < sizeof(szTabName) / sizeof(LPCTSTR); i++)
{
CTreeCtrl * pTreeCtrl = new CTreeCtrl;
DWORD dwStyle = WS_BORDER | WS_CHILD | TVS_HASLINES | TVS_HASBUTTONS |
TVS_LINESATROOT | TVS_SHOWSELALWAYS;
if (!pTreeCtrl->Create(dwStyle, rect, this, i))
{
TRACE0 ("Failed to create tree control\n");
return -1;
}
pTreeCtrl->ModifyStyleEx(0, WS_EX_CLIENTEDGE);
TC_ITEM TCI;
TCI.mask = TCIF_TEXT | TCIF_PARAM | TCIF_IMAGE;
TCI.pszText = (char *)szTabName[i];
TCI.lParam = (LPARAM)pTreeCtrl;
TCI.iImage = i;
VERIFY(m_TabCtrl.InsertItem(0, &TCI) != -1);
switch (i)
{
case 0:
{
HTREEITEM hHiWay =
pTreeCtrl->InsertItem (" 400 Series",TVI_ROOT);
pTreeCtrl->InsertItem (" 400",hHiWay);
pTreeCtrl->InsertItem (" 401",hHiWay);
HTREEITEM hXpresWays =
pTreeCtrl->InsertItem (" EXpress",TVI_ROOT);
pTreeCtrl->InsertItem (" QEW",hXpresWay);
pTreeCtrl->InsertItem (" HWY 7",hXpresWay);
}
break;
case 1:
{
HTREEITEM hXpresWays =
pTreeCtrl->InsertItem (" EXpress",TVI_ROOT);
pTreeCtrl->InsertItem (" QEW",hXpresWay);
pTreeCtrl->InsertItem (" HWY 7",hXpresWay);
HTREEITEM hHiWay =
pTreeCtrl->InsertItem (" 400 Series",TVI_ROOT);
pTreeCtrl->InsertItem (" 400",hHiWay);
pTreeCtrl->InsertItem (" 401",hHiWay);
}
break;
}
}
ShowSelTabWindow();
return 0;
}
CWnd * CWorkspaceBar::GetTabWindow(int nTab)
{
TC_ITEM TCI;
TCI.mask = TCIF_PARAM;
m_TabCtrl.GetItem(nTab, &TCI);
CWnd * pWnd = (CWnd *)TCI.lParam;
ASSERT(pWnd != NULL && pWnd->IsKindOf(RUNTIME_CLASS(CWnd)));
return pWnd;
}
void CWorkspaceBar::OnTabChange( NMHDR * pNM, LRESULT * pResult )
// hide all the windows - except the one with the currently selected tab
{
ShowSelTabWindow();
*pResult = TRUE;
}
void CWorkspaceBar::ShowSelTabWindow()
{
m_TabCtrl.GetCurSel();
int nSel = m_TabCtrl.GetCurSel();
ASSERT(nSel != -1);
for (int i = 0; i < m_TabCtrl.GetItemCount(); i++)
{
GetTabWindow(i)->ShowWindow(i == nSel ? SW_SHOW : SW_HIDE);
}
}
void CWorkspaceBar::OnSize(UINT nType, int cx, int cy)
{
CSizingControlBarG::OnSize(nType, cx, cy);
// m_TabCtrl.SetWindowPos (NULL, -1, -1, cx, cy,
// SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
CRect rect(0, 0, cx, cy);
if (IsFloating())
rect.InflateRect(-2, -2); // give space around controls.
else
rect.InflateRect(-4, -4);
// reposition the tab control.
m_TabCtrl.MoveWindow(&rect);
m_TabCtrl.AdjustRect(FALSE, &rect);
for (int i = 0; i < m_TabCtrl.GetItemCount(); i++)
{
GetTabWindow(i)->MoveWindow(&rect);
}
Invalidate();
}
void CWorkspaceBar::OnDestroy()
{
CSizingControlBarG::OnDestroy();
for (int i = 0; i < m_TabCtrl.GetItemCount(); i++)
{
delete GetTabWindow(i);
}
}
This header file:
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// WorkspaceBar.h : header file
//
#include <afxtempl.h>
#include "SizingControlBarG.h"
/////////////////////////////////////////////////////////////////////////////
// CWorkspaceBar window
class CWorkspaceBar : public CSizingControlBarG
{
// Construction
public:
CWorkspaceBar();
// Attributes
public:
CTabCtrl m_TabCtrl;
CImageList m_Images;
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CWorkspaceBar)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CWorkspaceBar();
// Generated message map functions
protected:
// int m_nActiveTab;
//{{AFX_MSG(CWorkspaceBar)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnDestroy();
//}}AFX_MSG
CWnd * GetTabWindow(int nTab);
void ShowSelTabWindow();
afx_msg void OnTabChange( NMHDR * pNotifyStruct, LRESULT * result );
DECLARE_MESSAGE_MAP()
};
It looks quite simple but needs fix.
|
|
|
|
|
When I run my program I get two assertion errors. One in WinFrm2.cpp line 106, shown below:
CFrameWnd::DockControlBar...
...
ASSERT(pDockBar != NULL);
...
If I go on and ignore it I get another error in bardock.cpp line 113. When the program does then load up it doesn't display the toolbar at all.
Any clues as to what a beginner is doing wrong?
Thanks to those who repond!
|
|
|
|
|
I tried to rebuild this app but not working properly. I like it. It will be very please if this code is fixed. Thanks.
|
|
|
|
|
By default, MFC doesn't have a clue how to pass command messages into child views of this bar. So I added some code here and there to help it:
BOOL CSizingTabCtrlBar::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
POSITION pos = m_views.GetHeadPosition();
while (pos)
{
TCB_ITEM * pMember = m_views.GetNext(pos);
if (pMember->pWnd->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
return TRUE;
}
return CWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
This code tries to handle the command message from menus etc in child views first, and if noone cares, passes it into control bar itself as usually.
The only other piece of code to support this goes into the CMainFrame:
BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
if (barThis.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
return TRUE;
if (barThat.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
return TRUE;
return CMDIFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
barThis and barThat are tab control bars with views that must respond to some command. Now you can add usual menu command handlers to view classes and they will receive the message. The only thing is that if two views can handle the same message, only first view will see it, second will have no idea of what is going on.
|
|
|
|
|
Good code to start with. I couldn't combine it with Christi's latest version of CSizingControlBar, so I combined CSizingTabCtrlBar with older version of CSizingControlBar into single class. Works great.
However, even in the original version there was a problem: If I add a view into the CSizingTabCtrlBar after it is already created, it doesn't show properly until I resize the bar. The easy workaround was to call OnSize() after adding a view.
I added protected members to CSizingTabCtrlBar:
int m_cx;
int m_cy;
UINT m_type;
They hold last parameters passed to OnSize so I can safely call the function again.
Code added to OnSize() after CControlBar::OnSize(nType, cx, cy);:
// store last size so we can resize after adding a tab
// extra check, if m_cx is 0xFDFDFDFD the thing is shutting down
if (m_cx != 0xFDFDFDFD)
{
m_cx = cx;
m_cy = cy;
m_type = nType;
}
The last change to the class was in AddView() right before returning TRUE:
OnSize(m_type, m_cx, m_cy);
That takes care of the view that is added after the bar is already displayed.
|
|
|
|
|
I have made some mods to support tabs on top (without TCS_BOTTOM attribute) and multiline tabs (with TCS_MULTILINE attribute). Maybe some pixels deviations, but works.
void CSizingTabCtrlBar::OnSize(UINT nType, int cx, int cy) <br />
{<br />
CSizingControlBar::OnSize(nType, cx, cy);<br />
<br />
CRect rect;<br />
this->GetClientRect(&rect);<br />
int bottom = (IsHorz() || IsFloating()) ? cy - 14 : cy - 18;<br />
m_tabctrl.MoveWindow(7, 7, rect.Width()-7, bottom);<br />
<br />
m_tabctrl.GetItemRect(0, &rect);<br />
int height = rect.Height() * m_tabctrl.GetRowCount();<br />
<br />
bool isBottom = (m_tabctrl.GetStyle() & TCS_BOTTOM) ? true : false; <br />
CWnd *pWnd;<br />
for (POSITION pos=m_views.GetHeadPosition(); pos; m_views.GetNext(pos)) {<br />
pWnd=m_views.GetAt(pos)->pWnd;<br />
if (isBottom)<br />
pWnd->MoveWindow(9, 9+3, cx-14, bottom-height-7-3);<br />
else<br />
pWnd->MoveWindow(9, 9+height+3, cx-14, bottom-height-7);<br />
}<br />
}
Best regards,
Jaime
|
|
|
|
|
void CSizingTabCtrlBar::OnSize(UINT nType, int cx, int cy)
{
CSizingControlBar::OnSize(nType, cx, cy);
int bottom = (IsHorz() || IsFloating()) ? cy - 14 : cy - 18;
m_tabctrl.MoveWindow(7, 7, cx-7, bottom);
CRect rect;
m_tabctrl.GetItemRect(0, &rect);
int height = rect.Height() * m_tabctrl.GetRowCount();
bool isBottom = (m_tabctrl.GetStyle() & TCS_BOTTOM) ? true : false;
for (POSITION pos=m_views.GetHeadPosition(); pos; m_views.GetNext(pos))
m_views.GetAt(pos)->pWnd->MoveWindow(10, isBottom?10:height+12, cx-13, bottom-height-8);
}
Jaime
|
|
|
|
|
I am working on a SDI. When i click any place on the formviews that i added to tab control bar, some buttons on toolbar are disabled. how can i fix this?
|
|
|
|
|
The sample project does not work on VC6.0 . When I change it to fit VC6.0, it is so nice. But it does not repaint when the main window is maximized or minimized. Please update a newer version, Dirk Clemens.
|
|
|
|
|
hy, at first sorry for my bad englisch. i'm still learning
So my problem is, my prog crashed when i click on X.
History:
I have made a Tree in the first tab. When i doubleclick on a Item, my prog get the text from the Item an write the text in the Document.
This works fine & without problems.
But click i now on X for closed my prog i became a warning Debug Assertion Failed!
The Debug show me the file "\VC98\MFC\SRC\WINFRAME.CPP"
and the function
<br />
<br />
void CFrameWnd::DestroyDockBars()<br />
{<br />
CPtrList listDockBars;<br />
POSITION pos = m_listControlBars.GetHeadPosition();<br />
while (pos != NULL)<br />
{<br />
CDockBar* pDockBar = (CDockBar*)m_listControlBars.GetNext(pos);<br />
ASSERT(pDockBar != NULL);<br />
if (pDockBar->IsDockBar())<br />
listDockBars.AddTail(pDockBar);<br />
}<br />
pos = listDockBars.GetHeadPosition();<br />
while (pos != NULL)<br />
{<br />
CDockBar* pDockBar = (CDockBar*)listDockBars.GetNext(pos);<br />
if (pDockBar->m_bFloating)<br />
{<br />
CFrameWnd* pFrameWnd = pDockBar->GetParentFrame();<br />
ASSERT_VALID(pFrameWnd);<br />
pFrameWnd->DestroyWindow();<br />
}<br />
else<br />
pDockBar->DestroyWindow();<br />
}<br />
}
the line in Debug how is wrong is by ASSERT(pDockBar != NULL);
in Debug pDockBar 0x00000000 {CDockBar hWnd = ???}
but start i my prog and closed it before i doubleclick on TreeView first Tab, my prog closed without warning.
And i can write into Doc & close my prog without warning.
The prog only crashed if i doubleclick on the TreeView and close it than.
can someone help me please
|
|
|
|
|
Hi,
I've been reading ppl struggling with drawing bugs, the flaw was in CSizingTabCtrlBar::OnSize, actually the tab wnd was covering the whole bar.
The layout code below sounds mutch better.
Define margins as needed and,
Enjoy!
void CSizingTabCtrlBar::OnSize(UINT nType, int cx, int cy)
{
CSizingControlBar::OnSize(nType, cx, cy);
CRect crect;
GetClientRect(crect);
crect.DeflateRect(TAB_XMARGIN,VIEW_YMARGIN,TAB_XMARGIN,TAB_YMARGIN);
CRect trect;
m_tabctrl.GetItemRect(0,trect);
trect = CRect(TAB_XMARGIN,(crect.Height() - TAB_YMARGIN) - trect.Height(),crect.Width() - 2 * TAB_XMARGIN, crect.Height() - TAB_YMARGIN);
m_tabctrl.MoveWindow(trect);
CRect vrect = crect;
vrect.DeflateRect(VIEW_XMARGIN,VIEW_YMARGIN,VIEW_XMARGIN,VIEW_YMARGIN + trect.Height() + TAB_YMARGIN);
CWnd *pWnd;
for (POSITION pos=m_views.GetHeadPosition(); pos; m_views.GetNext(pos))
{
pWnd = m_views.GetAt(pos)->pWnd;
pWnd->MoveWindow(vrect);
}
}
|
|
|
|
|
In your function:
TAB_XMARGIN
TAB_YMARGIN
VIEW_XMARGIN
VIEW_YMARGIN
are all undefined.
|
|
|
|
|
They just are placeholders ..
Just put whatever value/CONSTANT/variable you need/want...
|
|
|
|
|
I think here is a copy and paste error:
crect.DeflateRect(TAB_XMARGIN,VIEW_YMARGIN,TAB_XMARGIN,TAB_YMARGIN);
I replaced that with TAB_YMARGIN which worked fine.
|
|
|
|
|
Thanks for useful code. There are two small issues with controlbar when it is floating. The first one appears when closing main app, the second one when closing floating bar and focus was set in one of its view. The possible solution for first problem is to dock bar before exit:
void CMainFrame::OnClose()
{
if(m_wndSTCBar.IsFloating())
DockControlBar(&m_wndSTCBar, AFX_IDW_DOCKBAR_LEFT);
CFrameWnd::OnClose();
}
The possible solution to second issue is to set focus to MainFrame view when floating bar is being closed:
void CSizingTabCtrlBar::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
{
if ( IsFloating() && (lpwndpos->flags & SWP_HIDEWINDOW) )
{
CMainFrame *pFrame = (CMainFrame*)GetTopLevelFrame();
pFrame->SetActiveView(pFrame->m_cActiveView);
}
CSizingControlBar::OnWindowPosChanging(lpwndpos);
}
where m_cActiveView is a CView* object that need to be pointed to MainFrame View.
|
|
|
|
|
Is it possible to dock the window to the top or bottom of the frame
|
|
|
|
|
I have used this class, but i am faced with one problem,
I have a SDI application, and i have two other docking views, one on the left, and one in the bottom,
I have to refresh the tree controls, periodically say after every 4-5 seconds, and i access the Doc class, to get the data from there.
The problem is, that it all works fine, however when i click on the left tabcontrol view, the Doc pointer retrieved is NULL, and the application crashes, I cannot guess why a mouse click would cause such a behaviour,
I have also noticed, that if the dockign window is not docked and is floating the click of the mouse will not crash the prob, and the Doc pointer is retrieved correct,
What might be the reason to it ?
I guess it has some ting to do the way messages are routed from the windows ?
|
|
|
|
|
the sizing control tab bar doesn't seem to give up the wheel mouse when i click in another view (CScollView). Any ideas how to make it give up the wheel mouse?
thx steve
|
|
|
|
|
When I click on the X after making the bar float how do I show it again. It doesnt seem to act lick a normal toolbar.
D-MD
|
|
|
|
|
//when you click Button named "show/hide this Wnd"
void CMainFrame::OnButtonInfospace()
{
// TODO: Add your command handler code here
if (m_WndShowHDX.IsWindowVisible() == TRUE)
ShowControlBar(&m_WndShowHDX, FALSE, FALSE); //hide the Wnd
else
ShowControlBar(&m_WndShowHDX, TRUE, FALSE);//show the Wnd
RecalcLayout();
}
void CMainFrame::OnUpdateButtonInfospace(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetRadio(m_WndShowHDX.IsWindowVisible());
}
xiaobin
|
|
|
|
|
Hi, I found <big>it does not work well in VS.net 2003</big> ,It compile well but not run well !May anyone help me to solve it?
Thank you!!
|
|
|
|
|