⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 easytab.c

📁 基于Labwindows的电池故障诊断系统
💻 C
📖 第 1 页 / 共 5 页
字号:
#include <cvidef.h>
#if _NI_mswin32_
#include <windows.h>
#endif /* _NI_mswin32 */
#include <utility.h>
#include <userint.h>
#include "toolbox.h"
#include "easytab.h"

#define TABBUTTON_ACTIVE_EXTRA_TOP      2   /* tab is made larger when active */
#define TABBUTTON_ACTIVE_EXTRA_LEFT     2   
#define TABBUTTON_ACTIVE_EXTRA_RIGHT    2   

#define TABBUTTON_LEFT_MARGIN           6
#define TABBUTTON_RIGHT_MARGIN          6
#define TABBUTTON_TOP_MARGIN            3
#define TABBUTTON_BOTTOM_MARGIN         2

#define CLIENT_LEFT_FRAME_WIDTH         1
#define CLIENT_RIGHT_FRAME_WIDTH        2
#define CLIENT_TOP_FRAME_WIDTH          1
#define CLIENT_BOTTOM_FRAME_WIDTH       2
#define CLIENT_VERTICAL_FRAME_WIDTH     (CLIENT_TOP_FRAME_WIDTH + CLIENT_BOTTOM_FRAME_WIDTH)
#define CLIENT_HORIZONTAL_FRAME_WIDTH   (CLIENT_LEFT_FRAME_WIDTH + CLIENT_RIGHT_FRAME_WIDTH)

#define CLIENT_MIN_WIDTH                1
#define CLIENT_MIN_HEIGHT               1

#define EASY_TAB_SIGNATURE              CAT4CHARS('T', 'G', 'R', 'P')
#define SHEET_SIGNATURE                 CAT4CHARS('S', 'H', 'E', 'T')
#define TAB_BUTTON_SIGNATURE            CAT4CHARS('T', 'B', 'U', 'T')

#define THREAD_SLEEP_TIME               10L

#define ATTR_EASY_TAB_OVERRIDE_CTRL_ACTIVATION_POLICY   13000


typedef struct  /* for virtual tab-order lists */
    {
    int panel;          /* panel of the control */
    int ctrl;           /* a control in the tab list */
    int isTabStop;      /* TRUE if this control can be tabbed to */
    } TabOrderEntry;
    
typedef struct TabButtonStruct  /* object which represent the visual appearance of a tab button */
    {
    int                 signature;              /* debugging aid */   
    struct SheetStruct  *sheet;                 /* the sheet that owns this tab button */
    char                *label;                 /* CString that holds the given text for the buttons label */
    char                *displayLabel;          /* CString that holds the display text for the buttons label (same as label except double underlines have been removed) */
    Point               labelSize;              /* the width of the text in pixels given the owning groups current font */
    Point               minSize;                /* the minimum height and width the tab button can have given its label text and font */
    Rect                activeBounds;           /* in canvas coordinates */
    Rect                inactiveBounds;         /* in canvas coordinates */
    char                acceleratorKey;         /* 0 if button does not have an underline accelerator */
    int                 underlineOffset;        /* number of pixels from the start of the displayed label to the start of the accelerator underline */
    int                 underlineWidth;         /* how wide the accelerator underline is in pixels */
    int                 bitmap;                 /* bitmap image of text */
    int                 dimmed;                 /* true if dimmed */
    int                 tabColor;               /* the color of the tab */
    }   *TabButton;

typedef struct  SheetStruct     /* object which represents a tab sheet in a tab group */
    {
    int                     signature;          /* debugging aid */
    int                     panel;              /* panel that holds the controls, may be same as dialog panel */
    int                     ownsPanel;          /* TRUE if the sheet owns a child panel that contains the sheets controls */
    TabButton               tabButton;          /* the tab button for this sheet */
    int                     originalRow;        /* which row is the tab on (1-based, starting from the top) */
    struct TabGroupStruct   *group;             /* owner of this sheet */
    ListType                ctrlList;           /* controls on this sheet if ownsPanel == FALSE */
    int                     activatePanelWhenShown;  /* if TRUE, the panel of this sheet is activated the next time the group is redrawn, used to postpone panel activation since it can cause premature drawing */
    int                     originalWidth;      /* width of the panel when it was added to the group */
    int                     originalHeight;     /* height of the panel when it was added to the group */
    int                     hidden;             /* true if button for sheet is to be hidden */
    } *Sheet;

typedef struct TabGroupStruct   /* object which represents a group of tab sheets */
    {
    int                 signature;              /*  debugging aid */
    int                 dialogPanel;            /*  panel on which this tab dialog lives */
    struct SheetStruct  *activeSheet;           /*  which sheet is the active sheet */
    ListType            sheetList;              /*  list of sheets in this tab dialog */
    ListType            rowLists;               /*  list of lists of sheets on each row (currently displayed rows, not the rows the sheets were created on) */
    int                 canvas;                 /*  canvas to draw tab buttons on */
    Rect                originalCanvasRect;     /*  rect of the canvas when it was converted to a tab ctrl */
    Rect                frameRect;              /*  client area frame bounding box in panel coordinates (surrounds the client area) */
    Rect                clientRect;             /*  dialog area in panel coordinates, tab buttons appear above this */
    Rect                exteriorRect;           /*  canvas area in panel coordinates, dialog area, frame, and tab buttons appear within this */
    int                 sizeButtonsToFillRows;  /*  if TRUE, buttons stretch to fit all the available space */
    int                 tabButtonPositionsCalculated;   /* if FALSE, the tab button sizes need to be calculated */
    int                 canvasSetup;            /*  if FALSE, the canvas needs to be sized, etc.. */
    Rect                tabButtonBoundsUnion;   /*  in canvas coordinates */
    Rect                tabButtonEraseArea;     /*  same as tabButtonBoundsUnion, with a little extra to account for the widening of buttons when they become active */
    int                 displayInvalidated;     /*  if TRUE, the group is waiting for a pending deferred callback which was posted in to redraw the group */
    int                 textColor;              /*  color of the text in the Tab buttons (RGB) */
    int                 sizeHasBeenSet;         /*  TRUE if the size of the tab group has ever been explicitly set. */
    int                 buttonPosition;         /*  indicates where the tab buttons are in relation to the client area */
    int                 buttonGap;              /*  gap between tab buttons (-1 means use a much gap as possible if sizeButtonsToFillRows is TRUE) */
    char                metaFont[256];          /*  the font used to draw the text on the tab buttons */
    int                 hidden;                 /*  TRUE if the entire tab control is hidden */
    int                 bgColor;                /*  color for background of tabGroup (defaults to the panel background color of the panel holding the tabGroup ctrl), 
                                                    VAL_TRANSPARENT is the only other "reasonable" value, but it makes drawing slower */
    int                 valid;                  /* Tells if the lock is good. */
    int                 lockHandle;
    int                 overrideActivation;     /* if TRUE, easytab never activates the first control when switching tabs */
    } *TabGroup;
    
    /*  Add thread local variables here */
typedef struct
    {
    int    bitmapPanel;
    int    bitmapCanvas;        
    int    ctrlWasClicked;
    } threadLocalVars;

static TabButton    TabButton_Create(Sheet sheet, const char *label);
static void         TabButton_Dispose(TabButton tabButton);
static void         TabButton_GetMinBounds(TabButton tabButton, int active, Rect *r);
static void         TabButton_SetBounds(TabButton tabButton, Rect r);
static int          TabButton_SetLabel(TabButton tabButton, const char *label);
static void         TabButton_Draw(TabButton tabButton, int drawActive, int drawFocus);
static void         TabButton_DrawText(TabButton tabButton, int panel, int canvas, Point textPosition);
static void         TabButton_DrawLabel(TabButton tabButton, Rect bounds);
static int          TabButton_HasFocus(TabButton tabButton);
static int          TabButton_CreateTextBitmap(TabButton tabButton);
static int          TabButton_GetTextCanvas(int *panel, int *canvas, Point size);


static int          Sheet_Create(TabGroup group, int sheetPanel, int row, const char *label, ListType ctrlList, Sheet *sheet);
static void         Sheet_Dispose(Sheet sheet);
static void         Sheet_Remove(Sheet sheet);
static void         Sheet_ActivateFirstCtrl(Sheet sheet);
static int CVICALLBACK Sheet_PanelCallback (int panel, int event, void *callbackData, int eventData1, int eventData2);

static int          EasyTab_CreateFromCanvas(int panel, int canvas);
static void         EasyTab_Dispose(TabGroup group, int disposeCanvas);
static Sheet        EasyTab_IndexToSheet(TabGroup group, int index);
static int          EasyTab_SheetToIndex(TabGroup group, Sheet sheet);
static Sheet        EasyTab_PanelToSheet(TabGroup group, int panel);
static int          EasyTab_NumSheets(TabGroup sheetGroup);
static int          EasyTab_CalculateTabSizes(TabGroup group);
static void         EasyTab_FreeRowLists(TabGroup group);
static int          EasyTab_CalculateNumRows(TabGroup group);
static int          EasyTab_IdToGroup(int panel, int groupCanvas, TabGroup *group);
static int CVICALLBACK EasyTab_CanvasCallback (int panel, int control, int event, void *callbackData, int eventData1, int eventData2);
static int CVICALLBACK EasyTab_PanelCallback (int panel, int event, void *callbackData, int eventData1, int eventData2);
static Sheet        EasyTab_GetActive(TabGroup sheetGroup);
static void         EasyTab_ActivateHorizontalNeighbor(TabGroup group, int previous, int wrap);
static void         EasyTab_ActivateVerticalNeighbor(TabGroup group);
static void         EasyTab_SetActive(TabGroup group, Sheet activeSheet);
static int          EasyTab_Draw(TabGroup group);
static void         EasyTab_DrawTabButtons(TabGroup group);
static int          EasyTab_HasFocus(TabGroup group);
static void         EasyTab_SetFocus(TabGroup group);
static Rect         EasyTab_CtrlsBoundsUnion(TabGroup group);   
static Rect         EasyTab_PanelBoundsUnion(TabGroup group, int sizeOnly, int useOriginalPanelSizes);
static int          EasyTab_SetClientRect(TabGroup group, Rect clientRect);
static Rect         EasyTab_GetClientRect(TabGroup group);
static Rect         EasyTab_GetExteriorRect(TabGroup group);
static int          EasyTab_SetExteriorRect(TabGroup group, Rect exteriorRect);
static void         CVICALLBACK EasyTab_UpdateDisplay(void *callbackData);
static void         EasyTab_InvalDisplay(TabGroup group);
static void         EasyTab_InvalRowLists(TabGroup group);
static void         EasyTab_InvalTabPositions(TabGroup group);
static void         EasyTab_InvalAll(TabGroup group);
static void         EasyTab_InvalCanvasSetup(TabGroup group);
static ListType     EasyTab_GetRowLists(TabGroup group);
static void         EasyTab_SetupCanvas(TabGroup group);
static int          EasyTab_CalcMinButtonArea(TabGroup group, int *minHeight, int *minWidth);
static TabButton    EasyTab_TabButtonAtPoint(TabGroup group, Point p);
static void         EasyTab_HandleLeftClick(TabGroup group, Point p);
static void         EasyTab_DrawFrame(TabGroup group);
static int          EasyTab_CalculateMinClientWidth(TabGroup group, int *minWidth);
static Rect         EasyTab_GetAutoSizeRect(TabGroup group, int makeRoomForButtons);
static int          EasyTab_HandleNavigationKeys(TabGroup group, int key, int *callbackReturnVal);
static int          EasyTab_HandleAcceleratorKey(int key, int *callbackReturnVal);
static Sheet        EasyTab_AccelKeyToSheet(TabGroup group, int key);
static int          EasyTab_AddSheetFromParmInfo(int panel, int easyTabCtrl, const char *sheetName, void *module, int row, int numCtrls, va_list parmInfo);
static void         EasyTab_SetTextColorToDefault(TabGroup group);
static int          EasyTab_CheckButtonPosition(int buttonPosition);
static int          EasyTab_ResetLabels(TabGroup group);
static int          EasyTab_GetSheetDisplayPosition(TabGroup group, Sheet sheet, int *row, int *column);
static void         EasyTab_MoveActiveRowToEnd(TabGroup group);
static void         EasyTab_InvalDisplayForPanel(int panel);
static Sheet        EasyTab_GetVisibleInactiveSheet(TabGroup group);
static int          EasyTab_SetInactive(TabGroup group, Sheet sheet);
static int          EasyTab_NumVisibleTabsOnRow(TabGroup group, int rowIndex);
static int          EasyTab_CtrlCanBeTabStop(int panel, int ctrl);


static ListType     GetVirtualTabOrder(int panel, int tabGroupsOnly);
static int          AddToVirtualTabOrder(int panel, ListType list, int tabGroupsOnly);
static int          HandleTabKey(int key, int *callbackReturnVal);
static int          GetVirtualTabTopLevelPanel(int panel);
static int          NextVirtualTabStop(int panel, int ctrl, int tabbingForward, int wrap, TabOrderEntry *entry);
static void         InstallActivationHooks(int panel, int install);

static void         DrawRectFrameWithFill(int panel, int canvas, Rect r);
static int          CreateTransparentOneColorBitmap(int *pixels, int color, int height, int width, int *bitmap);
static int          RotatePixels90Degrees(int **pixels, int *height, int *width, int rotateLeft);
static int          IsSheetPanel(int panel) ;

static void CVIFUNC InitializeMultithreadingIfNecessary(void);
static void CVIANSI UninitializeMultithreadingProcedure(void);

static int          gThreadLocalHandle     = 0;

/*************************************************************/

static void CVIFUNC InitializeMultithreadingIfNecessary(void)
{
    static int sMultithreadingInitDone = 0;       /* Multithreading has already been initialized */
    static int sMultithreadingInitNow  = 0;       /* Thread local is currently being initialized. */
    int prev = 0;
    
    /* Check if already been initialized, if not, do so now. */
    if (!sMultithreadingInitDone)
        {
        prev = InterlockedExchange(&sMultithreadingInitNow, 1);
        if (prev)                                   /* If it is initialized or is in the process of initializing. */
            {
            while (!sMultithreadingInitDone)        /* Wait until the thread initializing the multithreading finishes */
                Sleep(THREAD_SLEEP_TIME);
            }
        else
            {
            CmtNewThreadLocalVar (sizeof(threadLocalVars),
                                  (void *)NULL, NULL, NULL,
                                  &gThreadLocalHandle);
            atexit(UninitializeMultithreadingProcedure);
            sMultithreadingInitDone = 1;
            }
        }
}
                                                                             
/*************************************************************/

static void CVIANSI UninitializeMultithreadingProcedure(void)
{
    /* This function used to call CmtDiscardThreadLocalVar.
       That is a problem:  This may be in a DLL which is being dynamically
       unloaded by a program.  We also added the check for
       CVIRTEHasBeenDetached, which is a new function in CVI 5.0.
    */
    if (!CVIRTEHasBeenDetached())
        {
        if (gThreadLocalHandle)
            CmtDiscardThreadLocalVar (gThreadLocalHandle);
        }
}

/*************************************************************/

static void FreeListOfLists(ListType listOfLists)
{
    int         index;
    ListType    list;
    int         numLists;
    
    if (listOfLists)
        {
        numLists = ListNumItems(listOfLists);
        
        for (index = 1; index <= numLists; index++)
            {
            ListGetItem(listOfLists, &list, index);
            ListDispose(list);
            }
        
        ListDispose(listOfLists);
        }
}

/*************************************************************/

static void EasyTab_InvalRowLists(TabGroup group)
{
    EasyTab_FreeRowLists(group);
}

/*************************************************************/

static void EasyTab_FreeRowLists(TabGroup group)
{
    FreeListOfLists(group->rowLists);
    group->rowLists = NULL;
}

/*************************************************************/

static int EasyTab_CalculateNumRows(TabGroup group)
{
    int     index;
    int     numSheets;
    int     numRows = 0;
    Sheet   sheet;
    
    numSheets = EasyTab_NumSheets(group);   
    for (index = 1; index <= numSheets; index++)
        {
        ListGetItem(group->sheetList, &sheet, index);
        numRows = Max(numRows, sheet->originalRow);
        }
        
    return numRows;
}

/*************************************************************/

    /*  Build a list of lists of the sheets in each tab button row.  The row member
        of a sheet determines its row, and its order in the groups sheet lists 
        determines its order respect to other sheets in the same row.
        
        Note: The active row (if any) is alway moved to the end of the list so it
        appears at the bottom.
    */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -