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.

435 lines
12 KiB

  1. // Copyright (c) 1997-1999 Microsoft Corporation
  2. #include "precomp.h"
  3. #ifdef EXT_DEBUG
  4. #undef THIS_FILE
  5. static char THIS_FILE[] = __FILE__;
  6. #endif
  7. #include "util.h"
  8. #include "shlwapi.h"
  9. //----------------------------------------------------------------
  10. HRESULT Extract(IDataObject *_DO, wchar_t* fmt, wchar_t* data)
  11. {
  12. HGLOBAL hMem = GlobalAlloc(GMEM_SHARE,1024);
  13. wchar_t *pRet = NULL;
  14. HRESULT hr = 0;
  15. if(hMem != NULL)
  16. {
  17. memset(hMem, 0, 1024);
  18. STGMEDIUM stgmedium = { TYMED_HGLOBAL, (HBITMAP) hMem};
  19. CLIPFORMAT regFmt = (CLIPFORMAT)RegisterClipboardFormat(fmt);
  20. FORMATETC formatetc = { regFmt,
  21. NULL,
  22. DVASPECT_CONTENT,
  23. -1,
  24. TYMED_HGLOBAL };
  25. if((hr = _DO->GetDataHere(&formatetc, &stgmedium)) == S_OK )
  26. {
  27. wcscpy(data, (wchar_t*)hMem);
  28. }
  29. GlobalFree(hMem);
  30. }
  31. return hr;
  32. }
  33. HRESULT Extract(IDataObject *_DO, wchar_t* fmt, bstr_t &data)
  34. {
  35. wchar_t temp[1024];
  36. memset(temp, 0, 1024 * sizeof(wchar_t));
  37. HRESULT hr = Extract(_DO, fmt, temp);
  38. data = temp;
  39. return hr;
  40. }
  41. ///////////////////////////////////////////////////////////////////////////////
  42. //
  43. // FUNCTION: Int64ToString
  44. //
  45. // DESCRIPTION:
  46. // Converts the numeric value of a _int64 to a text string.
  47. // The string may optionally be formatted to include decimal places
  48. // and commas according to current user locale settings.
  49. //
  50. // ARGUMENTS:
  51. // n
  52. // The 64-bit integer to format.
  53. //
  54. // szOutStr
  55. // Address of the destination buffer.
  56. //
  57. // nSize
  58. // Number of characters in the destination buffer.
  59. //
  60. // bFormat
  61. // TRUE = Format per locale settings.
  62. // FALSE = Leave number unformatted.
  63. //
  64. // pFmt
  65. // Address of a number format structure of type NUMBERFMT.
  66. // If NULL, the function automatically provides this information
  67. // based on the user's default locale settings.
  68. //
  69. // dwNumFmtFlags
  70. // Encoded flag word indicating which members of *pFmt to use in
  71. // formatting the number. If a bit is clear, the user's default
  72. // locale setting is used for the corresponding format value. These
  73. // constants can be OR'd together.
  74. //
  75. // NUMFMT_IDIGITS
  76. // NUMFMT_ILZERO
  77. // NUMFMT_SGROUPING
  78. // NUMFMT_SDECIMAL
  79. // NUMFMT_STHOUSAND
  80. // NUMFMT_INEGNUMBER
  81. //
  82. ///////////////////////////////////////////////////////////////////////////////
  83. INT WINAPI Int64ToString(_int64 n, LPTSTR szOutStr, UINT nSize, BOOL bFormat,
  84. NUMBERFMT *pFmt, DWORD dwNumFmtFlags)
  85. {
  86. INT nResultSize;
  87. TCHAR szBuffer[_MAX_PATH + 1] = {0};
  88. NUMBERFMT NumFmt;
  89. TCHAR szDecimalSep[5] = {0};
  90. TCHAR szThousandSep[5] = {0};
  91. //
  92. // Use only those fields in caller-provided NUMBERFMT structure
  93. // that correspond to bits set in dwNumFmtFlags. If a bit is clear,
  94. // get format value from locale info.
  95. //
  96. if (bFormat)
  97. {
  98. TCHAR szInfo[20] = {0};
  99. if (NULL == pFmt)
  100. dwNumFmtFlags = 0; // Get all format data from locale info.
  101. if (dwNumFmtFlags & NUMFMT_IDIGITS)
  102. {
  103. NumFmt.NumDigits = pFmt->NumDigits;
  104. }
  105. else
  106. {
  107. GetLocaleInfo(LOCALE_USER_DEFAULT,
  108. LOCALE_IDIGITS,
  109. szInfo,
  110. ARRAYSIZE(szInfo));
  111. _stscanf(szInfo, _T("%ld"), &(NumFmt.NumDigits));
  112. // NumFmt.NumDigits = StrToLong(szInfo);
  113. }
  114. if (dwNumFmtFlags & NUMFMT_ILZERO)
  115. {
  116. NumFmt.LeadingZero = pFmt->LeadingZero;
  117. }
  118. else
  119. {
  120. GetLocaleInfo(LOCALE_USER_DEFAULT,
  121. LOCALE_ILZERO,
  122. szInfo,
  123. ARRAYSIZE(szInfo));
  124. _stscanf(szInfo, _T("%ld"), &(NumFmt.LeadingZero));
  125. // NumFmt.LeadingZero = StrToLong(szInfo);
  126. }
  127. if (dwNumFmtFlags & NUMFMT_SGROUPING)
  128. {
  129. NumFmt.Grouping = pFmt->Grouping;
  130. }
  131. else
  132. {
  133. GetLocaleInfo(LOCALE_USER_DEFAULT,
  134. LOCALE_SGROUPING,
  135. szInfo,
  136. ARRAYSIZE(szInfo));
  137. _stscanf(szInfo, _T("%ld"), &(NumFmt.Grouping));
  138. // NumFmt.Grouping = StrToLong(szInfo);
  139. }
  140. if (dwNumFmtFlags & NUMFMT_SDECIMAL)
  141. {
  142. NumFmt.lpDecimalSep = pFmt->lpDecimalSep;
  143. }
  144. else
  145. {
  146. GetLocaleInfo(LOCALE_USER_DEFAULT,
  147. LOCALE_SDECIMAL,
  148. szDecimalSep,
  149. ARRAYSIZE(szDecimalSep));
  150. NumFmt.lpDecimalSep = szDecimalSep;
  151. }
  152. if (dwNumFmtFlags & NUMFMT_STHOUSAND)
  153. {
  154. NumFmt.lpThousandSep = pFmt->lpThousandSep;
  155. }
  156. else
  157. {
  158. GetLocaleInfo(LOCALE_USER_DEFAULT,
  159. LOCALE_STHOUSAND,
  160. szThousandSep,
  161. ARRAYSIZE(szThousandSep));
  162. NumFmt.lpThousandSep = szThousandSep;
  163. }
  164. if (dwNumFmtFlags & NUMFMT_INEGNUMBER)
  165. {
  166. NumFmt.NegativeOrder = pFmt->NegativeOrder;
  167. }
  168. else
  169. {
  170. GetLocaleInfo(LOCALE_USER_DEFAULT,
  171. LOCALE_INEGNUMBER,
  172. szInfo,
  173. ARRAYSIZE(szInfo));
  174. _stscanf(szInfo, _T("%ld"), &(NumFmt.NegativeOrder));
  175. // NumFmt.NegativeOrder = StrToLong(szInfo);
  176. }
  177. pFmt = &NumFmt;
  178. }
  179. Int64ToStr( n, szBuffer);
  180. //
  181. // Format the number string for the locale if the caller wants a
  182. // formatted number string.
  183. //
  184. if (bFormat)
  185. {
  186. if ( 0 != ( nResultSize = GetNumberFormat( LOCALE_USER_DEFAULT, // User's locale
  187. 0, // No flags
  188. szBuffer, // Unformatted number string
  189. pFmt, // Number format info
  190. szOutStr, // Output buffer
  191. nSize )) ) // Chars in output buffer.
  192. {
  193. // Remove nul terminator char from return size count.
  194. --nResultSize;
  195. }
  196. else
  197. {
  198. //
  199. // GetNumberFormat call failed, so just return the number string
  200. // unformatted.
  201. //
  202. DWORD err = GetLastError();
  203. lstrcpyn(szOutStr, szBuffer, nSize);
  204. nResultSize = lstrlen(szOutStr);
  205. }
  206. }
  207. else
  208. {
  209. // a-khint; give it back raw.
  210. lstrcpyn(szOutStr, szBuffer, nSize);
  211. nResultSize = lstrlen(szOutStr);
  212. }
  213. return nResultSize;
  214. }
  215. //---------------------------------------------------------------
  216. void Int64ToStr( _int64 n, LPTSTR lpBuffer)
  217. {
  218. TCHAR szTemp[MAX_INT64_SIZE] = {0};
  219. _int64 iChr;
  220. iChr = 0;
  221. do {
  222. szTemp[iChr++] = TEXT('0') + (TCHAR)(n % 10);
  223. n = n / 10;
  224. } while (n != 0);
  225. do {
  226. iChr--;
  227. *lpBuffer++ = szTemp[iChr];
  228. } while (iChr != 0);
  229. *lpBuffer++ = '\0';
  230. }
  231. //---------------------------------------------------------------
  232. // takes a DWORD add commas etc to it and puts the result in the buffer
  233. LPTSTR WINAPI AddCommas64(_int64 n, LPTSTR pszResult)
  234. {
  235. TCHAR szTemp[MAX_COMMA_NUMBER_SIZE] = {0};
  236. TCHAR szSep[5] = {0};
  237. NUMBERFMT nfmt;
  238. nfmt.NumDigits=0;
  239. nfmt.LeadingZero=0;
  240. GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SGROUPING, szSep, ARRAYSIZE(szSep));
  241. _stscanf(szSep, _T("%d"), &(nfmt.Grouping));
  242. // nfmt.Grouping = StrToInt(szSep);
  243. GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, szSep, ARRAYSIZE(szSep));
  244. nfmt.lpDecimalSep = nfmt.lpThousandSep = szSep;
  245. nfmt.NegativeOrder= 0;
  246. Int64ToStr(n, szTemp);
  247. if (GetNumberFormat(LOCALE_USER_DEFAULT, 0, szTemp, &nfmt, pszResult, ARRAYSIZE(szTemp)) == 0)
  248. lstrcpy(pszResult, szTemp);
  249. return pszResult;
  250. }
  251. //----------------------------------------------------------------------
  252. // takes a DWORD add commas etc to it and puts the result in the buffer
  253. LPTSTR WINAPI AddCommas(DWORD dw, LPTSTR pszResult)
  254. {
  255. return AddCommas64( dw, pszResult );
  256. }
  257. //----------------------------------------------------------------------
  258. long StrToLong(LPTSTR x)
  259. {
  260. long val;
  261. _stscanf(x, _T("%ld"), &val);
  262. return val;
  263. }
  264. //----------------------------------------------------------------------
  265. /*
  266. int StrToInt(LPTSTR x)
  267. {
  268. int val;
  269. _stscanf(x, _T("%d"), &val);
  270. return val;
  271. }
  272. //----------------------------------------------------------------------
  273. #define LEN_MID_ELLIPSES 4
  274. #define LEN_END_ELLIPSES 3
  275. #define MIN_CCHMAX LEN_MID_ELLIPSES + LEN_END_ELLIPSES
  276. // PathCompactPathEx
  277. // Output:
  278. // "."
  279. // ".."
  280. // "..."
  281. // "...\"
  282. // "...\."
  283. // "...\.."
  284. // "...\..."
  285. // "...\Truncated filename..."
  286. // "...\whole filename"
  287. // "Truncated path\...\whole filename"
  288. // "Whole path\whole filename"
  289. // The '/' might be used instead of a '\' if the original string used it
  290. // If there is no path, but only a file name that does not fit, the output is:
  291. // "truncated filename..."
  292. BOOL MyPathCompactPathEx(LPTSTR pszOut,
  293. LPCTSTR pszSrc,
  294. UINT cchMax,
  295. DWORD dwFlags)
  296. {
  297. if(pszSrc)
  298. {
  299. TCHAR * pszFileName, *pszWalk;
  300. UINT uiFNLen = 0;
  301. int cchToCopy = 0, n;
  302. TCHAR chSlash = TEXT('0');
  303. ZeroMemory(pszOut, cchMax * sizeof(TCHAR));
  304. if((UINT)lstrlen(pszSrc)+1 < cchMax)
  305. {
  306. lstrcpy(pszOut, pszSrc);
  307. ATLASSERT(pszOut[cchMax-1] == TEXT('\0'));
  308. return TRUE;
  309. }
  310. // Determine what we use as a slash - a / or a \ (default \)
  311. pszWalk = (TCHAR*)pszSrc;
  312. chSlash = TEXT('\\');
  313. // Scan the entire string as we want the path separator closest to the end
  314. // eg. "file://\\Themesrv\desktop\desktop.htm"
  315. while(*pszWalk)
  316. {
  317. if((*pszWalk == TEXT('/')) || (*pszWalk == TEXT('\\')))
  318. chSlash = *pszWalk;
  319. pszWalk = FAST_CharNext(pszWalk);
  320. }
  321. pszFileName = PathFindFileName(pszSrc);
  322. uiFNLen = lstrlen(pszFileName);
  323. // if the whole string is a file name
  324. if(pszFileName == pszSrc && cchMax > LEN_END_ELLIPSES)
  325. {
  326. lstrcpyn(pszOut, pszSrc, cchMax - LEN_END_ELLIPSES);
  327. #ifndef UNICODE
  328. if(IsTrailByte(pszSrc, pszSrc+cchMax-LEN_END_ELLIPSES))
  329. *(pszOut+cchMax-LEN_END_ELLIPSES-1) = TEXT('\0');
  330. #endif
  331. lstrcat(pszOut, TEXT("..."));
  332. ASSERT(pszOut[cchMax-1] == TEXT('\0'));
  333. return TRUE;
  334. }
  335. // Handle all the cases where we just use ellipses ie '.' to '.../...'
  336. if((cchMax < MIN_CCHMAX))
  337. {
  338. for(n = 0; n < (int)cchMax-1; n++)
  339. {
  340. if((n+1) == LEN_MID_ELLIPSES)
  341. pszOut[n] = chSlash;
  342. else
  343. pszOut[n] = TEXT('.');
  344. }
  345. ASSERT(0==cchMax || pszOut[cchMax-1] == TEXT('\0'));
  346. return TRUE;
  347. }
  348. // Ok, how much of the path can we copy ? Buffer - (Lenght of MID_ELLIPSES + Len_Filename)
  349. cchToCopy = cchMax - (LEN_MID_ELLIPSES + uiFNLen);
  350. if (cchToCopy < 0)
  351. cchToCopy = 0;
  352. #ifndef UNICODE
  353. if (cchToCopy > 0 && IsTrailByte(pszSrc, pszSrc+cchToCopy))
  354. cchToCopy--;
  355. #endif
  356. lstrcpyn(pszOut, pszSrc, cchToCopy);
  357. // Now throw in the ".../" or "...\"
  358. lstrcat(pszOut, TEXT(".../"));
  359. pszOut[lstrlen(pszOut) - 1] = chSlash;
  360. //Finally the filename and ellipses if necessary
  361. if(cchMax > (LEN_MID_ELLIPSES + uiFNLen))
  362. {
  363. lstrcat(pszOut, pszFileName);
  364. }
  365. else
  366. {
  367. cchToCopy = cchMax - LEN_MID_ELLIPSES - LEN_END_ELLIPSES;
  368. #ifndef UNICODE
  369. if(cchToCopy >0 && IsTrailByte(pszFileName, pszFileName+cchToCopy))
  370. cchToCopy--;
  371. #endif
  372. lstrcpyn(pszOut + LEN_MID_ELLIPSES, pszFileName, cchToCopy);
  373. lstrcat(pszOut, TEXT("..."));
  374. }
  375. ASSERT(pszOut[cchMax-1] == TEXT('\0'));
  376. return TRUE;
  377. }
  378. return FALSE;
  379. }
  380. */