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.

734 lines
14 KiB

  1. /*++
  2. Copyright (c) 1994-95 Microsoft Corporation
  3. Module Name:
  4. utils.cpp
  5. Abstract:
  6. Utiltities.
  7. Author:
  8. Don Ryan (donryan) 04-Jan-1995
  9. Environment:
  10. User Mode - Win32
  11. Revision History:
  12. Jeff Parham (jeffparh) 12-Nov-1995
  13. Copied from LLSMGR, stripped Tv (Tree view) functions,
  14. removed OLE support
  15. --*/
  16. #include "stdafx.h"
  17. #include "ccfapi.h"
  18. #include "utils.h"
  19. #define _AFX_NO_OLE_SUPPORT
  20. //
  21. // List view utilities
  22. //
  23. void LvInitColumns(CListCtrl* pListCtrl, PLV_COLUMN_INFO plvColumnInfo)
  24. /*++
  25. Routine Description:
  26. Initializes list view columns.
  27. Arguments:
  28. pListCtrl - list control.
  29. plvColumnInfo - column information.
  30. Return Values:
  31. None.
  32. --*/
  33. {
  34. ASSERT(plvColumnInfo);
  35. VALIDATE_OBJECT(pListCtrl, CListCtrl);
  36. int nStringId;
  37. CString strText;
  38. LV_COLUMN lvColumn;
  39. int nColumns = plvColumnInfo->nColumns;
  40. PLV_COLUMN_ENTRY plvColumnEntry = plvColumnInfo->lvColumnEntry;
  41. lvColumn.mask = LVCF_FMT|
  42. LVCF_TEXT|
  43. LVCF_SUBITEM;
  44. lvColumn.fmt = LVCFMT_LEFT;
  45. pListCtrl->SetRedraw(FALSE); // turn off drawing...
  46. while (nColumns--)
  47. {
  48. lvColumn.iSubItem = plvColumnEntry->iSubItem;
  49. if (nStringId = plvColumnEntry->nStringId)
  50. {
  51. strText.LoadString(nStringId);
  52. }
  53. else
  54. {
  55. strText = _T("");
  56. }
  57. lvColumn.pszText = strText.GetBuffer(0);
  58. int nColumnInserted = pListCtrl->InsertColumn( lvColumn.iSubItem, &lvColumn );
  59. ASSERT( -1 != nColumnInserted );
  60. plvColumnEntry++;
  61. strText.ReleaseBuffer();
  62. }
  63. SetDefaultFont(pListCtrl);
  64. LvResizeColumns(pListCtrl, plvColumnInfo);
  65. pListCtrl->SetRedraw(TRUE); // turn on drawing...
  66. }
  67. void LvResizeColumns(CListCtrl* pListCtrl, PLV_COLUMN_INFO plvColumnInfo)
  68. /*++
  69. Routine Description:
  70. Resizes list view columns.
  71. Arguments:
  72. pListCtrl - list control.
  73. plvColumnInfo - column information.
  74. Return Values:
  75. None.
  76. --*/
  77. {
  78. ASSERT(plvColumnInfo);
  79. VALIDATE_OBJECT(pListCtrl, CListCtrl);
  80. int nColumnWidth;
  81. int nRelativeWidth;
  82. int nEntireWidthSoFar = 0;
  83. int nColumns = plvColumnInfo->nColumns;
  84. PLV_COLUMN_ENTRY plvColumnEntry = plvColumnInfo->lvColumnEntry;
  85. CRect clientRect;
  86. pListCtrl->GetClientRect(clientRect);
  87. pListCtrl->SetRedraw(FALSE); // turn off drawing...
  88. while ((nRelativeWidth = plvColumnEntry->nRelativeWidth) != -1)
  89. {
  90. nColumnWidth = (nRelativeWidth * clientRect.Width()) / 100;
  91. pListCtrl->SetColumnWidth(plvColumnEntry->iSubItem, nColumnWidth);
  92. nEntireWidthSoFar += nColumnWidth;
  93. plvColumnEntry++;
  94. }
  95. nColumnWidth = clientRect.Width() - nEntireWidthSoFar;
  96. pListCtrl->SetColumnWidth(plvColumnEntry->iSubItem, nColumnWidth);
  97. pListCtrl->SetRedraw(TRUE); // turn on drawing...
  98. }
  99. void LvChangeFormat(CListCtrl* pListCtrl, UINT nFormatId)
  100. /*++
  101. Routine Description:
  102. Changes window style of list view.
  103. Arguments:
  104. pListCtrl - list control.
  105. nFormatId - format specification.
  106. Return Values:
  107. None.
  108. --*/
  109. {
  110. VALIDATE_OBJECT(pListCtrl, CListCtrl);
  111. DWORD dwStyle = ::GetWindowLong(pListCtrl->GetSafeHwnd(), GWL_STYLE);
  112. pListCtrl->BeginWaitCursor();
  113. pListCtrl->SetRedraw(FALSE); // turn off drawing...
  114. if ((dwStyle & LVS_TYPEMASK) != nFormatId)
  115. {
  116. ::SetWindowLong(
  117. pListCtrl->GetSafeHwnd(),
  118. GWL_STYLE,
  119. (dwStyle & ~LVS_TYPEMASK) | nFormatId
  120. );
  121. }
  122. pListCtrl->SetRedraw(TRUE); // turn on drawing...
  123. pListCtrl->EndWaitCursor();
  124. }
  125. LPVOID LvGetSelObj(CListCtrl* pListCtrl)
  126. /*++
  127. Routine Description:
  128. Retrieves the object selected (assumes one) from list view.
  129. Arguments:
  130. pListCtrl - list control.
  131. Return Values:
  132. Same as LvGetNextObj.
  133. --*/
  134. {
  135. int iItem = -1;
  136. return LvGetNextObj(pListCtrl, &iItem);
  137. }
  138. LPVOID LvGetNextObj(CListCtrl* pListCtrl, LPINT piItem, int nType)
  139. /*++
  140. Routine Description:
  141. Retrieves the next object selected from list view.
  142. Arguments:
  143. pListCtrl - list control.
  144. piItem - starting index (updated).
  145. nType - specifies search criteria.
  146. Return Values:
  147. Returns object pointer or null.
  148. --*/
  149. {
  150. ASSERT(piItem);
  151. VALIDATE_OBJECT(pListCtrl, CListCtrl);
  152. LV_ITEM lvItem;
  153. if ((lvItem.iItem = pListCtrl->GetNextItem(*piItem, nType)) != -1)
  154. {
  155. lvItem.mask = LVIF_PARAM;
  156. lvItem.iSubItem = 0;
  157. if (pListCtrl->GetItem(&lvItem))
  158. {
  159. *piItem = lvItem.iItem;
  160. return (LPVOID)lvItem.lParam;
  161. }
  162. }
  163. return NULL;
  164. }
  165. BOOL LvInsertObArray(CListCtrl* pListCtrl, PLV_COLUMN_INFO plvColumnInfo, CObArray* pObArray)
  166. /*++
  167. Routine Description:
  168. Insert object array into list view.
  169. Note list view must be unsorted and support LVN_GETDISPINFO.
  170. Arguments:
  171. pListCtrl - list control.
  172. plvColumnInfo - column info.
  173. pObArray - object array.
  174. Return Values:
  175. VT_BOOL.
  176. --*/
  177. {
  178. VALIDATE_OBJECT(pObArray, CObArray);
  179. VALIDATE_OBJECT(pListCtrl, CListCtrl);
  180. ASSERT(plvColumnInfo);
  181. ASSERT(pListCtrl->GetItemCount() == 0);
  182. BOOL bItemsInserted = FALSE;
  183. LV_ITEM lvItem;
  184. lvItem.mask = LVIF_TEXT|
  185. LVIF_PARAM|
  186. LVIF_IMAGE;
  187. lvItem.pszText = LPSTR_TEXTCALLBACK;
  188. lvItem.cchTextMax = LPSTR_TEXTCALLBACK_MAX;
  189. lvItem.iImage = I_IMAGECALLBACK;
  190. lvItem.iSubItem = 0;
  191. int iItem;
  192. int iSubItem;
  193. int nItems = (int)pObArray->GetSize();
  194. ASSERT(nItems != -1); // iItem is -1 if error...
  195. pListCtrl->SetRedraw(FALSE); // turn off drawing...
  196. pListCtrl->SetItemCount(nItems);
  197. CObject* pObject = NULL;
  198. for (iItem = 0; (-1 != iItem) && (iItem < nItems) && (pObject = pObArray->GetAt(iItem)); iItem++)
  199. {
  200. VALIDATE_OBJECT(pObject, CObject);
  201. lvItem.iItem = iItem;
  202. lvItem.lParam = (LPARAM)(LPVOID)pObject;
  203. iItem = pListCtrl->InsertItem(&lvItem);
  204. ASSERT((iItem == lvItem.iItem) || (iItem == -1));
  205. if ( -1 != iItem )
  206. {
  207. for (iSubItem = 1; iSubItem < plvColumnInfo->nColumns; iSubItem++)
  208. {
  209. BOOL ok = pListCtrl->SetItemText(iItem, iSubItem, LPSTR_TEXTCALLBACK);
  210. ASSERT( ok );
  211. }
  212. }
  213. }
  214. if (iItem == nItems)
  215. {
  216. bItemsInserted = TRUE;
  217. VERIFY(pListCtrl->SetItemState(
  218. 0,
  219. LVIS_FOCUSED|
  220. LVIS_SELECTED,
  221. LVIS_FOCUSED|
  222. LVIS_SELECTED
  223. ));
  224. }
  225. else
  226. {
  227. theApp.SetLastError(ERROR_OUTOFMEMORY);
  228. VERIFY(pListCtrl->DeleteAllItems());
  229. }
  230. LvResizeColumns(pListCtrl, plvColumnInfo);
  231. pListCtrl->SetRedraw(TRUE); // turn on drawing...
  232. return bItemsInserted;
  233. }
  234. BOOL
  235. LvRefreshObArray(
  236. CListCtrl* pListCtrl,
  237. PLV_COLUMN_INFO plvColumnInfo,
  238. CObArray* pObArray
  239. )
  240. /*++
  241. Routine Description:
  242. Refresh object array in list view.
  243. Arguments:
  244. pListCtrl - list control.
  245. plvColumnInfo - column info.
  246. pObArray - object array.
  247. Return Values:
  248. VT_BOOL.
  249. --*/
  250. {
  251. ASSERT(plvColumnInfo);
  252. VALIDATE_OBJECT(pObArray, CObArray);
  253. VALIDATE_OBJECT(pListCtrl, CListCtrl);
  254. long nObjects = (long)pObArray->GetSize();
  255. long nObjectsInList = pListCtrl->GetItemCount();
  256. if (!nObjects)
  257. {
  258. LvReleaseObArray(pListCtrl);
  259. return TRUE;
  260. }
  261. else if (!nObjectsInList)
  262. {
  263. return LvInsertObArray(
  264. pListCtrl,
  265. plvColumnInfo,
  266. pObArray
  267. );
  268. }
  269. CObject* pObject;
  270. int iObject = 0;
  271. int iObjectInList = 0;
  272. LV_ITEM lvItem;
  273. pListCtrl->SetRedraw(FALSE); // turn off drawing...
  274. while (nObjectsInList--)
  275. {
  276. lvItem.mask = LVIF_PARAM;
  277. lvItem.iItem = iObjectInList;
  278. lvItem.iSubItem = 0;
  279. VERIFY(pListCtrl->GetItem(&lvItem));
  280. pObject = (CObject*)lvItem.lParam;
  281. VALIDATE_OBJECT(pObject, CObject);
  282. if (iObject < nObjects)
  283. {
  284. pObject = pObArray->GetAt(iObject++);
  285. VALIDATE_OBJECT(pObject, CObject);
  286. lvItem.mask = LVIF_TEXT|LVIF_PARAM;
  287. lvItem.pszText = LPSTR_TEXTCALLBACK;
  288. lvItem.cchTextMax = LPSTR_TEXTCALLBACK_MAX;
  289. lvItem.lParam = (LPARAM)(LPVOID)pObject;
  290. VERIFY(pListCtrl->SetItem(&lvItem)); // overwrite...
  291. iObjectInList++; // increment count...
  292. }
  293. else
  294. {
  295. VERIFY(pListCtrl->DeleteItem(iObjectInList));
  296. }
  297. }
  298. lvItem.mask = LVIF_TEXT|
  299. LVIF_PARAM|
  300. LVIF_IMAGE;
  301. lvItem.pszText = LPSTR_TEXTCALLBACK;
  302. lvItem.cchTextMax = LPSTR_TEXTCALLBACK_MAX;
  303. lvItem.iImage = I_IMAGECALLBACK;
  304. lvItem.iSubItem = 0;
  305. int iItem;
  306. int iSubItem;
  307. while (iObject < nObjects)
  308. {
  309. lvItem.iItem = iObject;
  310. pObject = pObArray->GetAt(iObject++);
  311. VALIDATE_OBJECT(pObject, CObject);
  312. lvItem.lParam = (LPARAM)(LPVOID)pObject;
  313. iItem = pListCtrl->InsertItem(&lvItem);
  314. ASSERT((iItem == lvItem.iItem) && (iItem != -1));
  315. for (iSubItem = 1; iSubItem < plvColumnInfo->nColumns; iSubItem++)
  316. {
  317. VERIFY(pListCtrl->SetItemText(iItem, iSubItem, LPSTR_TEXTCALLBACK));
  318. }
  319. }
  320. LvResizeColumns(pListCtrl, plvColumnInfo);
  321. pListCtrl->SetRedraw(TRUE); // turn on drawing...
  322. return TRUE;
  323. }
  324. void LvReleaseObArray(CListCtrl* pListCtrl)
  325. /*++
  326. Routine Description:
  327. Release objects inserted into list view.
  328. Arguments:
  329. pListCtrl - list control.
  330. Return Values:
  331. None.
  332. --*/
  333. {
  334. VALIDATE_OBJECT(pListCtrl, CListCtrl);
  335. LV_ITEM lvItem;
  336. CObject* pObject;
  337. lvItem.mask = LVIF_PARAM;
  338. lvItem.iItem = 0;
  339. lvItem.iSubItem = 0;
  340. int nObjectsInList = pListCtrl->GetItemCount();
  341. pListCtrl->BeginWaitCursor();
  342. pListCtrl->SetRedraw(FALSE); // turn off drawing...
  343. while (nObjectsInList--)
  344. {
  345. VERIFY(pListCtrl->GetItem(&lvItem));
  346. pObject = (CObject*)lvItem.lParam;
  347. VALIDATE_OBJECT(pObject, CObject);
  348. VERIFY(pListCtrl->DeleteItem(lvItem.iItem));
  349. }
  350. pListCtrl->SetRedraw(TRUE); // turn on drawing...
  351. pListCtrl->EndWaitCursor();
  352. }
  353. void LvReleaseSelObjs(CListCtrl* pListCtrl)
  354. /*++
  355. Routine Description:
  356. Release selected objects in list view.
  357. Arguments:
  358. pListCtrl - list control.
  359. Return Values:
  360. None.
  361. --*/
  362. {
  363. VALIDATE_OBJECT(pListCtrl, CListCtrl);
  364. LV_ITEM lvItem;
  365. lvItem.mask = LVIF_PARAM;
  366. lvItem.iSubItem = 0;
  367. CObject* pObject;
  368. pListCtrl->SetRedraw(FALSE); // turn off drawing...
  369. int iItem = pListCtrl->GetNextItem(-1, LVNI_ALL|LVNI_SELECTED);
  370. while (iItem != -1)
  371. {
  372. lvItem.iItem = iItem;
  373. VERIFY(pListCtrl->GetItem(&lvItem));
  374. pObject = (CObject*)lvItem.lParam;
  375. VALIDATE_OBJECT(pObject, CObject);
  376. iItem = pListCtrl->GetNextItem(lvItem.iItem, LVNI_ALL|LVNI_SELECTED);
  377. VERIFY(pListCtrl->DeleteItem(lvItem.iItem));
  378. }
  379. LvSelObjIfNecessary(pListCtrl);
  380. pListCtrl->SetRedraw(TRUE); // turn on drawing...
  381. }
  382. void LvSelObjIfNecessary(CListCtrl* pListCtrl, BOOL bSetFocus)
  383. /*++
  384. Routine Description:
  385. Ensure that object selected.
  386. Arguments:
  387. pListCtrl - list control.
  388. bSetFocus - true if focus to be set focus as well.
  389. Return Values:
  390. None.
  391. --*/
  392. {
  393. VALIDATE_OBJECT(pListCtrl, CListCtrl);
  394. if (!IsItemSelectedInList(pListCtrl) && pListCtrl->GetItemCount())
  395. {
  396. pListCtrl->SendMessage(WM_KEYDOWN, VK_RIGHT); // HACKHACK...
  397. int iItem = pListCtrl->GetNextItem(-1, LVNI_FOCUSED|LVNI_ALL);
  398. int nState = bSetFocus ? (LVIS_SELECTED|LVIS_FOCUSED) : LVIS_SELECTED;
  399. VERIFY(pListCtrl->SetItemState((iItem == -1) ? 0 : iItem, nState, nState));
  400. }
  401. }
  402. #ifdef _DEBUG
  403. void LvDumpObArray(CListCtrl* pListCtrl)
  404. /*++
  405. Routine Description:
  406. Release objects inserted into list view.
  407. Arguments:
  408. pListCtrl - list control.
  409. Return Values:
  410. None.
  411. --*/
  412. {
  413. VALIDATE_OBJECT(pListCtrl, CListCtrl);
  414. LV_ITEM lvItem;
  415. CString strDump;
  416. CObject* pObject;
  417. lvItem.mask = LVIF_STATE|LVIF_PARAM;
  418. lvItem.stateMask = (DWORD)-1;
  419. lvItem.iSubItem = 0;
  420. int nObjectsInList = pListCtrl->GetItemCount();
  421. pListCtrl->SetRedraw(FALSE); // turn off drawing...
  422. while (nObjectsInList--)
  423. {
  424. lvItem.iItem = nObjectsInList;
  425. VERIFY(pListCtrl->GetItem(&lvItem));
  426. pObject = (CObject*)lvItem.lParam;
  427. VALIDATE_OBJECT(pObject, CObject);
  428. strDump.Format(_T("iItem %d"), lvItem.iItem);
  429. strDump += (lvItem.state & LVIS_CUT) ? _T(" LVIS_CUT ") : _T("");
  430. strDump += (lvItem.state & LVIS_FOCUSED) ? _T(" LVIS_FOCUSED ") : _T("");
  431. strDump += (lvItem.state & LVIS_SELECTED) ? _T(" LVIS_SELECTED ") : _T("");
  432. strDump += _T("\r\n");
  433. afxDump << strDump;
  434. }
  435. pListCtrl->SetRedraw(TRUE); // turn on drawing...
  436. }
  437. #endif
  438. void SetDefaultFont(CWnd* pWnd)
  439. /*++
  440. Routine Description:
  441. Set default font.
  442. Arguments:
  443. pWnd - window to change font.
  444. Return Values:
  445. None.
  446. --*/
  447. {
  448. VALIDATE_OBJECT(pWnd, CWnd);
  449. HFONT hFont;
  450. LOGFONT lFont;
  451. CHARSETINFO csi;
  452. DWORD dw = ::GetACP();
  453. TCHAR szData[7] ;
  454. LANGID wLang = GetUserDefaultUILanguage();
  455. csi.ciCharset = DEFAULT_CHARSET;
  456. if( GetLocaleInfo(MAKELCID(wLang, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, szData, (sizeof( szData ) / sizeof( TCHAR ))) > 0)
  457. {
  458. UINT uiCp = _ttoi(szData);
  459. TranslateCharsetInfo((DWORD*) (DWORD_PTR)uiCp, &csi, TCI_SRCCODEPAGE);
  460. }
  461. memset(&lFont, 0, sizeof(LOGFONT)); // initialize
  462. //
  463. // Merged from FE NT 4.0.
  464. //
  465. // if (!::TranslateCharsetInfo((DWORD*)dw, &csi, TCI_SRCCODEPAGE))
  466. // csi.ciCharset = DEFAULT_CHARSET;
  467. lFont.lfCharSet = (BYTE)csi.ciCharset;
  468. lFont.lfHeight = 13;
  469. lFont.lfWeight = 200; // non-bold
  470. hFont = ::CreateFontIndirect(&lFont);
  471. pWnd->SetFont(CFont::FromHandle(hFont));
  472. }