Active Directory 用户和计算机属性表

Active Directory 用户和计算机 MMC 管理单元旨在显示 Active Directory 服务器中各种对象的属性表。 属性表包含一个或多个用于查看和修改对象数据的页面。 不同的对象类型具有为它们显示的不同页面集。 Active Directory 用户和计算机 MMC 管理单元还使第三方供应商能够将自定义页面添加到特定类型的对象的属性表中。 有关详细信息,请参阅 用于显示说明符的属性页。

某些应用程序(Active Directory 用户和计算机 MMC 管理单元)必须为用户提供 Active Directory 服务器中对象的视图和编辑属性的功能。 应用程序可以实现自己的属性表,但最好提供一致的用户界面,以减少混淆和学习时间。 幸运的是,Active Directory 用户和计算机 MMC 管理单元允许任何 OLE COM 应用程序显示与同一对象的Active Directory 用户和计算机 MMC 管理单元显示的属性表相同的对象的属性表。

有关详细信息和承载Active Directory 用户和计算机属性表的代码示例,请参阅平台软件开发工具包 (SDK) 中的 PropSheetHost 示例。

开发人员受众

本文档假定读者熟悉使用 C++ 的 COM 操作和组件开发。 目前,无法使用 Visual Basic 创建 Active Directory 属性表扩展。

承载Active Directory 用户和计算机属性表

在 Active Directory 服务器中显示对象的属性表

  1. 创建可用于处理消息的窗口。 这可以是现有窗口或特殊用途窗口。 这称为 隐藏窗口

  2. 创建派生自 IDataObject 的 OLE COM 对象。 此数据对象必须支持以下数据格式:

    • CFSTR_DSOBJECTNAMES此数据格式包含一个 DSOBJECTNAMES,用于标识属性表应用于的对象。 托管属性表时,DSOBJECTNAMES 结构的更重要成员显示在以下列表中。

      clsidNamespace Reserved。 如果将来使用它,请将其设置为应用程序的 GUID。

      aObjects 包含 DSBOJECT 结构的数组。 每个 DSBOJECT 结构表示单个目录对象。 cItems 成员包含数组中的元素数。 仅使用此数组中的第一个对象。 忽略其他对象。

    • CFSTR_DSDISPLAYSPECOPTIONS此数据格式包含 DSDISPLAYSPECOPTIONS 结构,该结构包含属性页将使用的数据,例如从何处加载属性页、服务器和要使用的凭据等。 DSDISPLAYSPECOPTIONS更重要成员显示在以下列表中。

      offsetAttribPrefix 属性前缀字符串确定获取属性页列表的位置。 这必须包含以下字符串之一。

      属性前缀字符串 说明
      "admin"
      属性页从 adminPropertyPages 属性加载。
      “shell”
      属性页从 shellPropertyPages 属性加载。
    • CFSTR_DS_PROPSH企业版TCONFIG 此数据格式包含 PROPSH企业版TCFG 结构,其中包含属性表主机数据。 承载属性表时,PROPSH企业版TCFG 结构的更重要成员包含以下列表中显示的数据。

      lNotifyHandle 必须为零。 hwndParentSheet 包含窗口的句柄,当其中一个页面中的内容发生更改并应用时接收 WM_ADSPROP_NOTIFY_CHANGE 消息。 如果不需要此消息,可以为 NULL

      hwndHidden 包含接收WM_DSA_SH企业版T_CREATE_NOTIFYWM_DSA_SH企业版T_CLO标准版_NOTIFY消息的窗口句柄。 将此设置为隐藏窗口的句柄。

      wParamSheetClose 包含应用程序定义的标识符,该标识符在WM_DSA_SH企业版T_CLO标准版_NOTIFY消息的 wParam返回。 如果此成员为零,则不会将WM_DSA_SH企业版T_CLO标准版_NOTIFY消息发布到隐藏窗口。

  3. 创建CLSID_DsPropertyPages对象的实例并获取对象的 IShellExtInit 接口。 还可以复制CLSID_DsPropertyPages对象的行为。 有关详细信息,请参阅复制CLSID_DsPropertyPages对象的行为。

  4. 通过调用 IShellExtInit::Initialize 方法初始化CLSID_DsPropertyPages对象。 此方法不使用 pidlFolderhkeyProgID 参数。 pdtobj 参数是指向在步骤 2 中创建的数据对象的指针。 调用 IShellExtInit::Initialize 方法时, CLSID_DsPropertyPages 对象将保存对数据对象的引用。

  5. 获取CLSID_DsPropertyPages对象的 IShellPropSheetExt 接口,并调用 IShellPropSheetExt::AddPages 方法。 lpfnAddPage 参数是必须实现的回调函数的地址。 此函数的格式如下所示。 如果回调函数声明为 C++ 类的成员,则必须将回调函数声明为 静态函数。 lParam 参数是一个应用程序定义的值,可用于标识实现回调函数的对象。 调用 IShellPropSheetExt::AddPages 方法时, CLSID_DsPropertyPages 对象将从数据对象获取数据,并枚举为对象显示说明符注册的属性页。 然后,CLSID_DsPropertyPages对象将枚举属性页对象,调用每个对象的 IShellPropSheetExt::AddPages 方法。

    BOOL CALLBACK AddPagesCallback(HPROPSHEETPAGE, LPARAM)
    
  6. 由属性页对象添加的每个页面都将导致回调函数使用属性页和应用程序定义的值的句柄调用。 回调函数必须存储传递的每个属性页句柄。 当CLSID_DsPropertyPages对象的 IShellPropSheetExt::AddPages 方法返回时,将通过回调函数添加所有页面。

  7. 填写 PROPSH企业版THEADER 结构以显示属性表。 phpage 成员接收指向回调函数收集的页面句柄数组的指针。 nPages 成员接收页面句柄数组中的页数。

  8. 通过调用 PropertySheet 函数显示属性表。

如果更改了任何页面中的数据并且单击了“确定”或“应用”按钮,则由 PROPSH 的 hwndParentSheet 成员标识的窗口企业版TCFG 结构将收到WM_ADSPROP_NOTIFY_CHANGE消息。 此消息严格是通知,无需执行任何特定操作。

关闭页面后,由 PROPSH 的 hwndHidden 成员标识的窗口企业版TCFG 结构将收到WM_DSA_SH企业版T_CLO标准版_NOTIFY消息。 此消息严格是通知,不需要执行任何特定操作。

在某些情况下,现有属性表需要显示辅助属性表。 例如,如果显示用户对象的属性表并选择“ 成员 ”页,则会显示用户所属的组列表。 如果双击列表中的其中一个组,将显示该组的属性表。 主属性表本身不显示辅助工作表。 它请求主机通过将WM_DSA_SH企业版T_CREATE_NOTIFY消息发送到 PROPSH 的 hwndHidden 成员标识的窗口来显示辅助工作表企业版TCFG 结构。 WM_DSA_SH企业版T_CREATE_NOTIFY消息的 wParam 是指向DSA_标准版C_PAGE_INFO结构的指针,该结构包含有关辅助属性表及其表示的对象的信息。 为了响应此消息,属性表主机必须以与上面所示相同的方式显示辅助属性表。 处理WM_DSA_SH企业版T_CREATE_NOTIFY消息后,消息接收方必须将 wParam传递给 LocalFree 函数来释放DSA_标准版C_PAGE_INFO结构。

复制CLSID_DsPropertyPages对象的行为

复制CLSID_DsPropertyPages对象的行为

  1. 枚举对象类的显示说明符的 adminPropertyPagesshellPropertyPages 属性中的值。 每个值都是一个字符串,其中包含一个数字,后跟一个逗号,后跟属性页扩展的类标识符的字符串表示形式。 有关属性页显示说明符值的格式的详细信息,请参阅 在显示说明符中注册属性页 COM 对象。
  2. 使用 CLSIDFromString 函数将每个类标识符字符串转换为 CLSID
  3. 按属性值中每个类标识符字符串前面的数字对扩展类标识符进行排序。 如果两个数字相同,则按照从 Active Directory 服务器获取属性值的顺序对类标识符进行排序。
  4. 枚举扩展类标识符,创建每个扩展的实例。
  5. 对于每个扩展,按照上面排序的顺序,调用扩展的 IShellExtInit::Initialize,其信息与承载Active Directory 用户和计算机属性表过程的步骤 4 中所述的信息相同。
  6. 对于每个扩展,按照上面排序的顺序,调用扩展的 IShellPropSheetExt::AddPages,其信息与托管 Active Directory 用户和计算机 属性表过程的步骤 5 中所述的信息相同。

如果可能,请使用 CLSID_DsPropertyPages 对象创建页面,而不是手动执行此操作。 CLSID_DsPropertyPages已经过优化,并且将正确处理失败情况,例如,当没有显示说明符可用于当前区域设置时。 此外,CLSID_DsPropertyPages对象将来可能会更改,这意味着属性表可能与Active Directory 用户和计算机 MMC 管理单元显示的属性表不完全匹配。

特殊编程元素

目前,已发布的头文件中未定义以下编程元素。 若要使用这些元素,必须以特定引用页中显示的确切格式自行定义它们。

示例代码

以下 C++ 代码示例演示了一种安全的方法,用于定义这些元素,即使这些元素将来在已发布的头文件中定义,这些元素也会继续工作。

#ifndef CFSTR_DS_PROPSHEETCONFIG
    #define CFSTR_DS_PROPSHEETCONFIG_W L"DsPropSheetCfgClipFormat"
    #define CFSTR_DS_PROPSHEETCONFIG_A "DsPropSheetCfgClipFormat"

    #ifdef UNICODE
        #define CFSTR_DS_PROPSHEETCONFIG CFSTR_DS_PROPSHEETCONFIG_W
    #else
        #define CFSTR_DS_PROPSHEETCONFIG CFSTR_DS_PROPSHEETCONFIG_A
    #endif //UNICODE
#endif //CFSTR_DS_PROPSHEETCONFIG


#ifndef WM_ADSPROP_SHEET_CREATE
    #define WM_ADSPROP_SHEET_CREATE (WM_USER + 1108)
#endif


#ifndef WM_DSA_SHEET_CREATE_NOTIFY
    #define WM_DSA_SHEET_CREATE_NOTIFY (WM_USER + 6)
#endif


#ifndef WM_DSA_SHEET_CLOSE_NOTIFY
    #define WM_DSA_SHEET_CLOSE_NOTIFY (WM_USER + 5) 
#endif


#ifndef DSA_SEC_PAGE_INFO
    typedef struct _DSA_SEC_PAGE_INFO
    {
        HWND    hwndParentSheet;
        DWORD   offsetTitle;
        DSOBJECTNAMES dsObjectNames;
    } DSA_SEC_PAGE_INFO, *PDSA_SEC_PAGE_INFO;
#endif //DSA_SEC_PAGE_INFO

#ifndef PROPSHEETCFG
    typedef struct _PROPSHEETCFG
    {  
        LONG_PTR lNotifyHandle;  
        HWND hwndParentSheet;  
        HWND hwndHidden;  
        WPARAM wParamSheetClose;
    } PROPSHEETCFG, *PPROPSHEETCFG;
#endif //PROPSHEETCFG