?? visualfx.cpp
字號:
}
#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 destructor\n"));
TRACE0(_T(">>> It must be called in CFrameWnd derived class OnDestroy() message handler\n"));
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);
pItem->SetIcon(pObject->GetIcon());
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);
pItem->SetIcon(pObject->GetIcon());
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);
pItem->SetIcon(pObject->GetIcon());
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);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -