Highlight view with focus

Many times it would be nice to have some visual feedback as to which pane in a split view currently has the focus. This is very useful if you have multiple view types and different keyboard strokes cause different actions in each.

NOTE: This uses an undocumented feature in MFC so be careful in the future.

Step 1) Derive your own SplitterWnd class.
Step 2) Override the undocumented OnDrawSplitter function.
Step 3) Replace the CSplitterWnd instance in the child frame with your splitter.

This example draws in red but you can adjust the color and width of the frame by altering the define values.
///////////////////////////////////////////////////////////////////////////// 
// MySplitterWnd.h

class MySplitterWnd : public CSplitterWnd
{
public: 
	int cRow;
	int cCol; 
	MySplitterWnd();
	void OnDrawSplitter(CDC* pDC, ESplitType nType,
		const CRect& rectArg);
	void RefreshSplitBars(void);
};



///////////////////////////////////////////////////////////////////////////// 
// MySplitterWnd.cpp

#include "StdAfx.h"
#include "MySplitterWnd.h"

#define FOCUS_HILIGHT_COLOR_ULO RGB(180, 75, 25)
#define FOCUS_HILIGHT_COLOR_LRO RGB(245, 5, 25)
#define FOCUS_HILIGHT_COLOR_ULI RGB(145, 95, 75)
#define FOCUS_HILIGHT_COLOR_LRI RGB(220, 65, 40)

#define FOCUS_HILIGHT_SHOW TRUE

#define SPLITTER_CX 4
#define SPLITTER_CY 4
#define SPLITTER_GAPX 4
#define SPLITTER_GAPY 4

void MySplitterWnd::RefreshSplitBars(void)
{
	CRect rectInside;

	GetInsideRect(rectInside);
	DrawAllSplitBars(NULL, rectInside.right, rectInside.bottom);
}


MySplitterWnd::MySplitterWnd()
{
	cRow = 0;
	cCol = 0; 
	
	m_cxSplitter = SPLITTER_CX;
	m_cySplitter = SPLITTER_CY;
	m_cxSplitterGap = SPLITTER_GAPX;
	m_cySplitterGap = SPLITTER_GAPY;
}


void MySplitterWnd::OnDrawSplitter(CDC* pDC, ESplitType nType, const CRect& rectArg)
{
	if((FOCUS_HILIGHT_SHOW) && ((GetRowCount()>1) || (GetColumnCount()>1)) && (nType == splitBorder))
	{
		int pRow = 0;
		int pCol = 0;
		if(rectArg.top)
		{
			pRow = 1;
		}
		if(rectArg.left)
		{
			pCol = 1;
		}
		if((cRow == pRow) && (cCol == pCol))
		{
			if (pDC == NULL)
			{
				RedrawWindow(rectArg, NULL, RDW_INVALIDATE|RDW_NOCHILDREN);
				return; 
			}
			ASSERT_VALID(pDC);
			CRect rect = rectArg;
			pDC->Draw3dRect(rect, FOCUS_HILIGHT_COLOR_ULO, FOCUS_HILIGHT_COLOR_LRO);
			rect.InflateRect(-GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
			pDC->Draw3dRect(rect, FOCUS_HILIGHT_COLOR_ULI, FOCUS_HILIGHT_COLOR_LRI);
			return; 
		}
	}
	
	CSplitterWnd::OnDrawSplitter(pDC,nType,rectArg); 
}



Comments

  • Monster beats af Lady Gaga en virkelig afgørende element i de beats forsyne trÃ¥dløse hovedtelefoner

    Posted by wanzixiao on 06/04/2013 12:30pm

    [url=http://www.beatsbydrdredanmark.blinkweb.com/]beats by dre danmark[/url] Beats “Supreme Sound” Headsets forskydninger, der er valgt i form af vej erklæring – selv om det faktum, at faktisk syntes at tale om! “Jeg er en god overdreven person i hans teenageår” The hovedtelefon anker var oprindeligt strålende sammen med betydelig med hensyn til neon . Men i tidligere tider flere aldre, har kunderne allerede blevet anvendt som vil high-end konkurrerende virksomheder anvender personlig bank kan synes, sammen med Beats indgået et system var oprindeligt det meste af tydeligt. Artiklen udformet en slags in-house industri team – tidligere var næsten hele pakken jobbet oprindeligt dyrket ud – at drage fordel af luftstrøm sammen med forbedre enhver mp3. Den populære sti i disse dage har en god imprintede Great Tone. [url=http://www.kbhretelefonerbillig.webstarts.com/]Køb høretelefoner billig[/url] BIII booo din troede involverer let jazz, med essentials involverer normal, god ole ‘, sammen med digitalkameraer sange for dig at lave en ny specifikt eksklusiv lyd. BIII øjeblikket omdefinerer private musik ekspertise til at gøre dine musikernes øretelefoner. Enhver observere, hver eneste nuance, kan optaget med aldrig-hørt-før realistisk look, plus iøjnefaldende design og stil trådløse høretelefoner bestemt ved en ny trompet mundstykke har som en installation vidnesbyrd om den mestre kunsten. Disse former for sædvanligvis er ikke kun de bedste ørepuder vedrørende jazz. Uanset hvad nogen hører, vil BIII sikkert vokset til betragtes som en af dine nuværende all-time musikalske teknologi højder. [url=http://www.beatsbydrehretelefoner.weebly.com/]Beats by dre billig pris[/url] Fordelene og ulemperne ved de forskellige typer af hovedtelefonerHeadset hovedtelefoner, takket være en større enhed, lydkvaliteten er mere bedre, men på grund af nogle store volumen, ikke er nem at bære. Ørepropper lille enhed design, kompakt og let at bære, velegnet til udendørs brug. Ørekrog øretelefon typen headset med ørepropper i mellem et smukt udseende, komfortable at bære, lyde bedre egenskaber end ørepropper ulempe er følsom over for støj udefra, som er egnet til at bære i foråret, og denne sæson . Forskellige typer hovedtelefoner er anderledes, for at se om du ønsker at bruge under hvilke omstændigheder.

    Reply
  • Pot Dependency And Cigarettes Medical marijuana - 3 Motives To stop At this point

    Posted by NeleAstence on 02/18/2013 02:23pm

    There are many physical components influences the marijuana provide Marijuana is a safe and carefree drug to use. [url=http://vaporizerworld.org/best-vaporizer/]click go[/url] Huffman conducted was funded by the National Institute a 1999 fine nausea with less side effects as a result. Detection period of cocaine through hair not despite and paper and others smoke just to have some fun. It had been in 1996 when Proposition child susceptible that serious health risks associated with its long-term use.

    Reply
  • simpler solution

    Posted by Legacy on 08/20/2001 12:00am

    Originally posted by: Alan Kang

    Simply override CSplitterWnd::RecalcLayout - Works 
    
    with all sub-panes. You would still need to call
    SetRowInfo and SetColumnInfo as necessary but there is
    no need to do anything else

    void CSplitterWndEx::RecalcLayout()
    {
    CSplitterWnd::CRowColInfo* pInfo = m_pColInfo;
    CSplitterWnd::CRowColInfo* pInfoNext = pInfo;
    for (int i = 0; i < m_nCols - 1 && pInfo->nCurSize > -1; i++)
    {
    // Check next column
    int nXDiff = (++pInfoNext)->nMinSize -
    (pInfoNext->nCurSize - (pInfo->nIdealSize - pInfo->nCurSize));

    // Adjust the resizing step so that the size of the next col
    // will be at least its min size
    if (nXDiff > 0) pInfo->nIdealSize -= nXDiff;

    // Adjust the resizing step so that the size of this col
    // will be at least its min size
    pInfo->nIdealSize = max(pInfo->nIdealSize, pInfo->nMinSize);
    }

    pInfoNext = pInfo = m_pRowInfo;
    for (i = 0; i < m_nRows - 1 && pInfo->nCurSize > -1; i++)
    {
    // Check next row
    int nYDiff = (++pInfoNext)->nMinSize -
    (pInfoNext->nCurSize - (pInfo->nIdealSize - pInfo->nCurSize));

    // Adjust the resizing step so that the size of the next row
    // will be at least its min size
    if (nYDiff > 0) pInfo->nIdealSize -= nYDiff;

    // Adjust the resizing step so that the size of this row
    // will be at least its min size
    pInfo->nIdealSize = max(pInfo->nIdealSize, pInfo->nMinSize);
    }
    CSplitterWnd::RecalcLayout();
    }


    Reply
  • "total solution" improvements

    Posted by Legacy on 10/12/2000 12:00am

    Originally posted by: Hans-Georg Ulrich

    The "total solution" by Jiang Fan works, but ...
    
    - generates heavy flicker due to RedrawWindow
    - has some problems with more than 2 panes.

    Improvement: replace SetHighlight,
    and overwrite SetActivePane to call SetHighlight.

    --------------------------------------------------------

    void CSplitter::SetHighlight()
    {
    CWnd *pAct = GetActivePane();
    if(pAct && m_hwndAct != pAct->m_hWnd ) {
    // active pane changed
    m_hwndAct = pAct->m_hWnd;

    CPaintDC dc(this);
    CRect rectInside;
    GetInsideRect(rectInside);
    // CSplitterWnd::GetInsideRect -
    // undocumented public function
    // returns size of SplitterWnd minus size of scroll bars,
    // if any

    // CSplitterWnd::DrawAllSplitBars -
    // undocumented public function
    // Called with DeviceContext, it draws the frames.
    // Called with DeviceContext=NULL, it does a RedrawWindow
    // to make the changes visible

    DrawAllSplitBars(&dc,rectInside.right,rectInside.bottom);
    DrawAllSplitBars(NULL,rectInside.right,rectInside.bottom);

    //RedrawWindow(); // generates too much flicker
    }
    }

    // Do not forget to define this in the header
    void CSplitter::SetActivePane
    ( int row, int col, CWnd* pWnd /*= NULL*/ )
    {
    SplitterWnd::SetActivePane( row, col, pWnd);
    SetHighlight();
    }

    Reply
  • Total Solution

    Posted by Legacy on 03/19/1999 12:00am

    Originally posted by: Jiang Fan

    #if !defined(AFX_MYSPLITTERWND_H__138E6707_DE1A_11D2_BD45_0000F8771AA3__INCLUDED_)
    
    #define AFX_MYSPLITTERWND_H__138E6707_DE1A_11D2_BD45_0000F8771AA3__INCLUDED_

    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    // MySplitterWnd.h : header file
    //

    /////////////////////////////////////////////////////////////////////////////
    // CMySplitterWnd window

    class CMySplitterWnd : public CSplitterWnd
    {
    // Construction
    public:
    CMySplitterWnd();
    void SetHighlight();
    // Attributes
    public:
    HWND m_hwndAct;
    // Operations
    public:

    // Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CMySplitterWnd)
    protected:
    virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
    virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
    //}}AFX_VIRTUAL

    // Implementation
    public:
    virtual ~CMySplitterWnd();
    virtual void OnDrawSplitter(CDC* pDC, ESplitType nType, const CRect& rectArg);
    // Generated message map functions
    protected:
    //{{AFX_MSG(CMySplitterWnd)
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
    };

    /////////////////////////////////////////////////////////////////////////////

    //{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.

    #endif // !defined(AFX_MYSPLITTERWND_H__138E6707_DE1A_11D2_BD45_0000F8771AA3__INCLUDED_)


    // MySplitterWnd.cpp : implementation file
    //

    #include "stdafx.h"
    #include "ftms20.h"
    #include "MySplitterWnd.h"

    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif

    /////////////////////////////////////////////////////////////////////////////
    // CMySplitterWnd

    CMySplitterWnd::CMySplitterWnd()
    {
    m_hwndAct = NULL;
    }

    CMySplitterWnd::~CMySplitterWnd()
    {
    }


    BEGIN_MESSAGE_MAP(CMySplitterWnd, CSplitterWnd)
    //{{AFX_MSG_MAP(CMySplitterWnd)
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()


    /////////////////////////////////////////////////////////////////////////////
    // CMySplitterWnd message handlers

    void CMySplitterWnd::OnDrawSplitter(CDC* pDC, ESplitType nType, const CRect& rectArg)
    {
    CSplitterWnd::OnDrawSplitter(pDC, nType, rectArg);
    CWnd *pAct = GetActivePane();
    if(pDC && pAct && !pAct->IsKindOf( RUNTIME_CLASS( CSplitterWnd)) && nType == splitBorder)
    {
    CRect rect;
    pAct->GetWindowRect(&rect);
    pDC->GetWindow()->ScreenToClient(&rect);
    if(rectArg.PtInRect(rect.CenterPoint()))
    {
    ASSERT_VALID(pDC);
    rect = rectArg;
    pDC->Draw3dRect(rect, GetSysColor( COLOR_HIGHLIGHT),GetSysColor( COLOR_HIGHLIGHT));
    rect.InflateRect(-GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
    pDC->Draw3dRect(rect, GetSysColor( COLOR_HIGHLIGHT),GetSysColor( COLOR_HIGHLIGHT));
    }

    }

    }

    BOOL CMySplitterWnd::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
    {
    SetHighlight();
    return CSplitterWnd::OnNotify(wParam, lParam, pResult);
    }

    void CMySplitterWnd::SetHighlight()
    {
    CWnd *pAct = GetActivePane();
    if(pAct && m_hwndAct != pAct->m_hWnd )
    {
    m_hwndAct = pAct->m_hWnd;
    RedrawWindow();
    }
    }

    BOOL CMySplitterWnd::OnCommand(WPARAM wParam, LPARAM lParam)
    {
    SetHighlight();
    return CSplitterWnd::OnCommand(wParam, lParam);
    }

    Reply
  • Get highlight splitterWnd when I click on mouse on view

    Posted by Legacy on 02/28/1999 12:00am

    Originally posted by: sikong

    get highlight active pane...
    
    

    I used Randy More's source..
    You do first see Randy More's source.

    I changed his source.
    I checked "<--" mark for changing..

    /////////////////////////
    void MySplitterWnd::OnDrawSplitter(CDC* pDC, ESplitType nType, const CRect& rectArg)
    {
    int x_ActivePane, y_ActivePane; // <---
    GetActivePane(x_ActivePane, y_ActivePane); // <--
    TRACE("%d, %d\n", x_ActivePane, y_ActivePane);

    if((FOCUS_HILIGHT_SHOW) && ((GetRowCount()>1) || (GetColumnCount()>1)) && (nType == splitBorder))
    {
    int pRow = 0;
    int pCol = 0;
    if(rectArg.top)
    {
    pRow = 1;
    }
    if(rectArg.left)
    {
    pCol = 1;
    }
    if((pCol == y_ActivePane) && (pRow == x_ActivePane)) // <--
    {
    if (pDC == NULL)
    {
    RedrawWindow(rectArg, NULL, RDW_INVALIDATE|RDW_NOCHILDREN);
    return;
    }
    ASSERT_VALID(pDC);
    CRect rect = rectArg
    pDC->Draw3dRect(rect, FOCUS_HILIGHT_COLOR_ULO, FOCUS_HILIGHT_COLOR_LRO);
    rect.InflateRect(-GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
    pDC->Draw3dRect(rect, FOCUS_HILIGHT_COLOR_ULI, FOCUS_HILIGHT_COLOR_LRI);
    return;
    }
    }

    CSplitterWnd::OnDrawSplitter(pDC,nType,rectArg);
    }

    ///////////////////
    I add the Focus checking routine of View.
    this is left pane

    void CMyTree::OnSetFocus(CWnd* pOldWnd)
    {
    CTreeView::OnSetFocus(pOldWnd);

    // TODO: Add your message handler code here
    ((CMainFrame*)GetParentFrame())->m_wndSplitter.RefreshSplitBars();
    }

    void CMyTree::OnKillFocus(CWnd* pNewWnd)
    {
    CTreeView::OnKillFocus(pNewWnd);

    // TODO: Add your message handler code here
    ((CMainFrame*)GetParentFrame())->m_wndSplitter.RefreshSplitBars();
    }

    //////

    and this is right pane


    void MyRightView::OnSetFocus(CWnd* pOldWnd)
    {
    CEditView::OnSetFocus(pOldWnd);

    // TODO: Add your message handler code here
    ((CMainFrame*)GetParentFrame())->m_wndSplitter.RefreshSplitBars();
    TRACE("right get");
    }

    void MyRightView::OnKillFocus(CWnd* pNewWnd)
    {
    CEditView::OnKillFocus(pNewWnd);

    // TODO: Add your message handler code here
    ((CMainFrame*)GetParentFrame())->m_wndSplitter.RefreshSplitBars();
    TRACE("right kill");
    }

    thanks..


    Reply
  • How can I do if i want to get highlight splitterWnd when I click on mouse on view ?

    Posted by Legacy on 01/28/1999 12:00am

    Originally posted by: hg Choi

    hi.
    I called CMySplitterWnd , When WM_LBUTTONDOWN in view?
    but, it's not executed.


    How can I do if i want to get highlight splitterWnd when I click on mouse on view ?

    Thanks

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds