📄 toolbox.c
字号:
/*============================================================================*//* L a b W i n d o w s / C V I *//*----------------------------------------------------------------------------*//* Copyright (c) National Instruments 1987-1996. All Rights Reserved. *//*----------------------------------------------------------------------------*//* *//* Title: toolbox.c *//* Purpose: provides commonly useful functions *//* *//*============================================================================*/#include <ansi_c.h>#include <userint.h>#include <utility.h>#include <formatio.h>#if _NI_mswin16_ || _NI_mswin32_#include <easyio.h>#endif /* _NI_mswin16 || _NI_mswin32_ */#include "toolbox.h"typedef struct ListStructTag { int signature; /* debugging aid */ int percentIncrease; /* %of current size to increase by when list is out of space */ int minNumItemsIncrease; /* fixed number of items to increase by when list is out of space */ int listSize; /* number of items than can fit in the currently allocated memory */ int itemSize; /* the size of each item in the list (same for every item) */ int numItems; /* number of items currently in the list */ unsigned char itemList[1]; /* resizable array of list elements */ } ListStruct;#define kDefaultAllocationPercentIncrease 10 /* increase list size by 10% every time it is full */#define kDefaultAllocationminNumItemsIncrease 4 /* always increase list size by 4 items when it is full */ /* how many items to expand the list by when it becomes full = current listSize (in items) + (hiword percent of list size) + loword */#define NUMITEMSPERALLOC(list) Max(((*list)->listSize * ((*list)->percentIncrease + 100)) / 100 , (*list)->minNumItemsIncrease)#define ITEMPTR(list, item) &(((char *)(void *)&(*list)->itemList)[ (*(list))->itemSize * (item)])#define LIST_SIGNATURE CAT4CHARS('L', 'I', 'S', 'T');#define MOUSE_EVENTS_SIGNATURE CAT4CHARS('M', 'E', 'V', 'T');typedef struct { void *ptr; unsigned int size; } HandleRecord;typedef struct { int signature; /* debug help, makes this structure identifiable in Dynamic Memory Display */ char *type; /* copy of type string passed to ChainCtrlCallback(), example "DAQChart", or "DAQNumeric", or "Button With Right Click Help", etc... */ void *callbackData; /* callback data passed in to ChainCtrlCallback */ CtrlCallbackPtr callback; /* callback function passed in to ChainCtrlCallback */ void *previousCallbackData; /* if previously linked, this a ptr to the previous link structure */ CtrlCallbackPtr previousCallback; /* if previously linked, this is LinkedCtrlCallback() */ } *CtrlCallbackChainLink;typedef struct { int signature; /* debug help, makes this structure identifiable in Dynamic Memory Display */ char *type; /* copy of type string passed to ChainPanelCallback() */ void *callbackData; /* callback data passed in to ChainPanelCallback */ PanelCallbackPtr callback; /* callback function passed in to ChainPanelCallback */ void *previousCallbackData; /* if previously linked, this a ptr to the previous link structure */ PanelCallbackPtr previousCallback; /* if previously linked, this is LinkedPanelCallback() */ } *PanelCallbackChainLink; /* For adding extra mouse events to a control (see EnableExtendedMouseEvents) */typedef struct { int signature; /* debug help, makes this structure identifiable in Dynamic Memory Display */ int panel; /* owning panel of the ctrl receiving extended mouse events */ int ctrl; /* the control receiving extended mouse events */ int rightButtonDown; /* was the right button down the last time we checked? */ int leftButtonDown; /* was the left button down the last time we checked? */ int dispose; /* set to TRUE when the control is discarded, causes this struct to be discarded on the next delayed callback */ int lastX, lastY; /* mouse position the last time we checked */ double minPeriod; /* min time between mouse events */ int enabled; /* TRUE if extended mouse events are currently enabled for the control */ } *MouseEventsInfo; /********************/ /* Static Functions */ /********************/static int CVICALLBACK ListMemBlockCmp(void *a, void *b, int size);static void CVIFUNC FilterDownToCorrectHeapPosition(void *array, int numElements, int elementSize, CompareFunction compareFunction);static void CVIFUNC FilterUpToCorrectHeapLocation(void *array, int index, int elementSize, CompareFunction compareFunction);static void CVIFUNC BuildHeap(void *array, int numElements, int elementSize, CompareFunction compareFunction);static int CVIFUNC SetIntAttributeForCtrlsInCtrlList(int panel, int attribute, int value, int numCtrls, ListType ctrlList);static int CVIFUNC IsTBBoundsAttr(int attribute);static void CVIFUNC InterleavePartialLastScan(void *list, int itemSize, int numChannels, int numScans, int numItems);static void CVIFUNC TransposeDataInPlace(void *list, int itemSize, int numPoints, int numChannels);static int CVIFUNC ConvertNumStrToUint (char *str, unsigned long *n, int *negative);static int CVICALLBACK ProgressCancelCallback(int panel, int ctrl, int event, void *callbackData, int eventData1, int eventData2);static int CVIFUNC InternationalTimeString(time_t rawTime, char timeString[], int bufferSize);static int CVIFUNC InternationalDateString(time_t rawTime, char dateString[], int bufferSize);static void CVIANSI ToolBoxAtExitFunction(void);static double CVIFUNC GetRand(void);static int CVICALLBACK LinkedCtrlCallback(int panel, int control, int event, void *callbackData, int eventData1, int eventData2);static int CVIFUNC FindCtrlCallbackLink(int panel, int ctrl, char *type, CtrlCallbackChainLink *link);static int CVIFUNC GetOriginalCtrlCallbackData(int panel, int ctrl, void **callbackData);static void CVIFUNC InstallObjectDeletionProcedure(void);static void CVIANSI ObjectDeletionProcedure(void);static int CVIANSI RecordPanelWithLinkedCallback(int panel);static void CVIANSI UnrecordPanelWithLinkedCallback(int panel);static int CVICALLBACK ComparePanelToPnlWthLnkdCbksRec(void *ptrToItem, void *listItemPtr);static int CVIANSI GetPanelWithLinkedCallbackByIndex (int index, int *panel);static void CVIANSI DestroyPanelsWithLinkedCallbacksList(void);static int CVICALLBACK LinkedPanelCallback(int panel, int event, void *callbackData, int eventData1, int eventData2);static int CVIFUNC FindPanelCallbackLink(int panel, char *type, PanelCallbackChainLink *link);static int CVIFUNC GetOriginalPanelCallbackData(int panel, void **callbackData);static int CVIFUNC LastCtrl(int panel);static int CVIFUNC NextCtrl(int panel, int ctrl, int wrap);static void CVIFUNC MouseEvents_Check(MouseEventsInfo info);static int CVICALLBACK MouseEventsCallback (int panel, int control, int event, void *callbackData, int eventData1, int eventData2);static void CVICALLBACK MouseEvents_CheckCallback(void *callbackData);static char * CVIFUNC ToolBox_GetDAQErrorString (short int error);static char * CVIFUNC ToolBox_InternalGetDAQErrorString (short int error);static void CVIFUNC QSort(char * a, long n, long es, CompareFunction theCmp);/********************************************************************/#pragma warning(disable: 4761) /* floating point comparison with a tolerance to compensate for the inability to exactly represent some numbers */ /* returns -1 if a < b, 0 if a == b, and 1 if a > b */int CVIFUNC FP_Compare(double a, double b){ if (FP_EQ(a,b)) return 0; else if (FP_GT(a,b)) return 1; else return -1;}/********************************************************************/ /* floating point comparison with a tolerance to compensate for the inability to exactly represent some numbers */int CVIFUNC FP_EQ(double a, double b) /* is a == b */{ double tmp; if(b == 0) tmp= a; else tmp= a/b - 1; if(tmp < FP_CompareEpsilon && tmp > -FP_CompareEpsilon) if (ABS_VAL(a-b) < FP_CompareEpsilon) return TRUE; return FALSE;}/********************************************************************/ /* floating point comparison with a tolerance to compensate for the inability to exactly represent some numbers */int CVIFUNC FP_GT(double a, double b) /* is a > b */{ double tmp; int reply; if(b == 0) reply= (a > 0); else if(a == 0) reply= (b < 0); else { tmp= a/b; if(tmp > 0 && (ABS_VAL(a-b) <= FP_CompareEpsilon)) /* both neg, or both pos */ { if(b > 0) reply= (tmp - 1 >= FP_CompareEpsilon); else reply= (tmp - 1 <= -FP_CompareEpsilon); } else reply= a > b; } return reply;}/********************************************************************/ /* floating point comparison with a tolerance to compensate for the inability to exactly represent some numbers */int CVIFUNC FP_GE(double a, double b) /* is a >= b */{ double tmp; int reply; if(b == 0) reply= (a >= 0); else if(a == 0) reply= (b <= 0); else { tmp= a/b; if(tmp > 0 && (ABS_VAL(a-b) <= FP_CompareEpsilon)) /* both neg, or both pos */ { if(b > 0) reply= (tmp - 1 > -FP_CompareEpsilon); else reply= (tmp - 1 < FP_CompareEpsilon); } else reply= a > b; } return reply;}/********************************************************************/ /* floating point comparison with a tolerance to compensate for the inability to exactly represent some numbers */int CVIFUNC FP_LT(double a, double b) /* is a < b */{ return FP_GT(b, a);}/********************************************************************/ /* floating point comparison with a tolerance to compensate for the inability to exactly represent some numbers */int CVIFUNC FP_LE(double a, double b) /* is a <= b */{ return FP_GE(b, a);}/********************************************************************/double CVIFUNC Pin(double value, double low, double high){ if (value < low) return low; else if (value > high) return high; else return value;}/********************************************************************/static unsigned gRandomSeed = 0x38589391;static int gReSeed = TRUE;double CVIFUNC Random(double minimum, double maximum){ double range = maximum - minimum; if (range < 0) return minimum; else return minimum + GetRand() * range;}/*******************************************************/void CVIFUNC SetRandomSeed(unsigned long seed){ if (seed) gRandomSeed = seed; else do { gRandomSeed = clock(); } while (!gRandomSeed); /* make sure we don't somehow get zero, since that would cause an infinite loop */ gReSeed = TRUE;}/*******************************************************/static double CVIFUNC GetRand(void){ double randNum; static double numJ, numK, numH; static long seedX, seedY, seedZ; if (gReSeed) { gReSeed = FALSE; seedX = 0; } while(!seedX) { seedX = gRandomSeed & 0x3FFF; seedY = (seedX * 8191) & 0x3FFF; seedZ = (seedY * 8191) & 0x3FFF; numJ = 1.0 / 30269.0; numK = 1.0 / 30307.0; numH = 1.0 / 30323.0; } seedX = (171 * seedX) % 30269; seedY = (172 * seedY) % 30307; seedZ = (170 * seedZ) % 30323; randNum = seedX * numJ + seedY * numK + seedZ * numH; randNum -= floor(randNum); if(randNum < 0) randNum += 1.0; /* if floor does a Round To Nearest */ return randNum;}/********************************************************************/void CVIFUNC ConvertArrayType(void * sourceArray, int sourceDataType, void * targetArray, int targetDataType, int numberOfPoints){ int i; double temp; for (i=0; i < numberOfPoints; i++) /* watcom will optimize out the indexing overhead */ { switch (sourceDataType) { case VAL_CHAR: temp = ((char *)sourceArray)[i]; break; case VAL_INTEGER: temp = ((int *)sourceArray)[i]; break; case VAL_SHORT_INTEGER: temp = ((short int *)sourceArray)[i]; break; case VAL_FLOAT: temp = ((float *)sourceArray)[i]; break; case VAL_DOUBLE: temp = ((double *)sourceArray)[i]; break; case VAL_UNSIGNED_SHORT_INTEGER: temp = ((unsigned short *)sourceArray)[i]; break; case VAL_UNSIGNED_INTEGER: temp = ((unsigned int *)sourceArray)[i]; break; case VAL_UNSIGNED_CHAR: temp = ((unsigned char *)sourceArray)[i]; break; } switch (targetDataType) { case VAL_CHAR: ((char *)targetArray)[i] = (char)temp; break; case VAL_INTEGER: ((int *)targetArray)[i] = (int)temp; break; case VAL_SHORT_INTEGER: ((short *)targetArray)[i] = (short)temp; break; case VAL_FLOAT: ((float *)targetArray)[i] = (float)temp; break; case VAL_DOUBLE: ((double *)targetArray)[i] = temp; break; case VAL_UNSIGNED_SHORT_INTEGER: ((unsigned short *)targetArray)[i] = (unsigned short)temp; break; case VAL_UNSIGNED_INTEGER: ((unsigned int *)targetArray)[i] = (unsigned int)temp; break; case VAL_UNSIGNED_CHAR: ((unsigned char *)targetArray)[i] = (unsigned char)temp; break; } }}/********************************************************************/void CVIFUNC DoAssert(int passed, char *fileName, int line, char *msg){ extern void CVIFUNC_C _UPLibReportError(long, long, ...); if (!passed) { char buf[256]; sprintf(buf, "Assert!\n\n%s\n\nThe error was detected on line %d of file '%s'.\n\nProgram aborting.", msg ? msg : "Programming error detected.", line, fileName); MessagePopup("Assert", buf); abort(); }}/********************************************************************/ /* Binary search numElements of size elementSize in array for a match to the. item. Return the index of the element that matches (0 - numElements - 1). If no match is found return the -i-1 where i is the index (0 - numElements) where the item should be placed. (*theCmp)(a,b) should return <0 if a<b, 0 if a==b, >0 if a>b. This function is like the C-Library function bsearch() except that this function returns the index where the item should be placed if it is not found. */int CVIFUNC BinSearch(void *array, int numElements, int elementSize, void *itemPtr, CompareFunction compareFunction){ int low, high, mid, cmp; void *arrayItemPtr; for(low=0, high= numElements-1, mid=0, cmp= -1; low <= high; ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -