?? mylib.cpp
字號:
// mylib.cpp
#include "stdafx.h"
// ------------------------ CalcCRC (Local Generic) --------------------------------------
// PURPOSE: Calculates a CRC value.
// It is the responsibility of the caller of this routine to make sure
// that crc = 0xFFFF if a crc has to be calculated for a new buffer.
//
LONG CalcCRC( BYTE * crcStartPtr, // ->
DWORD buffLen, // ->
WORD * crc // <->
)
{
BYTE * bufferTop = crcStartPtr + buffLen;
BYTE * crcBuffPtr = crcStartPtr; // Get our own private copy of ptr
WORD i;
while(crcBuffPtr < bufferTop)
{
*crc = (WORD)(*crc & 0xff00) + (*(BYTE *)crcBuffPtr ^ LOBYTE(*crc));
for(i=0 ; i<8 ; i++)
{
if( (*crc & 0x0001) == TRUE )
*crc = (*crc >> 1) ^ 0xA001;
else
*crc = (*crc >> 1);
}
crcBuffPtr++;
}
return(SUCCESS);
} // CalcCRC
// ------------------------ CalcLRC (Local Generic) --------------------------------------
// PURPOSE: Calculates a CRC value.
// It is the responsibility of the caller of this routine to make sure
// that crc = 0xFFFF if a crc has to be calculated for a new buffer.
//
LONG CalcLRC(BYTE * lrcBuffPtr, // -> pointer to buffer at start of LRC
DWORD buffLen, // ->
BOOL calc2Comp, // -> Calculate 2's Complement also (last call)
BYTE * lrc // <->
)
{
// Allows us to keep calling CalcLRC for each part of the message
// and only do 2's compliment when buffLen == 0
// Add all bytes in buffer
while(buffLen--)
{
*lrc += *lrcBuffPtr++;
}
if(calc2Comp)
*lrc = ~(*lrc) + 1; // 2's compliment
return(SUCCESS);
} // CalcLRC
// --------------------------- EnumerateSerialPorts -----------------------------
// PURPOSE: Retrieve hardware configuration from registry instead of letting
// the user guess what ports he has available.
//
LONG EnumerateSerialPorts (char *deviceName, DWORD maxLen, DWORD index)
{
CHAR RegPath[MAX_PATH] = "HARDWARE\\DEVICEMAP\\SERIALCOMM";
HKEY hKey;
HKEY hKeyRoot = HKEY_LOCAL_MACHINE;
DWORD retCode;
CHAR ClassName[MAX_PATH] = ""; // Buffer for class name.
DWORD dwcClassLen = MAX_PATH; // Length of class string.
DWORD dwcSubKeys; // Number of sub keys.
DWORD dwcMaxSubKey; // Longest sub key size.
DWORD dwcMaxClass; // Longest class string.
DWORD dwcValues; // Number of values for this key.
CHAR valueName[MAX_VALUE_NAME] ;
DWORD dwcValueName = MAX_VALUE_NAME;
DWORD dwcMaxValueName; // Longest Value name.
DWORD dwcMaxValueData; // Longest Value data.
DWORD dwcSecDesc; // Security descriptor.
FILETIME ftLastWriteTime; // Last write time.
DWORD dwType;
DWORD retValue;
DWORD cbData;
// Use RegOpenKeyEx() with the new Registry path to get an open handle
// to the child key you want to enumerate.
retCode = RegOpenKeyEx (hKeyRoot,
RegPath,
0,
KEY_ENUMERATE_SUB_KEYS |
KEY_EXECUTE |
KEY_QUERY_VALUE,
&hKey);
if (retCode != ERROR_SUCCESS)
return(FAILED);
// Get Class name, Value count.
RegQueryInfoKey ( hKey, // Key handle.
ClassName, // Buffer for class name.
&dwcClassLen, // Length of class string.
NULL, // Reserved.
&dwcSubKeys, // Number of sub keys.
&dwcMaxSubKey, // Longest sub key size.
&dwcMaxClass, // Longest class string.
&dwcValues, // Number of values for this key.
&dwcMaxValueName, // Longest Value name.
&dwcMaxValueData, // Longest Value data.
&dwcSecDesc, // Security descriptor.
&ftLastWriteTime); // Last write time.
// Enumerate the Key Values
cbData = maxLen ;
dwcValueName = MAX_VALUE_NAME;
valueName[0] = '\0';
retValue = RegEnumValue (hKey, index, valueName,
&dwcValueName,
NULL,
&dwType,
(BYTE *)&deviceName[0],
&cbData);
RegCloseKey (hKey); // Close the key handle.
if(dwType == REG_SZ && retValue == (DWORD)ERROR_SUCCESS)
return(SUCCESS);
else
return(FAILED);
} // EnumerateSerialports
// ------------------------------ FillCharCBox ----------------------
void FillCharCBox(CComboBox * cBox, DWORD * table, char ** strTable,
WORD tableLen, DWORD currentsetting)
{
DWORD count;
CHAR ** strTablePtr = strTable;
ASSERT(cBox->m_hWnd!=0);
cBox->ResetContent();
for (count = 0; count < tableLen; count++)
{
cBox->AddString(strTablePtr[count]);
cBox->SetItemData(count, *(table + count));
if (*(table + count) == currentsetting)
cBox->SetCurSel(count);
}
} // FillCharCBox
// ----------------------------- FillSerialCBox -----------------------------
// the list box contains the strings that describe each serial comm port available
// the port names themselves are retrieved when destroying the combo box
void FillSerialCBox(CComboBox * cBox, LPCTSTR currentselection)
{
DWORD count;
LONG retCode;
CHAR portname[MAX_PORT_NAME];
ASSERT(cBox->m_hWnd!=0);
cBox->ResetContent();
count = 0;
while (TRUE)
{
retCode = EnumerateSerialPorts(portname, sizeof(portname), count);
if( retCode != SUCCESS)
break;
cBox->AddString(portname);
cBox->SetItemData(count, count);
if (strcmp(portname,currentselection)==0)
cBox->SetCurSel(count);
count++;
}
} // FillSerialCBox
// ----------------------------------- FixComPortName -----------------------
// fix com port names for port names above com9
// IN/OUT: portName - user displayable name
//
// RETURN: portName - is modified on return.
// NOTES: This function will accept a port name in the format "\\.\COMnn"
// without lengthening it in-correctly.
CHAR * FixComPortName(CHAR *portName)
{
CHAR tempPortName[MAX_PORT_NAME];
if (strlen(portName) > strlen("COM1"))
{
if (0==strncmp(portName, "COM",3))
{
sprintf(tempPortName, "\\\\.\\%s", portName);
strcpy(portName, tempPortName);
}
}
return (portName);
} // FixComPortName
// ----------------------------------- GetLongComPortName --------------------
// return a port name that caters for com 10 and above
// IN : portName - port name e.g. "COM10"
// IN/OUT : newName - port name "\\.\COM10"
// RETURNS: newName -
CHAR * GetLongComPortName(LPCTSTR portName, LPSTR newName)
{
strcpy(newName,portName);
return (FixComPortName(newName));
} // GetLongComPortName
// ---------------------------- PortInUse ------------------------------
// Returns whether the RS-232 port can currently be opened.
// It tests this by opening and closing the port.
BOOL PortInUse(LPCTSTR portName)
{
//CHAR * GetLongComPortName(LPCTSTR portName, LPSTR newName);
CHAR port[MAX_PORT_NAME];
HANDLE hPort;
GetLongComPortName(portName, port);
hPort = CreateFile( port, // PIP 1823-400-1997
GENERIC_READ | GENERIC_WRITE,
(DWORD)NULL, // exclusive access
NULL, // no security
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL // hTemplate
);
if (INVALID_HANDLE_VALUE != hPort)
{
CloseHandle(hPort);
return (FALSE);
}
return (TRUE);
} // PortInUse
// --------------------------- FillSerialCBoxUsedResources ------------------
// Calls the function FillSerialCBox(), and then puts a '*' next to all used
// ports.
void FillSerialCBoxUsedResources(CComboBox * cBox, LPCTSTR currentselection)
{
DWORD index, count;
LONG selection;
CString selectionText;
FillSerialCBox(cBox, currentselection);
count = cBox->GetCount();
selection = cBox->GetCurSel();
index = 0;
while (index < count)
{
cBox->GetLBText(index, selectionText);
if (PortInUse(selectionText))
{
cBox->DeleteString(index);
selectionText = selectionText + PORT_INUSESTR; // " *"
cBox->InsertString(index, selectionText);
cBox->SetItemData(index, index);
}
index++;
}
cBox->SetCurSel(selection);
} // FillSerialCBoxUsedResources
// ---------------------------- ClearPortUseMark -------------------------
// Removes the '*' mark from a port name if present.
// Use this function to tread the LB contents if U used FillSerialCBoxUsedResources()
void ClearPortUseMark(LPSTR name)
{
if (strtok(name, PORT_INUSESTR))
{ // empty statement, since strtok modifies the string.
}
} // ClearPortUseMark
// pip 1512-400-1997 added
// ------------------------ Round -----------------------------------------
// PURPOSE : Rounds a precision floating point value, to allow casting to an
// integer value. This is because the Casting of 2.9999999999999999999999999
// actually gives us 2, not 3 like expected.
double Round(double val)
{
double r = fmod(val,1);
if (r>=0.5)
return ceil(val);
return floor(val);
} // Round
// pip 1512-400-1997 added
// ---------------- SwopBytes (Global Generic) -----------------------------
// PURPOSE : Converts WORD from large indian to little indian
// (and back if called again)
LONG SwopBytes(WORD * x)
{
WORD loByte;
WORD hiByte;
loByte = LOBYTE(*x);
hiByte = HIBYTE(*x);
*x = (WORD)((loByte<<8) + hiByte);
return(SUCCESS);
} // SwopBytes
// --------------- SwopWords (Global Generic) --------------------------------
// PURPOSE : Converts DWORD from large endian to small endian
// (and back if called again)
LONG SwopWords(DWORD * x)
{
DWORD loWord;
DWORD hiWord;
loWord = LOWORD(*x);
hiWord = HIWORD(*x);
*x = (loWord<<16) + hiWord ;
return(SUCCESS);
} // SwopWords
// ----------------- SwopDWords (Global Generic) --------------------------------
// PURPOSE : Converts DWORD from large endian to small endian
// (and back if called again)
LONG SwopDWords(DWORD * x)
{
DWORD loWordLoByte; // Byte 0
DWORD loWordHiByte; // Byte 1
DWORD hiWordLoByte; // Byte 2
DWORD hiWordHiByte; // Byte 3
loWordLoByte = LOBYTE(LOWORD(*x)); // Byte 0
loWordHiByte = HIBYTE(LOWORD(*x)); // Byte 1
hiWordLoByte = LOBYTE(HIWORD(*x)); // Byte 2
hiWordHiByte = HIBYTE(HIWORD(*x)); // Byte 3
// byte 0 byte 1 byte 2 byte 3
*x = (loWordLoByte<<24) | (loWordHiByte<<16) | (hiWordLoByte<<8) | (hiWordHiByte);
// byte 3 byte 2 byte 1 byte 0
*x = (hiWordLoByte<<24) | (hiWordHiByte<<16) | (loWordLoByte<<8) | (loWordHiByte);
return(SUCCESS);
} // SwopDWords
// ------------------ BCDtoLONG (Global Generic) --------------------------------
// PURPOSE : Converts BCD (1 to 8 digit) to LONG
// Support a max of 8 digits BCD
LONG BCDtoLONG( DWORD bcdValue,
DWORD bcdDigits,
PLONG longValue
)
{
DWORD multiplier = 1;
DWORD i;
*longValue = 0;
if(bcdDigits > 8)
return(FAILED);
for(i=0 ; i < bcdDigits ; i++)
{
if( (bcdValue & 0x0000000F) > 9 )
return(FAILED);
*longValue += (bcdValue & 0x0000000F) * multiplier;
bcdValue = bcdValue >> 4;
multiplier = multiplier * 10;
}
return(SUCCESS);
} // BCDtoLONG
// ------------------- LONGtoBCD (Global Generic) ----------------------
// PURPOSE : Converts LONG to BCD (1 to 8 digit)
// Support a max of 8 digits BCD
LONG LONGtoBCD( LONG longValue,
DWORD bcdDigits,
DWORD *bcdValue
)
{
DWORD i;
CHAR longValueStr[9];
PCHAR strPtr = longValueStr;
if(bcdDigits > 8)
return(FAILED);
*bcdValue = 0;
sprintf(strPtr, "%08ld", longValue);
for(i=8 ; i > (8-bcdDigits) ; i--)
{
*bcdValue += (* (strPtr + i - 1) - 48) << ((8-i) * 4);
}
return(SUCCESS);
} // LONGtoBCD
// --------------------------- FillDWordCBox --------------------------
void FillDWordCBox(CComboBox * cBox, DWORD * table, WORD tableLen,
DWORD currentsetting)
{
DWORD count;
CHAR temp[256];
ASSERT(cBox->m_hWnd!=0);
cBox->ResetContent();
for (count = 0; count < tableLen; count++)
{
sprintf(temp,"%ld",(DWORD *)table[count]);
cBox->AddString(temp); //strTablePtr[count]);
cBox->SetItemData(count, *(table + count));
if (*(table + count) == currentsetting)
cBox->SetCurSel(count);
}
} // FillDWordCBox
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -