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.

374 lines
9.7 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997-2001.
  5. //
  6. // File: Util.cpp
  7. //
  8. // Contents:
  9. //
  10. //----------------------------------------------------------------------------
  11. /////////////////////////////////////////////////////////////////////
  12. // Util.cpp
  13. //
  14. // Utility routines.
  15. //
  16. // HISTORY
  17. // 4-Aug-97 t-danm Creation.
  18. /////////////////////////////////////////////////////////////////////
  19. #include "stdafx.h"
  20. #include "debug.h"
  21. #include "util.h"
  22. #include "resource.h"
  23. /////////////////////////////////////////////////////////////////////
  24. // ListView_FindString()
  25. //
  26. // Searches the listview items and return the index of the item
  27. // matching the string. Return -1 if no matches.
  28. //
  29. // INTERFACE NOTES
  30. // Although not documented, the search is performed without case.
  31. //
  32. int
  33. ListView_FindString(
  34. HWND hwndListview,
  35. LPCTSTR pszTextSearch)
  36. {
  37. Assert(IsWindow(hwndListview));
  38. Assert(pszTextSearch != NULL);
  39. LV_FINDINFO lvFindInfo;
  40. GarbageInit(&lvFindInfo, sizeof(lvFindInfo));
  41. lvFindInfo.flags = LVFI_STRING;
  42. lvFindInfo.psz = pszTextSearch;
  43. return ListView_FindItem(hwndListview, -1, &lvFindInfo);
  44. } // ListView_FindString()
  45. /////////////////////////////////////////////////////////////////////
  46. // ListView_GetSelectedItem()
  47. //
  48. // Return the index of the selected item.
  49. // If no items are selected, return -1.
  50. //
  51. int
  52. ListView_GetSelectedItem(HWND hwndListview)
  53. {
  54. Assert(IsWindow(hwndListview));
  55. return ListView_GetNextItem(hwndListview, -1, LVNI_SELECTED);
  56. }
  57. /////////////////////////////////////////////////////////////////////
  58. // ListView_SelectItem()
  59. //
  60. // Set the selection of a specific listview item.
  61. //
  62. void
  63. ListView_SelectItem(
  64. HWND hwndListview,
  65. int iItem)
  66. {
  67. Assert(IsWindow(hwndListview));
  68. Assert(iItem >= 0);
  69. ListView_SetItemState(hwndListview, iItem, LVIS_SELECTED, LVIS_SELECTED);
  70. } // ListView_SelectItem()
  71. /////////////////////////////////////////////////////////////////////
  72. // ListView_UnselectItem()
  73. //
  74. // Clear the selection of a specific listview item.
  75. //
  76. void
  77. ListView_UnselectItem(
  78. HWND hwndListview,
  79. int iItem)
  80. {
  81. Assert(IsWindow(hwndListview));
  82. Assert(iItem >= 0);
  83. ListView_SetItemState(hwndListview, iItem, 0, LVIS_SELECTED);
  84. } // ListView_UnselectItem()
  85. /////////////////////////////////////////////////////////////////////
  86. // ListView_UnselectAllItems()
  87. //
  88. // Remove the selection of any selected item.
  89. //
  90. void
  91. ListView_UnselectAllItems(HWND hwndListview)
  92. {
  93. Assert(IsWindow(hwndListview));
  94. int iItem = -1;
  95. while (TRUE)
  96. {
  97. // Search the listview for any selected items
  98. iItem = ListView_GetNextItem(hwndListview, iItem, LVNI_SELECTED);
  99. if (iItem < 0)
  100. break;
  101. // Clear the selection
  102. ListView_SetItemState(hwndListview, iItem, 0, LVIS_SELECTED);
  103. }
  104. } // ListView_UnselectAllItems()
  105. /////////////////////////////////////////////////////////////////////
  106. // ListView_SetItemImage()
  107. //
  108. // Change the image of a listview item.
  109. //
  110. void
  111. ListView_SetItemImage(HWND hwndListview, int iItem, int iImage)
  112. {
  113. Assert(IsWindow(hwndListview));
  114. Assert(iItem >= 0);
  115. LV_ITEM lvItem;
  116. GarbageInit(OUT &lvItem, sizeof(lvItem));
  117. lvItem.mask = LVIF_IMAGE;
  118. lvItem.iItem = iItem;
  119. lvItem.iSubItem = 0;
  120. lvItem.iImage = iImage;
  121. ListView_SetItem(hwndListview, IN &lvItem);
  122. } // ListView_SetItemImage()
  123. /////////////////////////////////////////////////////////////////////////////
  124. // FTrimString()
  125. //
  126. // Trim leading and trailing spaces of the string.
  127. // Return TRUE if one or more spaces has been removed, otherwise FALSE.
  128. //
  129. BOOL FTrimString(INOUT TCHAR szString[])
  130. {
  131. TCHAR * pchSrc;
  132. TCHAR * pchDst;
  133. Assert(szString != NULL);
  134. if (szString[0] == 0)
  135. return FALSE;
  136. pchSrc = szString;
  137. if (*pchSrc == ' ')
  138. {
  139. while (*pchSrc == ' ')
  140. pchSrc++;
  141. pchDst = szString;
  142. do
  143. {
  144. *pchDst++ = *pchSrc++;
  145. }
  146. while (*pchSrc != '\0');
  147. while (pchDst > szString && *(pchDst - 1) == ' ')
  148. pchDst--;
  149. *pchDst = '\0';
  150. return TRUE;
  151. }
  152. pchDst = szString;
  153. while (*pchDst != '\0')
  154. pchDst++;
  155. Assert(pchDst > szString);
  156. if (*(pchDst - 1) != ' ')
  157. return FALSE;
  158. while (pchDst > szString && *(pchDst - 1) == ' ')
  159. pchDst--;
  160. *pchDst = '\0';
  161. return TRUE;
  162. } // FTrimString()
  163. /////////////////////////////////////////////////////////////////////
  164. INT_PTR DoDialogBox(
  165. UINT wIdDialog,
  166. HWND hwndParent,
  167. DLGPROC dlgproc,
  168. LPARAM lParam)
  169. {
  170. Assert(wIdDialog != 0);
  171. Endorse(hwndParent == NULL);
  172. Assert(dlgproc != NULL);
  173. Endorse(lParam == NULL);
  174. INT_PTR nResult = ::DialogBoxParam(
  175. g_hInstance,
  176. MAKEINTRESOURCE(wIdDialog),
  177. hwndParent, (DLGPROC)dlgproc,
  178. lParam);
  179. Report(nResult != -1 && "Failure to display dialog");
  180. return nResult;
  181. } // DoDialogBox()
  182. /////////////////////////////////////////////////////////////////////
  183. int DoMessageBox(
  184. UINT uStringId,
  185. UINT uFlags)
  186. {
  187. TCHAR szCaption[128];
  188. TCHAR szMessage[512];
  189. CchLoadString(IDS_CAPTION, OUT szCaption, LENGTH(szCaption));
  190. CchLoadString(uStringId, OUT szMessage, LENGTH(szMessage));
  191. return ::MessageBox(::GetActiveWindow(), szMessage, szCaption, uFlags);
  192. } // DoMessageBox()
  193. #ifdef DEBUG
  194. /////////////////////////////////////////////////////////////////////////////
  195. // CchLoadString()
  196. //
  197. // Same as ::LoadString() but with extra error checking.
  198. // CchLoadString is #defined to ::LoadString in the retail build.
  199. //
  200. int CchLoadString(
  201. UINT uIdString, // IN: String Id
  202. TCHAR szBuffer[], // OUT: Buffer to receive the string
  203. int cchBuffer) // IN: Length of the buffer (in characters; not in bytes)
  204. {
  205. int cch;
  206. Assert(szBuffer != NULL);
  207. cch = ::LoadString(g_hInstance, uIdString, OUT szBuffer, cchBuffer);
  208. Report(cch > 0 && "String not found");
  209. Report(cch < cchBuffer - 2 && "Output buffer too small");
  210. return cch;
  211. } // CchLoadString()
  212. #endif // DEBUG
  213. /////////////////////////////////////////////////////////////////////
  214. // RegOpenOrCreateKey()
  215. //
  216. // Open an existing key or create it if does not exists
  217. //
  218. HKEY
  219. RegOpenOrCreateKey(
  220. HKEY hkeyRoot, // IN: Root of an existing key
  221. const TCHAR szSubkey[]) // IN: Subkey to create
  222. {
  223. Assert(hkeyRoot != NULL);
  224. Assert(szSubkey != NULL);
  225. HKEY hkey; // Primary Registry key
  226. DWORD dwDisposition; // Disposition (REG_OPENED_EXISTING_KEY or REG_CREATED_NEW_KEY)
  227. LONG lRetCode; // Code returned by the Registry functions
  228. lRetCode = RegCreateKeyEx(
  229. hkeyRoot, szSubkey,
  230. 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
  231. NULL, // SecurityAttributes
  232. &hkey, // OUT: Returned registry key handle
  233. &dwDisposition); // OUT: Returned disposition
  234. if (lRetCode != ERROR_SUCCESS)
  235. {
  236. Assert(hkey == NULL);
  237. return NULL;
  238. }
  239. return hkey;
  240. } // RegOpenOrCreateKey()
  241. /////////////////////////////////////////////////////////////////////
  242. // RegWriteString()
  243. //
  244. // Write a tring to the Registry.
  245. //
  246. BOOL
  247. RegWriteString(
  248. HKEY hkey, // IN: Key to append to
  249. const TCHAR szKey[], // IN: Key to save
  250. const TCHAR szValue[]) // IN: Value of the key
  251. {
  252. Assert(hkey != NULL); // Verify Registry has been opened
  253. Assert(szKey != NULL);
  254. Assert(szValue != NULL);
  255. LONG lRetCode = RegSetValueEx(hkey, szKey, 0, REG_SZ,
  256. (LPBYTE)szValue, lstrlen(szValue) * sizeof(TCHAR));
  257. // There should be no error writing to the Registry
  258. Report((lRetCode == ERROR_SUCCESS) && "RegWriteString() - Error writing to Registry");
  259. return (lRetCode == ERROR_SUCCESS);
  260. } // RegWriteString()
  261. /////////////////////////////////////////////////////////////////////
  262. BOOL
  263. RegWriteString(
  264. HKEY hkey, // IN: Key to append to
  265. const TCHAR szKey[], // IN: Key to save
  266. UINT uStringId) // IN: Value of the key
  267. {
  268. if ( szKey )
  269. {
  270. TCHAR szValue[512];
  271. CchLoadString(uStringId, OUT szValue, LENGTH(szValue));
  272. return RegWriteString(hkey, szKey, szValue);
  273. }
  274. else
  275. return FALSE;
  276. }
  277. /////////////////////////////////////////////////////////////////////////////
  278. // HrExtractDataAlloc()
  279. //
  280. // Extract data from a source DataObject for a particular clipboard format.
  281. //
  282. // RETURNS
  283. // Return S_OK if data was successfully retrieved and placed into allocated buffer.
  284. //
  285. // INTERFACE NOTES
  286. // The routine will allocate memory, copy the data from the source to
  287. // the allocated buffer and return a pointer to the allocated buffer.
  288. // The caller is responsible to free the allocated memory using GlobalFree()
  289. // when no longer needed.
  290. //
  291. // IMPLEMENTATION NOTES
  292. // The memory block is allocated by pDataObject->GetData() rather
  293. // than by the routine itself.
  294. //
  295. // HISTORY
  296. // 12-Aug-97 t-danm Creation.
  297. //
  298. HRESULT
  299. HrExtractDataAlloc(
  300. IDataObject * pDataObject, // IN: Data source to extract data from
  301. UINT cfClipboardFormat, // IN: Clipboard format to extract data
  302. PVOID * ppavData, // OUT: Pointer to allocated memory
  303. UINT * pcbData) // OUT: OPTIONAL: Number of bytes stored in memory buffer
  304. {
  305. Assert(pDataObject != NULL);
  306. Assert(cfClipboardFormat != NULL);
  307. Assert(ppavData != NULL);
  308. Assert(*ppavData == NULL && "Memory Leak");
  309. Endorse(pcbData == NULL); // TRUE => Don't care about the size of the allocated buffer
  310. FORMATETC formatetc = { (CLIPFORMAT)cfClipboardFormat, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
  311. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
  312. Assert(stgmedium.hGlobal == NULL);
  313. HRESULT hr = pDataObject->GetData(IN &formatetc, OUT &stgmedium);
  314. if (FAILED(hr))
  315. {
  316. Trace1("HrExtractDataAlloc() - Call to pDataObject->GetData() failed. hr=0x%X.\n", hr);
  317. return hr;
  318. }
  319. if (stgmedium.hGlobal == NULL)
  320. {
  321. // This is because the producer did not set the hGlobal handle
  322. Trace0("HrExtractDataAlloc() - Memory handle hGlobal is NULL.\n");
  323. return S_FALSE;
  324. }
  325. UINT cbData = (UINT)GlobalSize(stgmedium.hGlobal);
  326. if (cbData == 0)
  327. {
  328. Trace1("HrExtractDataAlloc() - Corrupted hGlobal handle. err=%d.\n", GetLastError());
  329. return E_UNEXPECTED;
  330. }
  331. *ppavData = stgmedium.hGlobal;
  332. if (pcbData != NULL)
  333. *pcbData = cbData;
  334. return S_OK;
  335. } // HrExtractDataAlloc()