📄 win32.cxx
字号:
#endif
theTime = (time_t)(timestamp/scale - delta);
microseconds = (long)(timestamp%scale/10);
}
#ifdef UNICODE
static void PWIN32GetLocaleInfo(LCID Locale,LCTYPE LCType,LPSTR lpLCData,int cchData)
{
TCHAR* pw = new TCHAR[cchData+1];
GetLocaleInfo(Locale,LCType,pw,cchData);
lpLCData[0]=0;
WideCharToMultiByte(GetACP(), 0, pw, -1, lpLCData, cchData, NULL, NULL);
}
#else
#define PWIN32GetLocaleInfo GetLocaleInfo
#endif
PString PTime::GetTimeSeparator()
{
PString str;
PWIN32GetLocaleInfo(GetUserDefaultLCID(), LOCALE_STIME, str.GetPointer(100), 99);
str.MakeMinimumSize();
return str;
}
BOOL PTime::GetTimeAMPM()
{
char str[2];
PWIN32GetLocaleInfo(GetUserDefaultLCID(), LOCALE_ITIME, str, sizeof(str));
return str[0] == '0';
}
PString PTime::GetTimeAM()
{
PString str;
PWIN32GetLocaleInfo(GetUserDefaultLCID(), LOCALE_S1159, str.GetPointer(100), 99);
str.MakeMinimumSize();
return str;
}
PString PTime::GetTimePM()
{
PString str;
PWIN32GetLocaleInfo(GetUserDefaultLCID(), LOCALE_S2359, str.GetPointer(100), 99);
str.MakeMinimumSize();
return str;
}
PString PTime::GetDayName(Weekdays dayOfWeek, NameType type)
{
PString str;
// Of course Sunday is 6 and Monday is 1...
PWIN32GetLocaleInfo(GetUserDefaultLCID(), (dayOfWeek+6)%7 +
(type == Abbreviated ? LOCALE_SABBREVDAYNAME1 : LOCALE_SDAYNAME1),
str.GetPointer(100), 99);
str.MakeMinimumSize();
return str;
}
PString PTime::GetDateSeparator()
{
PString str;
PWIN32GetLocaleInfo(GetUserDefaultLCID(), LOCALE_SDATE, str.GetPointer(100), 99);
str.MakeMinimumSize();
return str;
}
PString PTime::GetMonthName(Months month, NameType type)
{
PString str;
PWIN32GetLocaleInfo(GetUserDefaultLCID(), month-1 +
(type == Abbreviated ? LOCALE_SABBREVMONTHNAME1 : LOCALE_SMONTHNAME1),
str.GetPointer(100), 99);
str.MakeMinimumSize();
return str;
}
PTime::DateOrder PTime::GetDateOrder()
{
char str[2];
PWIN32GetLocaleInfo(GetUserDefaultLCID(), LOCALE_IDATE, str, sizeof(str));
return (DateOrder)(str[0] - '0');
}
BOOL PTime::IsDaylightSavings()
{
TIME_ZONE_INFORMATION tz;
DWORD result = GetTimeZoneInformation(&tz);
PAssertOS(result != 0xffffffff);
return result == TIME_ZONE_ID_DAYLIGHT;
}
int PTime::GetTimeZone(TimeZoneType type)
{
TIME_ZONE_INFORMATION tz;
PAssertOS(GetTimeZoneInformation(&tz) != 0xffffffff);
if (type == DaylightSavings)
tz.Bias += tz.DaylightBias;
return -tz.Bias;
}
PString PTime::GetTimeZoneString(TimeZoneType type)
{
TIME_ZONE_INFORMATION tz;
PAssertOS(GetTimeZoneInformation(&tz) != 0xffffffff);
return type == StandardTime ? tz.StandardName : tz.DaylightName;
}
///////////////////////////////////////////////////////////////////////////////
// PTimeInterval
static unsigned GetDivisor()
{
LARGE_INTEGER frequency;
if (QueryPerformanceFrequency(&frequency))
return (unsigned)frequency.QuadPart/1000;
return 0;
}
PTimeInterval PTimer::Tick()
{
static unsigned divisor = GetDivisor();
if (divisor == 0)
return (int)(GetTickCount()&0x7fffffff);
LARGE_INTEGER count;
QueryPerformanceCounter(&count);
return count.QuadPart/divisor;
}
unsigned PTimer::Resolution()
{
LARGE_INTEGER frequency;
if (QueryPerformanceFrequency(&frequency) && frequency.QuadPart >= 1000)
return 1;
DWORD err = GetLastError();
#ifndef _WIN32_WCE
DWORD timeAdjustment;
DWORD timeIncrement;
BOOL timeAdjustmentDisabled;
if (GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement, &timeAdjustmentDisabled))
return timeIncrement/10000;
err = GetLastError();
#endif
return 55;
}
///////////////////////////////////////////////////////////////////////////////
// Directories
void PDirectory::Construct()
{
hFindFile = INVALID_HANDLE_VALUE;
fileinfo.cFileName[0] = '\0';
PCaselessString::AssignContents(CreateFullPath(*this, TRUE));
}
void PDirectory::CopyContents(const PDirectory & dir)
{
scanMask = dir.scanMask;
hFindFile = dir.hFindFile;
fileinfo = dir.fileinfo;
}
BOOL PDirectory::Open(int newScanMask)
{
scanMask = newScanMask;
#ifdef UNICODE
USES_CONVERSION;
hFindFile = FindFirstFile(A2T(operator+("*.*")), &fileinfo);
#else
hFindFile = FindFirstFile(operator+("*.*"), &fileinfo);
#endif
if (hFindFile == INVALID_HANDLE_VALUE)
return FALSE;
return Filtered() ? Next() : TRUE;
}
BOOL PDirectory::Next()
{
if (hFindFile == INVALID_HANDLE_VALUE)
return FALSE;
do {
if (!FindNextFile(hFindFile, &fileinfo))
return FALSE;
} while (Filtered());
return TRUE;
}
PCaselessString PDirectory::GetEntryName() const
{
return fileinfo.cFileName;
}
BOOL PDirectory::IsSubDir() const
{
return (fileinfo.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) != 0;
}
PCaselessString PDirectory::GetVolume() const
{
#ifdef _WIN32_WCE
return PCaselessString("\\");
#else
char volName[100];
PAssertOS(GetVolumeInformation(NULL, volName, sizeof(volName), NULL, NULL, NULL, NULL, 0));
return PCaselessString(volName);
#endif
}
void PDirectory::Close()
{
if (hFindFile != INVALID_HANDLE_VALUE) {
FindClose(hFindFile);
hFindFile = INVALID_HANDLE_VALUE;
}
}
PString PDirectory::CreateFullPath(const PString & path, BOOL isDirectory)
{
#ifdef _WIN32_WCE //doesn't support Current Directory so the path suppose to be full
PString fullpath=path;
PINDEX len = fullpath.GetLength();
#else
PString partialpath = path;
if (path.IsEmpty())
partialpath = ".";
LPSTR dummy;
PString fullpath;
PINDEX len = (PINDEX)GetFullPathName(partialpath,
_MAX_PATH, fullpath.GetPointer(_MAX_PATH), &dummy);
#endif
if (isDirectory && len > 0 && fullpath[len-1] != PDIR_SEPARATOR)
fullpath += PDIR_SEPARATOR;
PINDEX pos = 0;
while ((pos = fullpath.Find('/', pos)) != P_MAX_INDEX)
fullpath[pos] = PDIR_SEPARATOR;
return fullpath;
}
typedef BOOL (WINAPI *GetDiskFreeSpaceExType)(LPCTSTR lpDirectoryName,
PULARGE_INTEGER lpFreeBytesAvailableToCaller,
PULARGE_INTEGER lpTotalNumberOfBytes,
PULARGE_INTEGER lpTotalNumberOfFreeBytes);
BOOL PDirectory::GetVolumeSpace(PInt64 & total, PInt64 & free, DWORD & clusterSize) const
{
clusterSize = 512;
total = free = ULONG_MAX;
PString root;
if ((*this)[1] == ':')
root = Left(3);
else if (theArray[0] == '\\' && theArray[1] == '\\') {
PINDEX backslash = Find('\\', 2);
if (backslash != P_MAX_INDEX) {
backslash = Find('\\', backslash+1);
if (backslash != P_MAX_INDEX)
root = Left(backslash+1);
}
}
if (root.IsEmpty())
return FALSE;
#ifndef _WIN32_WCE
BOOL needTotalAndFree = TRUE;
static GetDiskFreeSpaceExType GetDiskFreeSpaceEx =
(GetDiskFreeSpaceExType)GetProcAddress(LoadLibrary("KERNEL32.DLL"), "GetDiskFreeSpaceExA");
if (GetDiskFreeSpaceEx != NULL) {
ULARGE_INTEGER freeBytesAvailableToCaller;
ULARGE_INTEGER totalNumberOfBytes;
ULARGE_INTEGER totalNumberOfFreeBytes;
if (GetDiskFreeSpaceEx(root,
&freeBytesAvailableToCaller,
&totalNumberOfBytes,
&totalNumberOfFreeBytes)) {
total = totalNumberOfBytes.QuadPart;
free = totalNumberOfFreeBytes.QuadPart;
needTotalAndFree = FALSE;
}
}
clusterSize = 0;
char fsName[100];
if (GetVolumeInformation(root, NULL, 0, NULL, NULL, NULL, fsName, sizeof(fsName))) {
if (stricmp(fsName, "FAT32") == 0) {
clusterSize = 4096; // Cannot use GetDiskFreeSpace() results for FAT32
if (!needTotalAndFree)
return TRUE;
}
}
DWORD sectorsPerCluster; // address of sectors per cluster
DWORD bytesPerSector; // address of bytes per sector
DWORD numberOfFreeClusters; // address of number of free clusters
DWORD totalNumberOfClusters; // address of total number of clusters
if (!GetDiskFreeSpace(root,
§orsPerCluster,
&bytesPerSector,
&numberOfFreeClusters,
&totalNumberOfClusters))
{
if (root[0] != '\\' || ::GetLastError() != ERROR_NOT_SUPPORTED)
return FALSE;
PString drive = "A:";
while (WNetAddConnection(root, NULL, drive) != NO_ERROR) {
if (GetLastError() != ERROR_ALREADY_ASSIGNED)
return FALSE;
drive[0]++;
}
BOOL ok = GetDiskFreeSpace(drive+'\\',
§orsPerCluster,
&bytesPerSector,
&numberOfFreeClusters,
&totalNumberOfClusters);
WNetCancelConnection(drive, TRUE);
if (!ok)
return FALSE;
}
if (needTotalAndFree) {
free = numberOfFreeClusters*sectorsPerCluster*bytesPerSector;
total = totalNumberOfClusters*sectorsPerCluster*bytesPerSector;
}
if (clusterSize == 0)
clusterSize = bytesPerSector*sectorsPerCluster;
return TRUE;
#elif _WIN32_WCE < 300
USES_CONVERSION;
ULARGE_INTEGER freeBytesAvailableToCaller;
ULARGE_INTEGER totalNumberOfBytes;
ULARGE_INTEGER totalNumberOfFreeBytes;
if (GetDiskFreeSpaceEx(A2T(root),
&freeBytesAvailableToCaller,
&totalNumberOfBytes,
&totalNumberOfFreeBytes))
{
total = totalNumberOfBytes.QuadPart;
free = totalNumberOfFreeBytes.QuadPart;
clusterSize = 512; //X3
return TRUE;
}
return FALSE;
#else
return FALSE;
#endif
}
///////////////////////////////////////////////////////////////////////////////
// PFilePath
static PString IllegalFilenameCharacters =
"\\/:*?\"<>|"
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\0x10"
"\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f";
BOOL PFilePath::IsValid(char c)
{
return IllegalFilenameCharacters.Find(c) == P_MAX_INDEX;
}
BOOL PFilePath::IsValid(const PString & str)
{
return str != "." && str != ".." &&
str.FindOneOf(IllegalFilenameCharacters) == P_MAX_INDEX;
}
///////////////////////////////////////////////////////////////////////////////
// PChannel
PString PChannel::GetErrorText(Errors lastError, int osError)
{
if (osError == 0) {
if (lastError == NoError)
return PString();
static int const errors[NumNormalisedErrors] = {
0, ENOENT, EEXIST, ENOSPC, EACCES, EBUSY, EINVAL, ENOMEM, EBADF, EAGAIN, EINTR,
WSAEMSGSIZE|PWIN32ErrorFlag, EIO, 0x1000000|PWIN32ErrorFlag
};
osError = errors[lastError];
}
#ifndef _WIN32_WCE
if (osError > 0 && osError < _sys_nerr && _sys_errlist[osError][0] != '\0')
return _sys_errlist[osError];
#endif
if ((osError & PWIN32ErrorFlag) == 0)
return psprintf("C runtime error %u", osError);
DWORD err = osError & ~PWIN32ErrorFlag;
static const struct {
DWORD id;
const char * msg;
} win32_errlist[] = {
{ ERROR_FILE_NOT_FOUND, "File not found" },
{ ERROR_PATH_NOT_FOUND, "Path not found" },
{ ERROR_ACCESS_DENIED, "Access denied" },
{ ERROR_NOT_ENOUGH_MEMORY, "Not enough memory" },
{ ERROR_INVALID_FUNCTION, "Invalid function" },
{ WSAEADDRINUSE, "Address in use" },
{ WSAENETDOWN, "Network subsystem failed" },
{ WSAEISCONN, "Socket is already connected" },
{ WSAENETUNREACH, "Network unreachable" },
{ WSAEHOSTUNREACH, "Host unreachable" },
{ WSAECONNREFUSED, "Connection refused" },
{ WSAEINVAL, "Invalid operation" },
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -