//-------------------------------------------------------------------
// OWL Extensions (OWLEXT) Class Library
// Copyright(c) 1996 by Manic Software.
// All rights reserved.
//
// TTabWindow (& friends) implementation
//
// TODO: * Change tabbedWindowArray to be a collection of TTabWindowDatum,
// in order to support adding tabs w/ controls for client areas,
// since controls don't have a "title" per se
//-------------------------------------------------------------------
#include <owlext\pch.h>
#pragma hdrstop
#include <owlext/tabwin.h>
using namespace owl;
namespace OwlExt {
// Diagnostic group declarations/definitions
//
DIAG_DEFINE_GROUP_INIT(OWL_INI, OwlexTabWindow, 1, 0);
DIAG_DECLARE_GROUP(OwlMsg);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// TTabWindow
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*TResponseTableEntry< TTabWindow > TTabWindow::__entries[] =
{
{0, 0, 0, 0}
};
*/
DEFINE_RESPONSE_TABLE1(TTabWindow, TWindow)
END_RESPONSE_TABLE;
struct TTabWindowDatum
{
TWindow* m_ptr;
LPCTSTR m_title;
};
TTabWindow::TTabWindow(TWindow* parent, TWindow* array[])
:
TWindow(parent, (LPCTSTR)0)
{
Attr.X = Attr.Y = Attr.W = Attr.H = 0;
TRACEX(OwlexTabWindow, 1, _T("TTabWindow constructed @ ") << (void*)this);
// add array to tabbedWindowArray
if (array)
Attach(array);
}
TTabWindow::TTabWindow(TWindow* parent, uint32 X, uint32 Y, uint32 W, uint32 H, TWindow* array[])
:
TWindow(parent, (LPCTSTR)0)
{
Attr.X = X;
Attr.Y = Y;
Attr.W = W;
Attr.H = H;
TRACEX(OwlexTabWindow, 1, _T("TTabWindow constructed @ ") << (void*)this);
// add array to tabbedWindowArray
if (array)
Attach(array);
}
//DEFINE_RESPONSE_TABLE1(TTabWindow, TWindow)
//END_RESPONSE_TABLE;
/*bool TTabWindow::Find(TEventInfo& eventInfo, TEqualOperator equal)
{
eventInfo.Object = (TGeneric*)this;
return SearchEntries((TGenericTableEntry *)__entries, eventInfo, equal)
|| TWindow::Find(eventInfo, equal);
}*/
void TTabWindow::Attach(TWindow* ptr, LPCTSTR /*title*/)
{
// Add to collection of TWindow*'s
tabbedWindowArray.Add(const_cast<TWindow*>(ptr));
if (GetHandle()){
// Reparent the given widget
ptr->SetParent(this);
if (!ptr->GetHandle())
ptr->Create();
}
}
void TTabWindow::Attach(TWindow* windowArray[])
{
for (int i=0; windowArray[i]; i++)
Attach(windowArray[i]);
}
TWindow* TTabWindow::Detach(int32 index)
{
TWindow* retval = tabbedWindowArray[index];
// Remove window element from list
tabbedWindowArray.Detach(index);
return retval;
}
int32 TTabWindow::Retrieve(TWindow* ptr)
{
int index=0;
for (TPtrArray<TWindow*>::Iterator iter(tabbedWindowArray); iter; iter++, index++)
if (iter.Current() == ptr)
return index;
// throw an exception instead?
return -1;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// TWin95TabWindow
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DEFINE_RESPONSE_TABLE1(TWin95TabWindow, TTabWindow)
EV_WM_SIZE,
EV_TCN_SELCHANGE(TTabWindow::ID_TABCTRL, TabSelChange),
EV_TCN_SELCHANGING(TTabWindow::ID_TABCTRL, TabSelChanging),
EV_TCN_KEYDOWN(TTabWindow::ID_TABCTRL, TabKeyDown),
END_RESPONSE_TABLE;
TWin95TabWindow::TWin95TabWindow(TWindow* parent, TWindow* array[])
:
TTabWindow(parent, array),
m_tabCtrl(0)
{
}
TWin95TabWindow::TWin95TabWindow(TWindow* parent, uint32 X, uint32 Y, uint32 W, uint32 H, TWindow* array[])
:
TTabWindow(parent, X, Y, W, H, array),
m_tabCtrl(0)
{
}
TWin95TabWindow::~TWin95TabWindow()
{
delete m_tabCtrl;
}
int32 TWin95TabWindow::GetWindowCount()
{
if ((unsigned)m_tabCtrl->GetCount() != tabbedWindowArray.GetItemsInContainer()){
TRACE("This is a problem--tabCtrl->GetCount() != tabbedWindowArray");
}
return TTabWindow::GetWindowCount();
}
void TWin95TabWindow::SetupWindow()
{
// If our W/H values are still 0, pull them from our parent
if (Attr.W==0 || Attr.W==CW_USEDEFAULT)
Attr.W = Parent->GetClientRect().Width();
if (Attr.H==0 || Attr.H==CW_USEDEFAULT)
Attr.H = Parent->GetClientRect().Height();
// Create tab control, if not done already
if (GetTabCtrl()==0)
m_tabCtrl = new TTabControl(this, TTabWindow::ID_TABCTRL, 0, 0, Attr.W, Attr.H);
TTabWindow::SetupWindow();
// Add the tabs & pages already in tabbedWindowArray
TWindow* ptr;
uint i;
for (i=0; i<tabbedWindowArray.GetItemsInContainer(); i++) {
ptr = tabbedWindowArray[i];
// Reparent and create
ptr->SetParent(this);
if (!ptr->GetHandle())
ptr->Create();
// Retrieve window's text, use that for tab text
TAPointer<_TCHAR> txt(new _TCHAR[ptr->GetWindowTextLength()+1]);
ptr->GetWindowText(txt, ptr->GetWindowTextLength()+1);
m_tabCtrl->Add(TTabItem(txt));
// Select new tab as current
m_tabCtrl->SetSel(m_tabCtrl->GetCount()-1);
// Center and display associated TWindow*
AdjustTabClient();
}
// Hide all windows but the first
for (i=1; i<tabbedWindowArray.GetItemsInContainer(); i++)
tabbedWindowArray[i]->ShowWindow(SW_HIDE);
// Set to the first tab
SetSelectedTab(0);
m_tabCtrl->ShowWindow(SW_SHOW);
}
void TWin95TabWindow::Attach(TWindow* ptr, LPCTSTR /*title*/)
{
TTabWindow::Attach(ptr);
if (m_tabCtrl)
{
// Retrieve window's text, use that for tab text
TAPointer<_TCHAR> txt(new _TCHAR[ptr->GetWindowTextLength()+1]);
ptr->GetWindowText(txt, ptr->GetWindowTextLength()+1);
m_tabCtrl->Add(TTabItem(txt));
// Select new tab as current
SetSelectedTab(m_tabCtrl->GetCount()-1);
ptr->ShowWindow(SW_SHOW);
}
}
TWindow* TWin95TabWindow::Detach(int32 index)
{
// Remove tab from tab control
m_tabCtrl->Delete(index);
return TTabWindow::Detach(index);
}
void TWin95TabWindow::SetSelectedTab(int32 index)
{
m_tabCtrl->SetSel(index);
// TTabControl does not send the TCN_ messages, so we need to "fake" it
TNotify dummy;
TabSelChanging(dummy);
TabSelChange(dummy);
}
void TWin95TabWindow::AdjustTabClient()
{
// Retrieve pointer to tab control, the client window
if (m_tabCtrl && m_tabCtrl->GetHandle())
{
// Retrieve the window rectangle of the tab control
TRect rect;
m_tabCtrl->GetWindowRect(rect);
// NOTE: GetWindowRect returns screen coordinates... we'll need
// to have the coordinates relative to the frame window,
// the parent of both the tab and client window
::MapWindowPoints(HWND_DESKTOP, *this, (LPPOINT)&rect, 2);
// Ask the tab for it's 'client-area' based in it window location
m_tabCtrl->AdjustRect(false, rect);
// Move the Client window
TWindow* Client = tabbedWindowArray[m_tabCtrl->GetSel()];
if (Client && Client->GetHandle())
Client->SetWindowPos(HWND_TOP, rect, SWP_SHOWWINDOW);
}
}
void TWin95TabWindow::EvSize(uint sizeType, const TSize& size)
{
TWindow::EvSize(sizeType, size);
if (m_tabCtrl && m_tabCtrl->GetHandle())
{
// Adjust tab control to new window size
m_tabCtrl->SetWindowPos(0, 0, 0, size.cx, size.cy, SWP_NOZORDER | SWP_NOMOVE);
}
AdjustTabClient();
}
void TWin95TabWindow::TabSelChange(TNotify &)
{
AdjustTabClient();
// Here, GetSel() returns the after-the-click-current tab selected
tabbedWindowArray[m_tabCtrl->GetSel()]->ShowWindow(SW_SHOW);
tabbedWindowArray[m_tabCtrl->GetSel()]->SetWindowPos(HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
}
bool TWin95TabWindow::TabSelChanging(TNotify &)
{
// Here, GetSel() returns the before-the-click-current tab selected
if (tabbedWindowArray[m_tabCtrl->GetSel()])
tabbedWindowArray[m_tabCtrl->GetSel()]->ShowWindow(SW_HIDE);
return false;
}
void TWin95TabWindow::TabKeyDown(TTabKeyDown &)
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// TNoteTabWindow
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*
DEFINE_RESPONSE_TABLE1(TNoteTabWindow, TWindow)
EV_WM_SIZE,
EV_TCN_SELCHANGE(TTabWindow::ID_TABCTRL, TabSelChange),
EV_TCN_SELCHANGING(TTabWindow::ID_TABCTRL, TabSelChanging),
EV_TCN_KEYDOWN(TTabWindow::ID_TABCTRL, TabKeyDown),
END_RESPONSE_TABLE;
*/
} // OwlExt namespace
↑ V803 Decreased performance. In case 'iter' is iterator it's more effective to use prefix form of increment. Replace iterator++ with ++iterator.