// TabBarCtrl.cpp : implementation file
//
#include "stdafx.h"
#include <afxpriv.h>
#include "TabBarCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define NC_FUDGE 3
#define CLIENT_FUDGE 10
#define FIRST_TAB_VIEW_ID AFX_IDW_PANE_FIRST + 1
#define TCIF_ALL_BAR (TCIF_TEXT | TCIF_IMAGE | TCIF_RTLREADING | TCIF_PARAM | TCIF_STATE)
//private to implementation
typedef struct _BARTCITEMA
{
_BARTCITEMA()
: lParam(NULL)
, uiID(0)
, pWnd(NULL)
{
ZeroMemory(&hdr, sizeof(TCITEMHEADERA));
}
_BARTCITEMA(TCITEMA& tcItem)
{
hdr.cchTextMax = tcItem.cchTextMax;
hdr.iImage = tcItem.iImage;
hdr.lpReserved1 = tcItem.dwState;
hdr.lpReserved2 = tcItem.dwStateMask;
hdr.mask = tcItem.mask;
hdr.pszText = tcItem.pszText;
lParam = tcItem.lParam;
}
_BARTCITEMA(_BARTCITEMA& tcBarItem)
{
*this = tcBarItem;
}
_BARTCITEMA& operator =(const _BARTCITEMA& tcBarItem)
{
hdr.cchTextMax = tcBarItem.hdr.cchTextMax;
hdr.iImage = tcBarItem.hdr.iImage;
hdr.lpReserved1 = tcBarItem.hdr.lpReserved1;
hdr.lpReserved2 = tcBarItem.hdr.lpReserved2;
hdr.mask = tcBarItem.hdr.mask;
hdr.pszText = tcBarItem.hdr.pszText;
lParam = tcBarItem.lParam;
uiID = tcBarItem.uiID;
pWnd = tcBarItem.pWnd;
return *this;
}
TCITEMHEADERA hdr;
LPARAM lParam;
int uiID;
CWnd* pWnd;
} BARTCITEMA, FAR *LPBARTCITEMA;
typedef struct _BARTCITEMW
{
_BARTCITEMW()
: lParam(NULL)
, uiID(0)
, pWnd(NULL)
{
ZeroMemory(&hdr, sizeof(TCITEMHEADERW));
}
_BARTCITEMW(TCITEMW& tcItem)
{
hdr.cchTextMax = tcItem.cchTextMax;
hdr.iImage = tcItem.iImage;
hdr.lpReserved1 = tcItem.dwState;
hdr.lpReserved2 = tcItem.dwStateMask;
hdr.mask = tcItem.mask;
hdr.pszText = tcItem.pszText;
lParam = tcItem.lParam;
}
_BARTCITEMW(_BARTCITEMW& tcBarItem)
{
*this = tcBarItem;
}
_BARTCITEMW& operator =(const _BARTCITEMW& tcBarItem)
{
hdr.cchTextMax = tcBarItem.hdr.cchTextMax;
hdr.iImage = tcBarItem.hdr.iImage;
hdr.lpReserved1 = tcBarItem.hdr.lpReserved1;
hdr.lpReserved2 = tcBarItem.hdr.lpReserved2;
hdr.mask = tcBarItem.hdr.mask;
hdr.pszText = tcBarItem.hdr.pszText;
lParam = tcBarItem.lParam;
uiID = tcBarItem.uiID;
pWnd = tcBarItem.pWnd;
return *this;
}
TCITEMHEADERW hdr;
LPARAM lParam;
int uiID;
CWnd* pWnd;
} BARTCITEMW, FAR *LPBARTCITEMW;
#ifdef UNICODE
#define BARTCITEM BARTCITEMW
#define LPBARTCITEM LPBARTCITEMW
#else
#define BARTCITEM BARTCITEMA
#define LPBARTCITEM LPBARLPTCITEMA
#endif
/////////////////////////////////////////////////////////////////////////////
// CTabBarCtrl
IMPLEMENT_DYNAMIC(CTabBarCtrl, CControlBar)
CTabBarCtrl::CTabBarCtrl()
: m_pParentFrame(NULL)
, m_bSendInitialUpdate(FALSE)
, m_cyDefault(0)
{
}
CTabBarCtrl::~CTabBarCtrl()
{
DestroyWindow();
}
BEGIN_MESSAGE_MAP(CTabBarCtrl, CControlBar)
//{{AFX_MSG_MAP(CTabBarCtrl)
ON_WM_NCCALCSIZE()
ON_WM_NCPAINT()
ON_WM_DESTROY()
ON_WM_PAINT()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_SIZEPARENT, OnSizeParent)
ON_MESSAGE(WM_INITIALUPDATE, OnInitialUpdate)
ON_NOTIFY_REFLECT(TCN_SELCHANGE, OnSelchange)
ON_MESSAGE(TCM_GETROWCOUNT, OnDoNothing)
ON_MESSAGE(TCM_SETEXTENDEDSTYLE, OnDoNothing)
ON_MESSAGE(TCM_GETEXTENDEDSTYLE, OnDoNothing)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTabBarCtrl message handlers
LRESULT CTabBarCtrl::OnInitialUpdate(WPARAM wParam, LPARAM lParam)
{
HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
SetFont(CFont::FromHandle(hFont));
ASSERT(m_pParentFrame);
ASSERT(IsWindow(*m_pParentFrame));
int iSel = GetCurSel();
ASSERT(iSel > -1);
CWnd* pView = GetViewFromItem(iSel);
pView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
m_pParentFrame->RecalcLayout();
m_pParentFrame->SetActiveView((CView*)pView);
pView = m_pParentFrame->GetActiveView();
m_bSendInitialUpdate = TRUE;
CRect rectItem;
GetItemRect(0, rectItem);
m_cyDefault = rectItem.Height() + CLIENT_FUDGE;
return 0;
}
LRESULT CTabBarCtrl::OnSizeParent(WPARAM wParam, LPARAM lParam)
{
AFX_SIZEPARENTPARAMS* lpLayout = (AFX_SIZEPARENTPARAMS*)lParam;
CRect rectItem, rectClient(lpLayout->rect);
GetItemRect(0, rectItem);
rectClient.bottom = rectClient.top + rectItem.Height() + CLIENT_FUDGE;
lpLayout->rect.top = rectClient.bottom;
lpLayout->sizeTotal = rectClient.Size();
if (lpLayout->hDWP != NULL)
AfxRepositionWindow(lpLayout, m_hWnd, &rectClient);
return 0;
}
void CTabBarCtrl::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp)
{
lpncsp->rgrc[0].right += 5;
lpncsp->rgrc[0].left -= 1;
CControlBar::OnNcCalcSize(bCalcValidRects, lpncsp);
}
void CTabBarCtrl::OnNcPaint()
{
CRect rectCLient, rectNC;
GetWindowRect(rectNC);
rectNC.OffsetRect(-rectNC.left, -rectNC.top);
CWindowDC dc(this);
CPen pen;
DWORD dwSysGray = GetSysColor(COLOR_BTNFACE);
dc.DrawEdge(rectNC, EDGE_ETCHED, BF_TOP);
rectNC.DeflateRect(0, 2, 0, 0);
CBrush brush(dwSysGray);
dc.FrameRect(rectNC, &brush);
for(int iIndx = 0; iIndx < 2; iIndx++)
{
rectNC.DeflateRect(1, 1, 1, 1);
dc.FrameRect(rectNC, &brush);
}
rectNC.DeflateRect(0, 1, 0, 2);
pen.DeleteObject();
pen.CreatePen(PS_GEOMETRIC | PS_SOLID, 1, dwSysGray);
dc.SelectObject(&pen);
dc.MoveTo(rectNC.left, rectNC.top);
dc.LineTo(rectNC.right, rectNC.top);
}
void CTabBarCtrl::OnDestroy()
{
HIMAGELIST h = (HIMAGELIST)SendMessage(TCM_GETIMAGELIST);
if (CImageList::FromHandlePermanent(h) != NULL)
SendMessage(TCM_SETIMAGELIST, NULL, NULL);
CControlBar::OnDestroy();
}
BOOL CTabBarCtrl::Create(CFrameWnd* pParentWnd)
{
// initialize common controls
INITCOMMONCONTROLSEX icc;
icc.dwSize = sizeof(INITCOMMONCONTROLSEX);
icc.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&icc);
ASSERT_VALID(pParentWnd); // must have a parent
m_pParentFrame = pParentWnd;
m_dwStyle = NULL;
if (!CWnd::Create(WC_TABCONTROL, NULL, WS_CHILD | WS_VISIBLE/* | WS_BORDER*/| WS_DLGFRAME, CRect(0, 0, 0, 0), pParentWnd, AFX_IDC_TAB_CONTROL))
{
TRACE("Failed to create tab bar!\n");
return FALSE;
}
int iu = sizeof(DWORD);
LRESULT lres = ::SendMessage(m_hWnd, TCM_SETITEMEXTRA, 3 * sizeof(DWORD), 0);
return TRUE;
}
BOOL CTabBarCtrl::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
if (message != WM_DRAWITEM)
return CControlBar::OnChildNotify(message, wParam, lParam, pResult);
ASSERT(pResult == NULL); // no return needed
UNUSED(pResult);
DrawItem((LPDRAWITEMSTRUCT)lParam);
return TRUE;
}
void CTabBarCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// must override for overdrawn
ASSERT(FALSE);
}
BOOL CTabBarCtrl::GetItem(int iItem, TCITEM* pTabCtrlItem) const
{
ASSERT(::IsWindow(m_hWnd));
CTabBarCtrl *pBar = (CTabBarCtrl*)this;
return pBar->QueryInfo(TCM_GETITEM, iItem, pTabCtrlItem);
}
BOOL CTabBarCtrl::GetItem(int iItem, TCITEMHEADER* pBarItem) const
{
ASSERT(::IsWindow(m_hWnd));
BARTCITEM *pItem = (BARTCITEM*)pBarItem;
return (BOOL)::SendMessage(m_hWnd, TCM_GETITEM, iItem, (LPARAM)pBarItem);
}
BOOL CTabBarCtrl::SetItem(int iItem, TCITEM* pTabCtrlItem)
{
ASSERT(::IsWindow(m_hWnd));
return SetInfo(TCM_SETITEM, iItem, pTabCtrlItem);
}
DWORD CTabBarCtrl::GetItemState(int iItem, DWORD dwMask) const
{
ASSERT(::IsWindow(m_hWnd));
BARTCITEM item;
ZeroMemory(&item, sizeof(BARTCITEM));
item.hdr.mask = TCIF_STATE;
item.hdr.lpReserved1 = dwMask;
VERIFY(::SendMessage(m_hWnd, TCM_GETITEM, (WPARAM)iItem, (LPARAM)&item));
return item.hdr.lpReserved1;
}
BOOL CTabBarCtrl::SetItemState(int iItem, DWORD dwMask, DWORD dwState)
{
ASSERT(::IsWindow(m_hWnd));
BARTCITEM item;
ZeroMemory(&item, sizeof(BARTCITEM));
item.hdr.mask = TCIF_STATE;
item.hdr.lpReserved1 = dwMask;
return (BOOL)::SendMessage(m_hWnd, TCM_SETITEM, (WPARAM)iItem, (LPARAM)&item);
}
int CTabBarCtrl::SetCurSel(int iItem)
{
ASSERT(::IsWindow(m_hWnd));
return ::SendMessage(m_hWnd, TCM_SETCURSEL, iItem, 0L);
}
//////////////////////////////////////////////////////////////////////////
// InsertView overloads
int CTabBarCtrl::InsertView(CRuntimeClass *pViewClass, int iItem, LPCTSTR lpszItem, CCreateContext* pContext /*= NULL*/)
{
ASSERT(::IsWindow(m_hWnd));
return InsertView(pViewClass, TCIF_TEXT, iItem, lpszItem, 0, 0, 0, 0, pContext);
}
int CTabBarCtrl::InsertView(CRuntimeClass *pViewClass, int iItem, LPCTSTR lpszItem,
int iImage, CCreateContext* pContext/* = NULL*/)
{
ASSERT(::IsWindow(m_hWnd));
return InsertView(pViewClass, TCIF_TEXT | TCIF_IMAGE, iItem, lpszItem, iImage, 0, 0, 0, pContext);
}
int CTabBarCtrl::InsertView(CRuntimeClass *pViewClass, UINT uiMask, int iItem,
LPCTSTR lpszItem, int iImage, LPARAM lParam, CCreateContext* pContext/* = NULL*/)
{
ASSERT(::IsWindow(m_hWnd));
return InsertView(pViewClass, TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM, iItem, lpszItem,
iItem, lParam, 0, 0, pContext);
}
int CTabBarCtrl::InsertView(CRuntimeClass *pViewClass, UINT uiMask, int iItem,
LPCTSTR lpszItem, int iImage, LPARAM lParam, DWORD dwState, DWORD dwStateMask, CCreateContext* pContext/* = NULL*/)
{
ASSERT(::IsWindow(m_hWnd));
TCITEM item;
ZeroMemory(&item, sizeof(TCITEM));
item.mask = uiMask;
item.iImage = iImage;
item.lParam = lParam;
item.pszText = (LPTSTR)lpszItem;
item.dwState = dwState;
item.dwStateMask = dwStateMask;
return InsertView(pViewClass, iItem, &item, pContext);
}
int CTabBarCtrl::InsertView(CRuntimeClass *pViewClass, int iItem, TCITEM* pTabCtrlItem, CCreateContext* pContext /*= NULL*/)
{
ASSERT(::IsWindow(m_hWnd));
BARTCITEM item(*pTabCtrlItem);
if(!CreateView(pViewClass, (TCITEMHEADER*)&item, pContext))
{
return FALSE;
}
return ::SendMessage(m_hWnd, TCM_INSERTITEM, iItem, (LPARAM)&item);
}
//////////////////////////////////////////////////////////////////////////
// AddView overloads
int CTabBarCtrl::AddView(CRuntimeClass *pViewClass, LPCTSTR lpszItem, CCreateContext* pContext/* = NULL*/)
{
ASSERT(::IsWindow(m_hWnd));
return AddView(pViewClass, TCIF_TEXT, lpszItem, 0, 0, 0, 0, pContext);
}
int CTabBarCtrl::AddView(CRuntimeClass *pViewClass, LPCTSTR lpszItem, int iImage, CCreateContext* pContext/* = NULL*/)
{
ASSERT(::IsWindow(m_hWnd));
return AddView(pViewClass, TCIF_TEXT | TCIF_IMAGE, lpszItem, iImage, 0, 0, 0, pContext);
}
int CTabBarCtrl::AddView(CRuntimeClass *pViewClass, LPCTSTR lpszItem,
int iImage, LPARAM lParam, CCreateContext* pContext/* = NULL*/)
{
ASSERT(::IsWindow(m_hWnd));
return AddView(pViewClass, TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM, lpszItem, iImage, lParam, 0, 0, pContext);
}
int CTabBarCtrl::AddView(CRuntimeClass *pViewClass, UINT uiMask, LPCTSTR lpszItem,
int iImage, LPARAM lParam, DWORD dwState, DWORD dwStateMask, CCreateContext* pContext/* = NULL*/)
{
ASSERT(::IsWindow(m_hWnd));
int iCount = GetItemCount();
return InsertView(pViewClass, uiMask, iCount, lpszItem, iImage, lParam, dwState,
dwStateMask, pContext);
}
int CTabBarCtrl::AddView(CRuntimeClass *pViewClass, TCITEM* pTabCtrlItem, CCreateContext* pContext /*= NULL*/)
{
ASSERT(::IsWindow(m_hWnd));
int iCount = GetItemCount();
return InsertView(pViewClass, iCount, pTabCtrlItem, pContext);
}
// AddView overloads END
//////////////////////////////////////////////////////////////////////////
// RemoveView contains certain guards to tell whenever attempted remove is not valid
BOOL CTabBarCtrl::RemoveView(int iItem)
{
ASSERT(::IsWindow(m_hWnd));
int iCount = GetItemCount();
// if this fires, it is an attempt to remove view that does not exist or the last view
ASSERT((iCount > iItem) || (iCount > 1) || (iItem > 0));
// return FALSE to continue working
if((iCount <= iItem) || (iCount < 2))
{
return FALSE;
}
BARTCITEM item;
item.hdr.mask = TCIF_PARAM;
VERIFY(GetItem(iItem, (TCITEMHEADER*)&item));
ASSERT(item.pWnd);
ASSERT(IsWindow(*item.pWnd));
int iTabItem = -1;
CWnd *pNewView = NULL;
CWnd *pRemoveView = item.pWnd; // just to simplify
int iSetCurr = iItem + 1;
// this will set active tab either after or if tab does not exist before removed one
if(AFX_IDW_PANE_FIRST == pRemoveView->GetDlgCtrlID()) //removing active?
{
// to set active tab after removed
pNewView = GetViewFromItem(iSetCurr);
// is it last tab? if so set tab before
if(NULL == pNewView)
{
iSetCurr = iItem - 1;
// attempt to set active tab before removved
pNewView = GetViewFromItem(iSetCurr);
}
}
m_mapUsedID.RemoveKey(item.uiID);
pRemoveView->DestroyWindow();
// we just removed active, set new view.
if(pNewView)
{
pNewView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
pNewView->ShowWindow(SW_SHOW);
SetCurSel(iSetCurr);
m_pParentFrame->RecalcLayout();
pNewView->SetFocus();
}
return (BOOL)::SendMessage(m_hWnd, TCM_DELETEITEM, iItem, 0L);
}
BOOL CTabBarCtrl::RemoveAllViews()
{
ASSERT(::IsWindow(m_hWnd));
int iCount = GetItemCount();
ASSERT(iCount > 1); // 1 view must be left
if(iCount < 2)
{
return FALSE;
}
BARTCITEM itemSave;
BARTCITEM item;
CString csBuffer;
CString csItemText;
// kill all views except current
for(int iIndx = 0; iIndx < iCount; iIndx++)
{
item.hdr.mask = TCIF_ALL_BAR;
LPTSTR pBuf = csBuffer.GetBufferSetLength(MAX_PATH);
item.hdr.cchTextMax = MAX_PATH;
item.hdr.pszText = pBuf;
GetItem(iIndx, (TCITEMHEADER*)&item);
csBuffer.ReleaseBuffer();
ASSERT(item.pWnd);
if(AFX_IDW_PANE_FIRST == item.pWnd->GetDlgCtrlID())
{
// csBuffer has different pointer on each iteration
// this will just copy pointer of csBuffer string to csItemText data member
// so it will point to the same string in itemSave
csItemText = csBuffer;
// save for default view, do not destroy
itemSave = item;
continue;
}
item.pWnd->DestroyWindow();
}
// delete all items
BOOL bResult = ::SendMessage(m_hWnd, TCM_DELETEALLITEMS, 0, 0);
if(!bResult)
{
ASSERT(bResult); // something is wrong not right TCM_DELETEALLITEMS failed
return bResult;
}
m_mapUsedID.RemoveAll();
// insert first item to manage current view
bResult &= (-1 < ::SendMessage(m_hWnd, TCM_INSERTITEM, 0, (LPARAM)&itemSave));
m_mapUsedID.SetAt(itemSave.uiID, itemSave.uiID);
// TCM_INSERTITEM ignores state, we have to set item to set the same state
itemSave.hdr.mask = TCIF_STATE;
bResult &= ::SendMessage(m_hWnd, TCM_SETITEM, 0, (LPARAM)&itemSave);
ASSERT(bResult);
m_pParentFrame->RecalcLayout();
return bResult;
}
void CTabBarCtrl::OnPaint()
{
// do default tab view painting, not a control bar painting
Default();
}
void CTabBarCtrl::EnableDocking(DWORD dwDockStyle)
{
// docking not supported
ASSERT(FALSE);
}
void CTabBarCtrl::OnSelchange(NMHDR* pNMHDR, LRESULT* pResult)
{
int iSel = GetCurSel();
ASSERT(m_pParentFrame);
ASSERT(IsWindow(*m_pParentFrame));
// get current view
CWnd *pViewCurrent = m_pParentFrame->GetDlgItem(AFX_IDW_PANE_FIRST);
ASSERT(pViewCurrent);
ASSERT(IsWindow(*pViewCurrent));
// retrieve original ID
UINT uiID = GetViewTabID(pViewCurrent);
pViewCurrent->SetDlgCtrlID(uiID);
pViewCurrent->ShowWindow(SW_HIDE);
// get View for selected tab
CWnd *pNewViewWnd = GetViewFromItem(iSel);
ASSERT(pNewViewWnd);
ASSERT(IsWindow(*pNewViewWnd));
// make view current
pNewViewWnd->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
pNewViewWnd->ShowWindow(SW_SHOW);
m_pParentFrame->RecalcLayout();
m_pParentFrame->SetActiveView((CView*)pNewViewWnd);
*pResult = 0;
}
void CTabBarCtrl::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
{
Default();
}
BOOL CTabBarCtrl::CreateView(CRuntimeClass *pViewClass, TCITEMHEADER* pBarItem, CCreateContext *pContext)
{
UINT uiNewID = FIRST_TAB_VIEW_ID;
UINT uiFound = 0;
BARTCITEM* pItem = (BARTCITEM*)pBarItem;
// find valid ID >= FIRST_TAB_VIEW_ID
while(m_mapUsedID.Lookup(uiNewID, uiFound))
{
uiNewID++;
}
// Create View
CCreateContext cntxt;
cntxt.m_pCurrentDoc = pContext->m_pCurrentDoc;
cntxt.m_pCurrentFrame = pContext->m_pCurrentFrame;
cntxt.m_pLastView = pContext->m_pLastView;
cntxt.m_pNewDocTemplate = pContext->m_pNewDocTemplate;
cntxt.m_pNewViewClass = pViewClass;
ASSERT(m_pParentFrame);
ASSERT(IsWindow(*m_pParentFrame));
CWnd *pWnd = m_pParentFrame->CreateView(&cntxt, uiNewID);
if(NULL == pWnd)
{
TRACE("Failed to create view.");
return FALSE;
}
pItem->hdr.mask |= TCIF_PARAM;
pItem->pWnd = pWnd;
pItem->uiID = uiNewID;
m_mapUsedID.SetAt(uiNewID, uiNewID);
if(m_bSendInitialUpdate)
{
pWnd->SendMessage(WM_INITIALUPDATE);
}
return TRUE;
}
UINT CTabBarCtrl::GetViewTabID(CWnd* pWnd)
{
CWnd *pView = NULL;
int iTabItem = -1;
int iCount = GetItemCount();
for(int iIndx = 0; iIndx < iCount; iIndx++)
{
BARTCITEM barItem;
barItem.hdr.mask = TCIF_PARAM;
GetItem(iIndx, (TCITEMHEADER*)&barItem);
if(barItem.pWnd == pWnd)
{
// minimum ID is AFX_IDW_PANE_FIRST + 1
ASSERT(barItem.uiID > AFX_IDW_PANE_FIRST);
return barItem.uiID;
}
}
ASSERT(FALSE);
return 0;
}
CWnd* CTabBarCtrl::GetViewFromItem(int iItem)
{
BARTCITEM barItem;
barItem.hdr.mask = TCIF_PARAM;
BOOL bResult = GetItem(iItem, (TCITEMHEADER*)&barItem);
// item do not exists
if(!bResult)
{
return NULL;
}
ASSERT(barItem.uiID > AFX_IDW_PANE_FIRST); // minimum ID is AFX_IDW_PANE_FIRST + 1
return barItem.pWnd;
}
int CTabBarCtrl::QueryInfo(UINT uiType, int iItem, TCITEMHEADER* pBarItem)
{
return ::SendMessage(m_hWnd, uiType, iItem, (LPARAM)pBarItem);
}
int CTabBarCtrl::QueryInfo(UINT uiType, int iItem, TCITEM *pTabCtrlItem)
{
BARTCITEM BarItem(*pTabCtrlItem);
return QueryInfo(uiType, iItem, (TCITEMHEADER*)&BarItem);
}
int CTabBarCtrl::SetInfo(UINT uiType, int iItem, TCITEMHEADER* pBarItem)
{
return ::SendMessage(m_hWnd, uiType, iItem, (LPARAM)pBarItem);
}
int CTabBarCtrl::SetInfo(UINT uiType, int iItem, TCITEM *pTabCtrlItem)
{
BARTCITEM BarItem(*pTabCtrlItem);
BOOL bParam = ((pTabCtrlItem->mask & TCIF_PARAM) == TCIF_PARAM);
if(bParam)
{
BARTCITEM barItemQuerry;
barItemQuerry.hdr.mask = TCIF_PARAM;
VERIFY(GetItem(iItem, (TCITEMHEADER*)&barItemQuerry));
BarItem.uiID = barItemQuerry.uiID;
BarItem.pWnd = barItemQuerry.pWnd;
}
int iRet = SetInfo(uiType, iItem, (TCITEMHEADER*)&BarItem);
return iRet;
}
BOOL CTabBarCtrl::SetItemData(int iItem, LPARAM lParam)
{
BARTCITEM item;
item.hdr.mask = TCIF_PARAM;
if(!QueryInfo(TCM_GETITEM, iItem, (TCITEMHEADER*)&item))
{
return FALSE;
}
item.lParam = lParam;
return SetInfo(TCM_SETITEM, iItem, (TCITEMHEADER*)&item);
}
int CTabBarCtrl::SetItemImage(int iItem, UINT uiImage)
{
BARTCITEM item;
item.hdr.mask = TCIF_IMAGE;
item.hdr.iImage = uiImage;
return SetInfo(TCM_SETITEM, iItem, (TCITEMHEADER*)&item);
}
BOOL CTabBarCtrl::SetItemText(int iItem, CString csText)
{
BARTCITEM item;
item.hdr.mask = TCIF_TEXT;
item.hdr.pszText = (LPTSTR)(LPCTSTR)csText;
return SetInfo(TCM_SETITEM, iItem, (TCITEMHEADER*)&item);
}
CWnd* CTabBarCtrl::GetItemView(int iItem)
{
return GetViewFromItem(iItem);
}
LRESULT CTabBarCtrl::OnDoNothing(WPARAM wParam, LPARAM lParam)
{
// do nothing
return 0;
}