//----------------------------------------------------------------------------
// ObjectWindows
// Copyright (c) 1995, 1996 by Borland International, All Rights Reserved
//
/// \file
/// Implementation of classes TTabItem and TTabControl.
//----------------------------------------------------------------------------
#include <owl/pch.h>
#include <owl/tabctrl.h>
#include <owl/uihelper.h>
#include <owl/dc.h>
#include <owl/gdiobjec.h>
#if defined(__BORLANDC__)
# pragma option -w-ccc // Disable "Condition is always true/false"
#endif
namespace owl {
OWL_DIAGINFO;
DIAG_DECLARE_GROUP(OwlCommCtrl); // Common Controls diagnostic group
// Let the compiler know that the following template instances will be defined elsewhere.
//#pragma option -Jgx
//
// Constants used in OWL's implementation of Tab Controls
//
const int InitSize = 5; // Initial size of Tab Collection
const int InitDelta = 5; // Inc. when expanding collection
const int HorzPad = 6; // Pad on each side of tab label
const int VertPad = 4; // Pad above/below each tab label
const int HorzSelInc = 1; // Inc. for selected tab
const int VertSelInc = 1; // Inc. for selected tab
const int HorzMargin = 3; // Margin on left/right of control
const int VertMargin = 3; // Margin above control
const int ClientMargin = 2; // Inner margin of tab's client area
const int ID_Updown = 0x100; // Ctl. identifier of scroller;
//
/// The item is initialized with the state of an actual tab in
/// a created tab control.
//
TTabItem::TTabItem(const TTabControl& ctl, int index, uint msk,
int buffLen, LPTSTR buffer)
{
PRECONDITION(ctl.GetHandle());
// When retrieving text, a buffer and length must be supplied
//
PRECONDITION(!(msk & TCIF_TEXT) || (buffLen && buffer));
mask = msk;
if (buffer && buffLen)
SetLabel(buffer, buffLen);
ctl.GetItem(index, *this);
}
//
/// The tab item's label field is initialized to the specified buffer and extra
/// parameter set to the 'param' parameter.
//
TTabItem::TTabItem(LPCTSTR str, int buffLen, TParam2 param)
{
mask = 0;
iImage = -1;
SetParam(param);
SetLabel(str, buffLen);
}
//
/// The tab item is initialized with the IMAGELIST index and the extra parameter
/// specified.
//
TTabItem::TTabItem(int imageIndex, TParam2 param)
{
mask = 0;
pszText = 0;
cchTextMax = 0;
SetParam(param);
SetIcon(imageIndex);
}
//
/// The tab item is initialized with the IMAGELIST index and label specified.
//
TTabItem::TTabItem(int imageIndex, LPCTSTR str)
{
mask = 0;
SetIcon(imageIndex);
SetLabel(str);
}
//
// Initializes the structure member representing the tab's text
//
void
TTabItem::SetLabel(LPCTSTR str, int len)
{
pszText = CONST_CAST(LPTSTR, str);
cchTextMax = len ? len : static_cast<int>(::_tcslen(str));
mask |= TCIF_TEXT;
}
// Version 4.70
void
TTabItem::SetState(uint32 state, uint32 mask)
{
dwState = state;
dwStateMask = mask;
}
//----------------------------------------------------------------------------
DEFINE_RESPONSE_TABLE1(TTabControl, TControl)
EV_WM_HSCROLL,
EV_WM_VSCROLL,
END_RESPONSE_TABLE;
//
/// Constructor for TTabControl. Initializes its data fields using parameters passed
/// and default values by default. A TabControl associated with the TTabControl
/// will:
/// - be visible upon creation
/// - display only one row of tabs.
//
TTabControl::TTabControl(TWindow* parent,
int id,
int x, int y, int w, int h,
TModule* module)
:
TControl(parent, id, 0, x, y, w, h, module)
{
InitializeCommonControls(ICC_TAB_CLASSES);
Attr.Style |= (TCS_SINGLELINE|TCS_TABS|WS_CLIPCHILDREN|WS_CLIPSIBLINGS);
}
//
/// Constructor for a TTabControl object associated with a Tab Control specified in
/// a dialog resource.
//
TTabControl::TTabControl(TWindow* parent,
int resourceId,
TModule* module)
:
TControl(parent, resourceId, module)
{
InitializeCommonControls(ICC_TAB_CLASSES);
}
//
/// Constructor for a TTabControl object to be associated with
/// an already created Tab Control.
//
TTabControl::TTabControl(HWND hwnd) : TControl(hwnd)
{
PRECONDITION(hwnd && ::IsWindow(hwnd));
InitializeCommonControls(ICC_TAB_CLASSES);
}
//
/// Cleans up if underlying Tab support was provided by ObjectWindows.
//
TTabControl::~TTabControl()
{
}
//
/// Returns the class name of the underlying control associated with the TTabControl
/// object.
auto TTabControl::GetWindowClassName() -> TWindowClassName
{
return TWindowClassName{WC_TABCONTROL};
}
//
/// Transfer is not implemented in TTabControl, given that each item interacts with
/// settings outside of the TC_ITEM members. (For example, the image index points to
/// the ImageList).
//
uint
TTabControl::Transfer(void* /*buffer*/, TTransferDirection /*direction*/)
{
TRACEX(OwlCommCtrl, 0, "TTabControl::Transfer is not implemented");
return 0;
}
//
/// Keep TWindow from rerouting this message - it must be left as is
/// for the tab control as it may originate from the control's spin.
//
void
TTabControl::EvVScroll(uint, uint, THandle)
{
DefaultProcessing();
}
//
/// Keeps TWindow from rerouting this message.It must be left as is for the tab
/// control, as it may originate from the control's spin.
//
void
TTabControl::EvHScroll(uint, uint, THandle)
{
DefaultProcessing();
}
//
/// Inserts a new tab with the caption 'tabText' at the
/// specified 'index'. Returns the index of the new tab, if successful.
//
int
TTabControl::Insert(LPCTSTR tabText, int index)
{
return Insert(TTabItem(tabText), index);
}
//
// If the 'clientInWindowOut' parameter is false, this method calculates the
// display area of a tab control's display from a window rectangle specified by the
// 'rect' parameter. Otherwise, the method calculates the window rectangle that
// would correspond to the display area specified by the 'rect' parameter. The
// 'rect' parameter receives the newly computed rectangle.
//
void
TTabControl::AdjustRect(bool clientInWindowOut, TRect& rect)
{
SendMessage(TCM_ADJUSTRECT, TParam1(clientInWindowOut), TParam2(&rect));
}
//
/// Inserts a new tab described by the 'item' parameter to the tab control at the
/// position specified by the 'index' parameter. The return value is the index of
/// the new tab or -1 in case of error.
//
int
TTabControl::Add(const TTabItem& item)
{
return Insert(item, GetCount());
}
//
// Adds a new tab with the 'tabText' caption to the tab control Returns the index
// of the new tab, if successful or -1 otherwise.
//
int
TTabControl::Add(LPCTSTR tabText)
{
return Insert(tabText, GetCount());
}
//
// Inserts a new tab described by the 'item' parameter to the tab
// control at the position specified by the 'index' parameter.
// The return value is the index of the new tab or -1 in case of error.
//
int
TTabControl::Insert(const TTabItem& item, int index)
{
return (int)SendMessage(TCM_INSERTITEM, index, TParam2((const TC_ITEM *)(&item)));
}
//
// Removes the item at the position specified by the 'index' parameter.
// Returns 'true' if successful or 'false' otherwise.
//
bool
TTabControl::Delete(int index)
{
return SendMessage(TCM_DELETEITEM, index) != 0;
}
//
// Removes all items from the tab control. Returns 'true' if successful or
// 'false' otherwise.
//
bool
TTabControl::DeleteAll()
{
return SendMessage(TCM_DELETEALLITEMS) != 0;
}
//
// Returns the number of tab items in the tab control.
//
int
TTabControl::GetCount() const
{
return (int)CONST_CAST(TTabControl*, this)->SendMessage(TCM_GETITEMCOUNT);
}
//
// Retrieves the current number of rows in the tab control.
// NOTE: Only tabs with the TCS_MULTILINE style can have multiple rows.
//
int
TTabControl::GetRowCount() const
{
return (int)CONST_CAST(TTabControl*, this)->SendMessage(TCM_GETROWCOUNT);
}
//
// Returns the index of the currently selected tab item in the tab control.
// Returns -1 if no tab is selected.
//
int
TTabControl::GetSel() const
{
return (int)CONST_CAST(TTabControl*, this)->SendMessage(TCM_GETCURSEL);
}
//
// Selects the tab item at the position specified by the 'index' parameter.
// The return value is the index of the previously selected tab item if
// successful or -1 otherwise.
// NOTE: A tab control does not send TCN_SELCHANGING or TCN_SELCHANGE
// notifications when a tab item is selected via this method.
//
int
TTabControl::SetSel(int index)
{
return (int)SendMessage(TCM_SETCURSEL, index);
}
//
// Retrieves information about the tab at the position specified by
// the 'index' parameter. Returns true if successful or false otherwise.
// NOTE: The 'mask' member of the 'item' structure specifies which
// attributes of the tab to return. When spefying TCIF_TEXT, item's
// pszText member must point to a valid buffer and cchTextMax must
// specify the size of the buffer.
//
bool
TTabControl::GetItem(int index, TTabItem& item) const
{
return CONST_CAST(TTabControl*, this)->SendMessage(TCM_GETITEM, index, TParam2((TC_ITEM *)&item)) != 0;
}
//
// Retrieves the bounding rectangle of a tab within a tab control.
// Returns true if successful or false otherwise.
// NOTE: 'rect' receives the position in viewport coordinates.
//
bool
TTabControl::GetItemRect(int index, TRect& rect) const
{
return CONST_CAST(TTabControl*, this)->SendMessage(TCM_GETITEMRECT, index, TParam2((LPRECT)&rect)) != 0;
}
//
// Sets some or all of a tab's attributes. The 'mask' member of the
// 'item' parameter specifies which attributes to set.
// Returns true if successful or false otherwise.
//
bool
TTabControl::SetItem(int index, const TTabItem& item)
{
return SendMessage(TCM_SETITEM, index, TParam2((const TC_ITEM *)&item)) != 0;
}
//
// Sets the number of bytes per tab reserved for application-defined
// data in a tab control. Returns true if successful or false otherwise.
// NOTE: This method should be invoked only when the tab control does not
// contain any tabs.
//
bool
TTabControl::SetItemExtra(int extra)
{
return SendMessage(TCM_SETITEMEXTRA, extra) != 0;
}
//
// Sets the size (width/height) of tabs in a fixed-width or owner-draw
// tab control. Returns a TSize object containing the old width and height.
//
TSize
TTabControl::SetItemSize(const TSize& size)
{
const auto r = SendMessage(TCM_SETITEMSIZE, 0, MkParam2(size.cx, size.cy));
return TSize::CreateFromPackedExtents(r);
}
//
// Sets the amount of space around each tab's icon and label in a tab
// control.
//
void
TTabControl::SetPadding(const TSize& size)
{
SendMessage(TCM_SETPADDING, 0, MkParam2(size.cx, size.cy));
}
//
// Retrieves the ImageList associated with a tab control. Returns 0 if
// unsuccessful.
//
HIMAGELIST
TTabControl::GetImageList() const
{
return (HIMAGELIST)CONST_CAST(TTabControl*, this)->SendMessage(TCM_GETIMAGELIST);
}
//
// Assigns an imagelist to the tab control. Returns the handle of the
// previous imagelist or 0 if there is no previous image list.
//
HIMAGELIST
TTabControl::SetImageList(HIMAGELIST himl)
{
return (HIMAGELIST)SendMessage(TCM_SETIMAGELIST, 0, TParam2(himl));
}
//
// Removes the image at the position specified by 'index' from the
// imagelist associated with the tab control.
// NOTE: The tab automatically updates each tab's image index so each
// tab remains associated with the same image it had been.
//
void
TTabControl::RemoveImage(int index)
{
SendMessage(TCM_REMOVEIMAGE, index);
}
//
// Retrieves the handle of the tooltip control associated with the
// tab control. Returns 0 if unsuccessful.
//
TWindow::THandle
TTabControl::GetToolTips() const
{
return THandle(CONST_CAST(TTabControl*,this)->SendMessage(TCM_GETTOOLTIPS));
}
//
// Assigns a tooltip control to the tab control.
//
void
TTabControl::SetToolTips(THandle toolTip)
{
SendMessage(TCM_SETTOOLTIPS, TParam1(toolTip));
}
//
// Determines the index of the tab which is at the location
// specified in the 'pt' member of the 'htInfo' parameter.
// Returns -1 if no tab is at the specified position.
//
int
TTabControl::HitTest(TTabHitTestInfo& htInfo)
{
return (int)SendMessage(TCM_HITTEST, 0, TParam2((TC_HITTESTINFO *)&htInfo));
}
//----------------------------------------------------------------------------
} // OWL namespace
/* ========================================================================== */
↑ V688 The 'mask' function argument possesses the same name as one of the class members, which can result in a confusion.