Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

436 lines
12 KiB

// Copyright (c) 1997-1999 Microsoft Corporation
#include "precomp.h"
#ifdef EXT_DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#include "util.h"
#include "shlwapi.h"
//----------------------------------------------------------------
HRESULT Extract(IDataObject *_DO, wchar_t* fmt, wchar_t* data)
{
HGLOBAL hMem = GlobalAlloc(GMEM_SHARE,1024);
wchar_t *pRet = NULL;
HRESULT hr = 0;
if(hMem != NULL)
{
memset(hMem, 0, 1024);
STGMEDIUM stgmedium = { TYMED_HGLOBAL, (HBITMAP) hMem};
CLIPFORMAT regFmt = (CLIPFORMAT)RegisterClipboardFormat(fmt);
FORMATETC formatetc = { regFmt,
NULL,
DVASPECT_CONTENT,
-1,
TYMED_HGLOBAL };
if((hr = _DO->GetDataHere(&formatetc, &stgmedium)) == S_OK )
{
wcscpy(data, (wchar_t*)hMem);
}
GlobalFree(hMem);
}
return hr;
}
HRESULT Extract(IDataObject *_DO, wchar_t* fmt, bstr_t &data)
{
wchar_t temp[1024];
memset(temp, 0, 1024 * sizeof(wchar_t));
HRESULT hr = Extract(_DO, fmt, temp);
data = temp;
return hr;
}
///////////////////////////////////////////////////////////////////////////////
//
// FUNCTION: Int64ToString
//
// DESCRIPTION:
// Converts the numeric value of a _int64 to a text string.
// The string may optionally be formatted to include decimal places
// and commas according to current user locale settings.
//
// ARGUMENTS:
// n
// The 64-bit integer to format.
//
// szOutStr
// Address of the destination buffer.
//
// nSize
// Number of characters in the destination buffer.
//
// bFormat
// TRUE = Format per locale settings.
// FALSE = Leave number unformatted.
//
// pFmt
// Address of a number format structure of type NUMBERFMT.
// If NULL, the function automatically provides this information
// based on the user's default locale settings.
//
// dwNumFmtFlags
// Encoded flag word indicating which members of *pFmt to use in
// formatting the number. If a bit is clear, the user's default
// locale setting is used for the corresponding format value. These
// constants can be OR'd together.
//
// NUMFMT_IDIGITS
// NUMFMT_ILZERO
// NUMFMT_SGROUPING
// NUMFMT_SDECIMAL
// NUMFMT_STHOUSAND
// NUMFMT_INEGNUMBER
//
///////////////////////////////////////////////////////////////////////////////
INT WINAPI Int64ToString(_int64 n, LPTSTR szOutStr, UINT nSize, BOOL bFormat,
NUMBERFMT *pFmt, DWORD dwNumFmtFlags)
{
INT nResultSize;
TCHAR szBuffer[_MAX_PATH + 1] = {0};
NUMBERFMT NumFmt;
TCHAR szDecimalSep[5] = {0};
TCHAR szThousandSep[5] = {0};
//
// Use only those fields in caller-provided NUMBERFMT structure
// that correspond to bits set in dwNumFmtFlags. If a bit is clear,
// get format value from locale info.
//
if (bFormat)
{
TCHAR szInfo[20] = {0};
if (NULL == pFmt)
dwNumFmtFlags = 0; // Get all format data from locale info.
if (dwNumFmtFlags & NUMFMT_IDIGITS)
{
NumFmt.NumDigits = pFmt->NumDigits;
}
else
{
GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_IDIGITS,
szInfo,
ARRAYSIZE(szInfo));
_stscanf(szInfo, _T("%ld"), &(NumFmt.NumDigits));
// NumFmt.NumDigits = StrToLong(szInfo);
}
if (dwNumFmtFlags & NUMFMT_ILZERO)
{
NumFmt.LeadingZero = pFmt->LeadingZero;
}
else
{
GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_ILZERO,
szInfo,
ARRAYSIZE(szInfo));
_stscanf(szInfo, _T("%ld"), &(NumFmt.LeadingZero));
// NumFmt.LeadingZero = StrToLong(szInfo);
}
if (dwNumFmtFlags & NUMFMT_SGROUPING)
{
NumFmt.Grouping = pFmt->Grouping;
}
else
{
GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_SGROUPING,
szInfo,
ARRAYSIZE(szInfo));
_stscanf(szInfo, _T("%ld"), &(NumFmt.Grouping));
// NumFmt.Grouping = StrToLong(szInfo);
}
if (dwNumFmtFlags & NUMFMT_SDECIMAL)
{
NumFmt.lpDecimalSep = pFmt->lpDecimalSep;
}
else
{
GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_SDECIMAL,
szDecimalSep,
ARRAYSIZE(szDecimalSep));
NumFmt.lpDecimalSep = szDecimalSep;
}
if (dwNumFmtFlags & NUMFMT_STHOUSAND)
{
NumFmt.lpThousandSep = pFmt->lpThousandSep;
}
else
{
GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_STHOUSAND,
szThousandSep,
ARRAYSIZE(szThousandSep));
NumFmt.lpThousandSep = szThousandSep;
}
if (dwNumFmtFlags & NUMFMT_INEGNUMBER)
{
NumFmt.NegativeOrder = pFmt->NegativeOrder;
}
else
{
GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_INEGNUMBER,
szInfo,
ARRAYSIZE(szInfo));
_stscanf(szInfo, _T("%ld"), &(NumFmt.NegativeOrder));
// NumFmt.NegativeOrder = StrToLong(szInfo);
}
pFmt = &NumFmt;
}
Int64ToStr( n, szBuffer);
//
// Format the number string for the locale if the caller wants a
// formatted number string.
//
if (bFormat)
{
if ( 0 != ( nResultSize = GetNumberFormat( LOCALE_USER_DEFAULT, // User's locale
0, // No flags
szBuffer, // Unformatted number string
pFmt, // Number format info
szOutStr, // Output buffer
nSize )) ) // Chars in output buffer.
{
// Remove nul terminator char from return size count.
--nResultSize;
}
else
{
//
// GetNumberFormat call failed, so just return the number string
// unformatted.
//
DWORD err = GetLastError();
lstrcpyn(szOutStr, szBuffer, nSize);
nResultSize = lstrlen(szOutStr);
}
}
else
{
// a-khint; give it back raw.
lstrcpyn(szOutStr, szBuffer, nSize);
nResultSize = lstrlen(szOutStr);
}
return nResultSize;
}
//---------------------------------------------------------------
void Int64ToStr( _int64 n, LPTSTR lpBuffer)
{
TCHAR szTemp[MAX_INT64_SIZE] = {0};
_int64 iChr;
iChr = 0;
do {
szTemp[iChr++] = TEXT('0') + (TCHAR)(n % 10);
n = n / 10;
} while (n != 0);
do {
iChr--;
*lpBuffer++ = szTemp[iChr];
} while (iChr != 0);
*lpBuffer++ = '\0';
}
//---------------------------------------------------------------
// takes a DWORD add commas etc to it and puts the result in the buffer
LPTSTR WINAPI AddCommas64(_int64 n, LPTSTR pszResult)
{
TCHAR szTemp[MAX_COMMA_NUMBER_SIZE] = {0};
TCHAR szSep[5] = {0};
NUMBERFMT nfmt;
nfmt.NumDigits=0;
nfmt.LeadingZero=0;
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SGROUPING, szSep, ARRAYSIZE(szSep));
_stscanf(szSep, _T("%d"), &(nfmt.Grouping));
// nfmt.Grouping = StrToInt(szSep);
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, szSep, ARRAYSIZE(szSep));
nfmt.lpDecimalSep = nfmt.lpThousandSep = szSep;
nfmt.NegativeOrder= 0;
Int64ToStr(n, szTemp);
if (GetNumberFormat(LOCALE_USER_DEFAULT, 0, szTemp, &nfmt, pszResult, ARRAYSIZE(szTemp)) == 0)
lstrcpy(pszResult, szTemp);
return pszResult;
}
//----------------------------------------------------------------------
// takes a DWORD add commas etc to it and puts the result in the buffer
LPTSTR WINAPI AddCommas(DWORD dw, LPTSTR pszResult)
{
return AddCommas64( dw, pszResult );
}
//----------------------------------------------------------------------
long StrToLong(LPTSTR x)
{
long val;
_stscanf(x, _T("%ld"), &val);
return val;
}
//----------------------------------------------------------------------
/*
int StrToInt(LPTSTR x)
{
int val;
_stscanf(x, _T("%d"), &val);
return val;
}
//----------------------------------------------------------------------
#define LEN_MID_ELLIPSES 4
#define LEN_END_ELLIPSES 3
#define MIN_CCHMAX LEN_MID_ELLIPSES + LEN_END_ELLIPSES
// PathCompactPathEx
// Output:
// "."
// ".."
// "..."
// "...\"
// "...\."
// "...\.."
// "...\..."
// "...\Truncated filename..."
// "...\whole filename"
// "Truncated path\...\whole filename"
// "Whole path\whole filename"
// The '/' might be used instead of a '\' if the original string used it
// If there is no path, but only a file name that does not fit, the output is:
// "truncated filename..."
BOOL MyPathCompactPathEx(LPTSTR pszOut,
LPCTSTR pszSrc,
UINT cchMax,
DWORD dwFlags)
{
if(pszSrc)
{
TCHAR * pszFileName, *pszWalk;
UINT uiFNLen = 0;
int cchToCopy = 0, n;
TCHAR chSlash = TEXT('0');
ZeroMemory(pszOut, cchMax * sizeof(TCHAR));
if((UINT)lstrlen(pszSrc)+1 < cchMax)
{
lstrcpy(pszOut, pszSrc);
ATLASSERT(pszOut[cchMax-1] == TEXT('\0'));
return TRUE;
}
// Determine what we use as a slash - a / or a \ (default \)
pszWalk = (TCHAR*)pszSrc;
chSlash = TEXT('\\');
// Scan the entire string as we want the path separator closest to the end
// eg. "file://\\Themesrv\desktop\desktop.htm"
while(*pszWalk)
{
if((*pszWalk == TEXT('/')) || (*pszWalk == TEXT('\\')))
chSlash = *pszWalk;
pszWalk = FAST_CharNext(pszWalk);
}
pszFileName = PathFindFileName(pszSrc);
uiFNLen = lstrlen(pszFileName);
// if the whole string is a file name
if(pszFileName == pszSrc && cchMax > LEN_END_ELLIPSES)
{
lstrcpyn(pszOut, pszSrc, cchMax - LEN_END_ELLIPSES);
#ifndef UNICODE
if(IsTrailByte(pszSrc, pszSrc+cchMax-LEN_END_ELLIPSES))
*(pszOut+cchMax-LEN_END_ELLIPSES-1) = TEXT('\0');
#endif
lstrcat(pszOut, TEXT("..."));
ASSERT(pszOut[cchMax-1] == TEXT('\0'));
return TRUE;
}
// Handle all the cases where we just use ellipses ie '.' to '.../...'
if((cchMax < MIN_CCHMAX))
{
for(n = 0; n < (int)cchMax-1; n++)
{
if((n+1) == LEN_MID_ELLIPSES)
pszOut[n] = chSlash;
else
pszOut[n] = TEXT('.');
}
ASSERT(0==cchMax || pszOut[cchMax-1] == TEXT('\0'));
return TRUE;
}
// Ok, how much of the path can we copy ? Buffer - (Lenght of MID_ELLIPSES + Len_Filename)
cchToCopy = cchMax - (LEN_MID_ELLIPSES + uiFNLen);
if (cchToCopy < 0)
cchToCopy = 0;
#ifndef UNICODE
if (cchToCopy > 0 && IsTrailByte(pszSrc, pszSrc+cchToCopy))
cchToCopy--;
#endif
lstrcpyn(pszOut, pszSrc, cchToCopy);
// Now throw in the ".../" or "...\"
lstrcat(pszOut, TEXT(".../"));
pszOut[lstrlen(pszOut) - 1] = chSlash;
//Finally the filename and ellipses if necessary
if(cchMax > (LEN_MID_ELLIPSES + uiFNLen))
{
lstrcat(pszOut, pszFileName);
}
else
{
cchToCopy = cchMax - LEN_MID_ELLIPSES - LEN_END_ELLIPSES;
#ifndef UNICODE
if(cchToCopy >0 && IsTrailByte(pszFileName, pszFileName+cchToCopy))
cchToCopy--;
#endif
lstrcpyn(pszOut + LEN_MID_ELLIPSES, pszFileName, cchToCopy);
lstrcat(pszOut, TEXT("..."));
}
ASSERT(pszOut[cchMax-1] == TEXT('\0'));
return TRUE;
}
return FALSE;
}
*/