|
I added the following code so that I could have text on a row splitter bar. The following code is VERY specific to my needs, and I leave it as an exercise for the programmer to make it work on a column splitter bar.
First, I had to increase the height of the bar to accomdate the font and a surrounding rectangle (project requirements). In the constructor, I changed the 3 to a 15:
m_cxSplitter = m_cySplitter = 15 + 1 + 1;
m_cxBorderShare = m_cyBorderShare = 0;
m_cxSplitterGap = m_cySplitterGap = 15 + 1 + 1;
m_cxBorder = m_cyBorder = 1;
Next, I added a function I use to build fonts for output:
BOOL CFlatSplitterWnd::BuildFont(CDC* pDC, CFont* pFont, int nFontHeight, bool bBold, bool bItalic)
{
nFontHeight = -MulDiv(nFontHeight, pDC->GetDeviceCaps(LOGPIXELSY), 72);
CString sFontName = _T("Arial");
int nWeight = (bBold) ? FW_BOLD : FW_NORMAL;
BYTE nItalic = (bItalic) ? 1 : 0;
return pFont->CreateFont(nFontHeight, 0, 0, 0, nWeight, nItalic, 0, 0, DEFAULT_CHARSET,
OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH | FF_DONTCARE, sFontName);
}
Finally, I changed the OnDrawSplitter() function as follows:
void CFlatSplitterWnd::OnDrawSplitter(CDC* pDC, ESplitType nType, const CRect& rectArg)
{
if((nType != splitBorder && nType != splitBar) || (pDC == NULL))
{
CSplitterWnd::OnDrawSplitter(pDC, nType, rectArg);
return;
}
ASSERT_VALID(pDC);
switch (nType)
{
case splitBorder :
{
pDC->Draw3dRect(rectArg, GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNHIGHLIGHT));
}
break;
case splitBar :
{
pDC->Draw3dRect(rectArg, GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNHIGHLIGHT));
CFont docFont;
CFont* pOldFont;
CBrush newBrush;
CBrush* pOldBrush;
BuildFont(pDC, &docFont, 9, false, false);
pOldFont = pDC->SelectObject(&docFont);
newBrush.CreateSolidBrush(RGB(255,255,0));
pOldBrush = pDC->SelectObject(&newBrush);
CString sTitle = "INFO";
CSize sz = pDC->GetTextExtent(sTitle);
CRect tempRect = rectArg;
tempRect.DeflateRect(1,1,1,1);
CRect wndRect;
GetWindowRect(&wndRect);
int xPos = (int)((wndRect.Width() - sz.cx) * 0.50);
pDC->SetTextColor(RGB(0,0,0));
pDC->SetBkMode(TRANSPARENT);
pDC->Rectangle(&tempRect);
pDC->TextOut(xPos, tempRect.top, sTitle);
pDC->SelectObject(pOldBrush);
newBrush.DeleteObject();
pDC->SelectObject(pOldFont);
newBrush.CreateSolidBrush(RGB(0,0,0));
pOldBrush = pDC->SelectObject(&newBrush);
tempRect.DeflateRect(0,5,0,4);
CPoint pts[4];
int x = (int)((tempRect.Width() - sz.cx - 30) * 0.50);
int y = tempRect.top;
pts[0] = CPoint(x, y);
pts[1] = CPoint(x + 10, y);
pts[2] = CPoint(x + 5, y + 5);
pts[3] = CPoint(x, y);
pDC->Polygon(pts, 4);
x = (int)((tempRect.Width() + sz.cx + 15) * 0.50);
y = tempRect.top;
pts[0] = CPoint(x, y);
pts[1] = CPoint(x + 10, y);
pts[2] = CPoint(x + 5, y + 5);
pts[3] = CPoint(x, y);
pDC->Polygon(pts, 4);
pDC->SelectObject(pOldBrush);
newBrush.DeleteObject();
}
break;
}
}
The result is a splitter bar with a yellow rectangle showing the word "INFO", which itself is centered and flanked by two arrowheads pointing down.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
|
It is good .i need it.“I确DI
|
|
|
|
|
How to change the style of the splitter between each view?
In size or apprearance.
|
|
|
|
|
|
Hi,
Your article is excellent, Thanks!. The application has got only one view(2views merged) displayed by default but what about having different views to display.i.e,
For example,
When menu options are choosen
A Dialog window is displayed(not splitted)?
(i.e,a view without split)
and
A View is displayed(splitted,actuall ur example)?
Any ideas please?
regards,
mohan
|
|
|
|
|
Hi, nice job with this code.
I am trying to put the view inside a nester splitter and am having strange results. If CLeftView is created inside a nester splitter:
from CFrameWnd::OnCreateClient()
m_wndSplitter.CreateStatic(this,1,2)
m_wndSplitterLeft.CreateStatic(&m_wndSplitter,2,1,WS_CHILD | WS_VISIBLE | WS_BORDER,m_wndSplitter.IdFromRowCol(0, 0));
m_wndSplitterLeft.CreateView(0,0,RUNTIME_CLASS(CLeftView),CSize(rect.Width()/3,rect.Height()/2),pContext) );
What ends up happening is nothing is displayed in the listview. I noticed that the OnSize() function is only called once during program start.
Any ideas?
Thanks,
-justin
|
|
|
|
|
Use CSplitterWnd::RecalcLayout to update sizes.
Regards,
Bartosz Bien
|
|
|
|
|
Hello
Sorry, but I don't unerstand.
Where should I use RecalcLayout?
|
|
|
|
|
After creating views for m_wndSplitterLeft, you have to call RecalcLayout on views.
CView *pView=(CView *)m_m_wndSplitterLeft.GetPane(0,0);
pView->GetParentFrame()->RecalcLayout();
Vinod
Competent Solutions Pvt Limited
|
|
|
|
|
Actually, that will not work. The best solution that I've found is to use (in this case) m_wndSplitterLeft.GetParentFrame()->SetColumnInfo(column_to_resize,ideal_x_size,min_x_size);
that should take care of it. At least it worked for me.
-- modified at 1:00 Friday 2nd September, 2005
|
|
|
|
|
I am looking for a quick way to prevent the splitter bar
from being moved past a certain position. It seems like you
could override the OnMouseMove to do this with your control.
Have you done this at all?
Thanks for any help...
|
|
|
|
|
Actually, this feature is almost already implemented in CSplitterWnd, just waiting for us to take advantage of it
Just overwite CSplitterWnd::StartTracking .
In your derived function, start with calling the base class's StartTracking and then adjust m_rectLimit which contains the dragging limit
void CFlatSplitterWnd::StartTracking(int ht)
{
CSplitterWnd::StartTracking(ht);
m_rectLimit.left += 50;
}
In this example, the user will not be able to drag the splitter more than 50 pixels close to the 'normal' left limit.
Enjoy!
Marc
|
|
|
|
|
|
I ended up adding the following changes to constrain splitterbar movement. First, a new member function:
void SetLimits(UINT minLimit, UINT maxLimit); {m_minLimit = minLimit; m_maxLimit = maxLimit;}
Then the constructor initializes these to zero.
Then in StartTracking, I added the following:
void CUsefulSplitterWnd::StartTracking(int ht)
{
CSplitterWnd::StartTracking(ht);
if (ht >= 101 && ht <= 115) { // vSplitterBar1-vSplitterBar15
m_rectLimit.top += m_minLimit;
if (m_maxLimit != 0)
m_rectLimit.bottom -= (m_rectLimit.bottom - m_maxLimit);
}
else if (ht >= 201 && ht <= 215) { // hSplitterBar1-hSplitterBar15
m_rectLimit.left += m_minLimit;
if (m_maxLimit != 0)
m_rectLimit.right -= (m_rectLimit.bottom - m_maxLimit);
}
}
Since Microsoft did not embed enums in their CSplitterWnd class (dummies), I had to hardcode their hit (ht) codes into the routine
(101-115, 201-215). Once I know which direction the splitterbar can move (vertical or horizontal), then I use the min/max limits to adjust
the m_rectLimit as you suggested.
Thanks again
|
|
|
|
|
|
How can I set one of the views to a CHtmlView?
|
|
|
|
|
>How can I set one of the views to a CHtmlView?
Just the same way you would do with a 'normal' CSplitterWnd (check msdn)
Cheers!
|
|
|
|
|
It works splitter bar... but it doesn't work your OnDraw Code in the CHtmlView....
Any idea?
|
|
|
|
|
I found that changing the CWnd::OnSize() call to CSplitterWnd::OnSize() in CFlatSplitterWnd's implementation of OnSize got the CHtmlView working in my application.
I don't know if this change could cause undesireable side effects, though....
|
|
|
|
|
|
I tried this splitter without overriding the OnDrawSplitter command, leaving just
m_cxSplitter = m_cySplitter = 3 + 1 + 1;
m_cxBorderShare = m_cyBorderShare = 0;
m_cxSplitterGap = m_cySplitterGap = 3 + 1 + 1;
m_cxBorder = m_cyBorder = 1;
in the constructor, and the result is the same ?!
|
|
|
|
|
First, sorry for the delayed response.. guess i missed the notification e-mail.
Second, ..damn.. guess you're right
OnDrawSplitter doesn't need to be overridden! (but that's how i started experimenting, and I didn't realize it wasn't necessary)
Thanks a lot for your sharpmindness (was that word english??)
Cheers!
Marc Richarme
|
|
|
|
|
Well done, Marc! This is exactly what I needed, trivial though it is.
For those of you that haven't read the source that accompanies this article, it turns out that the OnDrawSplitter function does actually need to be implemented to correct a minor drawing bug in CSplitterWnd that is exposed using this simple technique of setting the border sizes (etc.). However, Marc has uploaded a correct version that uses this simplified technique and that corrects the bug.
Kudos!
-Ken Griggs
|
|
|
|
|
mmm... I think
OnDrawSplitter necessary!!!
do this : double click split window
|
|
|
|
|