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.

378 lines
11 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997-2002.
  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. PCWSTR pszTextSearch)
  36. {
  37. Assert(IsWindow(hwndListview));
  38. Assert(pszTextSearch != NULL);
  39. LV_FINDINFO lvFindInfo;
  40. ::ZeroMemory (&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. ::ZeroMemory (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 WCHAR szString[])
  130. {
  131. WCHAR * pchSrc;
  132. WCHAR * 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,
  178. dlgproc,
  179. lParam);
  180. Report(nResult != -1 && "Failure to display dialog");
  181. return nResult;
  182. } // DoDialogBox()
  183. /////////////////////////////////////////////////////////////////////
  184. int DoMessageBox(
  185. HWND hwndParent,
  186. UINT uStringId,
  187. UINT uFlags)
  188. {
  189. WCHAR szCaption[128];
  190. WCHAR szMessage[512];
  191. CchLoadString(IDS_CAPTION, OUT szCaption, LENGTH(szCaption));
  192. CchLoadString(uStringId, OUT szMessage, LENGTH(szMessage));
  193. return ::MessageBox(hwndParent ? hwndParent : ::GetActiveWindow(),
  194. szMessage, szCaption, uFlags);
  195. } // DoMessageBox()
  196. #ifdef DEBUG
  197. /////////////////////////////////////////////////////////////////////////////
  198. // CchLoadString()
  199. //
  200. // Same as ::LoadString() but with extra error checking.
  201. // CchLoadString is #defined to ::LoadString in the retail build.
  202. //
  203. int CchLoadString(
  204. UINT uIdString, // IN: String Id
  205. WCHAR szBuffer[], // OUT: Buffer to receive the string
  206. int cchBuffer) // IN: Length of the buffer (in characters; not in bytes)
  207. {
  208. int cch;
  209. Assert(szBuffer != NULL);
  210. cch = ::LoadString(g_hInstance, uIdString, OUT szBuffer, cchBuffer);
  211. Report(cch > 0 && "String not found");
  212. Report(cch < cchBuffer - 2 && "Output buffer too small");
  213. return cch;
  214. } // CchLoadString()
  215. #endif // DEBUG
  216. /////////////////////////////////////////////////////////////////////
  217. // RegOpenOrCreateKey()
  218. //
  219. // Open an existing key or create it if does not exists
  220. //
  221. HKEY
  222. RegOpenOrCreateKey(
  223. HKEY hkeyRoot, // IN: Root of an existing key
  224. const WCHAR szSubkey[]) // IN: Subkey to create
  225. {
  226. Assert(hkeyRoot != NULL);
  227. Assert(szSubkey != NULL);
  228. HKEY hkey; // Primary Registry key
  229. DWORD dwDisposition; // Disposition (REG_OPENED_EXISTING_KEY or REG_CREATED_NEW_KEY)
  230. LONG lRetCode; // Code returned by the Registry functions
  231. lRetCode = RegCreateKeyEx(
  232. hkeyRoot, szSubkey,
  233. 0, NULL, REG_OPTION_NON_VOLATILE,
  234. KEY_ALL_ACCESS, // required to create keys
  235. NULL, // SecurityAttributes
  236. &hkey, // OUT: Returned registry key handle
  237. &dwDisposition); // OUT: Returned disposition
  238. if (lRetCode != ERROR_SUCCESS)
  239. {
  240. Assert(hkey == NULL);
  241. return NULL;
  242. }
  243. return hkey;
  244. } // RegOpenOrCreateKey()
  245. /////////////////////////////////////////////////////////////////////
  246. // RegWriteString()
  247. //
  248. // Write a tring to the Registry.
  249. //
  250. BOOL
  251. RegWriteString(
  252. HKEY hkey, // IN: Key to append to
  253. const WCHAR szKey[], // IN: Key to save
  254. const WCHAR szValue[]) // IN: Value of the key
  255. {
  256. Assert(hkey != NULL); // Verify Registry has been opened
  257. Assert(szKey != NULL);
  258. Assert(szValue != NULL);
  259. LONG lRetCode = RegSetValueEx(hkey, szKey, 0, REG_SZ,
  260. (LPBYTE)szValue, (DWORD) (wcslen(szValue) * sizeof(WCHAR)));
  261. // There should be no error writing to the Registry
  262. Report((lRetCode == ERROR_SUCCESS) && "RegWriteString() - Error writing to Registry");
  263. return (lRetCode == ERROR_SUCCESS);
  264. } // RegWriteString()
  265. /////////////////////////////////////////////////////////////////////
  266. BOOL
  267. RegWriteString(
  268. HKEY hkey, // IN: Key to append to
  269. const WCHAR szKey[], // IN: Key to save
  270. UINT uStringId) // IN: Value of the key
  271. {
  272. if ( szKey )
  273. {
  274. WCHAR szValue[512];
  275. CchLoadString(uStringId, OUT szValue, LENGTH(szValue));
  276. return RegWriteString(hkey, szKey, szValue);
  277. }
  278. else
  279. return FALSE;
  280. }
  281. /////////////////////////////////////////////////////////////////////////////
  282. // HrExtractDataAlloc()
  283. //
  284. // Extract data from a source DataObject for a particular clipboard format.
  285. //
  286. // RETURNS
  287. // Return S_OK if data was successfully retrieved and placed into allocated buffer.
  288. //
  289. // INTERFACE NOTES
  290. // The routine will allocate memory, copy the data from the source to
  291. // the allocated buffer and return a pointer to the allocated buffer.
  292. // The caller is responsible to free the allocated memory using GlobalFree()
  293. // when no longer needed.
  294. //
  295. // IMPLEMENTATION NOTES
  296. // The memory block is allocated by pDataObject->GetData() rather
  297. // than by the routine itself.
  298. //
  299. // HISTORY
  300. // 12-Aug-97 t-danm Creation.
  301. //
  302. HRESULT
  303. HrExtractDataAlloc(
  304. IDataObject * pDataObject, // IN: Data source to extract data from
  305. UINT cfClipboardFormat, // IN: Clipboard format to extract data
  306. PVOID * ppavData, // OUT: Pointer to allocated memory
  307. UINT * pcbData) // OUT: OPTIONAL: Number of bytes stored in memory buffer
  308. {
  309. Assert(pDataObject != NULL);
  310. Assert(cfClipboardFormat != NULL);
  311. Assert(ppavData != NULL);
  312. Assert(*ppavData == NULL && "Memory Leak");
  313. Endorse(pcbData == NULL); // TRUE => Don't care about the size of the allocated buffer
  314. FORMATETC formatetc = { (CLIPFORMAT)cfClipboardFormat, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
  315. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
  316. Assert(stgmedium.hGlobal == NULL);
  317. HRESULT hr = pDataObject->GetData(IN &formatetc, OUT &stgmedium);
  318. if (FAILED(hr))
  319. {
  320. Trace1("HrExtractDataAlloc() - Call to pDataObject->GetData() failed. hr=0x%X.\n", hr);
  321. return hr;
  322. }
  323. if (stgmedium.hGlobal == NULL)
  324. {
  325. // This is because the producer did not set the hGlobal handle
  326. Trace0("HrExtractDataAlloc() - Memory handle hGlobal is NULL.\n");
  327. return S_FALSE;
  328. }
  329. UINT cbData = (UINT)GlobalSize(stgmedium.hGlobal);
  330. if (cbData == 0)
  331. {
  332. Trace1("HrExtractDataAlloc() - Corrupted hGlobal handle. err=%d.\n", GetLastError());
  333. return E_UNEXPECTED;
  334. }
  335. *ppavData = stgmedium.hGlobal;
  336. if (pcbData != NULL)
  337. *pcbData = cbData;
  338. return S_OK;
  339. } // HrExtractDataAlloc()