summaryrefslogtreecommitdiffstats
path: root/private/nw/convert/nwconv/tab.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/nw/convert/nwconv/tab.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to '')
-rw-r--r--private/nw/convert/nwconv/tab.c1512
1 files changed, 1512 insertions, 0 deletions
diff --git a/private/nw/convert/nwconv/tab.c b/private/nw/convert/nwconv/tab.c
new file mode 100644
index 000000000..f5a917331
--- /dev/null
+++ b/private/nw/convert/nwconv/tab.c
@@ -0,0 +1,1512 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright 1990-1993 Microsoft corporation
+// all rights reservered
+//////////////////////////////////////////////////////////////////////////////
+//
+// Program: (nominally)Bloodhound
+// Module: tab.c
+// Purpose: creates and operates a book tab (big file folder) custom control
+//
+// Note: the current implementation is limited to 4 booktabs, sorry.
+//
+//
+// ---------------------------- TABSTOP = 4 -------------------
+//
+// Entry Points:
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab
+//
+//
+//
+// Input:
+// hwnd - our window handle
+//
+// Returns:
+//
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+#define STRICT
+#include "switches.h"
+#include <windows.h>
+#include <windowsx.h>
+
+#include "tab.h"
+// #include "..\bhmem.h"
+
+//////////////////////////////////////////////////////////////////////////////
+// Constants
+//////////////////////////////////////////////////////////////////////////////
+#define MAX_TABS 4
+#define MAX_TAB_LABEL_LEN 128
+
+#define ANGLE_X 5
+#define ANGLE_Y 5
+
+#define CARAT_X 2
+#define CARAT_Y 2
+
+#define FLUFF_X 0
+#define FLUFF_Y 0
+
+#define FOOTROOM_Y 3
+
+// We use the selected tab for these calculations:
+//
+// tab_rect:
+//
+// ANGLE_X|--|
+//
+// - BBBBBBBBBBBBBBB
+// ANGLE_Y | BWWWWWWWWWWWWWWW
+// | BWWWWWWWWWWWWWWWW
+// - BWWW
+// BWW * <-- this is where the text_rect starts
+// BWW
+// BWW
+//
+//
+// text_rect: (defined by the *'s)
+//
+// FLUFF_X|----|
+//
+// - * *
+// |
+// FLUFF_Y |
+// | CARAT_X
+// | |---|
+// - ............................. -
+// . . |
+// . . | CARAT_Y
+// . . |
+// - . XXXXX XXXXX X X XXXXX . -
+// text hght| . X X X X X .
+// is from | . X XXX X X .
+// font | . X X X X X .
+// _ . X XXXXX X X X .
+// . .
+// . .
+// . .
+// .............................
+//
+// |---------------------|
+// text width is directly
+// from the font itself
+// * *
+//
+//
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Data Structures for this file
+//////////////////////////////////////////////////////////////////////////////
+typedef struct _ONETAB
+{
+ TCHAR label[ MAX_TAB_LABEL_LEN + 1 ];
+ DWORD data;
+ RECT tab_rect;
+ RECT text_rect;
+} ONETAB;
+
+typedef struct _TABDATA
+{
+ // do the tabs need updating ?
+ BOOL fUpdate;
+ RECT tabs_rect;
+
+ // font data
+ HFONT hfSelected;
+ HFONT hfUnselected;
+
+ // windows data
+ HWND hwndParent;
+
+ // tab data
+ UINT total_tabs;
+ UINT selected_tab;
+ ONETAB tab[ MAX_TABS ];
+
+} TABDATA;
+typedef TABDATA *LPTABDATA;
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Variables Global to this file
+//////////////////////////////////////////////////////////////////////////////
+TCHAR szBookTabName[]=BOOK_TAB_CONTROL;
+
+//////////////////////////////////////////////////////////////////////////////
+// Macros Global to this file
+//////////////////////////////////////////////////////////////////////////////
+#define GetInstanceDataPtr(hwnd) ((LPTABDATA)GetWindowLong(hwnd, 0))
+#define SetInstanceDataPtr(hwnd,x) (SetWindowLong(hwnd, 0, (DWORD)x))
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Functional Prototypes for Functions Local to this File
+//////////////////////////////////////////////////////////////////////////////
+LRESULT CALLBACK BookTab_WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
+BOOL BookTab_OnCreate(HWND hwnd, CREATESTRUCT FAR* lpCreateStruct);
+void BookTab_OnDestroy(HWND hwnd);
+void BookTab_OnLButtonDown(HWND hwnd, BOOL fDblClk, int x, int y, UINT keyFlags);
+void BookTab_OnPaint(HWND hwnd);
+UINT BookTab_OnGetDlgCode(HWND hwnd, MSG FAR* lpmsg);
+void BookTab_OnSize(HWND hwnd, UINT state, int cx, int cy);
+void BookTab_OnSetFocus(HWND hwnd, HWND hwndOldFocus);
+void BookTab_OnKillFocus(HWND hwnd, HWND hwndNewFocus);
+void BookTab_OnKey(HWND hwnd, UINT vk, BOOL fDown, int cRepeat, UINT flags);
+void BookTab_OnEnable(HWND hwnd, BOOL fEnable);
+
+UINT BookTab_OnAddItem( HWND hwnd, LPTSTR text );
+UINT BookTab_OnInsertItem( HWND hwnd, UINT index, LPTSTR text);
+BOOL BookTab_OnDeleteItem( HWND hwnd, UINT index );
+BOOL BookTab_OnDeleteAllItems( HWND hwnd);
+BOOL BookTab_OnSetItem( HWND hwnd, UINT index, LPTSTR text );
+BOOL BookTab_OnGetItem( HWND hwnd, UINT index, LPTSTR text );
+UINT BookTab_OnSetCurSel( HWND hand, UINT newsel );
+UINT BookTab_OnGetCurSel( HWND hand );
+UINT BookTab_OnGetItemCount( HWND hwnd );
+BOOL BookTab_OnSetItemData( HWND hwnd, UINT index, DWORD data );
+DWORD BookTab_OnGetItemData( HWND hwnd, UINT index);
+void BookTab_OnPutInBack( HWND hwnd );
+
+BOOL IsPointInRect( int given_x, int given_y, LPRECT pRect );
+void BookTab_UpdateButtons( HWND hwnd );
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_Initialize()
+//
+// Initializes and registers the BookTab custom class
+//
+// Input:
+// hInstance - the handle to our parent's instance
+//
+// Returns:
+// True if successful, else False
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+void BookTab_Initialize(HINSTANCE hInstance)
+{
+ WNDCLASS wndclass;
+
+ wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS | CS_PARENTDC;
+ wndclass.lpfnWndProc = BookTab_WndProc;
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = sizeof( LPTABDATA );
+ wndclass.hInstance = hInstance;
+ wndclass.hIcon = NULL;
+ wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
+ wndclass.hbrBackground = NULL;
+ wndclass.lpszMenuName = NULL;
+ wndclass.lpszClassName = szBookTabName;
+
+ RegisterClass ( &wndclass );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_WndProc()
+//
+// Distributes messages coming in to the BookTab control
+//
+// Input:
+// hwnd - Our handle
+// message - the ordinal of the incoming message
+// wParam - half of the incoming data
+// lParam - the other half of the incoming data
+//
+// Returns:
+// True if we handled the message, else False
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+LRESULT CALLBACK BookTab_WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ // standard windows messages
+ HANDLE_MSG( hwnd, WM_CREATE, BookTab_OnCreate);
+ HANDLE_MSG( hwnd, WM_DESTROY, BookTab_OnDestroy);
+ HANDLE_MSG( hwnd, WM_LBUTTONDOWN, BookTab_OnLButtonDown);
+ HANDLE_MSG( hwnd, WM_PAINT, BookTab_OnPaint);
+ HANDLE_MSG( hwnd, WM_SIZE, BookTab_OnSize);
+ HANDLE_MSG( hwnd, WM_SETFOCUS, BookTab_OnSetFocus);
+ HANDLE_MSG( hwnd, WM_KILLFOCUS, BookTab_OnKillFocus);
+ HANDLE_MSG( hwnd, WM_KEYDOWN, BookTab_OnKey);
+ HANDLE_MSG( hwnd, WM_KEYUP, BookTab_OnKey);
+
+ // messages specific to all custom controls
+ HANDLE_MSG( hwnd, WM_GETDLGCODE, BookTab_OnGetDlgCode);
+ HANDLE_MSG( hwnd, WM_ENABLE, BookTab_OnEnable);
+
+ // messages specific to THIS custom control
+ case BT_ADDITEM:
+ return( BookTab_OnAddItem( hwnd, (LPTSTR)lParam ));
+ case BT_INSERTITEM:
+ return( BookTab_OnInsertItem( hwnd, (UINT)wParam, (LPTSTR)lParam ));
+ case BT_DELETEITEM:
+ return( BookTab_OnDeleteItem( hwnd, (UINT)wParam ));
+ case BT_DELETEALLITEMS:
+ return( BookTab_OnDeleteAllItems( hwnd ));
+ case BT_SETITEM:
+ return( BookTab_OnSetItem( hwnd, (UINT)wParam, (LPTSTR)lParam ));
+ case BT_GETITEM:
+ return( BookTab_OnGetItem( hwnd, (UINT)wParam, (LPTSTR)lParam ));
+ case BT_SETCURSEL:
+ return( BookTab_OnSetCurSel( hwnd, (UINT)wParam ));
+ case BT_GETCURSEL:
+ return( BookTab_OnGetCurSel( hwnd ));
+ case BT_GETITEMCOUNT:
+ return( BookTab_OnGetItemCount( hwnd ));
+ case BT_SETITEMDATA:
+ return( BookTab_OnSetItemData( hwnd, (UINT)wParam, (DWORD)lParam ));
+ case BT_GETITEMDATA:
+ return( BookTab_OnGetItemData( hwnd, (UINT)wParam ));
+ case BT_PUTINBACK:
+ BookTab_OnPutInBack( hwnd );
+ return (TRUE);
+ }
+ // pass unprocessed messages to DefWndProc...
+ return DefWindowProc(hwnd, message, wParam, lParam);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_OnCreate()
+//
+// Initializes a new instance of our lovely custom control
+//
+// Input:
+// hwnd - our window handle
+// lpcreatestruct - pointer to the data with which to do our thing
+//
+// Returns:
+// True if the instance is created, else false
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+BOOL BookTab_OnCreate(HWND hwnd, CREATESTRUCT FAR* lpCreateStruct)
+{
+ LPTABDATA pData;
+ UINT i;
+
+ // allocate the instance data for this control
+ pData = LocalAlloc( LPTR, sizeof( TABDATA ));
+ if( pData == NULL )
+ return FALSE;
+ SetInstanceDataPtr( hwnd, pData );
+
+ // initialize values in the control
+ pData->total_tabs = 0;
+ pData->selected_tab = 0;
+
+ pData->hwndParent = lpCreateStruct->hwndParent;
+
+ // fill the prospective tab slots with data
+ for( i = 0; i < MAX_TABS; i++ )
+ {
+ pData->tab[i].label[0] = TEXT('\0');
+ pData->tab[i].data = (DWORD)0;
+ }
+
+#ifdef JAPAN // BookTab_OnCreate()
+ // create the proper fonts:
+ // 8 pt MS Gothic bold for selected and
+ // 8 pt MS Gothic regular for not selected
+ {
+ #ifdef UNICODE
+ WCHAR szGothic[] = {0xff2d, 0xff33, 0x20, 0x30b4, 0x30b7, 0x30c3, 0x30af, 0 };
+ #else
+ #error Ansi string of szGothic is nessesory.
+ #endif
+
+ pData->hfSelected = CreateFont( -8, 0, 0, 0,
+ FW_BOLD, FALSE, FALSE, FALSE,
+ SHIFTJIS_CHARSET, OUT_TT_PRECIS,
+ CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
+ 0x4, szGothic );
+ pData->hfUnselected = CreateFont( -8, 0, 0, 0,
+ FW_NORMAL, FALSE, FALSE, FALSE,
+ SHIFTJIS_CHARSET, OUT_TT_PRECIS,
+ CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
+ 0x4, szGothic );
+ }
+#else
+ // create the proper fonts:
+ // 8 pt sans serif bold for selected and
+ // 8 pt sans serif regular for not selected
+ pData->hfSelected = CreateFont( -8, 0, 0, 0,
+ FW_BOLD, FALSE, FALSE, FALSE,
+ ANSI_CHARSET, OUT_TT_PRECIS,
+ CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
+ 0x4, TEXT("MS Sans Serif") );
+ pData->hfUnselected = CreateFont( -8, 0, 0, 0,
+ FW_NORMAL, FALSE, FALSE, FALSE,
+ ANSI_CHARSET, OUT_TT_PRECIS,
+ CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
+ 0x4, TEXT("MS Sans Serif") );
+#endif // JAPAN
+
+ // fill the rest of the sizing info
+ BookTab_OnSize( hwnd, 0, lpCreateStruct->cx, lpCreateStruct->cy );
+
+ // make sure that we are on the bottom
+ SetWindowPos( hwnd, HWND_BOTTOM, 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW );
+
+ // make sure we update
+ pData->fUpdate = TRUE;
+
+ // put us last
+ BookTab_PutInBack( hwnd );
+
+ return TRUE;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_OnDestroy()
+//
+// Cleans up as our control goes away
+//
+// Input:
+// hwnd - our window handle
+//
+// Returns:
+// nothing
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+void BookTab_OnDestroy(HWND hwnd)
+{
+ LPTABDATA pData;
+
+ // get the instance data
+ pData = GetInstanceDataPtr( hwnd );
+
+ // delete our fonts
+ DeleteObject( pData->hfSelected );
+ DeleteObject( pData->hfUnselected );
+
+ // free up our instance data
+ LocalFree( pData );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_OnLButtonDown()
+//
+// Handles the event where a user has the left mouse button down
+//
+// Input:
+// hwnd - our window handle
+// fDblClk - an indication on the second message of a double click
+// x - the mouses x coordinate at the time of the message
+// y - the mouses y coordinate at the time of the message
+// keyFlags - an indication of which keys were pressed at the time
+//
+// Returns:
+// nuthin'
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+void BookTab_OnLButtonDown(HWND hwnd, BOOL fDblClk, int x, int y, UINT keyFlags)
+{
+ LPTABDATA pData;
+ UINT i;
+
+ // get the instance data
+ pData = GetInstanceDataPtr( hwnd );
+
+ // where did they click the mouse...
+ // loop thru the tabs to find the one struck
+ for( i = 0; i < pData->total_tabs; i++ )
+ {
+ if( IsPointInRect( x, y, &(pData->tab[i].tab_rect) ) )
+ {
+ // this is the correct spot
+ BookTab_OnSetCurSel( hwnd, i );
+
+ // notify our parent that the selection has changed
+ SendMessage( pData->hwndParent, BTN_SELCHANGE,
+ pData->selected_tab, (DWORD)hwnd);
+
+ SetFocus( hwnd );
+ return;
+ }
+ }
+
+ // the mouse was clicked outside any of the button areas
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_OnPaint()
+//
+// Handles requests from windows that the control repaint itself
+//
+// Input:
+// hwnd - our window handle
+//
+// Returns:
+// hopefully :)
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+void BookTab_OnPaint(HWND hwnd)
+{
+ LPTABDATA pData;
+ PAINTSTRUCT ps;
+ HDC hdc;
+ TEXTMETRIC tm;
+ UINT i;
+ HWND hwndFocus;
+
+ HPEN hOldPen;
+ HPEN hShadowPen;
+ HPEN hHighlightPen;
+ HPEN hFramePen;
+ HPEN hBackPen;
+ HBRUSH hBackBrush;
+ HFONT hfOldFont;
+
+ WORD cyChar;
+ WORD yWidth;
+ WORD xWidth;
+ RECT total;
+ RECT temp;
+ LPRECT pTab;
+ LPRECT pText;
+
+ // get the instance data
+ pData = GetInstanceDataPtr( hwnd );
+
+ // right before drawing, make sure that the button sizes are accurate
+ BookTab_UpdateButtons( hwnd );
+
+ // get the instance data
+ pData = GetInstanceDataPtr( hwnd );
+
+ // get the handle to the window with the current focus
+ hwndFocus = GetFocus();
+
+ // prepare for painting...
+ BeginPaint( hwnd, &ps );
+ hdc = GetDC( hwnd );
+
+ // set text stuff
+ SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
+ SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT));
+ SetTextAlign( hdc, TA_TOP | TA_LEFT );
+
+ // determine proper sizes
+ GetTextMetrics(hdc, &tm);
+ cyChar = (WORD)tm.tmHeight;
+ xWidth = GetSystemMetrics(SM_CXBORDER);
+ yWidth = GetSystemMetrics(SM_CYBORDER);
+ GetClientRect( hwnd, &total );
+ //BUGBUG fudge the rectangle so that the bottom and left do not get cut off
+ total.bottom -= yWidth;
+ total.right -= xWidth;
+
+ // set up the pens that we will need
+ hHighlightPen = CreatePen(PS_SOLID, yWidth, GetSysColor(COLOR_BTNHIGHLIGHT));
+ hShadowPen = CreatePen(PS_SOLID, yWidth, GetSysColor(COLOR_BTNSHADOW));
+ hFramePen = CreatePen(PS_SOLID, yWidth, GetSysColor(COLOR_WINDOWFRAME));
+ hBackPen = CreatePen(PS_SOLID, yWidth, GetSysColor(COLOR_BTNFACE));
+ hBackBrush = CreateSolidBrush( GetSysColor(COLOR_BTNFACE));
+
+ // get the old pen by setting a new one
+ hOldPen = SelectPen( hdc, hHighlightPen );
+
+ // clear out behind the tabs if we need to
+ if( pData->fUpdate == TRUE )
+ {
+ FillRect( hdc, &(pData->tabs_rect), hBackBrush );
+ pData->fUpdate = FALSE;
+ }
+
+ // draw the box...
+ // left side dark border
+ SelectPen( hdc, hFramePen );
+ MoveToEx( hdc, total.left, pData->tab[0].tab_rect.bottom+yWidth, NULL );
+ LineTo ( hdc, total.left, total.bottom );
+ // bottom dark border
+ LineTo ( hdc, total.right, total.bottom );
+ // right side dark border
+ LineTo ( hdc, total.right, pData->tab[0].tab_rect.bottom+yWidth);
+ // top dark border, right half (over to selection)
+ LineTo ( hdc, pData->tab[pData->selected_tab].tab_rect.right-yWidth,
+ pData->tab[0].tab_rect.bottom+yWidth);
+ // skip area under the selected tab
+ MoveToEx( hdc, pData->tab[pData->selected_tab].tab_rect.left,
+ pData->tab[0].tab_rect.bottom+yWidth, NULL);
+ // top dark border, left half (from selection to left border)
+ LineTo ( hdc, total.left, pData->tab[0].tab_rect.bottom+yWidth);
+
+ // left side highlight #1
+ SelectPen( hdc, hHighlightPen );
+ MoveToEx( hdc, total.left+xWidth, pData->tab[0].tab_rect.bottom+2*yWidth, NULL );
+ LineTo( hdc, total.left+xWidth, total.bottom-yWidth );
+
+ // bottom shadow #1
+ SelectPen( hdc, hShadowPen );
+ LineTo( hdc, total.right-xWidth, total.bottom-yWidth );
+ // right side shadow #1
+ LineTo( hdc, total.right-xWidth, pData->tab[0].tab_rect.bottom+2*yWidth );
+
+ // top hilite #1
+ SelectPen( hdc, hHighlightPen );
+ // top hilite, right half (over to selection)
+ LineTo ( hdc, pData->tab[pData->selected_tab].tab_rect.right-yWidth,
+ pData->tab[0].tab_rect.bottom+2*yWidth);
+ // skip area under the selected tab
+ MoveToEx( hdc, pData->tab[pData->selected_tab].tab_rect.left,
+ pData->tab[0].tab_rect.bottom+2*yWidth, NULL);
+ // top hilite, left half (from selection to left border)
+ if( pData->selected_tab != 0 )
+ LineTo ( hdc, total.left+2*xWidth,
+ pData->tab[0].tab_rect.bottom+2*yWidth);
+
+ // left side highlight #2
+ SelectPen( hdc, hHighlightPen );
+ MoveToEx( hdc, total.left+2*xWidth, pData->tab[0].tab_rect.bottom+3*yWidth, NULL );
+ LineTo( hdc, total.left+2*xWidth, total.bottom-2*yWidth );
+
+ // bottom shadow #2
+ SelectPen( hdc, hShadowPen );
+ LineTo( hdc, total.right-2*xWidth, total.bottom-2*yWidth );
+ // right side shadow #2
+ LineTo( hdc, total.right-2*xWidth, pData->tab[0].tab_rect.bottom+3*yWidth );
+
+ // top hilite #2
+ SelectPen( hdc, hHighlightPen );
+ // top hilite, right half (over to selection)
+ LineTo ( hdc, pData->tab[pData->selected_tab].tab_rect.right-2*yWidth,
+ pData->tab[0].tab_rect.bottom+3*yWidth);
+ // skip area under the selected tab
+ MoveToEx( hdc, pData->tab[pData->selected_tab].tab_rect.left,
+ pData->tab[0].tab_rect.bottom+3*yWidth, NULL);
+ // top hilite, left half (from selection to left border)
+ if( pData->selected_tab != 0 )
+ LineTo ( hdc, total.left+2*xWidth,
+ pData->tab[0].tab_rect.bottom+3*yWidth);
+
+ // Draw the tabs...
+ // loop thru the tabs
+ for( i = 0; i < pData->total_tabs; i++ )
+ {
+ // point our local variables at the current rects
+ pTab = &(pData->tab[i].tab_rect);
+ pText = &(pData->tab[i].text_rect);
+
+ if( i == pData->selected_tab )
+ {
+ // this is the selection, it should not be pushed down...
+ // left side dark border
+ SelectPen( hdc, hFramePen );
+ MoveToEx(hdc, pTab->left, pTab->bottom, NULL);
+ LineTo(hdc, pTab->left, pTab->top + ANGLE_Y*yWidth);
+ // left side angle dark border
+ LineTo(hdc, pTab->left + ANGLE_X*xWidth, pTab->top);
+ // top dark border
+ LineTo(hdc, pTab->right - ANGLE_X*xWidth, pTab->top);
+ // right side angle dark border
+ LineTo(hdc, pTab->right, pTab->top + ANGLE_Y*yWidth);
+ // right side dark border (overshoot by one)
+ LineTo(hdc, pTab->right, pTab->bottom+yWidth);
+
+ // left side hilite #1 (extends down 3 below the box to handle
+ // melding the hilites with the box below)
+ SelectPen( hdc, hHighlightPen);
+ MoveToEx(hdc, pTab->left+xWidth, pTab->bottom+3*yWidth, NULL);
+ LineTo(hdc, pTab->left+xWidth, pTab->top+ANGLE_Y*yWidth );
+ // left side angle hilight #1
+ LineTo(hdc, pTab->left+ANGLE_X*xWidth, pTab->top+yWidth );
+ // top hilite #1
+ LineTo(hdc, pTab->right-ANGLE_X*xWidth, pTab->top+yWidth );
+ // right side angle shadow #1
+ SelectPen( hdc, hShadowPen);
+ LineTo(hdc, pTab->right-xWidth, pTab->top+ANGLE_Y*yWidth );
+ // right side shadow #1 (overshoot by one) (see above)
+ LineTo(hdc, pTab->right-xWidth, pTab->bottom+3*yWidth);
+
+ // left side hilite #2 (the 2* are becaus we are the 2nd hilite)
+ SelectPen( hdc, hHighlightPen);
+ MoveToEx(hdc, pTab->left+2*xWidth, pTab->bottom+3*yWidth, NULL);
+ LineTo(hdc, pTab->left+2*xWidth, pTab->top+ANGLE_Y*yWidth );
+ // left side angle hilight #2
+ LineTo(hdc, pTab->left+ANGLE_X*xWidth, pTab->top+2*yWidth );
+ // top hilite #2
+ LineTo(hdc, pTab->right-ANGLE_X*xWidth, pTab->top+2*yWidth );
+ // right side angle shadow #2
+ SelectPen( hdc, hShadowPen);
+ LineTo(hdc, pTab->right-2*xWidth, pTab->top+ANGLE_Y*yWidth );
+ // right side shadow #2 (overshoot by one)
+ LineTo(hdc, pTab->right-2*xWidth, pTab->bottom+4*yWidth );
+
+ // clear out the chunk below the active tab
+ SelectPen(hdc, hBackPen );
+ MoveToEx(hdc, pTab->left+3*xWidth, pTab->bottom+yWidth, NULL);
+ LineTo(hdc, pTab->right-2*xWidth, pTab->bottom+yWidth);
+ MoveToEx(hdc, pTab->left+3*xWidth, pTab->bottom+2*yWidth, NULL);
+ LineTo(hdc, pTab->right-2*xWidth, pTab->bottom+2*yWidth);
+ MoveToEx(hdc, pTab->left+3*xWidth, pTab->bottom+3*yWidth, NULL);
+ LineTo(hdc, pTab->right-2*xWidth, pTab->bottom+3*yWidth);
+
+ // clear out the old label...
+ FillRect( hdc, pText, hBackBrush );
+
+ // now print in the label ...
+ hfOldFont = SelectObject( hdc, pData->hfSelected );
+ ExtTextOut( hdc,
+ pText->left+ CARAT_X*xWidth + FLUFF_X*xWidth,
+ pText->top + CARAT_Y*yWidth + FLUFF_Y*yWidth,
+ 0, NULL, pData->tab[i].label,
+ lstrlen(pData->tab[i].label), NULL );
+ SelectFont( hdc, hfOldFont );
+
+ // if we have the focus, print the caret
+ if( hwnd == hwndFocus )
+ {
+ // we have the focus
+ temp.top = pText->top + FLUFF_X*xWidth;
+ temp.left = pText->left + FLUFF_Y*yWidth;
+ temp.bottom = pText->bottom - FLUFF_X*xWidth;
+ temp.right = pText->right - FLUFF_Y*yWidth;
+ DrawFocusRect( hdc, &temp );
+ }
+
+ }
+ else
+ {
+ // push this tab down one border width...
+ // this will mean an extra +1 on all ANGLE_Ys...
+ // left side dark border
+ SelectPen( hdc, hFramePen );
+ MoveToEx(hdc, pTab->left, pTab->bottom, NULL);
+ LineTo(hdc, pTab->left, pTab->top + (ANGLE_Y+1)*yWidth);
+ // left side angle dark border
+ LineTo(hdc, pTab->left + ANGLE_X*xWidth, pTab->top+yWidth);
+ // top dark border
+ LineTo(hdc, pTab->right - ANGLE_X*yWidth, pTab->top+yWidth);
+ // right side angle dark border
+ LineTo(hdc, pTab->right, pTab->top + (ANGLE_Y+1)*yWidth);
+ // right side dark border (overshoot by one)
+ LineTo(hdc, pTab->right, pTab->bottom+yWidth);
+
+ // left side hilite
+ SelectPen( hdc, hHighlightPen);
+ MoveToEx(hdc, pTab->left+xWidth, pTab->bottom, NULL);
+ LineTo(hdc, pTab->left+xWidth, pTab->top+(ANGLE_Y+1)*yWidth);
+ // left side angle hilight
+ LineTo(hdc, pTab->left+ANGLE_X*xWidth, pTab->top+2*yWidth);
+ // top hilite
+ LineTo(hdc, pTab->right-ANGLE_X*xWidth, pTab->top+2*yWidth);
+
+ // right side angle shadow
+ SelectPen( hdc, hShadowPen);
+ LineTo(hdc, pTab->right-xWidth, pTab->top+(ANGLE_Y+1)*yWidth);
+ // right side shadow (overshoot by one)
+ LineTo(hdc, pTab->right-xWidth, pTab->bottom+yWidth);
+
+ // clean above left angle
+ SelectPen( hdc, hBackPen );
+ MoveToEx(hdc, pTab->left, pTab->top+ANGLE_Y*yWidth, NULL );
+ LineTo(hdc, pTab->left+ANGLE_X*xWidth, pTab->top );
+ // clean above top
+ LineTo(hdc, pTab->right-ANGLE_X*xWidth, pTab->top);
+ // clean above right angle
+ LineTo(hdc, pTab->right, pTab->top+ANGLE_Y*yWidth );
+ // clean last corner
+ LineTo(hdc, pTab->right, pTab->top+(ANGLE_Y+1)*yWidth );
+
+ // clean up inside left hilite
+ MoveToEx(hdc, pTab->left+2*xWidth, pTab->bottom, NULL );
+ LineTo(hdc, pTab->left+2*xWidth, pTab->top+(ANGLE_Y+1)*yWidth);
+ // clean up inside left angle hilite
+ LineTo(hdc, pTab->left+ANGLE_X*xWidth, pTab->top+3*yWidth);
+ // clean up inside top hilite (noop)
+ LineTo(hdc, pTab->right-ANGLE_X*xWidth, pTab->top+3*yWidth);
+ // clean up inside right angle shadow (noop)
+ LineTo(hdc, pTab->right-2*xWidth, pTab->top+(ANGLE_Y+1)*yWidth);
+ // clean up inside left hilite (overshoot by one)
+ LineTo(hdc, pTab->right-2*xWidth, pTab->bottom+yWidth);
+
+ // clear out the old label...
+ FillRect( hdc, pText, hBackBrush );
+
+ // now print in the label ...
+ hfOldFont = SelectObject( hdc, pData->hfUnselected );
+ ExtTextOut( hdc,
+ pText->left+ CARAT_X*xWidth + FLUFF_X*xWidth,
+ pText->top + CARAT_Y*yWidth + FLUFF_Y*yWidth + yWidth,
+ 0, NULL, pData->tab[i].label,
+ lstrlen(pData->tab[i].label), NULL );
+ SelectFont( hdc, hfOldFont );
+ }
+ }
+
+ SelectPen( hdc, hOldPen);
+
+ // put the DC we used back into circulation
+ ReleaseDC( hwnd, hdc );
+
+ // tell windows that we're done
+ EndPaint( hwnd, &ps );
+
+ // clean up
+ DeleteObject( hHighlightPen );
+ DeleteObject( hShadowPen );
+ DeleteObject( hFramePen );
+ DeleteObject( hBackPen );
+ DeleteObject( hBackBrush );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_OnSize()
+//
+// Handles requests from windows that we should resize ourselves
+//
+// Input:
+// hwnd - our window handle
+// state - an indication of Minimized, maximized, iconic, blah blah blah
+// cx - our new width
+// cy - our new height
+//
+// Returns:
+// hopefully :)
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+void BookTab_OnSize(HWND hwnd, UINT state, int cx, int cy)
+{
+ // need to update the button size stuff, just for hit testing
+ BookTab_UpdateButtons(hwnd);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_OnSetFocus()
+//
+// Handles windows telling us that we just got the focus
+//
+// Input:
+// hwnd - our window handle
+// hwndOld - the guy who used to have the focus (i don't use)
+//
+// Returns:
+// nyaytay
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+void BookTab_OnSetFocus(HWND hwnd, HWND hwndOldFocus)
+{
+ LPTABDATA pData;
+
+ // get the instance data
+ pData = GetInstanceDataPtr( hwnd );
+
+ // make sure that we are on the bottom
+ SetWindowPos( hwnd, HWND_BOTTOM, 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW );
+
+ // we gotta repaint just the rect for the active tab
+ InvalidateRect( hwnd, &(pData->tab[pData->selected_tab].tab_rect), FALSE );
+ UpdateWindow( hwnd );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_OnKillFocus()
+//
+// Handles windows telling us that we are just about to lose the focus
+//
+// Input:
+// hwnd - our window handle
+// hwndNew - the lucky guy who is about to have the focus (i don't use)
+//
+// Returns:
+// nyaytay
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+void BookTab_OnKillFocus(HWND hwnd, HWND hwndNewFocus)
+{
+ LPTABDATA pData;
+
+ // get the instance data
+ pData = GetInstanceDataPtr( hwnd );
+
+ // we gotta repaint just the rect for the active tab
+ InvalidateRect( hwnd, &(pData->tab[pData->selected_tab].tab_rect), FALSE );
+ UpdateWindow( hwnd );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_OnKey()
+//
+// Handes key messages sent to the control
+//
+// Input:
+// hwnd - our window handle
+// vk - the virtual key code
+// fDown - is the key down?
+// cRepeat - how many times it was pressed
+// flags - i don't use
+//
+// Returns:
+// nada
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+void BookTab_OnKey(HWND hwnd, UINT vk, BOOL fDown, int cRepeat, UINT flags)
+{
+ LPTABDATA pData;
+
+ // get the instance data
+ pData = GetInstanceDataPtr( hwnd );
+
+ // don't want key up messages
+ if( fDown == FALSE )
+ return;
+
+ // we only handle left and right cursor
+ switch( vk )
+ {
+ case VK_LEFT:
+ // move to the tab to the left (wrap if needed)
+ BookTab_OnSetCurSel( hwnd, (pData->selected_tab == 0)?
+ (pData->total_tabs-1):(pData->selected_tab-1));
+
+ // notify our parent that the selection has changed
+ SendMessage( pData->hwndParent, BTN_SELCHANGE,
+ pData->selected_tab, (DWORD)hwnd);
+ break;
+
+
+
+ case VK_RIGHT:
+ BookTab_OnSetCurSel( hwnd,
+ (pData->selected_tab+1) % (pData->total_tabs));
+
+ // notify our parent that the selection has changed
+ SendMessage( pData->hwndParent, BTN_SELCHANGE,
+ pData->selected_tab, (DWORD)hwnd);
+ break;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_OnGetDlgCode()
+//
+// The windows dialog manager is asking us what type of user inputs we want
+//
+// Input:
+// hwnd - our window handle
+// lpmsg - who knows, I don't use it, it's not in the paper docs...
+//
+// Returns:
+// a word which is a bitmap of input types
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+UINT BookTab_OnGetDlgCode(HWND hwnd, MSG FAR* lpmsg)
+{
+ // We just want cursor keys and character keys
+ return( DLGC_WANTARROWS | DLGC_WANTCHARS );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_OnEnable()
+//
+// Windows is telling us that we are being enabled/disabled
+//
+// Input:
+// hwnd - our window handle
+// fEnable - Are we being enabled?
+//
+// Returns:
+// nada
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+void BookTab_OnEnable(HWND hwnd, BOOL fEnable)
+{
+ // BUGBUG - we look no different in either state
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_OnAddItem()
+//
+// Adds an item to the end of the tab list
+//
+// Input:
+// hwnd - our window handle
+// text - the label of the tab to add
+//
+// Returns:
+// the index of the item as added
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+UINT BookTab_OnAddItem( HWND hwnd, LPTSTR text )
+{
+ LPTABDATA pData;
+
+ // get the instance data
+ pData = GetInstanceDataPtr( hwnd );
+
+ // call the worker for insert with the current end of the tab lizst
+ return( BookTab_OnInsertItem( hwnd, pData->total_tabs, text) );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_OnInsertItem()
+//
+// Inserts the given item at the spot indicated and shoves the others down
+//
+// Input:
+// hwnd - our window handle
+// index - the proposed index of the new item
+// text - the label to add to the new tab
+//
+// Returns:
+// the ACTUAL new index of the item (we could sort or have to reduce
+// the initial request if it would leave a gap)
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+UINT BookTab_OnInsertItem( HWND hwnd, UINT index, LPTSTR text)
+{
+ LPTABDATA pData;
+ int i;
+
+ // get the instance data
+ pData = GetInstanceDataPtr( hwnd );
+
+ // make sure that the text will fit
+ if( lstrlen( text ) > MAX_TAB_LABEL_LEN-1 )
+ return (UINT)-1;
+
+ // are we full
+ // BUGBUG, silly limit in the future
+ if( pData->total_tabs >= MAX_TABS )
+ // we can not add at this time
+ return (UINT)-1;
+
+ // make sure that the requested index is within or adjacent to currently
+ // used spots
+ if( index > pData->total_tabs )
+ // change it so that index now points at the next open slot
+ index = pData->total_tabs;
+
+ // slide over all tabs above
+ for( i = (int)pData->total_tabs; i > (int)index; i-- )
+ {
+ memcpy( &(pData->tab[i]), &(pData->tab[i-1]), sizeof( ONETAB) );
+ }
+
+ // your room is ready sir
+ lstrcpy( pData->tab[index].label, text );
+ pData->total_tabs++;
+
+ // should clear the background
+ pData->fUpdate = TRUE;
+
+ return index;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_OnDeleteItem()
+//
+// Deletes the item at the index given and closes up the gaps
+//
+// Input:
+// hwnd - our window handle
+// index - item to be deleted
+//
+// Returns:
+// nuthin'
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+BOOL BookTab_OnDeleteItem( HWND hwnd, UINT index )
+{
+ LPTABDATA pData;
+ UINT i;
+
+ // get the instance data
+ pData = GetInstanceDataPtr( hwnd );
+
+ // make sure that we even have an element like this
+ if( index >= pData->total_tabs )
+ return FALSE;
+
+ // slide all of the deceased successors over
+ for( i = index+1; i < pData->total_tabs; i++ )
+ {
+ memcpy( &(pData->tab[i-1]), &(pData->tab[i]), sizeof( ONETAB) );
+ }
+
+ // reduce the count to account for the deletion
+ pData->total_tabs--;
+
+ // should clear the background
+ pData->fUpdate = TRUE;
+
+ return TRUE;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_OnDeleteAllItems()
+//
+// Genocide on tabs
+//
+// Input:
+// hwnd - our window handle
+//
+// Returns:
+// nothing
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+BOOL BookTab_OnDeleteAllItems( HWND hwnd)
+{
+ LPTABDATA pData;
+
+ // get the instance data
+ pData = GetInstanceDataPtr( hwnd );
+
+ // BUGBUG just set our count to zero
+ pData->total_tabs = 0;
+
+ return TRUE;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_OnSetItem()
+//
+// Sets the title of the booktab given
+//
+// Input:
+// hwnd - our window handle
+// index - the tab to label
+// text - the words to put on the tab
+//
+// Returns:
+// TRUE if successful, else False
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+BOOL BookTab_OnSetItem( HWND hwnd, UINT index, LPTSTR text )
+{
+ LPTABDATA pData;
+
+ // get the instance data
+ pData = GetInstanceDataPtr( hwnd );
+
+ // make sure that the text will fit
+ if( lstrlen( text ) > MAX_TAB_LABEL_LEN-1 )
+ return FALSE;
+
+ // make sure that the index is legal
+ if( index >= pData->total_tabs )
+ return FALSE;
+
+ // set the title
+ lstrcpy( pData->tab[index].label, text );
+
+ // we are changing the size of the tab, we will need to clean out behind
+ pData->fUpdate = TRUE;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_OnGetItem()
+//
+// Retrieves a booktab title
+//
+// Input:
+// hwnd - our window handle
+// index - the tab to label
+// text - the buffer to fill with the tab title
+//
+// Returns:
+// a pointer to the filled buffer if successful, else NULL
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+BOOL BookTab_OnGetItem( HWND hwnd, UINT index, LPTSTR text )
+{
+ LPTABDATA pData;
+
+ // get the instance data
+ pData = GetInstanceDataPtr( hwnd );
+
+ // make sure that the index is legal
+ if( index >= pData->total_tabs )
+ return FALSE;
+
+ // get the title
+ lstrcpy( text, pData->tab[index].label );
+ return( TRUE );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_OnSetCurSel()
+//
+// Sets the current selection
+//
+// Input:
+// hwnd - our window handle
+// newsel - the requested selection
+//
+// Returns:
+// the new current selection
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+UINT BookTab_OnSetCurSel( HWND hwnd, UINT newsel )
+{
+ LPTABDATA pData;
+
+ // get the instance data
+ pData = GetInstanceDataPtr( hwnd );
+
+ // make sure that the requested selection is within the proper bounds
+ if( newsel >= pData->total_tabs )
+ return( pData->selected_tab );
+
+ // make sure that the selection actually changed
+ if( newsel != pData->selected_tab )
+ {
+ // set selection
+ pData->selected_tab = newsel;
+
+ // make us redraw
+ InvalidateRect( hwnd, NULL, FALSE );
+ UpdateWindow( hwnd );
+ }
+
+ return( pData->selected_tab );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_GetCurSel()
+//
+// Retrieves the current selection
+//
+// Input:
+// hwnd - our window handle
+//
+// Returns:
+// the current selection
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+UINT BookTab_OnGetCurSel( HWND hwnd )
+{
+ LPTABDATA pData;
+
+ // get the instance data
+ pData = GetInstanceDataPtr( hwnd );
+
+ // get selection
+ return( pData->selected_tab );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_OnGetItemCount()
+//
+// Retrieves the number of tabs currently in use
+//
+// Input:
+// hwnd - our window handle
+//
+// Returns:
+// the number of tabs in use
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+UINT BookTab_OnGetItemCount( HWND hwnd )
+{
+ LPTABDATA pData;
+
+ // get the instance data
+ pData = GetInstanceDataPtr( hwnd );
+
+ // get the number of tabs
+ return( pData->total_tabs );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_OnSetItemData()
+//
+// Adds a DWORD of data to the data structure for the given tab
+//
+// Input:
+// hwnd - our window handle
+// index - which tab to add data to
+// data - what to add
+//
+// Returns:
+// TRUE if succcessful, else FALSE
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+BOOL BookTab_OnSetItemData( HWND hwnd, UINT index, DWORD data )
+{
+ LPTABDATA pData;
+
+ // get the instance data
+ pData = GetInstanceDataPtr( hwnd );
+
+ // set the instance data
+ pData->tab[index].data = data;
+
+ return TRUE;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_OnPutInBack()
+//
+// Sets the focus to the booktab and then back to whoever had it first,
+// this seemes to put this control in the very back.
+//
+// Input:
+// hwnd - our window handle
+//
+// Returns:
+// <nothing>
+//
+// History
+// Arthur Brooking 1/21/93 created
+//////////////////////////////////////////////////////////////////////////////
+void BookTab_OnPutInBack( HWND hwnd )
+{
+ HWND hwndOldFocus;
+
+ // set the focus to us
+ hwndOldFocus = SetFocus( hwnd );
+
+ // if there was an old focus, set it back to that.
+ if( hwndOldFocus )
+ SetFocus( hwndOldFocus );
+
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_OnGetItemData()
+//
+// Gets the DWORD of data stored in the data structure for the given tab
+//
+// Input:
+// hwnd - our window handle
+// index - which tab to get data from
+//
+// Returns:
+// the stored DWORD
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+DWORD BookTab_OnGetItemData( HWND hwnd, UINT index)
+{
+ LPTABDATA pData;
+
+ // get the instance data
+ pData = GetInstanceDataPtr( hwnd );
+
+ // get the instance data
+ return( (DWORD)pData->tab[index].data );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// IsPointInRect()
+//
+// determines if the point specifier is in the rectangle specified
+//
+// Input:
+// given_x - x coordinate of the point to be tested
+// given_y - y coordinate of the point to be tested
+// pTab - a pointer to the rectangle to test against
+//
+// Returns:
+// True if the point is within the rectangle, False if not
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+BOOL IsPointInRect( int given_x, int given_y, LPRECT pRect )
+{
+ // is it above
+ if( given_y < pRect->top )
+ return FALSE;
+
+ // is it below
+ if( given_y > pRect->bottom )
+ return FALSE;
+
+ // is it to the left
+ if( given_x < pRect->left )
+ return FALSE;
+
+ // is it to the right
+ if( given_x > pRect->right )
+ return FALSE;
+
+ // well, it must be inside
+ return TRUE;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_UpdateButtons()
+//
+// Takes the current data and updates the sizes of the tabs
+//
+// Input:
+// hwnd - our window handle
+//
+// Returns:
+// nuthin
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+void BookTab_UpdateButtons( HWND hwnd )
+{
+ LPTABDATA pData;
+ HDC hdc;
+ SIZE cur_size;
+ RECT total_rect;
+ WORD yWidth;
+ WORD xWidth;
+ UINT left;
+ UINT i;
+ HFONT hfOldFont;
+
+
+ // get the instance data
+ pData = GetInstanceDataPtr( hwnd );
+
+ // preset this so that the MAXes later will work
+ pData->tabs_rect.bottom = 0;
+
+ xWidth = GetSystemMetrics(SM_CXBORDER);
+ yWidth = GetSystemMetrics(SM_CYBORDER);
+ GetClientRect( hwnd, &total_rect);
+ // BUGBUG cheat to see the whole thing
+ total_rect.bottom -= yWidth;
+ total_rect.right -= xWidth;
+
+ hdc = GetDC( hwnd );
+
+ // use the selected font (BOLD) to size the tabs
+ hfOldFont = SelectObject( hdc, pData->hfSelected );
+
+ // loop thru the tabs
+ left = total_rect.left;
+ for( i = 0; i < pData->total_tabs; i++ )
+ {
+ // get the size of the data for this tab
+ GetTextExtentPoint( hdc, pData->tab[i].label,
+ lstrlen( pData->tab[i].label), &cur_size);
+
+ // calculate the text rectatangle first ...
+ // the text top is down the size of the angle
+ pData->tab[i].text_rect.top = total_rect.top + ANGLE_Y*yWidth;
+
+ // the text left is over the size of the angle
+ pData->tab[i].text_rect.left = left + ANGLE_X*xWidth;
+
+ // the text bottom is down from the top the size of the text +
+ // 2x the fluff(top and bottom) + 2x the carat space
+ pData->tab[i].text_rect.bottom = pData->tab[i].text_rect.top +
+ cur_size.cy + 2*FLUFF_Y*yWidth + 2*CARAT_Y*yWidth;
+
+ // the text right is over from the left the size of the text +
+ // 2x the fluff(left and right) + 2x the carat space
+ pData->tab[i].text_rect.right = pData->tab[i].text_rect.left +
+ cur_size.cx + 2*FLUFF_X*xWidth + 2*CARAT_X*xWidth;
+
+
+ // then calculate the full tab rectangle
+ // the tab top is the top of the control
+ pData->tab[i].tab_rect.top = total_rect.top;
+
+ // the left side of the tab is next to the previous right
+ pData->tab[i].tab_rect.left = left;
+
+ // the tab bottom is down the footroom from the text bottom
+ pData->tab[i].tab_rect.bottom = pData->tab[i].text_rect.bottom +
+ FOOTROOM_Y*yWidth;
+
+ // the tab right is over the size of the angle from the text right
+ pData->tab[i].tab_rect.right = pData->tab[i].text_rect.right +
+ ANGLE_Y*yWidth;
+
+ // set the left for the next guy to be our right
+ left = pData->tab[i].tab_rect.right;
+
+ // set the bottom of the all tabs rectangle
+ pData->tabs_rect.bottom = max( pData->tabs_rect.bottom,
+ pData->tab[i].tab_rect.bottom);
+
+ // BUGBUG check for run off the side
+ }
+
+ // set the rest of the cumulative tabs rect
+ pData->tabs_rect.top = total_rect.top;
+ pData->tabs_rect.right = total_rect.right;
+ pData->tabs_rect.left = total_rect.left;
+ // BUGBUG why
+ pData->tabs_rect.bottom++;
+
+ // reset the font
+ SelectObject( hdc, hfOldFont );
+
+ // free up the resources used
+ ReleaseDC( hwnd, hdc );
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+// BookTab_()
+//
+//
+//
+// Input:
+// hwnd - our window handle
+//
+// Returns:
+//
+//
+// History
+// Arthur Brooking 8/06/93 created
+//////////////////////////////////////////////////////////////////////////////
+