VisualFx.cpp
资源名称:(vc).rar [点击查看]
上传用户:wpp2016
上传日期:2010-02-01
资源大小:1250k
文件大小:63k
源码类别:
Telnet服务器
开发平台:
Visual C++
- /*#############################################################################
- # VISUALFX.CPP
- #
- # SCA Software International S.A.
- # http://www.scasoftware.com
- # scaadmin@scasoftware.com
- #
- # Copyright (c) 1999 SCA Software International S.A.
- #
- # Date: 03.01.2000
- # Author: Zoran M.Todorovic
- #
- # This software is provided "AS IS", without a warranty of any kind.
- # You are free to use/modify this code but leave this header intact.
- #
- #############################################################################*/
- #include "stdafx.h"
- #include <afxpriv.h> // Needed for WM_SIZEPARENT
- #include "VisualFx.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #endif
- //=============================================================================
- // class TTabItem
- //
- //=============================================================================
- // Create a tab item
- TTabItem::TTabItem(CWnd *pParent, LPCTSTR szLabel)
- {
- m_pWnd = NULL;
- m_nMinX = m_nMaxX = 0;
- m_bVisible = TRUE;
- m_bEnabled = TRUE;
- m_bWndEnabled = TRUE;
- RECT rect;
- ::ZeroMemory(&rect,sizeof(RECT));
- m_pCaption = new CStatic;
- ASSERT(m_pCaption);
- m_pCaption->Create(szLabel, WS_CHILD|SS_CENTER|WS_VISIBLE,rect,pParent);
- }
- TTabItem::TTabItem(const TTabItem& obj)
- {
- *this = obj;
- }
- TTabItem& TTabItem::operator=(const TTabItem& obj)
- {
- m_pWnd = obj.m_pWnd;
- m_pCaption = obj.m_pCaption;
- m_bWndEnabled = obj.m_bWndEnabled;
- m_bEnabled = obj.m_bEnabled;
- m_bVisible = obj.m_bVisible;
- m_nMinX = obj.m_nMinX;
- m_nMaxX = obj.m_nMaxX;
- return *this;
- }
- TTabItem::~TTabItem()
- {
- // This is done in TVisualFramework::Destroy()
- //if (m_pWnd->IsKindOf(RUNTIME_CLASS(CSplitterWnd)))
- // delete m_pWnd;
- ASSERT(m_pCaption);
- delete m_pCaption;
- }
- // Set rectangle for tab caption
- void TTabItem::SetRect(CRect& rect)
- {
- ASSERT(m_pCaption);
- m_pCaption->MoveWindow(&rect);
- }
- // Set font for tab caption
- void TTabItem::SetFont(CFont *pFont)
- {
- ASSERT(m_pCaption);
- ASSERT(pFont);
- m_pCaption->SetFont(pFont,FALSE);
- }
- // Get tab caption text
- CString TTabItem::GetText(void)
- {
- ASSERT(m_pCaption);
- CString str;
- m_pCaption->GetWindowText(str);
- return str;
- }
- int TTabItem::GetLength(void)
- {
- return m_nMaxX - m_nMinX;
- }
- // Set tab caption text
- void TTabItem::SetText(LPCTSTR szLabel)
- {
- ASSERT(m_pCaption);
- ASSERT(szLabel);
- m_pCaption->SetWindowText(szLabel);
- }
- // Enable/disable a window
- void TTabItem::Enable(BOOL bEnable)
- {
- m_bWndEnabled = bEnable;
- }
- // Enable/disable tab caption
- void TTabItem::EnableTab(BOOL bEnable)
- {
- ASSERT(m_pCaption);
- m_bEnabled = bEnable;
- m_pCaption->EnableWindow(m_bEnabled);
- }
- // Show/hide tab caption
- void TTabItem::ShowTab(BOOL bShow)
- {
- ASSERT(m_pCaption);
- m_bVisible = bShow;
- m_pCaption->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
- }
- CWnd *TTabItem::GetSafeWnd(void)
- {
- return (m_pWnd && ::IsWindow(m_pWnd->m_hWnd)) ? m_pWnd : NULL;
- }
- //=============================================================================
- // class TTabWnd
- //
- //=============================================================================
- #define TABWND_DEFAULT_ID 0x2578
- #define TABWND_HEIGHT 30 // Height of the gray border between the toolbar
- // and the client area
- #define TAB_HEIGHT 20 // Height on the normal tab
- #define TABSEL_HEIGHT 20 // Height of the selected tab
- #define TAB_SPACE 6 // Add to tab caption text width
- #define TAB_DEPL 4 // Distance between the tabs and the client area
- #define TAB_MAXLEN 200
- IMPLEMENT_DYNCREATE(TTabWnd,CWnd)
- BEGIN_MESSAGE_MAP(TTabWnd, CWnd)
- //{{AFX_MSG_MAP(TTabWnd)
- ON_MESSAGE(WM_SIZEPARENT, OnSizeParent)
- ON_WM_ERASEBKGND()
- ON_WM_PAINT()
- ON_WM_LBUTTONUP()
- ON_WM_DESTROY()
- ON_WM_SIZE()
- ON_WM_CREATE()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- TTabWnd::TTabWnd()
- {
- m_nSelectedTab = 0;
- m_bLockFlag = FALSE;
- m_nTabPos = TP_BOTTOM;
- // cache most used resources
- m_BrushBlack.CreateSolidBrush(RGB(0,0,0));
- m_BrushLGray.CreateSolidBrush(::GetSysColor(COLOR_BTNFACE));
- m_PenBlack.CreatePen(PS_SOLID, 1, (COLORREF)0);
- m_PenLGray.CreatePen(PS_SOLID, 1, ::GetSysColor(COLOR_BTNFACE));
- m_PenWhite.CreatePen(PS_SOLID, 1, ::GetSysColor(COLOR_BTNHIGHLIGHT));
- m_PenWhite2.CreatePen(PS_SOLID, 2, ::GetSysColor(COLOR_BTNHIGHLIGHT));
- m_PenDGray.CreatePen(PS_SOLID, 1, ::GetSysColor(COLOR_BTNSHADOW));
- m_PenDGray2.CreatePen(PS_SOLID, 2, ::GetSysColor(COLOR_BTNSHADOW));
- }
- TTabWnd::~TTabWnd()
- {
- }
- // Find a tab within this tab window
- TTabItem *TTabWnd::findTabItem(int nIndex)
- {
- int nNdx = 0;
- TTabItemList::iterator iterator;
- for (iterator = m_TabList.begin(); iterator != m_TabList.end(); iterator++) {
- if (nNdx == nIndex)
- return (*iterator);
- nNdx ++;
- }
- return NULL;
- }
- // Create a tab window
- BOOL TTabWnd::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName,
- DWORD dwStyle, const RECT& prect, CWnd* pParentWnd,
- UINT nID, CCreateContext *pContext)
- {
- ASSERT(pParentWnd);
- dwStyle &= ~WS_BORDER;
- CRect rect(prect);
- if (!CWnd::Create(NULL, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext))
- return FALSE;
- if (pParentWnd->IsKindOf(RUNTIME_CLASS(CFrameWnd))) {
- ((CFrameWnd*)pParentWnd)->ModifyStyleEx(WS_EX_CLIENTEDGE,0,SWP_FRAMECHANGED);
- ((CFrameWnd*)pParentWnd)->RecalcLayout();
- }
- ResizeTab();
- return TRUE;
- }
- int TTabWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- if (CWnd::OnCreate(lpCreateStruct) == -1)
- return -1;
- createFont();
- return 0;
- }
- void TTabWnd::OnDestroy()
- {
- CWnd::OnDestroy();
- TTabItemList::iterator iterator;
- for (iterator = m_TabList.begin(); iterator != m_TabList.end(); iterator ++) {
- delete (*iterator);
- }
- m_TabList.clear();
- // This is done in TVisualFramework
- //if (GetParent()->IsKindOf(RUNTIME_CLASS(CSplitterWnd)))
- // delete this;
- }
- // Virtual function to check whether switch to new tab can be done
- BOOL TTabWnd::CanSetActivePane(CWnd *pOldPane, CWnd *pNewPane)
- {
- return TRUE;
- }
- // Virtual function (after the switch is done)
- void TTabWnd::OnSetActivePane(CWnd *pOldPane, CWnd *pNewPane)
- {
- }
- // Create fonts for tab labels
- void TTabWnd::createFont()
- {
- NONCLIENTMETRICS metrics;
- metrics.cbSize = sizeof(metrics);
- ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &metrics, 0);
- CWindowDC wdc(NULL);
- int nLPixY = GetDeviceCaps(wdc.m_hDC, LOGPIXELSY);
- m_Font.CreateFontIndirect(&metrics.lfStatusFont);
- }
- // Add a tab to this window
- TTabItem *TTabWnd::addTab(CWnd *pWnd, LPCTSTR szLabel)
- {
- ASSERT(pWnd);
- ASSERT(szLabel);
- TTabItem *pItem = new TTabItem(this,szLabel);
- pItem->m_pWnd = pWnd;
- m_TabList.insert(m_TabList.end(), pItem);
- return pItem;
- }
- int TTabWnd::GetTabLength()
- {
- int nLength = 0;
- TTabItemList::iterator iterator;
- for (iterator = m_TabList.begin(); iterator != m_TabList.end(); iterator++) {
- nLength += (*iterator)->GetLength();
- }
- return nLength;
- }
- // Get index of currently selected tab
- int TTabWnd::GetTabIndex(void)
- {
- return m_nSelectedTab;
- }
- // Get number of tabs
- int TTabWnd::GetTabCount(void)
- {
- return m_TabList.size();
- }
- // Get index of the tab associated with specified window
- int TTabWnd::GetTabIndex(CWnd *pWnd)
- {
- ASSERT(pWnd);
- int nIndex = 0;
- TTabItem *pItem;
- TTabItemList::iterator iterator;
- for (iterator = m_TabList.begin(); iterator != m_TabList.end(); iterator++) {
- pItem = *iterator;
- if (pItem->m_pWnd == pWnd)
- return nIndex;
- nIndex ++;
- }
- return -1;
- }
- // Get pointer to window associated with the specified tab index
- CWnd *TTabWnd::GetTabWnd(int index)
- {
- TTabItem *pItem = findTabItem(index);
- ASSERT(pItem);
- return ::IsWindow(pItem->m_pWnd->m_hWnd) ? pItem->m_pWnd : NULL;
- }
- // Get tab caption text of the specified tab
- CString TTabWnd::GetTabLabel(int nIndex)
- {
- TTabItem *pItem = findTabItem(nIndex);
- ASSERT(pItem);
- return pItem->GetText();
- }
- // Set text of tab caption
- void TTabWnd::SetTabLabel(int nIndex, LPCTSTR szLabel)
- {
- ASSERT(szLabel);
- TTabItem *pItem = findTabItem(nIndex);
- ASSERT(pItem);
- pItem->SetText(szLabel);
- invalidateTabArea();
- }
- // Enable/disable a view
- void TTabWnd::Enable(int nIndex, BOOL bEnable)
- {
- TTabItem *pItem = findTabItem(nIndex);
- ASSERT(pItem);
- pItem->Enable(bEnable);
- //pItem->m_pWnd->EnableWindow(bEnable);
- }
- // Cannot disable currently selected tab
- void TTabWnd::EnableTab(int nIndex, BOOL bEnable)
- {
- ASSERT(nIndex != m_nSelectedTab);
- TTabItem *pItem = findTabItem(nIndex);
- ASSERT(pItem);
- pItem->EnableTab(bEnable);
- invalidateTabArea();
- }
- // Cannot make invisible currently selected tab
- void TTabWnd::ShowTab(int nIndex, BOOL bShow)
- {
- ASSERT(nIndex != m_nSelectedTab);
- TTabItem *pItem = findTabItem(nIndex);
- ASSERT(pItem);
- pItem->ShowTab(bShow);
- invalidateTabArea();
- }
- // Is tab enabled
- BOOL TTabWnd::IsTabEnabled(int nIndex)
- {
- TTabItem *pItem = findTabItem(nIndex);
- ASSERT(pItem);
- return pItem->m_bEnabled;
- }
- // Is tab visible
- BOOL TTabWnd::IsTabVisible(int nIndex)
- {
- TTabItem *pItem = findTabItem(nIndex);
- ASSERT(pItem);
- return pItem->m_bVisible;
- }
- // Set font
- void TTabWnd::SetFont(CFont *pFont)
- {
- ASSERT(pFont);
- CWnd::SetFont(pFont);
- m_Font.DeleteObject();
- LOGFONT lf;
- pFont->GetLogFont(&lf);
- m_Font.CreateFontIndirect(&lf);
- invalidateTabArea();
- }
- // Set position of tabs (top or bottom)
- void TTabWnd::SetTabPos(TTabPos nTabPos)
- {
- m_nTabPos = nTabPos;
- }
- // Invalidate rectangle to redraw tabs
- void TTabWnd::invalidateTabArea(void)
- {
- CRect rect;
- switch (m_nTabPos) {
- case TP_TOP:
- InvalidateRect(&CRect(0, 0, 32000, TABWND_HEIGHT));
- break;
- case TP_BOTTOM:
- GetClientRect(&rect);
- InvalidateRect(&CRect(CPoint(0,rect.Height()-TABWND_HEIGHT),
- CSize(32000,TABWND_HEIGHT)));
- break;
- };
- }
- // Draws a selected tab and returns its height
- int TTabWnd::drawSelTabTop(CDC *pDC, int x, CRect& client, TTabItem *pItem)
- {
- ASSERT(pItem);
- ASSERT(pDC);
- CString str = pItem->GetText();
- CSize textSize = pDC->GetTextExtent(str);
- textSize.cx += 10;
- if (textSize.cx > TAB_MAXLEN)
- textSize.cx = TAB_MAXLEN;
- int y = TABWND_HEIGHT - TABSEL_HEIGHT - TAB_DEPL;
- // black border, no bottom line
- pDC->SelectObject(&m_PenBlack);
- pDC->MoveTo(x,y+TABSEL_HEIGHT-1);
- pDC->LineTo(x,y);
- pDC->LineTo(x+textSize.cx+TAB_SPACE-1, y);
- pDC->LineTo(x+textSize.cx+TAB_SPACE-1, y+TABSEL_HEIGHT);
- // left and upper border in white, double line
- pDC->SelectObject(&m_PenWhite2);
- pDC->MoveTo(x+2,y+TABSEL_HEIGHT-1);
- pDC->LineTo(x+2,y+2);
- pDC->LineTo(x+textSize.cx+TAB_SPACE-4, y+2);
- // right border, dark gray, double line
- pDC->SelectObject(&m_PenDGray2);
- pDC->MoveTo(x+textSize.cx+TAB_SPACE-2, y+2);
- pDC->LineTo(x+textSize.cx+TAB_SPACE-2, y+TABSEL_HEIGHT-1);
- // clean up
- pDC->SelectObject(&m_PenLGray);
- pDC->MoveTo(x-1, y+TABSEL_HEIGHT);
- pDC->LineTo(x+textSize.cx+TAB_SPACE, y+TABSEL_HEIGHT);
- pDC->MoveTo(x-1, y+TABSEL_HEIGHT+1);
- pDC->LineTo(x+textSize.cx+TAB_SPACE, y+TABSEL_HEIGHT+1);
- // a black line to far left and right
- pDC->SelectObject(&m_PenBlack);
- pDC->MoveTo(0, y+TABSEL_HEIGHT-1);
- pDC->LineTo(x, y+TABSEL_HEIGHT-1);
- pDC->MoveTo(x+textSize.cx+TAB_SPACE+1, y+TABSEL_HEIGHT-1);
- pDC->LineTo(client.right, y+TABSEL_HEIGHT-1);
- // and a white double line
- pDC->SelectObject(&m_PenWhite2);
- if (x!=0) {
- pDC->MoveTo(0, y+TABSEL_HEIGHT+1);
- pDC->LineTo(x, y+TABSEL_HEIGHT+1);
- }
- pDC->MoveTo(x+textSize.cx+TAB_SPACE, y+TABSEL_HEIGHT+1);
- pDC->LineTo(client.right, y+TABSEL_HEIGHT+1);
- // gray inside
- pDC->FillSolidRect(x+3, y+3,textSize.cx+TAB_SPACE-6, TABSEL_HEIGHT,
- ::GetSysColor(COLOR_BTNFACE));
- CRect rect(CPoint(x+TAB_SPACE/2, y+(TAB_HEIGHT-textSize.cy)/2+1), textSize);
- pItem->SetFont(&m_Font);
- pItem->SetRect(rect);
- return textSize.cx+TAB_SPACE;
- }
- // Draw a selected tab at the bottom
- int TTabWnd::drawSelTabBottom(CDC *pDC, int x, CRect& client, TTabItem *pItem)
- {
- ASSERT(pItem);
- ASSERT(pDC);
- CString str = pItem->GetText();
- CSize textSize = pDC->GetTextExtent(str);
- textSize.cx += 10;
- if (textSize.cx > TAB_MAXLEN)
- textSize.cx = TAB_MAXLEN;
- int y = client.Height() - TABWND_HEIGHT + TAB_DEPL;
- // black border, no bottom line
- pDC->SelectObject(&m_PenBlack);
- pDC->MoveTo(x,y);
- pDC->LineTo(x,y+TABSEL_HEIGHT);
- pDC->LineTo(x+textSize.cx+TAB_SPACE-1, y+TABSEL_HEIGHT);
- pDC->LineTo(x+textSize.cx+TAB_SPACE-1, y);
- // left border in white, double line
- pDC->SelectObject(&m_PenWhite2);
- pDC->MoveTo(x+2,y);
- pDC->LineTo(x+2,y+TABSEL_HEIGHT-1);
- // right and bottom border, dark gray, double line
- pDC->SelectObject(&m_PenDGray2);
- pDC->LineTo(x+textSize.cx+TAB_SPACE-4, y+TABSEL_HEIGHT-1);
- pDC->MoveTo(x+textSize.cx+TAB_SPACE-2, y);
- pDC->LineTo(x+textSize.cx+TAB_SPACE-2, y+TABSEL_HEIGHT-1);
- // a black line to far left and right
- pDC->SelectObject(&m_PenBlack);
- pDC->MoveTo(0, y);
- pDC->LineTo(x, y);
- pDC->MoveTo(x+textSize.cx+TAB_SPACE, y);
- pDC->LineTo(client.right, y);
- // and a gray line to far left and right
- pDC->SelectObject(&m_PenDGray);
- if (x != 0) {
- pDC->MoveTo(0, y-1);
- pDC->LineTo(x, y-1);
- }
- pDC->MoveTo(x+textSize.cx+TAB_SPACE-2, y-1);
- pDC->LineTo(client.right, y-1);
- // gray inside
- pDC->FillSolidRect(x+3,y,textSize.cx+TAB_SPACE-6, TABSEL_HEIGHT-2,
- ::GetSysColor(COLOR_BTNFACE));
- CRect rect(CPoint(x+TAB_SPACE/2, y+(TAB_HEIGHT-textSize.cy)/2), textSize);
- pItem->SetFont(&m_Font);
- pItem->SetRect(rect);
- return textSize.cx+TAB_SPACE;
- }
- // Draws an unselected tab and returs its height
- int TTabWnd::drawTabTop(CDC *pDC, int x, CRect& client, TTabItem *pItem)
- {
- ASSERT(pItem);
- ASSERT(pDC);
- CString str = pItem->GetText();
- CSize textSize = pDC->GetTextExtent(str);
- textSize.cx += 10;
- if (textSize.cx > TAB_MAXLEN)
- textSize.cx = TAB_MAXLEN;
- int y = TABWND_HEIGHT-TAB_HEIGHT-TAB_DEPL;
- // black border
- pDC->FrameRect(&CRect(CPoint(x,y), CSize(textSize.cx+TAB_SPACE, TAB_HEIGHT)),
- &m_BrushBlack);
- pDC->SelectObject(&m_PenWhite);
- pDC->MoveTo(x+1, y+1);
- pDC->LineTo(x+1, y+TAB_HEIGHT-1);
- pDC->MoveTo(x+1, y+1);
- pDC->LineTo(x+textSize.cx+TAB_SPACE-2, y+1);
- pDC->SelectObject(&m_PenDGray);
- pDC->MoveTo(x+textSize.cx+TAB_SPACE-2, y+1);
- pDC->LineTo(x+textSize.cx+TAB_SPACE-2, y+TAB_HEIGHT-1);
- pDC->FillRect(&CRect(CPoint(x+2,y+2), CSize(textSize.cx+TAB_SPACE-4, TAB_HEIGHT-3)),
- &m_BrushLGray);
- // clean up
- int dy = TABSEL_HEIGHT-TAB_HEIGHT;
- pDC->FillSolidRect(x, y-dy, textSize.cx+TAB_SPACE, dy, GetSysColor(COLOR_BTNFACE));
- CRect rect(CPoint(x+TAB_SPACE/2, y+(TAB_HEIGHT-textSize.cy)/2+1), textSize);
- pItem->SetFont(&m_Font);
- pItem->SetRect(rect);
- return textSize.cx+TAB_SPACE;
- }
- // Draw an unselected tab at the bottom
- int TTabWnd::drawTabBottom(CDC *pDC, int x, CRect& client, TTabItem *pItem)
- {
- ASSERT(pItem);
- ASSERT(pDC);
- CString str = pItem->GetText();
- CSize textSize = pDC->GetTextExtent(str);
- textSize.cx += 10;
- if (textSize.cx > TAB_MAXLEN)
- textSize.cx = TAB_MAXLEN;
- int y = client.Height() - TABWND_HEIGHT + TAB_DEPL;
- // black border
- pDC->FrameRect(&CRect(CPoint(x,y), CSize(textSize.cx+TAB_SPACE, TAB_HEIGHT+1)),
- &m_BrushBlack);
- // Gray border bottom and right side
- pDC->SelectObject(&m_PenDGray);
- pDC->MoveTo(x+1, y+TAB_HEIGHT-1);
- pDC->LineTo(x+textSize.cx+TAB_SPACE-2, y+TAB_HEIGHT-1);
- pDC->MoveTo(x+textSize.cx+TAB_SPACE-2, y);
- pDC->LineTo(x+textSize.cx+TAB_SPACE-2, y+TAB_HEIGHT-1);
- pDC->FillRect(&CRect(CPoint(x+1,y+1), CSize(textSize.cx+TAB_SPACE-4, TAB_HEIGHT-3)),
- &m_BrushLGray);
- CRect rect(CPoint(x+TAB_SPACE/2, y+(TAB_HEIGHT-textSize.cy)/2), textSize);
- pItem->SetFont(&m_Font);
- pItem->SetRect(rect);
- return textSize.cx+TAB_SPACE;
- }
- // Draw edge arround client area
- void TTabWnd::drawClient(CDC *pDc, CRect& rect)
- {
- ASSERT(pDc);
- CWnd *pParent = GetParent();
- ASSERT(pParent);
- switch (m_nTabPos) {
- case TP_TOP:
- if (pParent->IsKindOf(RUNTIME_CLASS(CFrameWnd))) {
- pDc->DrawEdge(&rect, EDGE_ETCHED, BF_TOP);
- }
- pDc->Draw3dRect(0,TABWND_HEIGHT, rect.right, rect.bottom-TABWND_HEIGHT,
- ::GetSysColor(COLOR_BTNSHADOW), ::GetSysColor(COLOR_BTNHIGHLIGHT));
- pDc->Draw3dRect(1,TABWND_HEIGHT+1, rect.right-2, rect.bottom-TABWND_HEIGHT-2,
- 0, ::GetSysColor(COLOR_3DLIGHT));
- break;
- case TP_BOTTOM:
- if (pParent->IsKindOf(RUNTIME_CLASS(CFrameWnd))) {
- pDc->DrawEdge(&rect, EDGE_ETCHED, BF_BOTTOM);
- }
- pDc->Draw3dRect(0,0, rect.right, rect.bottom-TABWND_HEIGHT+1,
- ::GetSysColor(COLOR_BTNSHADOW), ::GetSysColor(COLOR_BTNHIGHLIGHT));
- pDc->Draw3dRect(1,1, rect.right-2, rect.bottom-TABWND_HEIGHT-1,
- 0, ::GetSysColor(COLOR_3DLIGHT));
- break;
- }
- }
- void TTabWnd::OnPaint()
- {
- CPaintDC dc(this); // device context for painting
- CRect client;
- GetClientRect(&client);
- drawClient(&dc, client);
- int x = 0, nIndex = 0;
- TTabItemList::iterator iterator;
- for (iterator = m_TabList.begin(); iterator != m_TabList.end(); iterator++) {
- TTabItem *pItem = *iterator;
- ASSERT(pItem != NULL);
- if (pItem->m_bVisible) {
- pItem->m_nMinX = x;
- if (nIndex != m_nSelectedTab) {
- switch (m_nTabPos) {
- case TP_TOP: x += drawTabTop(&dc, x, client, pItem); break;
- case TP_BOTTOM: x += drawTabBottom(&dc, x, client, pItem); break;
- }
- } else {
- switch (m_nTabPos) {
- case TP_TOP: x += drawSelTabTop(&dc, x, client, pItem); break;
- case TP_BOTTOM: x += drawSelTabBottom(&dc, x, client, pItem); break;
- }
- }
- }
- pItem->m_nMaxX = x;
- nIndex ++;
- }
- }
- // Returns tab index that holds specified point
- int TTabWnd::HitTest(CPoint& point)
- {
- return HitTest(point.x,point.y);
- }
- // Returns tab index that holds specified point
- int TTabWnd::HitTest(int x, int y)
- {
- int notsel_y_min, sel_y_min, y_max;
- CRect rect;
- GetClientRect(&rect);
- switch (m_nTabPos) {
- case TP_TOP:
- notsel_y_min = TABWND_HEIGHT - TAB_HEIGHT - TAB_DEPL;
- sel_y_min = TABWND_HEIGHT - TABSEL_HEIGHT - TAB_DEPL;
- y_max = TABWND_HEIGHT - TAB_DEPL;
- break;
- case TP_BOTTOM:
- notsel_y_min = rect.Height() - TABWND_HEIGHT + TAB_DEPL;
- sel_y_min = rect.Height() - TABWND_HEIGHT + TAB_DEPL;
- y_max = rect.Height() - TABWND_HEIGHT + TAB_DEPL + TAB_HEIGHT;
- break;
- };
- int nIndex = 0;
- TTabItemList::iterator iterator;
- for (iterator = m_TabList.begin(); iterator != m_TabList.end(); iterator++) {
- TTabItem *pItem = (*iterator);
- if (pItem->m_bEnabled && pItem->m_bVisible) {
- if (nIndex != m_nSelectedTab && (y < notsel_y_min || y > y_max))
- continue;
- if (nIndex == m_nSelectedTab && (y < sel_y_min || y > y_max))
- continue;
- if (x >= pItem->m_nMinX && x <= pItem->m_nMaxX)
- return nIndex;
- }
- nIndex++;
- }
- return -1;
- }
- // Switch focus to specified tab index
- BOOL TTabWnd::SetActivePane(int nIndex, BOOL bActivate)
- {
- if (nIndex == -1)
- return FALSE;
- if (nIndex == m_nSelectedTab)
- return TRUE;
- TTabItem *pNewPane = findTabItem(nIndex);
- if (!pNewPane->m_bEnabled || !pNewPane->m_bVisible)
- return FALSE;
- TTabItem *pOldPane = NULL;
- if (m_nSelectedTab != -1)
- pOldPane = findTabItem(m_nSelectedTab);
- if (CanSetActivePane(pOldPane ? pOldPane->m_pWnd : NULL, pNewPane->m_pWnd)) {
- // Deactivate old pane
- if (m_nSelectedTab != -1) {
- pOldPane->m_pWnd->EnableWindow(FALSE);
- pOldPane->m_pWnd->ShowWindow(SW_HIDE);
- }
- // Activate new pane
- pNewPane->m_pWnd->EnableWindow(pNewPane->m_bWndEnabled ? TRUE : FALSE);
- pNewPane->m_pWnd->ShowWindow(SW_SHOW);
- pNewPane->m_pWnd->SetFocus();
- // Save index of new pane
- m_nSelectedTab = nIndex;
- // Invalidate tab
- invalidateTabArea();
- // Inform derived class
- OnSetActivePane(pOldPane ? pOldPane->m_pWnd : NULL, pNewPane->m_pWnd);
- // Update frame window
- if (bActivate) {
- CWnd *pParent = GetParent();
- while (pParent && !pParent->IsKindOf(RUNTIME_CLASS(CFrameWnd)))
- pParent = pParent->GetParent();
- ASSERT(pParent != NULL);
- updateFrame((CFrameWnd*)pParent, pNewPane->m_pWnd);
- }
- return TRUE;
- }
- return FALSE;
- }
- // Update frame window active view based on newly selected tab item
- BOOL TTabWnd::updateFrame(CFrameWnd *pFrame, CWnd *pWnd)
- {
- ASSERT(pFrame);
- ASSERT(pWnd);
- if (pWnd->IsKindOf(RUNTIME_CLASS(CView))) {
- // New tab item is a view
- pFrame->SetActiveView((CView*)pWnd);
- return TRUE;
- } else if (pWnd->IsKindOf(RUNTIME_CLASS(CSplitterWnd))) {
- CSplitterWnd *pSplitter = (CSplitterWnd*)pWnd;
- CWnd *pView = pSplitter->GetActivePane();
- if (pView == NULL) {
- CWnd *pTmpView;
- for (int x = 0; x < pSplitter->GetRowCount(); x ++) {
- for (int y = 0; y < pSplitter->GetColumnCount(); y ++) {
- pTmpView = pSplitter->GetPane(x,y);
- if (pTmpView->IsWindowEnabled()) {
- if (updateFrame(pFrame, pTmpView))
- return TRUE;
- }
- }
- }
- }
- if (pView == NULL)
- pView = pSplitter->GetPane(0,0);
- pFrame->SetActiveView((CView*)pView);
- } else if (pWnd->IsKindOf(RUNTIME_CLASS(TTabWnd))) {
- TTabWnd *pTab = (TTabWnd*)pWnd;
- int nIndex = pTab->GetTabIndex();
- CWnd *pTabWnd = pTab->GetTabWnd(nIndex);
- if (updateFrame(pFrame, pTabWnd))
- return TRUE;
- }
- return FALSE;
- }
- // Resize tab
- void TTabWnd::ResizeTab(int cx, int cy)
- {
- CRect rect;
- CWnd *pParent = (CWnd*)GetParent();
- ASSERT(pParent);
- pParent->GetClientRect(&rect);
- if (pParent->IsKindOf(RUNTIME_CLASS(CSplitterWnd))) {
- CSplitterWnd *splitter = (CSplitterWnd*)pParent;
- ASSERT(pParent);
- int row,col;
- splitter->IsChildPane(this,row,col);
- splitter->RecalcLayout();
- } else if (pParent->IsKindOf(RUNTIME_CLASS(CFrameWnd))) {
- m_bLockFlag = TRUE;
- pParent->RepositionBars(0, 0xFFFF, AFX_IDW_PANE_FIRST, CWnd::reposQuery, &rect);
- MoveWindow(rect.left,rect.top,rect.Width(),rect.Height());
- m_bLockFlag = FALSE;
- }
- m_bLockFlag = TRUE; // reentrancy check (might get called recursivly from OnSize)
- CWnd *pWnd;
- TTabItemList::iterator iterator;
- for (iterator = m_TabList.begin(); iterator != m_TabList.end(); iterator++) {
- pWnd = (*iterator)->m_pWnd;
- if (cx == -1 && cy == -1) {
- switch (m_nTabPos) {
- case TP_TOP:
- pWnd->MoveWindow(1, TABWND_HEIGHT+1,
- rect.Width()-2, rect.Height()-TABWND_HEIGHT-2);
- break;
- case TP_BOTTOM:
- pWnd->MoveWindow(1, 0, rect.Width()-2, rect.Height()-TABWND_HEIGHT);
- break;
- }
- } else {
- switch (m_nTabPos) {
- case TP_TOP:
- pWnd->MoveWindow(1, TABWND_HEIGHT+1, cx, cy-TABWND_HEIGHT-2);
- break;
- case TP_BOTTOM:
- pWnd->MoveWindow(1, 0, cx, cy-TABWND_HEIGHT);
- break;
- }
- }
- }
- m_bLockFlag=FALSE;
- }
- // Erase area where the tabs are displayed
- BOOL TTabWnd::OnEraseBkgnd(CDC* pDC)
- {
- ASSERT(pDC);
- CRect rect;
- GetClientRect(&rect);
- switch (m_nTabPos) {
- case TP_TOP:
- pDC->FillSolidRect(&CRect(0, 0, rect.right, TABWND_HEIGHT),
- ::GetSysColor(COLOR_BTNFACE));
- break;
- case TP_BOTTOM:
- pDC->FillSolidRect(&CRect(0, rect.bottom-TABWND_HEIGHT-3, rect.right, rect.bottom),
- ::GetSysColor(COLOR_BTNFACE));
- break;
- }
- return TRUE;
- }
- // Handle couse click on tabs
- void TTabWnd::OnLButtonUp(UINT nFlags, CPoint point)
- {
- int nNewTab = HitTest(point.x, point.y);
- SetActivePane(nNewTab);
- CWnd::OnLButtonUp(nFlags, point);
- }
- // Handle resize
- LRESULT TTabWnd::OnSizeParent(WPARAM, LPARAM lParam)
- {
- if (m_bLockFlag)
- return 0;
- ResizeTab();
- return 0;
- }
- // Handle resize
- void TTabWnd::OnSize(UINT nType, int cx, int cy)
- {
- CWnd::OnSize(nType, cx, cy);
- ResizeTab(cx,cy);
- }
- // Create a CView derived class as a tab
- TTabItem *TTabWnd::CreatePane(LPCTSTR lpszLabel, CRuntimeClass *pViewClass,
- CCreateContext *pContext)
- {
- CRect rect, client;
- ASSERT(pViewClass && pContext);
- CWnd *pWnd = (CWnd*)pViewClass->CreateObject();
- if (!pWnd)
- return NULL;
- GetClientRect(&client);
- rect.left = 0;
- rect.top = TABWND_HEIGHT+2;
- rect.right = client.right;
- rect.bottom = client.bottom;
- int dwStyle = AFX_WS_DEFAULT_VIEW;
- if (GetParent()->IsKindOf(RUNTIME_CLASS(CSplitterWnd))) {
- dwStyle &= ~WS_BORDER;
- }
- if (!pWnd->Create(NULL, NULL, dwStyle, rect, this, 13576+m_TabList.size(), pContext))
- {
- TRACE0("Warning: couldn't create client area for tab viewn");
- // pWnd will be cleaned up by PostNcDestroy
- return NULL;
- }
- // Insert new tab object into the list
- TTabItem *pTab = addTab(pWnd,lpszLabel);
- ASSERT(pTab);
- if (m_TabList.size() != 1) {
- pWnd->EnableWindow(FALSE);
- pWnd->ShowWindow(SW_HIDE);
- /*
- // Framework is responsible to set the active view
- } else {
- CWnd *pParent = GetParent();
- if (pParent->IsKindOf(RUNTIME_CLASS(CFrameWnd))) {
- ((CFrameWnd*)pParent)->SetActiveView((CView*)pWnd);
- } else if (pParent->IsKindOf(RUNTIME_CLASS(CSplitterWnd))) {
- ((CSplitterWnd*)pParent)->SetActivePane(0,0,pWnd);
- }
- */
- }
- return pTab;
- }
- // Create a splitter window as a tab
- TTabItem *TTabWnd::CreatePane(LPCTSTR lpszLabel, int nRows, int nCols,
- CWnd *pWnd, UINT nID)
- {
- ASSERT(pWnd);
- ASSERT(pWnd->IsKindOf(RUNTIME_CLASS(CSplitterWnd)));
- // Moved to TVisualFramework to handle creation of CSplitterWnd derived classes
- //CSplitterWnd *pWnd = new CSplitterWnd;
- //if (!pWnd)
- // return NULL;
- int dwStyle = AFX_WS_DEFAULT_VIEW;
- dwStyle &= ~WS_BORDER;
- CSplitterWnd *pSplitter = (CSplitterWnd*)pWnd;
- if (!pSplitter->CreateStatic(this, nRows, nCols, dwStyle, nID)) {
- TRACE0("Warning: couldn't create client area for tab viewn");
- // pWnd will be cleaned up by PostNcDestroy
- return NULL;
- }
- TTabItem *pTab = addTab(pWnd,lpszLabel);
- ASSERT(pTab);
- if (m_TabList.size() != 1) {
- pWnd->EnableWindow(FALSE);
- pWnd->ShowWindow(SW_HIDE);
- }
- /*
- // Framework will set the active view
- CWnd *paneWnd = pWnd->GetActivePane();
- if (paneWnd) {
- ((CFrameWnd*)GetParent())->SetActiveView((CView*)paneWnd);
- } else {
- paneWnd = pWnd->GetPane(0,0);
- pWnd->SetActivePane(0,0);
- ((CFrameWnd*)GetParent())->SetActiveView((CView*)paneWnd);
- }
- */
- return pTab;
- }
- //=============================================================================
- // class TVisualObject
- //
- //=============================================================================
- // Private constructor
- TVisualObject::TVisualObject()
- {
- }
- // Create a plain view
- TVisualObject::TVisualObject(DWORD dwId, CCreateContext *pContext,
- CRuntimeClass *pClass)
- {
- ASSERT(pContext);
- ASSERT(pClass);
- ASSERT(pClass->IsDerivedFrom(RUNTIME_CLASS(CView)));
- zeroAll();
- m_dwId = dwId;
- m_nObjectType = OT_VIEW;
- m_pContext = pContext;
- m_pRuntimeClass = pClass;
- checkStyle();
- }
- // Create a view within a tab window or a tab window
- TVisualObject::TVisualObject(DWORD dwId, LPCTSTR szTitle, CCreateContext *pContext,
- CRuntimeClass *pClass, DWORD dwStyle)
- {
- ASSERT(szTitle);
- ASSERT(pContext);
- ASSERT(pClass);
- zeroAll();
- m_dwId = dwId;
- if (pClass->IsDerivedFrom(RUNTIME_CLASS(TTabWnd))) {
- m_nObjectType = OT_TAB;
- } else if (pClass->IsDerivedFrom(RUNTIME_CLASS(CView))) {
- m_nObjectType = OT_TABVIEW;
- } else {
- ASSERT(FALSE);
- }
- m_strTitle = szTitle;
- m_pContext = pContext;
- m_pRuntimeClass = pClass;
- m_dwStyle = dwStyle;
- checkStyle();
- }
- // Create a splitter window
- TVisualObject::TVisualObject(DWORD dwId, LPCTSTR szTitle, int nRows, int nCols,
- CCreateContext *pContext, DWORD dwStyle)
- {
- ASSERT(szTitle);
- ASSERT(pContext);
- ASSERT(nRows);
- ASSERT(nCols);
- zeroAll();
- m_dwId = dwId;
- m_nObjectType = OT_SPLITTER;
- m_strTitle = szTitle;
- m_pContext = pContext;
- m_nRows = nRows;
- m_nCols = nCols;
- m_dwStyle = dwStyle;
- checkStyle();
- }
- // Create a view within a splitter window
- TVisualObject::TVisualObject(DWORD dwId, int nRow, int nCol, CCreateContext *pContext,
- CRuntimeClass *pClass, CSize size, DWORD dwStyle)
- {
- ASSERT(pContext);
- ASSERT(pClass);
- ASSERT(pClass->IsDerivedFrom(RUNTIME_CLASS(CView)) ||
- pClass->IsDerivedFrom(RUNTIME_CLASS(TTabWnd)));
- zeroAll();
- m_dwId = dwId;
- m_nObjectType = OT_SPLITTERVIEW;
- m_pContext = pContext;
- m_pRuntimeClass = pClass;
- m_nRowIndex = nRow;
- m_nColIndex = nCol;
- m_Size = size;
- m_dwStyle = dwStyle;
- checkStyle();
- }
- // Create a splitter within a splitter window
- TVisualObject::TVisualObject(DWORD dwId, int nRow, int nCol, int nRows, int nCols,
- CCreateContext *pContext, DWORD dwStyle)
- {
- ASSERT(pContext);
- ASSERT(nRows);
- ASSERT(nCols);
- zeroAll();
- m_dwId = dwId;
- m_nObjectType = OT_SPLITTERSPLITTER;
- m_pContext = pContext;
- m_nRowIndex = nRow;
- m_nColIndex = nCol;
- m_nRows = nRows;
- m_nCols = nCols;
- m_dwStyle = dwStyle;
- checkStyle();
- }
- TVisualObject::TVisualObject(const TVisualObject& obj)
- {
- zeroAll();
- *this = obj;
- }
- TVisualObject::~TVisualObject()
- {
- }
- TVisualObject& TVisualObject::operator=(const TVisualObject& obj)
- {
- // No need to copy m_ObjectList since it is populated after
- // this code is executed in STL container
- m_nObjectType = obj.m_nObjectType;
- m_dwId = obj.m_dwId;
- m_pWnd = obj.m_pWnd;
- m_pParent = obj.m_pParent;
- m_strTitle = obj.m_strTitle;
- m_nRows = obj.m_nRows;
- m_nCols = obj.m_nCols;
- m_nRowIndex = obj.m_nRowIndex;
- m_nColIndex = obj.m_nColIndex;
- m_pContext = obj.m_pContext;
- m_pRuntimeClass = obj.m_pRuntimeClass;
- m_Size = obj.m_Size;
- m_bEnabled = obj.m_bEnabled;
- m_dwStyle = obj.m_dwStyle;
- m_cHotKey = obj.m_cHotKey;
- m_pOwner = obj.m_pOwner;
- m_pFramework = obj.m_pFramework;
- return *this;
- }
- void TVisualObject::zeroAll(void)
- {
- // No need to zero m_ObjectList since it is already empty
- m_nObjectType = OT_UNKNOWN;
- m_dwId = 0;
- m_pWnd = NULL;
- m_pParent = NULL;
- m_strTitle = _T("");
- m_nRows = 0;
- m_nCols = 0;
- m_nRowIndex = 0;
- m_nColIndex = 0;
- m_pContext = NULL;
- m_pRuntimeClass = NULL;
- m_Size = CSize(0,0);
- m_bEnabled = TRUE;
- m_dwStyle = 0;
- m_cHotKey = 0;
- m_pOwner = NULL;
- m_pFramework = NULL;
- }
- // Check if style is valid
- void TVisualObject::checkStyle(void)
- {
- if ((m_dwStyle & TOS_TABTOP) || (m_dwStyle & TOS_TABBOTTOM)) {
- ASSERT(m_pRuntimeClass);
- // Tab position valid only for tab window derived classes
- ASSERT(m_pRuntimeClass->IsDerivedFrom(RUNTIME_CLASS(TTabWnd)));
- }
- if (m_dwStyle & TOS_SELECTED) {
- // Selected valid only for tab panes that are not splitters and tabs
- // In this case, use TVisualFramework::SetActivePane() to set the active pane
- // once the framework is created
- if (m_pRuntimeClass == NULL) {
- // Splitters canot be dynamically create (m_pRuntimeClass is NULL)
- ASSERT((m_nObjectType != OT_SPLITTER) && (m_nObjectType != OT_SPLITTERVIEW));
- } else {
- ASSERT(!m_pRuntimeClass->IsDerivedFrom(RUNTIME_CLASS(TTabWnd)));
- }
- }
- }
- // Delete the window pointer and optionally destroy the window
- void TVisualObject::Destroy(BOOL bDestroyWindow)
- {
- if (m_pWnd) {
- if (bDestroyWindow)
- m_pWnd->DestroyWindow();
- delete m_pWnd;
- m_pWnd = NULL;
- }
- }
- // If this object is a tab window or splitter window that it
- // cannot be focused
- BOOL TVisualObject::CanFocus(void)
- {
- ASSERT(m_pWnd);
- if (m_pWnd->IsKindOf(RUNTIME_CLASS(CSplitterWnd)) ||
- m_pWnd->IsKindOf(RUNTIME_CLASS(TTabWnd)))
- {
- return FALSE;
- }
- return TRUE;
- }
- // Set hot key for this tab object
- void TVisualObject::SetHotKey(CHAR cHotKey)
- {
- m_cHotKey = cHotKey;
- }
- // Optional: Set description
- void TVisualObject::SetDescription(LPCTSTR szDesc)
- {
- m_strDescription = szDesc;
- }
- // Set this object as active pane
- BOOL TVisualObject::SetActivePane(void)
- {
- ASSERT(m_pFramework);
- return m_pFramework->SetActivePane(this);
- }
- // Set this tab to be active tab (not the active pane)
- BOOL TVisualObject::SetActiveTab(void)
- {
- ASSERT(m_pFramework);
- return m_pFramework->SetActiveTab(this);
- }
- // Enable/disable this object
- BOOL TVisualObject::Enable(BOOL bEnable)
- {
- ASSERT(m_pFramework);
- return m_pFramework->Enable(this,bEnable);
- }
- // Enable/disable tab
- BOOL TVisualObject::EnableTab(BOOL bEnable)
- {
- ASSERT(m_pFramework);
- return m_pFramework->EnableTab(this,bEnable);
- }
- // SHow/hide this object
- BOOL TVisualObject::ShowTab(BOOL bShow)
- {
- ASSERT(m_pFramework);
- return m_pFramework->ShowTab(this,bShow);
- }
- // Is this object enabled
- BOOL TVisualObject::IsEnabled(BOOL& bEnabled)
- {
- ASSERT(m_pFramework);
- return m_pFramework->IsEnabled(this,bEnabled);
- }
- // Is this object enabled
- BOOL TVisualObject::IsTabEnabled(BOOL& bEnabled)
- {
- ASSERT(m_pFramework);
- return m_pFramework->IsTabEnabled(this,bEnabled);
- }
- // Is this object visible
- BOOL TVisualObject::IsTabVisible(BOOL& bVisible)
- {
- ASSERT(m_pFramework);
- return m_pFramework->IsTabVisible(this,bVisible);
- }
- // Returns TRUE if this object is a tab within a tab window
- BOOL TVisualObject::IsTabPane(void)
- {
- ASSERT(m_pFramework);
- return m_pFramework->IsTabPane(this);
- }
- // Returns TRUE if this object is a tab window
- BOOL TVisualObject::IsTabWindow(void)
- {
- ASSERT(m_pFramework);
- return m_pFramework->IsTabWindow(this);
- }
- // Returns TRUE if this object is a pane within a splitter window
- BOOL TVisualObject::IsSplitterPane(void)
- {
- ASSERT(m_pFramework);
- return m_pFramework->IsSplitterPane(this);
- }
- // Returns TRUE if this object is a splitter window
- BOOL TVisualObject::IsSplitterWindow(void)
- {
- ASSERT(m_pFramework);
- return m_pFramework->IsSplitterWindow(this);
- }
- // Returns TRUE if this object is derived from CView
- BOOL TVisualObject::IsView(void)
- {
- ASSERT(m_pFramework);
- return m_pFramework->IsView(this);
- }
- // Get object ID
- #ifdef _DEBUG
- DWORD TVisualObject::GetID(void)
- {
- return m_dwId;
- }
- #endif
- // Get object window
- #ifdef _DEBUG
- CWnd *TVisualObject::GetWnd(void)
- {
- return m_pWnd;
- }
- #endif
- // Get safe object window
- #ifdef _DEBUG
- CWnd *TVisualObject::GetSafeWnd(void)
- {
- return ::IsWindow(m_pWnd->m_hWnd) ? m_pWnd : NULL;
- }
- #endif
- #ifdef _DEBUG
- CString TVisualObject::GetTitle(void)
- {
- return m_strTitle;
- }
- #endif
- #ifdef _DEBUG
- CString TVisualObject::GetDescription(void)
- {
- return m_strDescription;
- }
- #endif
- #ifdef _DEBUG
- CWnd *TVisualObject::GetParentWnd(void)
- {
- return m_pParent;
- }
- #endif
- #ifdef _DEBUG
- TVisualFramework *TVisualObject::GetFramework(void)
- {
- return m_pFramework;
- }
- #endif
- #ifdef _DEBUG
- TVisualObject *TVisualObject::GetOwner(void)
- {
- return m_pOwner;
- }
- #endif
- //=============================================================================
- // class TVisualFramework
- //
- //=============================================================================
- IMPLEMENT_DYNCREATE(TVisualFramework, CCmdTarget)
- BEGIN_MESSAGE_MAP(TVisualFramework, CCmdTarget)
- //{{AFX_MSG_MAP(TVisualFramework)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- TVisualFramework::TVisualFramework()
- {
- m_pOwner = NULL;
- m_bEnableCtrlTab = TRUE;
- }
- TVisualFramework::~TVisualFramework()
- {
- if (m_ObjectMap.size() && m_ObjectList.size()) {
- TRACE0(_T(">>> TVisualFramework::Destroy() called in TVisualFramework destructorn"));
- TRACE0(_T(">>> It must be called in CFrameWnd derived class OnDestroy() message handlern"));
- Destroy();
- }
- }
- // Find an object in the map with the specified unique id
- TVisualObject *TVisualFramework::findObject(DWORD dwId)
- {
- TVisualObjectMap::iterator iterator;
- for (iterator = m_ObjectMap.begin(); iterator != m_ObjectMap.end(); iterator++) {
- if (dwId == iterator->first)
- return iterator->second;
- }
- return NULL;
- }
- // Find an object in the map with the specified window
- TVisualObject *TVisualFramework::findObject(CWnd *pWnd)
- {
- TVisualObjectMap::iterator iterator;
- for (iterator = m_ObjectMap.begin(); iterator != m_ObjectMap.end(); iterator++) {
- if (pWnd == iterator->second->m_pWnd)
- return iterator->second;
- }
- return NULL;
- }
- // Add object to the container (this is a root level object)
- // There is only one root level object (either splitter or tab)
- BOOL TVisualFramework::Add(TVisualObject *pObject)
- {
- ASSERT(pObject);
- ASSERT(m_ObjectList.size() == 0); // Only one root level object allowed
- // Root level object is either a view, splitter or a tab
- ASSERT((pObject->m_nObjectType == TVisualObject::OT_TAB) ||
- (pObject->m_nObjectType == TVisualObject::OT_VIEW) ||
- (pObject->m_nObjectType == TVisualObject::OT_SPLITTER));
- if (findObject(pObject->m_dwId) == NULL) {
- m_ObjectList.insert(m_ObjectList.end(), pObject);
- pObject->m_pFramework = this;
- m_ObjectMap[pObject->m_dwId] = pObject;
- return TRUE;
- }
- ASSERT(FALSE); // Duplicate object Id
- return FALSE;
- }
- // Add child object to the specified object
- BOOL TVisualFramework::Add(TVisualObject *pOwner, TVisualObject *pObject)
- {
- ASSERT(pObject);
- #ifdef _DEBUG
- // Validate definition
- if (pOwner->m_nObjectType == TVisualObject::OT_TAB) {
- if ((pObject->m_nObjectType != TVisualObject::OT_TABVIEW) &&
- (pObject->m_nObjectType != TVisualObject::OT_SPLITTER) &&
- (pObject->m_nObjectType != TVisualObject::OT_TAB))
- {
- ASSERT(FALSE);
- }
- } else if (pOwner->m_nObjectType == TVisualObject::OT_SPLITTER) {
- if ((pObject->m_nObjectType != TVisualObject::OT_SPLITTERVIEW) &&
- (pObject->m_nObjectType != TVisualObject::OT_SPLITTERSPLITTER))
- {
- ASSERT(FALSE);
- }
- } else if (pOwner->m_nObjectType == TVisualObject::OT_SPLITTERSPLITTER) {
- if ((pObject->m_nObjectType != TVisualObject::OT_SPLITTERVIEW) &&
- (pObject->m_nObjectType != TVisualObject::OT_SPLITTERSPLITTER))
- {
- ASSERT(FALSE);
- }
- } else if (pOwner->m_nObjectType == TVisualObject::OT_TABVIEW) {
- if ((pObject->m_nObjectType != TVisualObject::OT_SPLITTER))
- {
- ASSERT(FALSE);
- }
- }
- #endif
- if (findObject(pObject->m_dwId) == NULL) {
- pOwner->m_ObjectList.insert(pOwner->m_ObjectList.end(), pObject);
- pObject->m_pOwner = pOwner;
- pObject->m_pFramework = this;
- m_ObjectMap[pObject->m_dwId] = pObject;
- return TRUE;
- }
- ASSERT(FALSE); // Duplicate object Id
- return FALSE;
- }
- // Create all objects within the framework
- BOOL TVisualFramework::Create(CWnd *pWnd)
- {
- ASSERT(pWnd);
- ASSERT(pWnd->IsKindOf(RUNTIME_CLASS(CFrameWnd)));
- // Save owner for later
- m_pOwner = pWnd;
- // Disable Ctrl+Tab for MDI applications
- if (pWnd->IsKindOf(RUNTIME_CLASS(CMDIChildWnd)))
- m_bEnableCtrlTab = FALSE;
- // Walk thru visual object hierarchy and create windows
- BOOL rc;
- TVisualObject *pObject;
- TVisualObjectList::iterator it;
- for (it = m_ObjectList.begin(); it != m_ObjectList.end(); it++) {
- pObject = *it;
- rc = execCreate(pWnd, pObject);
- if (rc == FALSE) {
- TRACE0(_T("Create visual object failed!n"));
- return FALSE;
- }
- }
- // Walk thru the map and find first object that can be focused
- // Then set focus
- TVisualObjectMap::iterator mapit;
- for (mapit = m_ObjectMap.begin(); mapit != m_ObjectMap.end(); mapit ++) {
- pObject = mapit->second;
- if (pObject->CanFocus()) {
- SetActivePane(pObject);
- break;
- }
- }
- return TRUE;
- }
- // Destroy all objects in the framework
- void TVisualFramework::Destroy(void)
- {
- TVisualObject *pObject;
- // Recursive delete of all objects
- TVisualObjectList::iterator it;
- for (it = m_ObjectList.begin(); it != m_ObjectList.end(); it++) {
- pObject = *it;
- execDestroy(pObject);
- }
- // Delete pointers in object map
- TVisualObjectMap::iterator mapit;
- for (mapit = m_ObjectMap.begin(); mapit != m_ObjectMap.end(); mapit++) {
- pObject = mapit->second;
- delete pObject;
- }
- // Empty all containers (for check in destructor)
- m_ObjectMap.clear();
- m_ObjectList.clear();
- }
- // Recursive function to delete all object windows. Does not delete views since
- // they are destroyed by frame.
- void TVisualFramework::execDestroy(TVisualObject *pObject)
- {
- if (pObject->m_pWnd && ::IsWindow(pObject->m_pWnd->m_hWnd)) {
- if (pObject->m_pWnd->IsKindOf(RUNTIME_CLASS(TTabWnd))) {
- TVisualObject *pObj;
- TVisualObjectList::iterator it;
- for (it = pObject->m_ObjectList.begin(); it != pObject->m_ObjectList.end(); it++) {
- pObj = *it;
- execDestroy(pObj);
- }
- pObject->Destroy(TRUE);
- } else if (pObject->m_pWnd->IsKindOf(RUNTIME_CLASS(CSplitterWnd))) {
- TVisualObject *pObj;
- TVisualObjectList::iterator it;
- for (it = pObject->m_ObjectList.begin(); it != pObject->m_ObjectList.end(); it++) {
- pObj = *it;
- execDestroy(pObj);
- }
- pObject->Destroy(TRUE);
- }
- }
- }
- // Create specified object and all its childs
- BOOL TVisualFramework::execCreate(CWnd *pWnd, TVisualObject *pObject)
- {
- ASSERT(pWnd);
- ASSERT(pObject);
- BOOL rc = FALSE;
- switch (pObject->m_nObjectType) {
- case (TVisualObject::OT_SPLITTER):
- rc = execCreateSplitter(pWnd,pObject);
- break;
- case (TVisualObject::OT_SPLITTERVIEW):
- rc = execCreateSplitterView(pWnd, pObject);
- break;
- case (TVisualObject::OT_SPLITTERSPLITTER):
- rc = execCreateSplitterSplitter(pWnd, pObject);
- break;
- case (TVisualObject::OT_TAB):
- rc = execCreateTabWnd(pWnd, pObject);
- break;
- case (TVisualObject::OT_TABVIEW):
- rc = execCreateTabView(pWnd, pObject);
- break;
- case (TVisualObject::OT_VIEW):
- rc = execCreateView(pWnd, pObject);
- break;
- }
- return rc;
- }
- // Create a simple view
- BOOL TVisualFramework::execCreateView(CWnd *pWnd, TVisualObject *pObject)
- {
- ASSERT(pWnd);
- ASSERT(pWnd->IsKindOf(RUNTIME_CLASS(CFrameWnd)));
- ASSERT(pObject);
- ASSERT(pObject->m_pContext);
- ASSERT(pObject->m_pRuntimeClass);
- CFrameWnd *pFrame = (CFrameWnd*)pWnd;
- pObject->m_pContext->m_pNewViewClass = pObject->m_pRuntimeClass;
- pObject->m_pWnd = pFrame->CreateView(pObject->m_pContext);
- ASSERT(pObject->m_pWnd);
- ASSERT(::IsWindow(pObject->m_pWnd->m_hWnd));
- pObject->m_pParent = pFrame;
- setTabWndProperties(pObject);
- return TRUE;
- }
- // Create a view within a tab window
- BOOL TVisualFramework::execCreateTabView(CWnd *pWnd, TVisualObject *pObject)
- {
- ASSERT(pWnd);
- ASSERT(pWnd->IsKindOf(RUNTIME_CLASS(TTabWnd)));
- ASSERT(pObject);
- ASSERT(pObject->m_pContext);
- ASSERT(pObject->m_pRuntimeClass);
- ASSERT(!pObject->m_strTitle.IsEmpty());
- TTabWnd *pTab = (TTabWnd*)pWnd;
- TTabItem *pItem;
- pItem = pTab->CreatePane(pObject->m_strTitle, pObject->m_pRuntimeClass,
- pObject->m_pContext);
- ASSERT(pItem);
- pObject->m_pWnd = pItem->GetSafeWnd();
- ASSERT(pObject->m_pWnd);
- ASSERT(::IsWindow(pObject->m_pWnd->m_hWnd));
- pObject->m_pParent = pTab;
- setTabWndProperties(pObject);
- return TRUE;
- }
- // Create a splitter window
- BOOL TVisualFramework::execCreateSplitter(CWnd *pWnd, TVisualObject *pObject)
- {
- ASSERT(pWnd);
- ASSERT(pObject);
- // Cannot use pObject->m_pRuntimeClass->CreateObject() since splitters
- // do not support dynamic creation
- pObject->m_pWnd = CreateSplitter(pObject->m_dwId);
- ASSERT(pObject->m_pWnd);
- ASSERT(pObject->m_pWnd->IsKindOf(RUNTIME_CLASS(CSplitterWnd)));
- if (pWnd->IsKindOf(RUNTIME_CLASS(TTabWnd))) {
- TTabWnd *pTab = (TTabWnd*)pWnd;
- TTabItem *pItem = pTab->CreatePane(pObject->m_strTitle, pObject->m_nRows,
- pObject->m_nCols, pObject->m_pWnd);
- ASSERT(::IsWindow(pObject->m_pWnd->m_hWnd));
- pObject->m_pParent = pWnd;
- } else if (pWnd->IsKindOf(RUNTIME_CLASS(CFrameWnd))) {
- ((CSplitterWnd*)pObject->m_pWnd)->CreateStatic(pWnd,pObject->m_nRows,pObject->m_nCols);
- ASSERT(::IsWindow(pObject->m_pWnd->m_hWnd));
- pObject->m_pParent = pWnd;
- }
- setTabWndProperties(pObject);
- TVisualObjectList::iterator it;
- for (it = pObject->m_ObjectList.begin(); it != pObject->m_ObjectList.end(); it++) {
- execCreate(pObject->m_pWnd, *it);
- }
- return TRUE;
- }
- // Create a view within a splitter. Then create all childs of this view.
- BOOL TVisualFramework::execCreateSplitterView(CWnd *pWnd, TVisualObject *pObject)
- {
- ASSERT(pWnd);
- ASSERT(pWnd->IsKindOf(RUNTIME_CLASS(CSplitterWnd)));
- ASSERT(pObject);
- CSplitterWnd *pSplitter = (CSplitterWnd*)pWnd;
- pSplitter->CreateView(pObject->m_nRowIndex, pObject->m_nColIndex,
- pObject->m_pRuntimeClass, pObject->m_Size,
- pObject->m_pContext);
- pObject->m_pWnd = pSplitter->GetPane(pObject->m_nRowIndex, pObject->m_nColIndex);
- ASSERT(pObject->m_pWnd);
- ASSERT(::IsWindow(pObject->m_pWnd->m_hWnd));
- pObject->m_pParent = pSplitter;
- setTabWndProperties(pObject);
- TVisualObjectList::iterator it;
- for (it = pObject->m_ObjectList.begin(); it != pObject->m_ObjectList.end(); it++) {
- execCreate(pObject->m_pWnd, *it);
- }
- return TRUE;
- }
- // Create a nested splitter window
- BOOL TVisualFramework::execCreateSplitterSplitter(CWnd *pWnd, TVisualObject *pObject)
- {
- ASSERT(pWnd);
- ASSERT(pWnd->IsKindOf(RUNTIME_CLASS(CSplitterWnd)));
- CSplitterWnd *pParent = (CSplitterWnd*)pWnd;
- // Cannot use pObject->m_pRuntimeClass->CreateObject() since splitters
- // do not support dynamic creation
- pObject->m_pWnd = CreateSplitter(pObject->m_dwId);
- ASSERT(pObject->m_pWnd);
- ASSERT(pObject->m_pWnd->IsKindOf(RUNTIME_CLASS(CSplitterWnd)));
- CSplitterWnd *pSplitter = (CSplitterWnd*)pObject->m_pWnd;
- pSplitter->CreateStatic(pParent, pObject->m_nRows, pObject->m_nCols,
- WS_CHILD|WS_VISIBLE|WS_BORDER,
- pParent->IdFromRowCol(pObject->m_nRowIndex,pObject->m_nColIndex));
- ASSERT(::IsWindow(pSplitter->m_hWnd));
- pObject->m_pParent = pParent;
- TVisualObjectList::iterator it;
- for (it = pObject->m_ObjectList.begin(); it != pObject->m_ObjectList.end(); it++) {
- execCreate(pObject->m_pWnd, *it);
- }
- return TRUE;
- }
- // Create a tab window and all its childs (tabs)
- BOOL TVisualFramework::execCreateTabWnd(CWnd *pWnd, TVisualObject *pObject)
- {
- ASSERT(pWnd);
- ASSERT(pObject);
- if (pWnd->IsKindOf(RUNTIME_CLASS(TTabWnd))) {
- TTabWnd *pTab = (TTabWnd*)pWnd;
- TTabItem *pItem = pTab->CreatePane(pObject->m_strTitle, pObject->m_pRuntimeClass,
- pObject->m_pContext);
- ASSERT(pItem);
- pObject->m_pWnd = pItem->GetSafeWnd();
- ASSERT(pObject->m_pWnd);
- ASSERT(::IsWindow(pObject->m_pWnd->m_hWnd));
- pObject->m_pParent = pWnd;
- setTabWndProperties(pObject);
- } else {
- CRect rect;
- pObject->m_pWnd = (CWnd*)pObject->m_pRuntimeClass->CreateObject();
- ASSERT(pObject->m_pWnd);
- pObject->m_pParent = pWnd;
- pObject->m_pWnd->Create(NULL,_T(""),WS_VISIBLE|WS_CHILD,
- rect,pWnd,TABWND_DEFAULT_ID);
- ASSERT(::IsWindow(pObject->m_pWnd->m_hWnd));
- setTabWndProperties(pObject);
- }
- TVisualObject *pObj;
- TVisualObjectList::iterator it;
- for (it = pObject->m_ObjectList.begin(); it != pObject->m_ObjectList.end(); it++) {
- pObj = *it;
- execCreate(pObject->m_pWnd, pObj);
- }
- return TRUE;
- }
- // Set properties of tab window
- void TVisualFramework::setTabWndProperties(TVisualObject *pObject)
- {
- ASSERT(pObject);
- ASSERT(pObject->m_pWnd != NULL);
- // If this is a tab window then set the position of tabs
- if (pObject->m_pWnd->IsKindOf(RUNTIME_CLASS(TTabWnd))) {
- TTabWnd *pTab = (TTabWnd*)pObject->m_pWnd;
- if (pObject->m_dwStyle & TVisualObject::TOS_TABTOP)
- pTab->SetTabPos(TTabWnd::TP_TOP);
- else if (pObject->m_dwStyle & TVisualObject::TOS_TABBOTTOM)
- pTab->SetTabPos(TTabWnd::TP_BOTTOM);
- }
- // If this is a pane within a tab then check if this pane
- // should be a selected pane
- ASSERT(pObject->m_pParent);
- if (pObject->m_pParent->IsKindOf(RUNTIME_CLASS(TTabWnd))) {
- TTabWnd *pTab = (TTabWnd*)pObject->m_pParent;
- if (pObject->m_dwStyle & TVisualObject::TOS_SELECTED) {
- int nIndex = pTab->GetTabIndex(pObject->m_pWnd);
- pTab->SetActivePane(nIndex);
- }
- }
- }
- // Get owner pointer (CFrameWnd derived class)
- CWnd *TVisualFramework::GetWnd(void)
- {
- return m_pOwner;
- }
- // Get safe owner pointer (CFrameWnd derived class)
- CWnd *TVisualFramework::GetSafeWnd(void)
- {
- if (m_pOwner && ::IsWindow(m_pOwner->m_hWnd))
- return m_pOwner;
- return NULL;
- }
- // Get window associated with the visual object specified with its id
- // Can be any object (view, splitter or tab window)
- CWnd *TVisualFramework::GetObject(DWORD dwId)
- {
- TVisualObject *pObject = findObject(dwId);
- if (pObject == NULL)
- return NULL;
- return pObject->m_pWnd;
- }
- // Get ID associated with the visual object specified with its window pointer
- // Can be any object (view, splitter or tab window)
- DWORD TVisualFramework::GetObject(CWnd *pWnd)
- {
- ASSERT(pWnd);
- TVisualObject *pObject = findObject(pWnd);
- if (pObject == NULL)
- return NULL;
- return pObject->m_dwId;
- }
- // Return a visual object with the specified id
- TVisualObject *TVisualFramework::Get(DWORD dwId)
- {
- return findObject(dwId);
- }
- // Return a visual object with the specified window
- TVisualObject *TVisualFramework::Get(CWnd *pWnd)
- {
- return findObject(pWnd);
- }
- // Returns an object that represents the currently active tab within the
- // supplied tab window object. This may not be the active pane
- TVisualObject *TVisualFramework::GetActiveTab(TVisualObject *pObject)
- {
- ASSERT(pObject);
- ASSERT(pObject->m_pWnd);
- if (!pObject->m_pWnd->IsKindOf(RUNTIME_CLASS(TTabWnd)))
- return NULL;
- TTabWnd *pTab = (TTabWnd*)pObject->m_pWnd;
- int nIndex = pTab->GetTabIndex();
- CWnd *pWnd = pTab->GetTabWnd(nIndex);
- ASSERT(pWnd);
- return Get(pWnd);
- }
- // Set the active tab of the parent tab window. This will not activate the
- // pane associated with the active tab.
- BOOL TVisualFramework::SetActiveTab(TVisualObject *pObject)
- {
- ASSERT(pObject);
- ASSERT(pObject->m_pWnd);
- ASSERT(pObject->m_pParent);
- if (!pObject->m_pParent->IsKindOf(RUNTIME_CLASS(TTabWnd)))
- return FALSE;
- TTabWnd *pTab = (TTabWnd*)pObject->m_pParent;
- int nIndex = pTab->GetTabIndex(pObject->m_pWnd);
- return pTab->SetActivePane(nIndex,FALSE);
- }
- // Returns TRUE if object is a tab within a tab window
- BOOL TVisualFramework::IsTabPane(TVisualObject* pObject)
- {
- ASSERT(pObject);
- ASSERT(pObject->m_pWnd);
- ASSERT(pObject->m_pParent);
- if (pObject->m_pParent->IsKindOf(RUNTIME_CLASS(TTabWnd)))
- return TRUE;
- return FALSE;
- }
- // Returns TRUE if object is a tab window
- BOOL TVisualFramework::IsTabWindow(TVisualObject* pObject)
- {
- ASSERT(pObject);
- ASSERT(pObject->m_pWnd);
- if (pObject->m_pWnd->IsKindOf(RUNTIME_CLASS(TTabWnd)))
- return TRUE;
- return FALSE;
- }
- // Returns TRUE if object is a pane within a splitter window
- BOOL TVisualFramework::IsSplitterPane(TVisualObject* pObject)
- {
- ASSERT(pObject);
- ASSERT(pObject->m_pWnd);
- ASSERT(pObject->m_pParent);
- if (pObject->m_pParent->IsKindOf(RUNTIME_CLASS(CSplitterWnd)))
- return TRUE;
- return FALSE;
- }
- // Returns TRUE if object is a pane within a splitter window
- BOOL TVisualFramework::IsSplitterWindow(TVisualObject* pObject)
- {
- ASSERT(pObject);
- ASSERT(pObject->m_pWnd);
- if (pObject->m_pWnd->IsKindOf(RUNTIME_CLASS(CSplitterWnd)))
- return TRUE;
- return FALSE;
- }
- // Returns TRUE if object is derived from CView
- BOOL TVisualFramework::IsView(TVisualObject *pObject)
- {
- ASSERT(pObject);
- ASSERT(pObject->m_pWnd);
- if (pObject->m_pWnd->IsKindOf(RUNTIME_CLASS(CView)))
- return TRUE;
- return FALSE;
- }
- // Get the count of visual objects
- int TVisualFramework::GetCount(void)
- {
- return m_ObjectMap.size();
- }
- // Set font for complete framework
- void TVisualFramework::SetFont(CFont *pFont)
- {
- ASSERT(pFont);
- TVisualObject *pObject;
- TVisualObjectMap::iterator mapit;
- for (mapit = m_ObjectMap.begin(); mapit != m_ObjectMap.end(); mapit ++) {
- pObject = mapit->second;
- if (pObject->m_pWnd->IsKindOf(RUNTIME_CLASS(TTabWnd))) {
- ((TTabWnd*)pObject->m_pWnd)->SetFont(pFont);
- } else if (pObject->m_pWnd->IsKindOf(RUNTIME_CLASS(TVisualFormView))) {
- ((TVisualFormView*)pObject->m_pWnd)->SetFont(pFont);
- } else {
- pObject->m_pWnd->SetFont(pFont);
- }
- }
- }
- // Enable/disable CtrlTab for tab window
- void TVisualFramework::EnableCtrlTab(BOOL bEnable)
- {
- // If framework is used in an MDI application, then Ctrl+Tab is used to switch
- // among open windows. If it is enabled, Ctrl+Tab will then switch among
- // tab panes within the MDI child frame window (this disables default Ctrl+Tab
- // for MDI windows).
- // Ctrl+Tab works only if CWinApp derived class overloads PreTranslateMessage
- // and calles ProcessMessage() of the active TVisualFramework object
- m_bEnableCtrlTab = bEnable;
- }
- // Since CSplitterWnd does not support dynamic creation, this is a chance for
- // derived class to supply CSplitterWnd derived class instead of CSplitterWnd
- CSplitterWnd *TVisualFramework::CreateSplitter(DWORD dwId)
- {
- return new CSplitterWnd;
- }
- // Set focus to visual object
- BOOL TVisualFramework::SetActivePane(TVisualObject *pObject)
- {
- ASSERT(pObject);
- // Cannot set focus to splitter or tab window
- if (!pObject->CanFocus())
- return FALSE;
- // Cannot set focus to disabled window
- BOOL bEnabled;
- if (pObject->IsEnabled(bEnabled) && !bEnabled)
- return FALSE;
- // Build a list that walks thru the object hierarchy from specified
- // object to the root
- TVisualObjectList list;
- TVisualObject *pObj = pObject;
- while (pObj) {
- list.insert(list.end(),pObj);
- pObj = pObj->m_pOwner;
- }
- // Reverse the list so that we can walk from root to the desired object
- list.reverse();
- // Now, walk thru the list and set focus as desired
- TVisualObjectList::iterator it;
- for (it = list.begin(); it != list.end(); it ++) {
- pObj = *it;
- if (pObj->m_pOwner && pObj->m_pOwner->m_pWnd->IsKindOf(RUNTIME_CLASS(TTabWnd))) {
- TTabWnd *pTab = (TTabWnd*)pObj->m_pOwner->m_pWnd;
- int nIndex = pTab->GetTabIndex(pObj->m_pWnd);
- if (!pTab->SetActivePane(nIndex))
- return FALSE;
- }
- }
- // Update framework owner
- CFrameWnd *pFrame = (CFrameWnd*)m_pOwner;
- pFrame->SetActiveView((CView*)pObject->m_pWnd);
- return TRUE;
- }
- // Return a pointer to visual object that represents the currently active pane
- TVisualObject *TVisualFramework::GetActivePane(void)
- {
- CFrameWnd *pFrame = (CFrameWnd*)m_pOwner;
- ASSERT(pFrame);
- CView *pView = pFrame->GetActiveView();
- ASSERT(pView);
- return findObject(pView);
- }
- // Enable/disable a view. Returns TRUE if sucessful
- BOOL TVisualFramework::Enable(TVisualObject *pObject, BOOL bEnable)
- {
- ASSERT(pObject);
- ASSERT(pObject->m_pWnd);
- if (pObject->m_pWnd->IsKindOf(RUNTIME_CLASS(CView))) {
- pObject->m_bEnabled = bEnable;
- pObject->m_pWnd->EnableWindow(bEnable);
- if (pObject->m_pParent->IsKindOf(RUNTIME_CLASS(TTabWnd))) {
- TTabWnd *pTab = (TTabWnd*)pObject->m_pParent;
- int nIndex = pTab->GetTabIndex(pObject->m_pWnd);
- pTab->Enable(nIndex, bEnable);
- }
- return TRUE;
- }
- return FALSE;
- }
- // Enable/disable a tab
- BOOL TVisualFramework::EnableTab(TVisualObject *pObject, BOOL bEnable)
- {
- ASSERT(pObject);
- ASSERT(pObject->m_pWnd);
- ASSERT(pObject->m_pParent);
- // Check if parent is a tab window
- if (pObject->m_pParent->IsKindOf(RUNTIME_CLASS(TTabWnd))) {
- TTabWnd *pTab = (TTabWnd*)pObject->m_pParent;
- int nIndex = pTab->GetTabIndex(pObject->m_pWnd);
- if (nIndex == pTab->GetTabIndex())
- return FALSE;
- pTab->EnableTab(nIndex, bEnable);
- pObject->m_bEnabled = bEnable;
- return TRUE;
- }
- return FALSE;
- }
- // Show/hide a tab
- BOOL TVisualFramework::ShowTab(TVisualObject *pObject, BOOL bShow)
- {
- ASSERT(pObject);
- ASSERT(pObject->m_pWnd);
- ASSERT(pObject->m_pParent);
- if (!pObject->m_pParent->IsKindOf(RUNTIME_CLASS(TTabWnd)))
- return FALSE;
- TTabWnd *pTab = (TTabWnd*)pObject->m_pParent;
- int nIndex = pTab->GetTabIndex(pObject->m_pWnd);
- if (nIndex == pTab->GetTabIndex())
- return FALSE;
- pTab->ShowTab(nIndex, bShow);
- return TRUE;
- }
- // Is object enabled. Returns FALSE if this is not a valid call for the supplied
- // object. If return code is TRUE, check bEnabled
- BOOL TVisualFramework::IsEnabled(TVisualObject *pObject, BOOL& bEnabled)
- {
- ASSERT(pObject);
- ASSERT(pObject->m_pWnd);
- bEnabled = pObject->m_bEnabled;
- return TRUE;
- /*
- if (pObject->m_pWnd->IsKindOf(RUNTIME_CLASS(CView))) {
- bEnabled = pObject->m_pWnd->IsWindowEnabled();
- return TRUE;
- }
- return FALSE;
- */
- }
- // Is tab enabled. Returns FALSE if this is not a valid call for the supplied
- // object. If return code is TRUE, check bEnabled
- BOOL TVisualFramework::IsTabEnabled(TVisualObject *pObject, BOOL& bEnabled)
- {
- ASSERT(pObject);
- ASSERT(pObject->m_pWnd);
- ASSERT(pObject->m_pParent);
- if (pObject->m_pParent->IsKindOf(RUNTIME_CLASS(TTabWnd))) {
- TTabWnd *pTab = (TTabWnd*)pObject->m_pParent;
- int nIndex = pTab->GetTabIndex(pObject->m_pWnd);
- bEnabled = pTab->IsTabEnabled(nIndex);
- return TRUE;
- }
- return FALSE;
- }
- // Is tab visible. Returns FALSE if this is not a valid call for the supplied
- // object. If return code is TRUE then check bVisible.
- BOOL TVisualFramework::IsTabVisible(TVisualObject *pObject, BOOL& bVisible)
- {
- ASSERT(pObject);
- ASSERT(pObject->m_pWnd);
- ASSERT(pObject->m_pParent);
- if (pObject->m_pParent->IsKindOf(RUNTIME_CLASS(TTabWnd))) {
- TTabWnd *pTab = (TTabWnd*)pObject->m_pParent;
- int nIndex = pTab->GetTabIndex(pObject->m_pWnd);
- bVisible = pTab->IsTabVisible(nIndex);
- return TRUE;
- }
- return FALSE;
- }
- // This should be called from CWinApp derived PreTranslateMessage to handle
- // any framework related messages
- BOOL TVisualFramework::ProcessMessage(MSG *pMsg)
- {
- ASSERT(pMsg);
- if (pMsg->message == WM_KEYDOWN) {
- // Handle Ctrl+Tab for tab windows
- if (m_bEnableCtrlTab) {
- if ((pMsg->wParam == VK_TAB) && (::GetAsyncKeyState(VK_CONTROL) != 0)) {
- CWnd *pWnd = CWnd::FromHandle(pMsg->hwnd);
- ASSERT(pWnd);
- if (pWnd->IsKindOf(RUNTIME_CLASS(CFrameWnd)))
- return FALSE;
- // If we are in form view then pWnd is a control
- while (pWnd && !pWnd->IsKindOf(RUNTIME_CLASS(CView)))
- pWnd = pWnd->GetParent();
- // Find object for this window
- //if (!pWnd) return FALSE;//jojo
- ASSERT(pWnd);
- TVisualObject *pObject = findObject(pWnd);
- //if (pObject==NULL) return FALSE;//jojo
- ASSERT(pObject != NULL);
- while (pObject && !pObject->m_pWnd->IsKindOf(RUNTIME_CLASS(TTabWnd)))
- pObject = pObject->m_pOwner;
- if (pObject) {
- TTabWnd *pTab = (TTabWnd*)pObject->m_pWnd;
- BOOL bShift = (::GetAsyncKeyState(VK_SHIFT) != 0);
- int nIndex = pTab->GetTabIndex();
- int nNdx = nIndex;
- // Switch to new pane (skip invisible and disabled)
- do {
- if (bShift) {
- // Does not work
- nNdx--;
- if (nNdx < 0)
- nNdx = pTab->GetTabCount()-1;
- } else {
- nNdx ++;
- if (nNdx == pTab->GetTabCount())
- nNdx = 0;
- }
- } while (!pTab->SetActivePane(nNdx) && (nNdx != nIndex));
- return TRUE;
- }
- }
- }
- } else if (pMsg->message == WM_SYSKEYDOWN) {
- // Handle hot keys for views (if defined)
- TVisualObject *pObject;
- TVisualObjectMap::iterator mapit;
- for (mapit = m_ObjectMap.begin(); mapit != m_ObjectMap.end(); mapit ++) {
- pObject = mapit->second;
- if (pObject->m_cHotKey == pMsg->wParam) {
- if (SetActivePane(pObject))
- return TRUE;
- }
- }
- }
- return FALSE;
- }
- BOOL TVisualFramework::OnCmdMsg(UINT nID, int nCode, void* pExtra,
- AFX_CMDHANDLERINFO* pHandlerInfo)
- {
- // TODO: Add your specialized code here and/or call the base class
- return CCmdTarget::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
- }
- //=============================================================================
- // class TVisualFormView
- //
- // This class implements the code to set the font for all child controls.
- // If it belongs to the visual framework (as a pane) then setting the font
- // for the framework's panes will automatically set the font for all child
- // controls in the form view.
- //=============================================================================
- static BOOL __stdcall setChildFont(HWND hwnd, LPARAM lparam);
- static BOOL __stdcall setChildEnabled(HWND hwnd, LPARAM lparam);
- IMPLEMENT_DYNAMIC(TVisualFormView, CFormView)
- BEGIN_MESSAGE_MAP(TVisualFormView, CFormView)
- //{{AFX_MSG_MAP(TVisualFormView)
- ON_WM_ENABLE()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- TVisualFormView::TVisualFormView(LPCTSTR lpszTemplateName)
- : CFormView(lpszTemplateName)
- {
- }
- TVisualFormView::TVisualFormView(UINT nIDTemplate)
- : CFormView(nIDTemplate)
- {
- }
- void TVisualFormView::SetFont(CFont *pFont)
- {
- ASSERT(pFont);
- ::EnumChildWindows(m_hWnd, ::setChildFont, (LPARAM)pFont);
- }
- void TVisualFormView::OnEnable(BOOL bEnable)
- {
- CFormView::OnEnable(bEnable);
- ::EnumChildWindows(m_hWnd, ::setChildEnabled, (LPARAM)bEnable);
- }
- // lParam is a pointer to CFont object
- BOOL __stdcall setChildFont(HWND hwnd, LPARAM lparam)
- {
- CFont *pFont = (CFont*)lparam;
- ASSERT(pFont);
- CWnd *pWnd = CWnd::FromHandle(hwnd);
- ASSERT(pWnd);
- pWnd->SetFont(pFont);
- return TRUE;
- }
- // lParam is a BOOL
- BOOL __stdcall setChildEnabled(HWND hwnd, LPARAM lparam)
- {
- BOOL bEnabled = (BOOL)lparam;
- CWnd *pWnd = CWnd::FromHandle(hwnd);
- ASSERT(pWnd);
- pWnd->EnableWindow(bEnabled);
- return TRUE;
- }
- /*#############################################################################
- # End of file VISUALFX.CPP
- #############################################################################*/