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.

837 lines
26 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Windows NT Directory Service Property Pages
  4. //
  5. // Microsoft Windows
  6. // Copyright (C) Microsoft Corporation, 1992 - 2001
  7. //
  8. // File: shlprop.cxx
  9. //
  10. // Contents: Tables for table-driven Shell DS property pages
  11. //
  12. // History: 14-July-97 Jimharr created from dsprop.cxx by ericb
  13. //
  14. // Note: Attribute LDAP display names, types, upper ranges, and so
  15. // forth, have been manually copied from schema.ini. Thus,
  16. // consistency is going to be difficult to maintain. If you know
  17. // of schema.ini changes that affect any of the attributes in
  18. // this file, then please make any necessary corrections here.
  19. //
  20. //-----------------------------------------------------------------------------
  21. #include "pch.h"
  22. #include "proppage.h"
  23. #include "user.h"
  24. #include "group.h"
  25. #include "computer.h"
  26. #include "pages.hm" // HIDC_*
  27. #include <ntdsadef.h>
  28. #include "dsprop.cxx"
  29. HRESULT
  30. ROList(CDsPropPageBase * pPage, PATTR_MAP pAttrMap, PADS_ATTR_INFO pAttrInfo,
  31. LPARAM lParam, PATTR_DATA pAttrData, DLG_OP DlgOp);
  32. #define NT_GROUP_PAGE
  33. #ifdef NT_GROUP_PAGE
  34. HRESULT
  35. BmpPictureCtrl(CDsPropPageBase * pPage, PATTR_MAP pAttrMap,
  36. PADS_ATTR_INFO pAttrInfo, LPARAM lParam, PATTR_DATA pAttrData,
  37. DLG_OP DlgOp);
  38. INT_PTR CALLBACK
  39. PictureDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  40. //+----------------------------------------------------------------------------
  41. //
  42. // Class: CBmpPicCtrl
  43. //
  44. // Purpose: Picture control sub-class window proc for displaying bitmaps.
  45. //
  46. //-----------------------------------------------------------------------------
  47. class CBmpPicCtrl
  48. {
  49. public:
  50. #ifdef _DEBUG
  51. char szClass[32];
  52. #endif
  53. CBmpPicCtrl(HWND hCtrl, PBYTE pb);
  54. ~CBmpPicCtrl(void);
  55. //
  56. // Static WndProc to be passed as subclass address.
  57. //
  58. static LRESULT CALLBACK StaticCtrlProc(HWND hWnd, UINT uMsg,
  59. WPARAM wParam, LPARAM lParam);
  60. //
  61. // Member functions, called by WndProc
  62. //
  63. LRESULT OnPaint(void);
  64. HRESULT CreateBmpPalette(void);
  65. //
  66. // Data members
  67. //
  68. protected:
  69. HWND m_hCtrl;
  70. HWND m_hDlg;
  71. WNDPROC m_pOldProc;
  72. PBYTE m_pbBmp;
  73. HPALETTE m_hPal;
  74. };
  75. #endif // NT_GROUP_PAGE
  76. //+----------------------------------------------------------------------------
  77. // User Object.
  78. //-----------------------------------------------------------------------------
  79. //
  80. // General page, first name
  81. //
  82. ATTR_MAP USGFirstName = {IDC_SH_FIRST_NAME_EDIT, FALSE, FALSE, 64,
  83. {L"givenName", ADS_ATTR_UPDATE,
  84. ADSTYPE_CASE_IGNORE_STRING, NULL, 0}, NULL, NULL};
  85. //
  86. // General page, last name
  87. //
  88. ATTR_MAP USGLastName = {IDC_SH_LAST_NAME_EDIT, FALSE, FALSE, 64,
  89. {L"sn", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING,
  90. NULL, 0}, NULL, NULL};
  91. //
  92. // General page, friendly name
  93. //
  94. ATTR_MAP USGFriendlyName = {IDC_SH_DISPLAY_NAME_EDIT, FALSE, FALSE,
  95. ATTR_LEN_UNLIMITED, {L"displayName",
  96. ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING,
  97. NULL, 0}, NULL, NULL};
  98. //
  99. // General page, phone number
  100. //
  101. ATTR_MAP USGPhone = {IDC_PHONE_EDIT, FALSE, FALSE, 32,
  102. {L"telephoneNumber", ADS_ATTR_UPDATE,
  103. ADSTYPE_CASE_IGNORE_STRING, NULL, 0}, NULL, NULL};
  104. //
  105. // General page, email
  106. //
  107. ATTR_MAP USGEMail = {IDC_EMAIL_EDIT, FALSE, FALSE, 256,
  108. {L"mail", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING,
  109. NULL, 0}, NULL, NULL};
  110. //
  111. // General page, URL
  112. //
  113. ATTR_MAP USGURL = {IDC_URL_EDIT, FALSE, FALSE, 2048,
  114. {L"wWWHomePage", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, NULL,
  115. 0}, NULL, NULL};
  116. //
  117. // The list of attributes on the User General page.
  118. //
  119. PATTR_MAP rgpUSGAttrMap[] = {{&GenIcon}, {&AttrName}, {&USGFirstName},
  120. {&USGLastName}, {&USGFriendlyName},
  121. {&USGPhone}, {&USGEMail}, {&USGURL}};
  122. //--------------------------------------------------------
  123. // Business page, title
  124. //
  125. ATTR_MAP USBTitle = {IDC_TITLE, FALSE, FALSE, ATTR_LEN_UNLIMITED,
  126. {L"title", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING,
  127. NULL, 0}, NULL, NULL};
  128. //
  129. // Business page, Company
  130. //
  131. ATTR_MAP USBCo = {IDC_COMPANY, FALSE, FALSE, 64,
  132. {L"company", ADS_ATTR_UPDATE,
  133. ADSTYPE_CASE_IGNORE_STRING, NULL, 0}, NULL, NULL};
  134. //
  135. // Business page, Department
  136. //
  137. ATTR_MAP USBDept = {IDC_DEPARTMENT, FALSE, FALSE, 64,
  138. {L"department", ADS_ATTR_UPDATE,
  139. ADSTYPE_CASE_IGNORE_STRING, NULL, 0}, NULL, NULL};
  140. //
  141. // Business page, office
  142. //
  143. ATTR_MAP USBOffice = {IDC_OFFICE, FALSE, FALSE, 128,
  144. {L"physicalDeliveryOfficeName", ADS_ATTR_UPDATE,
  145. ADSTYPE_CASE_IGNORE_STRING, NULL, 0}, NULL, NULL};
  146. //
  147. // Business page, Manager
  148. //
  149. ATTR_MAP USBMgr = {IDC_MANAGER, TRUE, FALSE, ATTR_LEN_UNLIMITED,
  150. {L"manager", ADS_ATTR_UPDATE,
  151. ADSTYPE_DN_STRING, NULL, 0}, ManagerEdit, NULL};
  152. //
  153. // Business page, direct reports
  154. //
  155. ATTR_MAP USBReports = {IDC_REPORTS_LIST, TRUE, TRUE, 0,
  156. {L"directReports", ADS_ATTR_UPDATE,
  157. ADSTYPE_DN_STRING, NULL, 0}, DirectReportsList, NULL};
  158. //
  159. // The list of attributes on the User Business page.
  160. //
  161. PATTR_MAP rgpUSBAttrMap[] = {{&USBTitle}, {&USBCo}, {&USBDept}, {&USBOffice},
  162. {&USBMgr}, {&USBReports}};
  163. //
  164. // The User General page description.
  165. //
  166. DSPAGE ShellUserGeneral = {IDS_TITLE_GENERAL, IDD_SHELL_USER_GEN, 0, 0, NULL,
  167. CreateTableDrivenPage,
  168. sizeof(rgpUSGAttrMap)/sizeof(PATTR_MAP), rgpUSGAttrMap};
  169. //
  170. // The User Business page description.
  171. //
  172. DSPAGE ShellUserBusiness = {IDS_TITLE_BUSINESS, IDD_SHELL_BUSINESS, 0, 0, NULL,
  173. CreateTableDrivenPage,
  174. sizeof(rgpUSBAttrMap)/sizeof(PATTR_MAP), rgpUSBAttrMap};
  175. #ifdef NT_GROUP_PAGE
  176. //----------------------------------------------
  177. // Special User page, Home phone primary/other
  178. //
  179. ATTR_MAP USpecHomePhone = {IDC_HOMEPHONE_EDIT, FALSE, FALSE, 64,
  180. {L"homePhone", ADS_ATTR_UPDATE,
  181. ADSTYPE_CASE_IGNORE_STRING, NULL, 0}, NULL, NULL};
  182. ATTR_MAP USpecHomeOther = {IDC_OTHER_HOME_BTN, FALSE, TRUE, 64,
  183. {L"otherHomePhone", ADS_ATTR_UPDATE,
  184. ADSTYPE_CASE_IGNORE_STRING, NULL, 0}, OtherValuesBtn, NULL};
  185. //
  186. // Special page, Pager
  187. //
  188. ATTR_MAP USpecPager = {IDC_PAGER_EDIT, FALSE, FALSE, 64,
  189. {L"pager", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING,
  190. NULL, 0}, NULL, NULL};
  191. ATTR_MAP USpecOtherPager = {IDC_OTHER_PAGER_BTN, FALSE, TRUE, 64,
  192. {L"otherPager", ADS_ATTR_UPDATE,
  193. ADSTYPE_CASE_IGNORE_STRING, NULL, 0}, OtherValuesBtn, NULL};
  194. //
  195. // Special page, Mobile
  196. //
  197. ATTR_MAP USpecMobile = {IDC_MOBILE_EDIT, FALSE, FALSE, 64,
  198. {L"mobile", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING,
  199. NULL, 0}, NULL, NULL};
  200. ATTR_MAP USpecOtherMobile = {IDC_OTHER_MOBLE_BTN, FALSE, TRUE, 64,
  201. {L"otherMobile", ADS_ATTR_UPDATE,
  202. ADSTYPE_CASE_IGNORE_STRING, NULL, 0}, OtherValuesBtn, NULL};
  203. //
  204. // Special page, user's home page
  205. //
  206. ATTR_MAP USpecURL = {IDC_HOME_PAGE_EDIT, FALSE, FALSE, 2048,
  207. {L"wWWHomePage", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING,
  208. NULL, 0}, NULL, NULL};
  209. //
  210. // Special page, other home pages
  211. //
  212. ATTR_MAP USpecOtherURL = {IDC_OTHER_URL_BTN, FALSE, TRUE, 2048,
  213. {L"url", ADS_ATTR_UPDATE,
  214. ADSTYPE_CASE_IGNORE_STRING, NULL, 0}, OtherValuesBtn, NULL};
  215. //
  216. // Special page, Address
  217. //
  218. ATTR_MAP USpecAddress = {IDC_ADDRESS_EDIT, FALSE, FALSE, 1024,
  219. {L"homePostalAddress", ADS_ATTR_UPDATE,
  220. ADSTYPE_CASE_IGNORE_STRING, NULL, 0}, NULL, NULL};
  221. //
  222. // Special page, Picture
  223. //
  224. ATTR_MAP USpecPicture = {IDC_PICTURE_BMP, TRUE, FALSE, 0,
  225. {L"thumbnailPhoto", ADS_ATTR_UPDATE,
  226. ADSTYPE_OCTET_STRING, NULL, 0}, BmpPictureCtrl, NULL};
  227. //
  228. // The list of attributes on the User Special page.
  229. //
  230. PATTR_MAP rgpUSpecAttrMap[] = {{&USpecHomePhone}, {&USpecHomeOther}, {&USpecPager},
  231. {&USpecOtherPager}, {&USpecMobile}, {&USpecOtherMobile},
  232. {&USpecURL}, {&USpecOtherURL}, {&USpecAddress},
  233. {&USpecPicture}};
  234. //
  235. // The Special page description.
  236. //
  237. DSPAGE NTGroup = {IDS_NT_GRP_TITLE, IDD_NT_GROUP, 0, 0, NULL,
  238. CreateTableDrivenPage,
  239. sizeof(rgpUSpecAttrMap)/sizeof(PATTR_MAP),
  240. rgpUSpecAttrMap};
  241. //----------------------------------------------
  242. // The list of Special pages.
  243. //
  244. PDSPAGE rgShellUSpecPages[] = {{&NTGroup}};
  245. //
  246. // The User Special class description.
  247. //
  248. DSCLASSPAGES ShellUSpecCls = {&CLSID_SpecialUserInfo, TEXT("User Special Info"),
  249. sizeof(rgShellUSpecPages)/sizeof(PDSPAGE),
  250. rgShellUSpecPages};
  251. #endif // NT_GROUP_PAGE
  252. //----------------------------------------------
  253. // The list of User pages.
  254. //
  255. PDSPAGE rgShellUserPages[] = {{&ShellUserGeneral}, {&UserAddress}, {&ShellUserBusiness}};
  256. //
  257. // The User class description.
  258. //
  259. DSCLASSPAGES ShellUserCls = {&CLSID_DsShellUserPropPages, TEXT("User"),
  260. sizeof(rgShellUserPages)/sizeof(PDSPAGE),
  261. rgShellUserPages};
  262. //-------------------------------------------------------
  263. // Contact object
  264. //-------------------------------------------------------
  265. //
  266. // The list of Contact pages.
  267. //
  268. PDSPAGE rgShellContactPages[] = {{&ShellUserGeneral}, {&ShellUserBusiness}};
  269. //
  270. // The Contact class description.
  271. //
  272. DSCLASSPAGES ShellContactCls = {&CLSID_DsShellContactPropPages, TEXT("Contact"),
  273. sizeof(rgShellContactPages)/sizeof(PDSPAGE),
  274. rgShellContactPages};
  275. //-------------------------------------------------------
  276. // Volume object
  277. //-------------------------------------------------------
  278. //
  279. // Volume page, path
  280. //
  281. ATTR_MAP VSPath = {IDC_PATH, FALSE, FALSE,
  282. ATTR_LEN_UNLIMITED, {L"uNCName",
  283. ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING,
  284. NULL, 0}, NULL, NULL};
  285. ATTR_MAP VolKey = {IDC_KEYWORDS_LIST, TRUE, TRUE, 0,
  286. {L"keywords", ADS_ATTR_UPDATE,
  287. ADSTYPE_CASE_IGNORE_STRING, NULL, 0}, ROList, NULL};
  288. //
  289. // The list of attributes on the Volume General page.
  290. //
  291. PATTR_MAP rgpVSAttrMap[] = {{&GenIcon}, {&AttrName}, {&Description}, {&VSPath}, {&VolKey}};
  292. //
  293. // The Volume General page description.
  294. //
  295. DSPAGE ShellVolumeGeneral = {IDS_TITLE_GENERAL, IDD_SHELL_VOLUME_GEN, 0, 0, NULL,
  296. CreateTableDrivenPage,
  297. sizeof(rgpVSAttrMap)/sizeof(PATTR_MAP),
  298. rgpVSAttrMap};
  299. //----------------------------------------------
  300. // The list of Volume pages.
  301. //
  302. PDSPAGE rgShellVolumePages[] = {{&ShellVolumeGeneral}};
  303. //
  304. // The Volume class description.
  305. //
  306. DSCLASSPAGES ShellVolumeCls = {&CLSID_DsShellVolumePropPages, TEXT("Volume"),
  307. sizeof(rgShellVolumePages)/sizeof(PDSPAGE),
  308. rgShellVolumePages};
  309. //
  310. //-----------------------------------------------
  311. // computer object
  312. //----------------------------------------------
  313. //
  314. // Computer General page, Network Address.
  315. //
  316. //ATTR_MAP CSComputerNetAddr = {IDC_NET_ADDR_EDIT, FALSE, FALSE, 256,
  317. // {L"networkAddress", ADS_ATTR_UPDATE,
  318. // ADSTYPE_CASE_IGNORE_STRING, NULL, 0}, NULL};
  319. //
  320. // Computer General page, Role.
  321. //
  322. ATTR_MAP CSComputerRoleAttr = {IDC_ROLE, TRUE, FALSE, 260,
  323. {g_wzUserAccountControl, ADS_ATTR_UPDATE,
  324. ADSTYPE_INTEGER, NULL, 0}, ShComputerRole, NULL};
  325. //
  326. // The list of attributes on the Computer General page.
  327. //
  328. PATTR_MAP rgpCSAttrMap[] = {{&GenIcon}, {&AttrName},
  329. {&Description}, // {&CSComputerNetAddr},
  330. {&CSComputerRoleAttr}};
  331. //
  332. // The Computer General page description.
  333. //
  334. DSPAGE ShellComputerGeneral = {IDS_TITLE_GENERAL, IDD_SHELL_COMPUTER_GEN, 0, 0, NULL,
  335. CreateTableDrivenPage,
  336. sizeof(rgpCSAttrMap)/sizeof(PATTR_MAP),
  337. rgpCSAttrMap};
  338. //----------------------------------------------
  339. // The list of Computer pages.
  340. //
  341. PDSPAGE rgShellComputerPages[] = {{&ShellComputerGeneral}};
  342. //
  343. // The Computer class description.
  344. //
  345. DSCLASSPAGES ShellComputerCls = {&CLSID_DsShellComputerPropPages, TEXT("Computer"),
  346. sizeof(rgShellComputerPages)/sizeof(PDSPAGE),
  347. rgShellComputerPages};
  348. //----------------------------------------------
  349. // Domain object
  350. //----------------------------------------------
  351. //
  352. // The list of attributes on the General page.
  353. //
  354. PATTR_MAP rgpDSAttrMap[] = {{&GenIcon}, {&AttrName},
  355. {&Description}};
  356. //
  357. // The Computer General page description.
  358. //
  359. DSPAGE ShellDomainGeneral = {IDS_TITLE_GENERAL, IDD_SHELL_DOMAIN_GEN, 0, 0, NULL,
  360. CreateTableDrivenPage,
  361. sizeof(rgpDSAttrMap)/sizeof(PATTR_MAP),
  362. rgpDSAttrMap};
  363. //----------------------------------------------
  364. // The list of Domain pages.
  365. //
  366. PDSPAGE rgShellDomainPages[] = {{&ShellDomainGeneral}};
  367. //
  368. // The Domain class description.
  369. //
  370. DSCLASSPAGES ShellDomainCls = {&CLSID_DsShellDomainPropPages, TEXT("Domain"),
  371. sizeof(rgShellDomainPages)/sizeof(PDSPAGE),
  372. rgShellDomainPages};
  373. //----------------------------------------------
  374. // OU object
  375. //----------------------------------------------
  376. //
  377. // The list of attributes on the OU General page.
  378. //
  379. PATTR_MAP rgpOSAttrMap[] = {{&GenIcon}, {&AttrName},
  380. {&Description}};
  381. //
  382. // The OU General page description.
  383. //
  384. DSPAGE ShellOUGeneral = {IDS_TITLE_GENERAL, IDD_SHELL_DOMAIN_GEN, 0, 0, NULL,
  385. CreateTableDrivenPage,
  386. sizeof(rgpOSAttrMap)/sizeof(PATTR_MAP),
  387. rgpOSAttrMap};
  388. //----------------------------------------------
  389. // The list of OU pages.
  390. //
  391. PDSPAGE rgShellOUPages[] = {{&ShellOUGeneral}};
  392. //
  393. // The OU class description.
  394. //
  395. DSCLASSPAGES ShellOUCls = {&CLSID_DsShellOUPropPages, TEXT("OU"),
  396. sizeof(rgShellOUPages)/sizeof(PDSPAGE),
  397. rgShellOUPages};
  398. //----------------------------------------------
  399. // Group object
  400. //----------------------------------------------
  401. //
  402. // The Group General page description.
  403. //
  404. DSPAGE ShellGroupGeneral = {IDS_TITLE_GENERAL, IDD_SHELL_GROUP_GEN, 0, 0, NULL,
  405. CreateGrpShlGenPage, 0, NULL};
  406. //----------------------------------------------
  407. // The list of Group pages.
  408. //
  409. PDSPAGE rgShellGroupPages[] = {{&ShellGroupGeneral}};
  410. //
  411. // The Group class description.
  412. //
  413. DSCLASSPAGES ShellGroupCls = {&CLSID_DsShellGroupPropPages, TEXT("Group"),
  414. sizeof(rgShellGroupPages)/sizeof(PDSPAGE),
  415. rgShellGroupPages};
  416. #ifdef NT_GROUP_PAGE
  417. //+----------------------------------------------------------------------------
  418. //
  419. // Function: BmpPictureCtrl
  420. //
  421. // Synopsis: Fetches the bitmap from the user object Picture attribute
  422. // and draws it on the page.
  423. //
  424. //-----------------------------------------------------------------------------
  425. HRESULT
  426. BmpPictureCtrl(CDsPropPageBase * pPage, PATTR_MAP pAttrMap,
  427. PADS_ATTR_INFO pAttrInfo, LPARAM, PATTR_DATA pAttrData,
  428. DLG_OP DlgOp)
  429. {
  430. HWND hPicCtrl;
  431. PBYTE pb;
  432. CBmpPicCtrl * pPicCtrlObj;
  433. switch (DlgOp)
  434. {
  435. case fInit:
  436. pAttrData->pVoid = NULL;
  437. if (pAttrInfo == NULL)
  438. {
  439. return S_OK;
  440. }
  441. hPicCtrl = GetDlgItem(pPage->GetHWnd(), pAttrMap->nCtrlID);
  442. dspAssert(pAttrInfo->pADsValues != NULL);
  443. dspAssert(pAttrInfo->dwADsType == ADSTYPE_OCTET_STRING);
  444. dspAssert(pAttrInfo->dwNumValues == 1);
  445. dspAssert(pAttrInfo->pADsValues->dwType == ADSTYPE_OCTET_STRING);
  446. dspAssert(pAttrInfo->pADsValues->OctetString.dwLength > 0);
  447. dspAssert(pAttrInfo->pADsValues->OctetString.lpValue != NULL);
  448. //
  449. // Enforce the maximum size.
  450. //
  451. pb = pAttrInfo->pADsValues->OctetString.lpValue;
  452. PBITMAPINFO pBmpInfo;
  453. pBmpInfo = (PBITMAPINFO)((PBYTE)pb + sizeof(BITMAPFILEHEADER));
  454. dspDebugOut((DEB_ITRACE, "Bitmap size: (%d, %d)\n",
  455. pBmpInfo->bmiHeader.biWidth, pBmpInfo->bmiHeader.biHeight));
  456. #define MAX_PIC_SIZE 100
  457. if ((pBmpInfo->bmiHeader.biWidth > MAX_PIC_SIZE) ||
  458. (pBmpInfo->bmiHeader.biHeight > MAX_PIC_SIZE))
  459. {
  460. LONG_PTR lStyle = GetWindowLongPtr(hPicCtrl, GWL_STYLE);
  461. lStyle &= ~(SS_BITMAP);
  462. lStyle |= SS_LEFT;
  463. SetWindowLongPtr(hPicCtrl, GWL_STYLE, lStyle);
  464. TCHAR szMsg[200];
  465. wsprintf(szMsg, TEXT("Bitmap is too large (%d, %d)!"),
  466. pBmpInfo->bmiHeader.biWidth, pBmpInfo->bmiHeader.biHeight);
  467. SetWindowText(hPicCtrl, szMsg);
  468. dspDebugOut((DEB_ITRACE, "Bitmap too large! (%d, %d) max allowed.\n",
  469. MAX_PIC_SIZE, MAX_PIC_SIZE));
  470. return S_OK;
  471. }
  472. //
  473. // Save the bitmap.
  474. //
  475. pb = (PBYTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
  476. pAttrInfo->pADsValues->OctetString.dwLength);
  477. CHECK_NULL_REPORT(pb, pPage->GetHWnd(), return E_OUTOFMEMORY);
  478. memcpy(pb, pAttrInfo->pADsValues->OctetString.lpValue,
  479. pAttrInfo->pADsValues->OctetString.dwLength);
  480. //
  481. // Subclass the picture "static" control.
  482. //
  483. pPicCtrlObj = new CBmpPicCtrl(hPicCtrl, pb);
  484. CHECK_NULL_REPORT(pPicCtrlObj, pPage->GetHWnd(), return E_OUTOFMEMORY);
  485. pAttrData->pVoid = reinterpret_cast<LPARAM>(pPicCtrlObj);
  486. break;
  487. case fOnDestroy:
  488. pPicCtrlObj = reinterpret_cast<CBmpPicCtrl*>(pAttrData->pVoid);
  489. DO_DEL(pPicCtrlObj);
  490. break;
  491. }
  492. return S_OK;
  493. }
  494. //+----------------------------------------------------------------------------
  495. //
  496. // Class: CBmpPicCtrl
  497. //
  498. // Synopsis: Icon control window subclass object, so we can paint a class-
  499. // specific icon.
  500. //
  501. //-----------------------------------------------------------------------------
  502. CBmpPicCtrl::CBmpPicCtrl(HWND hCtrl, PBYTE pb) :
  503. m_hCtrl(hCtrl),
  504. m_pbBmp(pb),
  505. m_pOldProc(NULL),
  506. m_hPal(NULL)
  507. {
  508. #ifdef _DEBUG
  509. strcpy(szClass, "CBmpPicCtrl");
  510. #endif
  511. SetWindowLongPtr(hCtrl, GWLP_USERDATA, (LONG_PTR)this);
  512. m_pOldProc = (WNDPROC)SetWindowLongPtr(hCtrl, GWLP_WNDPROC, (LONG_PTR)StaticCtrlProc);
  513. m_hDlg = GetParent(hCtrl);
  514. }
  515. CBmpPicCtrl::~CBmpPicCtrl(void)
  516. {
  517. SetWindowLongPtr(m_hCtrl, GWLP_WNDPROC, (LONG_PTR)m_pOldProc);
  518. if (m_pbBmp)
  519. {
  520. GlobalFree(m_pbBmp);
  521. }
  522. if (m_hPal)
  523. {
  524. DeleteObject(m_hPal);
  525. }
  526. }
  527. //+----------------------------------------------------------------------------
  528. //
  529. // Method: CBmpPicCtrl::StaticCtrlProc
  530. //
  531. // Synopsis: control sub-proc
  532. //
  533. //-----------------------------------------------------------------------------
  534. LRESULT CALLBACK
  535. CBmpPicCtrl::StaticCtrlProc(HWND hCtrl, UINT uMsg, WPARAM wParam, LPARAM lParam)
  536. {
  537. HRESULT hr;
  538. HDC hDC;
  539. HPALETTE hOldPal;
  540. UINT iChanged = 0;
  541. CBmpPicCtrl * pCCtrl = (CBmpPicCtrl*)GetWindowLongPtr(hCtrl, GWLP_USERDATA);
  542. dspAssert(pCCtrl != NULL);
  543. switch (uMsg)
  544. {
  545. case WM_PALETTECHANGED:
  546. if ((HWND)wParam == hCtrl)
  547. {
  548. break;
  549. }
  550. // Fall through:
  551. case WM_QUERYNEWPALETTE:
  552. dspDebugOut((DEB_ITRACE, "Got palette message.\n"));
  553. if (pCCtrl->m_hPal == NULL)
  554. {
  555. hr = pCCtrl->CreateBmpPalette();
  556. CHECK_HRESULT(hr, return FALSE);
  557. }
  558. hDC = GetDC(hCtrl);
  559. if (hDC != NULL)
  560. {
  561. hOldPal = SelectPalette(hDC, pCCtrl->m_hPal, FALSE);
  562. iChanged = RealizePalette(hDC);
  563. SelectPalette(hDC, hOldPal, TRUE);
  564. RealizePalette(hDC);
  565. ReleaseDC(hCtrl, hDC);
  566. if (iChanged > 0 && iChanged != GDI_ERROR)
  567. {
  568. InvalidateRect(hCtrl, NULL, TRUE);
  569. }
  570. }
  571. return(iChanged);
  572. case WM_PAINT:
  573. if (!pCCtrl->OnPaint())
  574. {
  575. return FALSE;
  576. }
  577. break;
  578. default:
  579. break;
  580. }
  581. return CallWindowProc(pCCtrl->m_pOldProc, hCtrl, uMsg, wParam, lParam);
  582. }
  583. //+----------------------------------------------------------------------------
  584. //
  585. // Method: CBmpPicCtrl::OnPaint
  586. //
  587. // Synopsis: Paint the DS specified icon.
  588. //
  589. //-----------------------------------------------------------------------------
  590. LRESULT
  591. CBmpPicCtrl::OnPaint(void)
  592. {
  593. TRACE(CBmpPicCtrl,OnPaint);
  594. HRESULT hr = S_OK;
  595. HDC hDC = NULL;
  596. PAINTSTRUCT ps;
  597. HPALETTE hOldPal = NULL;
  598. if (m_hPal == NULL)
  599. {
  600. hr = CreateBmpPalette();
  601. CHECK_HRESULT(hr, return FALSE);
  602. }
  603. hDC = BeginPaint(m_hCtrl, &ps);
  604. CHECK_NULL_REPORT(hDC, m_hDlg, return FALSE);
  605. if (m_hPal)
  606. {
  607. hOldPal = SelectPalette(hDC, m_hPal, FALSE);
  608. RealizePalette(hDC);
  609. }
  610. dspAssert(m_pbBmp != NULL);
  611. PBITMAPFILEHEADER pBmpFileHdr = (PBITMAPFILEHEADER)m_pbBmp;
  612. // Advance past the BITMAPFILEHEADER struct.
  613. //
  614. PBITMAPINFO pBmpInfo = (PBITMAPINFO)(m_pbBmp + sizeof(BITMAPFILEHEADER));
  615. if (SetDIBitsToDevice(hDC,
  616. 0, 0,
  617. pBmpInfo->bmiHeader.biWidth,
  618. pBmpInfo->bmiHeader.biHeight,
  619. 0, 0, 0,
  620. pBmpInfo->bmiHeader.biHeight,
  621. m_pbBmp + pBmpFileHdr->bfOffBits,
  622. pBmpInfo,
  623. DIB_RGB_COLORS) == 0)
  624. {
  625. REPORT_ERROR(GetLastError(), m_hDlg);
  626. }
  627. if (m_hPal)
  628. {
  629. SelectPalette(hDC, hOldPal, TRUE);
  630. }
  631. EndPaint(m_hCtrl, &ps);
  632. return TRUE;
  633. }
  634. //+----------------------------------------------------------------------------
  635. //
  636. // Function: CreateBmpPalette
  637. //
  638. // Synopsis: Creates the palette for the bitmap.
  639. //
  640. //-----------------------------------------------------------------------------
  641. HRESULT
  642. CBmpPicCtrl::CreateBmpPalette(void)
  643. {
  644. TRACE(CBmpPicCtrl,CreateBmpPalette);
  645. PBITMAPINFO pBmpInfo;
  646. pBmpInfo = (PBITMAPINFO)(m_pbBmp + sizeof(BITMAPFILEHEADER));
  647. WORD nColors, cClrBits = pBmpInfo->bmiHeader.biBitCount;
  648. if (cClrBits == 1)
  649. cClrBits = 1;
  650. else if (cClrBits <= 4)
  651. cClrBits = 4;
  652. else if (cClrBits <= 8)
  653. cClrBits = 8;
  654. else if (cClrBits <= 16)
  655. cClrBits = 16;
  656. else if (cClrBits <= 24)
  657. cClrBits = 24;
  658. else
  659. cClrBits = 32;
  660. if (cClrBits >= 24)
  661. {
  662. // True color BMPs don't need explicit palettes.
  663. //
  664. return S_OK;
  665. }
  666. nColors = static_cast<WORD>(1 << cClrBits);
  667. dspDebugOut((DEB_ITRACE, "Bitmap has %d colors.\n", nColors));
  668. PLOGPALETTE plp = (PLOGPALETTE)LocalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
  669. sizeof(LOGPALETTE) +
  670. sizeof (PALETTEENTRY) * nColors);
  671. CHECK_NULL_REPORT(plp, m_hDlg, return E_OUTOFMEMORY);
  672. plp->palVersion = 0x300;
  673. plp->palNumEntries = nColors;
  674. for (WORD i = 0; i < nColors; i++)
  675. {
  676. plp->palPalEntry[i].peBlue = pBmpInfo->bmiColors[i].rgbBlue;
  677. plp->palPalEntry[i].peGreen = pBmpInfo->bmiColors[i].rgbGreen;
  678. plp->palPalEntry[i].peRed = pBmpInfo->bmiColors[i].rgbRed;
  679. plp->palPalEntry[i].peFlags = 0; //PC_NOCOLLAPSE;
  680. }
  681. m_hPal = CreatePalette(plp);
  682. if (m_hPal == NULL)
  683. {
  684. REPORT_ERROR(GetLastError(), m_hDlg);
  685. return HRESULT_FROM_WIN32(GetLastError());
  686. }
  687. LocalFree(plp);
  688. return S_OK;
  689. }
  690. #endif // NT_GROUP_PAGE
  691. HRESULT
  692. ROList(CDsPropPageBase * pPage, PATTR_MAP pAttrMap, PADS_ATTR_INFO pAttrInfo,
  693. LPARAM, PATTR_DATA, DLG_OP DlgOp)
  694. {
  695. if (DlgOp != fInit)
  696. {
  697. return S_OK;
  698. }
  699. if (pAttrInfo == NULL)
  700. {
  701. return S_OK;
  702. }
  703. dspAssert(pAttrInfo->pADsValues != NULL);
  704. for (DWORD i = 0; i < pAttrInfo->dwNumValues; i++)
  705. {
  706. SendDlgItemMessage(pPage->GetHWnd(), pAttrMap->nCtrlID, LB_ADDSTRING, 0,
  707. (LPARAM)pAttrInfo->pADsValues[i].CaseIgnoreString);
  708. }
  709. return S_OK;
  710. }
  711. //+----------------------------------------------------------------------------
  712. // The list of classes.
  713. //-----------------------------------------------------------------------------
  714. PDSCLASSPAGES rgClsPages[] = {
  715. &ShellComputerCls,
  716. &ShellVolumeCls,
  717. &ShellUserCls,
  718. &ShellContactCls,
  719. &ShellDomainCls,
  720. &ShellGroupCls,
  721. &ShellOUCls,
  722. &ShellUSpecCls
  723. };
  724. //+----------------------------------------------------------------------------
  725. // The global struct containing the list of classes.
  726. //-----------------------------------------------------------------------------
  727. RGDSPPCLASSES g_DsPPClasses = {sizeof(rgClsPages)/sizeof(PDSCLASSPAGES),
  728. rgClsPages};