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.

369 lines
12 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1998.
  5. //
  6. // File: CatList.cpp
  7. //
  8. // Contents: main tool-wide categories list property page
  9. //
  10. // Classes: CCatList
  11. //
  12. // History: 03-14-1998 stevebl Commented
  13. //
  14. //---------------------------------------------------------------------------
  15. #include "precomp.hxx"
  16. #ifdef _DEBUG
  17. #define new DEBUG_NEW
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21. #define MAXCATEGORYNAME 40
  22. /////////////////////////////////////////////////////////////////////////////
  23. // CCatList property page
  24. IMPLEMENT_DYNCREATE(CCatList, CPropertyPage)
  25. CCatList::CCatList() : CPropertyPage(CCatList::IDD)
  26. {
  27. //{{AFX_DATA_INIT(CCatList)
  28. //}}AFX_DATA_INIT
  29. }
  30. CCatList::~CCatList()
  31. {
  32. *m_ppThis = NULL;
  33. }
  34. void CCatList::DoDataExchange(CDataExchange* pDX)
  35. {
  36. CPropertyPage::DoDataExchange(pDX);
  37. //{{AFX_DATA_MAP(CCatList)
  38. DDX_Control(pDX, IDC_LIST1, m_cList);
  39. //}}AFX_DATA_MAP
  40. }
  41. BEGIN_MESSAGE_MAP(CCatList, CPropertyPage)
  42. //{{AFX_MSG_MAP(CCatList)
  43. ON_BN_CLICKED(IDC_BUTTON1, OnAdd)
  44. ON_BN_CLICKED(IDC_BUTTON2, OnRemove)
  45. ON_LBN_DBLCLK(IDC_LIST1, OnModify)
  46. ON_BN_CLICKED(IDC_BUTTON3, OnModify)
  47. ON_WM_CONTEXTMENU()
  48. //}}AFX_MSG_MAP
  49. END_MESSAGE_MAP()
  50. /////////////////////////////////////////////////////////////////////////////
  51. // CCatList message handlers
  52. void CCatList::OnAdd()
  53. {
  54. CEditString dlgEditString;
  55. dlgEditString.m_szTitle.LoadString(IDS_NEWCATEGORY);
  56. if (IDOK == dlgEditString.DoModal())
  57. {
  58. if (dlgEditString.m_sz.GetLength() == 0)
  59. {
  60. // empty name
  61. CString szMessage;
  62. szMessage.LoadString(IDS_SHORTCATNAME);
  63. MessageBox(szMessage,
  64. NULL,
  65. MB_OK | MB_ICONEXCLAMATION);
  66. return;
  67. }
  68. if (dlgEditString.m_sz.GetLength() > MAXCATEGORYNAME)
  69. {
  70. // long name
  71. CString szMessage;
  72. szMessage.LoadString(IDS_LONGCATNAME);
  73. MessageBox(szMessage,
  74. NULL,
  75. MB_OK | MB_ICONEXCLAMATION);
  76. return;
  77. }
  78. // only add categories that are unique
  79. if (m_Categories.find(dlgEditString.m_sz) == m_Categories.end())
  80. {
  81. m_Categories.insert(pair<const CString,ULONG>(dlgEditString.m_sz, (ULONG)-1));
  82. m_cList.AddString(dlgEditString.m_sz);
  83. m_cList.SelectString(0, dlgEditString.m_sz);
  84. GetDlgItem(IDC_BUTTON2)->EnableWindow(TRUE);
  85. GetDlgItem(IDC_BUTTON3)->EnableWindow(TRUE);
  86. CDC * pDC = m_cList.GetDC();
  87. CSize size = pDC->GetTextExtent(dlgEditString.m_sz);
  88. pDC->LPtoDP(&size);
  89. m_cList.ReleaseDC(pDC);
  90. if (m_cList.GetHorizontalExtent() < size.cx)
  91. {
  92. m_cList.SetHorizontalExtent(size.cx);
  93. }
  94. SetModified();
  95. }
  96. }
  97. }
  98. void CCatList::OnRemove()
  99. {
  100. int i = m_cList.GetCurSel();
  101. if (i != LB_ERR)
  102. {
  103. CString sz;
  104. m_cList.GetText(i, sz);
  105. m_Categories.erase(m_Categories.find(sz));
  106. m_cList.DeleteString(i);
  107. if (i > 0 && i >= m_cList.GetCount())
  108. {
  109. i = m_cList.GetCount() - 1;
  110. }
  111. m_cList.SetCurSel(i);
  112. int n = m_cList.GetCount();
  113. BOOL fEnable = n > 0;
  114. GetDlgItem(IDC_BUTTON2)->EnableWindow(fEnable);
  115. GetDlgItem(IDC_BUTTON3)->EnableWindow(fEnable);
  116. if (NULL == GetFocus())
  117. {
  118. GetParent()->GetDlgItem(IDOK)->SetFocus();
  119. }
  120. SetModified();
  121. }
  122. }
  123. LRESULT CCatList::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
  124. {
  125. switch (message)
  126. {
  127. case WM_HELP:
  128. StandardHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, IDD);
  129. return 0;
  130. case WM_USER_REFRESH:
  131. RefreshData();
  132. return 0;
  133. case WM_USER_CLOSE:
  134. return GetOwner()->SendMessage(WM_CLOSE);
  135. default:
  136. return CPropertyPage::WindowProc(message, wParam, lParam);
  137. }
  138. }
  139. void CCatList::RefreshData(void)
  140. {
  141. // build up m_Categories and populate the list box
  142. m_cList.ResetContent();
  143. m_cList.SetHorizontalExtent(0);
  144. m_Categories.erase(m_Categories.begin(), m_Categories.end());
  145. UINT i = m_pScopePane->m_CatList.cCategory;
  146. while (i--)
  147. {
  148. m_Categories.insert(pair<const CString, ULONG>(m_pScopePane->m_CatList.pCategoryInfo[i].pszDescription, i));
  149. m_cList.AddString(m_pScopePane->m_CatList.pCategoryInfo[i].pszDescription);
  150. CDC * pDC = m_cList.GetDC();
  151. CSize size = pDC->GetTextExtent(m_pScopePane->m_CatList.pCategoryInfo[i].pszDescription);
  152. pDC->LPtoDP(&size);
  153. m_cList.ReleaseDC(pDC);
  154. if (m_cList.GetHorizontalExtent() < size.cx)
  155. {
  156. m_cList.SetHorizontalExtent(size.cx);
  157. }
  158. }
  159. m_cList.SetCurSel(0);
  160. int n = m_cList.GetCount();
  161. BOOL fEnable = (n > 0) && (!m_fRSOP);
  162. GetDlgItem(IDC_BUTTON2)->EnableWindow(fEnable);
  163. GetDlgItem(IDC_BUTTON3)->EnableWindow(fEnable);
  164. if (NULL == GetFocus())
  165. {
  166. GetParent()->GetDlgItem(IDOK)->SetFocus();
  167. }
  168. SetModified(FALSE);
  169. }
  170. BOOL CCatList::OnInitDialog()
  171. {
  172. CPropertyPage::OnInitDialog();
  173. CWnd * pCtrl = GetDlgItem(IDC_STATIC1);
  174. CString sz;
  175. CString szNew;
  176. pCtrl->GetWindowText(sz);
  177. szNew.Format(sz, m_szDomainName);
  178. pCtrl->SetWindowText(szNew);
  179. // unmarshal the IClassAdmin interface
  180. RefreshData();
  181. return TRUE; // return TRUE unless you set the focus to a control
  182. // EXCEPTION: OCX Property Pages should return FALSE
  183. }
  184. void CCatList::OnModify()
  185. {
  186. int i = m_cList.GetCurSel();
  187. if (i != LB_ERR)
  188. {
  189. CEditString dlgEditString;
  190. dlgEditString.m_szTitle.LoadString(IDS_CHANGECATEGORY);
  191. CString sz;
  192. m_cList.GetText(i, sz);
  193. dlgEditString.m_sz = sz;
  194. if (IDOK == dlgEditString.DoModal())
  195. {
  196. if (dlgEditString.m_sz.GetLength() == 0)
  197. {
  198. // empty name
  199. CString szMessage;
  200. szMessage.LoadString(IDS_SHORTCATNAME);
  201. MessageBox( szMessage,
  202. NULL,
  203. MB_OK | MB_ICONEXCLAMATION);
  204. return;
  205. }
  206. if (dlgEditString.m_sz.GetLength() > MAXCATEGORYNAME)
  207. {
  208. // long name
  209. CString szMessage;
  210. szMessage.LoadString(IDS_LONGCATNAME);
  211. MessageBox( szMessage,
  212. NULL,
  213. MB_OK | MB_ICONEXCLAMATION);
  214. return;
  215. }
  216. multimap<CString, ULONG>::iterator element = m_Categories.find(sz);
  217. ULONG index = element->second;
  218. m_Categories.erase(element);
  219. m_Categories.insert(pair<const CString, ULONG>(dlgEditString.m_sz, index));
  220. m_cList.DeleteString(i);
  221. m_cList.AddString(dlgEditString.m_sz);
  222. m_cList.SelectString(0, dlgEditString.m_sz);
  223. CDC * pDC = m_cList.GetDC();
  224. CSize size = pDC->GetTextExtent(dlgEditString.m_sz);
  225. pDC->LPtoDP(&size);
  226. m_cList.ReleaseDC(pDC);
  227. if (m_cList.GetHorizontalExtent() < size.cx)
  228. {
  229. m_cList.SetHorizontalExtent(size.cx);
  230. }
  231. SetModified();
  232. }
  233. }
  234. }
  235. BOOL CCatList::OnApply()
  236. {
  237. if (this->m_fRSOP)
  238. {
  239. return CPropertyPage::OnApply();
  240. }
  241. // Build up a set of indexes. As an element is found in our private
  242. // list, it will be removed from this set. Whatever is left in the set
  243. // are elements that are to be removed from the class store.
  244. set<ULONG> sIndexes;
  245. ULONG n = m_pScopePane->m_CatList.cCategory;
  246. while (n--)
  247. {
  248. sIndexes.insert(n);
  249. }
  250. // walk our list of categories modifying or adding categories on the
  251. // class store as necessary
  252. HRESULT hr = S_OK;
  253. multimap<CString, ULONG>::iterator element;
  254. for (element = m_Categories.begin(); element != m_Categories.end(); element++)
  255. {
  256. if (element->second == (ULONG)-1)
  257. {
  258. // this is a new category
  259. APPCATEGORYINFO AppCategory;
  260. AppCategory.Locale = GetUserDefaultLCID();
  261. AppCategory.pszDescription = (LPOLESTR)((LPCOLESTR)element->first);
  262. hr = CoCreateGuid(&AppCategory.AppCategoryId);
  263. if (FAILED(hr))
  264. {
  265. LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_NOCATEGORYGUID_ERROR, hr, AppCategory.pszDescription);
  266. goto failure;
  267. }
  268. hr = CsRegisterAppCategory(&AppCategory);
  269. if (FAILED(hr))
  270. {
  271. LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_ADDCATEGORY_ERROR, hr, AppCategory.pszDescription);
  272. goto failure;
  273. }
  274. LogADEEvent(EVENTLOG_SUCCESS, EVENT_ADE_ADDCATEGORY, hr, AppCategory.pszDescription);
  275. }
  276. else
  277. {
  278. // this is an old category
  279. sIndexes.erase(element->second);
  280. if (0 != element->first.Compare(m_pScopePane->m_CatList.pCategoryInfo[element->second].pszDescription))
  281. {
  282. // the category has been renamed
  283. APPCATEGORYINFO AppCategory;
  284. AppCategory.Locale = GetUserDefaultLCID();
  285. AppCategory.pszDescription = (LPOLESTR)((LPCOLESTR)element->first);
  286. AppCategory.AppCategoryId = m_pScopePane->m_CatList.pCategoryInfo[element->second].AppCategoryId;
  287. hr = CsRegisterAppCategory(&AppCategory);
  288. if (FAILED(hr))
  289. {
  290. LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_RENAMECATEGORY_ERROR, hr, AppCategory.pszDescription);
  291. goto failure;
  292. }
  293. LogADEEvent(EVENTLOG_SUCCESS, EVENT_ADE_RENAMECATEGORY, hr, AppCategory.pszDescription);
  294. }
  295. }
  296. }
  297. // remove deleted categories
  298. {
  299. set<ULONG>::iterator i;
  300. for (i = sIndexes.begin(); i != sIndexes.end(); i++)
  301. {
  302. hr = CsUnregisterAppCategory(&m_pScopePane->m_CatList.pCategoryInfo[*i].AppCategoryId);
  303. if (FAILED(hr))
  304. {
  305. LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_REMOVECATEGORY_ERROR, hr, m_pScopePane->m_CatList.pCategoryInfo[*i].pszDescription);
  306. goto failure;
  307. }
  308. LogADEEvent(EVENTLOG_SUCCESS, EVENT_ADE_REMOVECATEGORY, hr, m_pScopePane->m_CatList.pCategoryInfo[*i].pszDescription);
  309. }
  310. }
  311. failure:
  312. // reload the list of categories from the class store
  313. m_pScopePane->ClearCategories();
  314. CsGetAppCategories(&m_pScopePane->m_CatList);
  315. // tell any open package category property pages to refresh
  316. {
  317. map<MMC_COOKIE, CAppData>::iterator i;
  318. for (i = m_pScopePane->m_AppData.begin(); i != m_pScopePane->m_AppData.end(); i++)
  319. {
  320. if (i->second.m_pCategory)
  321. {
  322. i->second.m_pCategory->SendMessage(WM_USER_REFRESH, 0, 0);
  323. }
  324. }
  325. }
  326. // refresh the data
  327. RefreshData();
  328. if (FAILED(hr))
  329. {
  330. CString sz;
  331. sz.LoadString(IDS_CATEGORYFAILED);
  332. ReportGeneralPropertySheetError(m_hWnd, sz, hr);
  333. return FALSE;
  334. }
  335. return CPropertyPage::OnApply();
  336. }
  337. void CCatList::OnContextMenu(CWnd* pWnd, CPoint point)
  338. {
  339. StandardContextMenu(pWnd->m_hWnd, IDD_CATEGORIES);
  340. }