Source code of Windows XP (NT5)
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.

527 lines
10 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999 - 1999
  6. //
  7. // File: tfc.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include <pch.cpp>
  11. #pragma hdrstop
  12. #include "tfc.h"
  13. #include <stdarg.h>
  14. extern HINSTANCE g_hInstance;
  15. const WCHAR* wszNull = L"";
  16. BOOL AssertFailedLine(LPCSTR lpszFileName, int nLine)
  17. {
  18. WCHAR szMessage[_MAX_PATH*2];
  19. // format message into buffer
  20. wsprintf(szMessage, L"File %hs, Line %d\n",
  21. lpszFileName, nLine);
  22. OutputDebugString(szMessage);
  23. int iCode = MessageBox(NULL, szMessage, L"Assertion Failed!",
  24. MB_TASKMODAL|MB_ICONHAND|MB_ABORTRETRYIGNORE|MB_SETFOREGROUND);
  25. if (iCode == IDIGNORE)
  26. return FALSE;
  27. if (iCode == IDRETRY)
  28. return TRUE;
  29. // abort!
  30. ExitProcess(0);
  31. return FALSE;
  32. }
  33. //////////////////////////////////////////////////////////////////////////////////
  34. //////////////////////////////////////////////////////////////////////////////////
  35. // CString
  36. //////////////////////////////////////////////////////////////////////////////////
  37. //////////////////////////////////////////////////////////////////////////////////
  38. CString::CString()
  39. {
  40. Init();
  41. }
  42. CString::CString(const CString& stringSrc)
  43. {
  44. Init();
  45. *this = stringSrc;
  46. }
  47. CString::CString(LPCSTR lpsz)
  48. {
  49. Init();
  50. *this = lpsz;
  51. }
  52. CString::CString(LPCWSTR lpsz)
  53. {
  54. Init();
  55. *this = lpsz;
  56. }
  57. CString::~CString()
  58. {
  59. if (szData)
  60. {
  61. LocalFree(szData);
  62. szData = NULL;
  63. }
  64. dwDataLen = 0;
  65. }
  66. // called to initialize cstring
  67. void CString::Init()
  68. {
  69. szData = NULL;
  70. dwDataLen = 0;
  71. }
  72. // called to make cstring empty
  73. void CString::Empty()
  74. {
  75. if (szData)
  76. {
  77. // Allow us to use ReAlloc
  78. szData[0]=L'\0';
  79. dwDataLen = sizeof(WCHAR);
  80. }
  81. else
  82. dwDataLen = 0;
  83. }
  84. BOOL CString::IsEmpty() const
  85. {
  86. return ((NULL == szData) || (szData[0] == L'\0'));
  87. }
  88. LPWSTR CString::GetBuffer(DWORD cch)
  89. {
  90. // get buffer of at least cch CHARS
  91. cch ++; // incl null term
  92. cch *= sizeof(WCHAR); // cb
  93. if (cch > dwDataLen)
  94. {
  95. LPWSTR szTmp;
  96. if (szData)
  97. szTmp = (LPWSTR)LocalReAlloc(szData, cch, LMEM_MOVEABLE);
  98. else
  99. szTmp = (LPWSTR)LocalAlloc(LMEM_FIXED, cch);
  100. if (!szTmp)
  101. {
  102. LocalFree(szData);
  103. dwDataLen = 0;
  104. }
  105. else
  106. {
  107. dwDataLen = cch;
  108. }
  109. szData = szTmp;
  110. }
  111. return szData;
  112. }
  113. BSTR CString::AllocSysString() const
  114. {
  115. return SysAllocStringLen(szData, (dwDataLen-1)/sizeof(WCHAR));
  116. }
  117. DWORD CString::GetLength() const
  118. {
  119. // return # chars in string (not incl NULL term)
  120. return ((dwDataLen > 0) ? wcslen(szData) : 0);
  121. }
  122. // warning: insertion strings cannot exceed MAX_PATH chars
  123. void CString::Format(LPCWSTR lpszFormat, ...)
  124. {
  125. Empty();
  126. DWORD cch = wcslen(lpszFormat) + MAX_PATH;
  127. GetBuffer(cch); // chars (don't count NULL term)
  128. if (szData != NULL)
  129. {
  130. DWORD dwformatted;
  131. va_list argList;
  132. va_start(argList, lpszFormat);
  133. dwformatted = vswprintf(szData, lpszFormat, argList);
  134. va_end(argList);
  135. dwformatted = (dwformatted+1)*sizeof(WCHAR); // cvt to bytes
  136. VERIFY (dwformatted <= dwDataLen);
  137. dwDataLen = dwformatted;
  138. }
  139. else
  140. {
  141. ASSERT(dwDataLen == 0);
  142. dwDataLen = 0;
  143. }
  144. }
  145. BOOL CString::LoadString(UINT iRsc)
  146. {
  147. WCHAR awc[4096];
  148. if (! ::LoadString(g_hInstance, iRsc, awc, 4096))
  149. return FALSE;
  150. *this = (LPCWSTR)awc;
  151. return TRUE;
  152. }
  153. BOOL CString::FromWindow(HWND hWnd)
  154. {
  155. Empty();
  156. DWORD dwBytes;
  157. INT iCh = (INT)SendMessage(hWnd, WM_GETTEXTLENGTH, 0, 0);
  158. GetBuffer(iCh);
  159. if (NULL == szData)
  160. return FALSE;
  161. if (dwDataLen != (DWORD)SendMessage(hWnd, WM_GETTEXT, (WPARAM)(dwDataLen/sizeof(WCHAR)), (LPARAM)szData))
  162. {
  163. // truncation!
  164. }
  165. return TRUE;
  166. }
  167. BOOL CString::ToWindow(HWND hWnd)
  168. {
  169. return (BOOL)SendMessage(hWnd, WM_SETTEXT, 0, (LPARAM)szData);
  170. }
  171. void CString::SetAt(int nIndex, WCHAR ch)
  172. {
  173. ASSERT(nIndex <= (int)(dwDataLen / sizeof(WCHAR)) );
  174. if (nIndex <= (int)(dwDataLen / sizeof(WCHAR)) )
  175. szData[nIndex] = ch;
  176. }
  177. // test
  178. BOOL CString::IsEqual(LPCWSTR sz)
  179. {
  180. if ((szData == NULL) || (szData[0] == L'\0'))
  181. return ((sz == NULL) || (sz[0] == L'\0'));
  182. if (sz == NULL)
  183. return FALSE;
  184. return (0 == lstrcmp(sz, szData));
  185. }
  186. // assignmt
  187. const CString& CString::operator=(const CString& stringSrc)
  188. {
  189. if (stringSrc.IsEmpty())
  190. Empty();
  191. else
  192. {
  193. GetBuffer( stringSrc.GetLength() );
  194. if (szData != NULL)
  195. {
  196. CopyMemory(szData, stringSrc.szData, sizeof(WCHAR)*(stringSrc.GetLength()+1));
  197. }
  198. }
  199. return *this;
  200. }
  201. // W Const
  202. const CString& CString::operator=(LPCWSTR lpsz)
  203. {
  204. if (lpsz == NULL)
  205. Empty();
  206. else
  207. {
  208. GetBuffer(wcslen(lpsz));
  209. if (szData != NULL)
  210. {
  211. CopyMemory(szData, lpsz, sizeof(WCHAR)*(wcslen(lpsz)+1));
  212. }
  213. }
  214. return *this;
  215. }
  216. // W
  217. const CString& CString::operator=(LPWSTR lpsz)
  218. {
  219. *this = (LPCWSTR)lpsz;
  220. return *this;
  221. }
  222. // A Const
  223. const CString& CString::operator=(LPCSTR lpsz)
  224. {
  225. if (lpsz == NULL)
  226. Empty();
  227. else
  228. {
  229. DWORD cch;
  230. cch = ::MultiByteToWideChar(CP_ACP, 0, lpsz, -1, NULL, 0);
  231. GetBuffer(cch-1);
  232. if (szData != NULL)
  233. {
  234. ::MultiByteToWideChar(CP_ACP, 0, lpsz, -1, szData, cch);
  235. }
  236. }
  237. return *this;
  238. }
  239. // A
  240. const CString& CString::operator=(LPSTR lpsz)
  241. {
  242. *this = (LPCSTR)lpsz;
  243. return *this;
  244. }
  245. // concat
  246. const CString& CString::operator+=(LPCWSTR lpsz)
  247. {
  248. if (IsEmpty())
  249. {
  250. *this = lpsz;
  251. return *this;
  252. }
  253. if (lpsz != NULL)
  254. {
  255. GetBuffer(wcslen(lpsz) + GetLength() );
  256. if (szData != NULL)
  257. {
  258. wcscat(szData, lpsz);
  259. }
  260. }
  261. return *this;
  262. }
  263. const CString& CString::operator+=(const CString& string)
  264. {
  265. if (IsEmpty())
  266. {
  267. *this = string;
  268. return *this;
  269. }
  270. if (!string.IsEmpty())
  271. {
  272. GetBuffer( string.GetLength() + GetLength() ); // don't count NULL terms
  273. if (szData != NULL)
  274. {
  275. wcscat(szData, string.szData);
  276. }
  277. }
  278. return *this;
  279. }
  280. //////////////////////////////////////////////////////////////////////////////////
  281. //////////////////////////////////////////////////////////////////////////////////
  282. // CBitmap
  283. //////////////////////////////////////////////////////////////////////////////////
  284. //////////////////////////////////////////////////////////////////////////////////
  285. CBitmap::CBitmap()
  286. {
  287. m_hBmp = NULL;
  288. }
  289. CBitmap::~CBitmap()
  290. {
  291. if(m_hBmp)
  292. DeleteObject(m_hBmp);
  293. m_hBmp = NULL;
  294. }
  295. HBITMAP CBitmap::LoadBitmap(UINT iRsc)
  296. {
  297. m_hBmp = (HBITMAP)LoadImage(g_hInstance, MAKEINTRESOURCE(iRsc), IMAGE_BITMAP, 0, 0, 0);
  298. return m_hBmp;
  299. }
  300. //////////////////////////////////////////////////////////////////////////////////
  301. //////////////////////////////////////////////////////////////////////////////////
  302. // CComboBox
  303. //////////////////////////////////////////////////////////////////////////////////
  304. //////////////////////////////////////////////////////////////////////////////////
  305. void CComboBox::Init(HWND hWnd)
  306. {
  307. m_hWnd = hWnd;
  308. }
  309. void CComboBox::ResetContent()
  310. {
  311. ASSERT(m_hWnd);
  312. SendMessage(m_hWnd, CB_RESETCONTENT, 0, 0);
  313. }
  314. int CComboBox::SetItemData(int idx, DWORD dwData)
  315. {
  316. ASSERT(m_hWnd);
  317. return (INT)SendMessage(m_hWnd, CB_SETITEMDATA, (WPARAM)idx, (LPARAM)dwData);
  318. }
  319. DWORD CComboBox::GetItemData(int idx)
  320. {
  321. ASSERT(m_hWnd);
  322. return (DWORD)SendMessage(m_hWnd, CB_GETITEMDATA, (WPARAM)idx, 0);
  323. }
  324. int CComboBox::AddString(LPWSTR sz)
  325. {
  326. ASSERT(m_hWnd);
  327. return (INT)SendMessage(m_hWnd, CB_ADDSTRING, 0, (LPARAM) sz);
  328. }
  329. int CComboBox::AddString(LPCWSTR sz)
  330. {
  331. return (INT)AddString((LPWSTR)sz);
  332. }
  333. int CComboBox::GetCurSel()
  334. {
  335. ASSERT(m_hWnd);
  336. return (INT)SendMessage(m_hWnd, CB_GETCURSEL, 0, 0);
  337. }
  338. int CComboBox::SetCurSel(int iSel)
  339. {
  340. ASSERT(m_hWnd);
  341. return (INT)SendMessage(m_hWnd, CB_SETCURSEL, (WPARAM)iSel, 0);
  342. }
  343. int CComboBox::SelectString(int nAfter, LPCWSTR szItem)
  344. {
  345. ASSERT(m_hWnd);
  346. return (INT)SendMessage(m_hWnd, CB_SELECTSTRING, (WPARAM) nAfter, (LPARAM)szItem);
  347. }
  348. int ListView_NewItem(HWND hList, int iIndex, LPCWSTR szText, LPARAM lParam /* = NULL*/, int iImage /*=-1*/)
  349. {
  350. LVITEM sItem;
  351. ZeroMemory(&sItem, sizeof(sItem));
  352. sItem.iItem = iIndex;
  353. sItem.iImage = iImage;
  354. if (lParam)
  355. {
  356. sItem.mask = LVIF_PARAM;
  357. if(-1!=iImage)
  358. sItem.mask |= LVIF_IMAGE;
  359. sItem.lParam = lParam;
  360. }
  361. sItem.iItem = ListView_InsertItem(hList, &sItem);
  362. ListView_SetItemText(hList, sItem.iItem, 0, (LPWSTR)szText);
  363. return sItem.iItem;
  364. }
  365. int ListView_NewColumn(HWND hwndListView, int iCol, int cx, LPCWSTR szHeading /*=NULL*/, int fmt/*=0*/)
  366. {
  367. LVCOLUMN lvCol;
  368. lvCol.mask = LVCF_WIDTH;
  369. lvCol.cx = cx;
  370. if (szHeading)
  371. {
  372. lvCol.mask |= LVCF_TEXT;
  373. lvCol.pszText = (LPWSTR)szHeading;
  374. }
  375. if (fmt)
  376. {
  377. lvCol.mask |= LVCF_FMT;
  378. lvCol.fmt = fmt;
  379. }
  380. return ListView_InsertColumn(hwndListView, iCol, &lvCol);
  381. }
  382. LPARAM ListView_GetItemData(HWND hListView, int iItem)
  383. {
  384. LVITEM lvItem;
  385. lvItem.iItem = iItem;
  386. lvItem.mask = LVIF_PARAM;
  387. lvItem.iSubItem = 0;
  388. ListView_GetItem(hListView, &lvItem);
  389. return lvItem.lParam;
  390. }
  391. int ListView_GetCurSel(HWND hwndList)
  392. {
  393. int iTot = ListView_GetItemCount(hwndList);
  394. int i=0;
  395. while(i<iTot)
  396. {
  397. if (LVIS_SELECTED == ListView_GetItemState(hwndList, i, LVIS_SELECTED))
  398. break;
  399. i++;
  400. }
  401. return (i<iTot) ? i : -1;
  402. }
  403. void
  404. ListView_SetItemFiletime(
  405. IN HWND hwndList,
  406. IN int iItem,
  407. IN int iColumn,
  408. IN FILETIME const *pft)
  409. {
  410. HRESULT hr;
  411. WCHAR *pwszDateTime = NULL;
  412. // convert filetime to string
  413. hr = myGMTFileTimeToWszLocalTime(pft, FALSE, &pwszDateTime);
  414. if (S_OK != hr)
  415. {
  416. _PrintError(hr, "myGMTFileTimeToWszLocalTime");
  417. }
  418. else
  419. {
  420. ListView_SetItemText(hwndList, iItem, iColumn, pwszDateTime);
  421. }
  422. if (NULL != pwszDateTime)
  423. {
  424. LocalFree(pwszDateTime);
  425. }
  426. }