254 lines
8.2 KiB
C++
254 lines
8.2 KiB
C++
#pragma once
|
|
|
|
#include "XClassArray.h"
|
|
// Creation :
|
|
//-----------
|
|
// 1) create an instance of VITabCtrl
|
|
// 2) call Create() method
|
|
// 3) add tabs with one of the InsertTab() methods
|
|
// 4) set the flags according to the style you want (up, down, fixed width ..), using SetFlags() or ModifyFlags() methods from VIControl.h
|
|
// 5) Activate the tab you want , default activated is 0, with SetActiveTabIndex() method
|
|
//
|
|
// Functioning :
|
|
//--------------
|
|
// when the user click on a tab,
|
|
// parent windows receives a WM_COMMAND message,
|
|
// with in wParam : LOWORD = id of VITabCtrl control in wParam, HIWORD = (activated tab index & 0x0ff) + (old activated index & 0x0ff <<8)
|
|
// when the user right click on a tab
|
|
// parent windows recieves a WM_NOTIFY message,
|
|
// with in wParam : id
|
|
// in lParam : a NMTABACTIVATE* with code = NM_RCLICK
|
|
//
|
|
// when a tab switch is done, the control sends a notifcation with a NMTABSWITCH* in lParam
|
|
//
|
|
// Important note : 255 max tabs allowed, no more, since in activate tab WM_COMMAND, we have just a short to put old and new activated tab index
|
|
//
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// VITabCtrl window
|
|
|
|
class AFX_EXT_CLASS VITabCtrl : public CWnd, public VIControl
|
|
{
|
|
public:
|
|
|
|
struct NMTABACTIVATE
|
|
{
|
|
NMHDR hdr;
|
|
int activatedTab;
|
|
};
|
|
|
|
struct NMTABSWITCH
|
|
{
|
|
NMHDR hdr;
|
|
int index1;
|
|
int index2;
|
|
};
|
|
|
|
struct VITab
|
|
{
|
|
XString m_Name;
|
|
CWnd* m_Wnd;
|
|
int m_Width;
|
|
DWORD m_Flags;
|
|
DWORD m_Data;
|
|
|
|
enum VITAB_FLAGS
|
|
{
|
|
};
|
|
|
|
VITab() {memset(this,0,sizeof(VITab));}
|
|
};
|
|
|
|
enum VITABCTRL_NOTIFICATION{
|
|
VITAB_NM_BEGIN_DRAG = 0x00001000,
|
|
VITAB_NM_DRAG = 0x00001001,
|
|
VITAB_NM_END_DRAG = 0x00001002,
|
|
VITAB_NM_SWITCH = 0x00001003,
|
|
};
|
|
//Flags
|
|
enum VITABCTRL_FLAGS{
|
|
VITAB_UP = 0x00000001, //tabs are rounded upside
|
|
VITAB_DOWN = 0x00000002, //tabs are rounded downside
|
|
VITAB_FIXEDWIDTH = 0x00000004, //tabs have a fixed width
|
|
VITAB_BORDER = 0x00000008, //tabs have a border on the opposite side of the rounded rect
|
|
VITAB_NEEDARROWBUTTONS = 0x00000010, //Used Internally.too much tabs for wnd width=>, so need arrow buttons to scroll
|
|
VITAB_LEFTBUTTON_ROLLOVER = 0x00000020, //Used Internally. rollover on left arrow button info for redraw
|
|
VITAB_RIGHTBUTTON_ROLLOVER = 0x00000040, //Used Internally. rollover on right arrow button info for redraw
|
|
VITAB_LEFTBUTTON_DOWN = 0x00000080, //Used Internally. left arrow button is pushed info for redraw
|
|
VITAB_RIGHTBUTTON_DOWN = 0x00000100, //Used Internally. right arrow button is pushed info for redraw
|
|
VITAB_LEFTBUTTON_AVAILABLE = 0x00000200, //Used Internally. left button is available for clicking
|
|
VITAB_RIGHTBUTTON_AVAILABLE = 0x00000400, //Used Internally. right button is available for clicking
|
|
VITAB_MANAGEWNDS = 0x00000800, //if m_Wnd members of VITAb structs exists, then these windows are shown/hidden when tabs are activated/deactivated
|
|
VITAB_MANAGEDRAGNDROPINTERNAL = 0x00001000, //tabs can be dragged & dropped to switch their position
|
|
VITAB_MANAGEDRAGNDROPEXTERNAL = 0x00002000, //tabs can be dragged & dropped and notify any wnd about current state of drag & drop
|
|
VITAB_MANAGEDRAGNDROP = 0x00003000, //global drag & drop management
|
|
VITAB_AUTORESIZETOMINWIDTH = 0x00004000, //Not effective yet. according to added / removed tab, the tab control autoresizes to min width maximized by parent client rect width
|
|
};
|
|
|
|
public:
|
|
// Construction
|
|
VITabCtrl();
|
|
~VITabCtrl();
|
|
|
|
HRESULT Create(const char* name,DWORD style,RECT &r,CWnd* parent,int id);
|
|
|
|
//return value : index or -1 if failed
|
|
int InsertTab(int index,VITab* tab,BOOL redraw=FALSE); //-1 => append
|
|
int InsertTab(int index,const char* name,CWnd* wnd=NULL,BOOL redraw=FALSE); //-1 => append
|
|
|
|
// Get index of tab under mouse, -1 if any
|
|
int GetTabUnderMouse();
|
|
|
|
// Get index of tab under given client coordinaates
|
|
int GetTabAt(POINT &clientP);
|
|
|
|
//get tab struct ptr, to change on the fly
|
|
int GetTabCount() const;
|
|
VITab* GetTab(int index);
|
|
|
|
//update tab after having modified a VITab struct
|
|
int UpdateTab(int index,BOOL recomputeWidth=TRUE);
|
|
|
|
//remove a tab
|
|
int RemoveTab(int index,BOOL redraw=TRUE);
|
|
|
|
//remove all tabs
|
|
int RemoveAllTabs(BOOL redraw=TRUE);
|
|
|
|
//set active tab. -1 means no activate tab
|
|
int SetActiveTab(int index=-1,BOOL redraw=TRUE,BOOL sendMessageToParent=FALSE);
|
|
|
|
//switch tabs
|
|
int SwitchTabs(int index1,int index2);
|
|
|
|
|
|
// Data access
|
|
int GetTabMargin() {return m_TabMargin;}
|
|
int SetTabMargin(int m); //free space around text in tabs
|
|
|
|
int GetTabSeparationSpace() {return m_TabSeparationSpace;}
|
|
int SetTabSeparationSpace(int s); //space in pixel between end of textof 1st tab and drawing of next tab
|
|
|
|
int GetActiveTabIndex() {return m_ActiveTabIndex;}
|
|
|
|
int GetTabFixedWidth() {return m_TabFixedWidth;}
|
|
int SetTabFixedWidth(int width);
|
|
|
|
COLORREF GetActiveTabColor() {return m_ActiveTabColor;}
|
|
int SetActiveTabColor(COLORREF c);
|
|
|
|
CImageList* CreateDragImage(int index);
|
|
|
|
//compute total max width
|
|
int ComputeTotalTabWidth();
|
|
|
|
//get maximum width (to use width flag VITAB_AUTORESIZETOMINWIDTH)
|
|
int GetMaximumWidth();
|
|
|
|
//set maximum width (to use width flag VITAB_AUTORESIZETOMINWIDTH)
|
|
void SetMaximumWidth(int newmaxwidth);
|
|
|
|
protected:
|
|
//DATAS
|
|
//array of string / tabs
|
|
XClassArray<VITab> m_Tabs;
|
|
|
|
//free space around text in tabs (so x2, margin added to text width left and right)
|
|
int m_TabMargin;
|
|
|
|
//separation between two tabs, after the end of text of the 1st tab
|
|
int m_TabSeparationSpace;
|
|
|
|
//fixed width
|
|
int m_TabFixedWidth;
|
|
|
|
//active tab backcolor
|
|
COLORREF m_ActiveTabColor;
|
|
|
|
//index of first visible tab
|
|
int m_FirstVisibleTab;
|
|
|
|
//image list for internal drag & drop
|
|
CImageList* m_DragNDropImageList;
|
|
|
|
//drag & drop hot spot
|
|
POINT m_DragNDropHotspot;
|
|
|
|
//maximum width, to use with flag VITAB_AUTORESIZETOMINWIDTH.
|
|
int m_MaximumWidth;
|
|
|
|
//FUNCS
|
|
//callbacks
|
|
int DoOnPaint();
|
|
int DoOnLButtonDown(int x,int y,int dblclk=0);
|
|
int DoOnLButtonUp(int x,int y);
|
|
int DoOnRButtonUp(int x,int y);
|
|
int DoOnMouseMove(int x,int y);
|
|
int DoOnSize(int width,int height);
|
|
int OnClickLeftArrowButton();
|
|
int OnClickRightArrowButton();
|
|
int OnClickOnTab(int index);
|
|
|
|
//draw a tab button
|
|
int DrawTab(VITab* tab,CDC* dc,int xoffset=-1,int active = 0);
|
|
|
|
//draw arrow buttons. Return Value : new available width left. If rollover==1 draws only left button filled, if ==2, draws only right button filled, ==3, left is down, ==4 right is down
|
|
int DrawArrowButtons(CDC* dc,int rollover=0);
|
|
|
|
//test available arrow buttons. Modify m_CtrlFlags in consequence
|
|
int TestAvailableArrowButtons();
|
|
|
|
//add/remove VITAB_NEEDARROWBUTTONS flag according to total tab width (ComputeTotalTabWidth()) and client rect .Returns total width
|
|
int CheckForArrowButtons();
|
|
|
|
//get arrow buttons rect.Return Value : new available width left
|
|
int GetArrowButtonsRect(RECT* oR1=NULL,RECT* oR2=NULL);
|
|
|
|
//compute tab width (after insertion, or if need update)
|
|
int ComputeTabWidth(VITab* tab);
|
|
|
|
//return 1 if is 1st visible tab and tabindex!=0, otherwise 0
|
|
int IsFirstVisibleTab(int tabIndex);
|
|
|
|
//return 1 if is last visible tab, otherwise 0
|
|
int IsLastVisibleTab(int tabIndex);
|
|
|
|
//Manage wnds
|
|
int ActivatedTabChange(int oldActivatedIndex,int newActivatedIndex);
|
|
|
|
//return x position of tab, fill oRect
|
|
int GetTabRect(int index,RECT* oRect=NULL);
|
|
|
|
//drag & drop
|
|
int BeginDrag(POINT &hotspot);
|
|
int DragStop();
|
|
int DragCont();
|
|
int IsDragActive();
|
|
int DragMove();
|
|
int EndDrag();
|
|
|
|
private:
|
|
//active tab. Must be set only via SetActiveTab func
|
|
int m_ActiveTabIndex;
|
|
|
|
//---------------------------------------------------------------------------
|
|
//----------WINDOWS----------------------------------------------------------
|
|
public:
|
|
// Overrides
|
|
// ClassWizard generated virtual function overrides
|
|
//{{AFX_VIRTUAL(VITabCtrl)
|
|
public:
|
|
virtual BOOL PreTranslateMessage(MSG* pMsg);
|
|
protected:
|
|
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
|
|
//}}AFX_VIRTUAL
|
|
|
|
// Generated message map functions
|
|
protected:
|
|
//{{AFX_MSG(VITabCtrl)
|
|
//}}AFX_MSG
|
|
DECLARE_MESSAGE_MAP()
|
|
//----------WINDOWS----------------------------------------------------------
|
|
//---------------------------------------------------------------------------
|
|
};
|