用ATL编写MMC Snapin的Sample 

ATLSNAP.H // This is a part of the Active Template Library. // Copyright (C) 1996-1998 Microsoft Corporation // All rights reserved. // // This source code is only intended as a supplement to the // Active Temp 阅读详情

关键字 MMC Snapin ATL
原作者姓名 Fang

读者评分 15 评分次数 4

正文
关键字:MMC Snapin ATL
作者:Fang(fangguicheng@21cn.com)

用ATL编写MMC Snapin的Sample
MMC相关的编程接口
MMC 实现了下面的接口:
IColumnData (new in MMC 1.2)
IConsole2
IConsoleNameSpace2
IConsoleVerb
IContextMenuCallback
IContextMenuProvider
IControlbar
IDisplayHelp
IHeaderCtrl2 (new in MMC 1.2)
IImageList
IMenuButton
IPropertySheetCallback
IPropertySheetProvider
IRequiredExtensions
IResultData
IToolbar
Snap-ins 实现了下面的接口:
IComponent
IComponentData
IEnumTASK
IExtendContextMenu
IExtendControlbar
IExtendPropertySheet2
IExtendTaskPad
IRequiredExtensions
IResultDataCompare
IResultDataCompareEx (new in MMC 1.2)
IResultOwnerData
ISnapinAbout
ISnapinHelp2

IComponent接口表示了右边的结果栏(Result pane)里的对象,MMC需要和结果栏里的对象通信时使用这个接口;
IComponentData接口表示了左边的目录栏(scopet pane)里的对象(这些对象可以称之为节点),MMC需要和目录栏里的对象通信时使用这个接口;
IExtendContextMenu接口,无论用户用鼠标右键点击了左边的节点(scope pane item)还是右边的项(result pane item),MMC都会弹出一个默认的关联菜单,这时MMC会使用这个接口询问该对象(Item),是否需要添加自己的菜单项。
IExtendControlbar和IExtendPropertySheet2也是类似的道理。
ISnapinAbout实现了一个关于对话框的接口,MMC通过这个接口了解Snapin的版本、描述信息、提供者信息、对话框图标,并且特别重要的是,MMC通过这个接口得到了Snapin的所有结点、项的默认图标,要修改根结点的图标也可以通过这个函数GetStaticFolderImage来向MMC提供。

详尽的描述请参考Platform SDK。

Snapin不需要实现全部接口,Sample仅实现了其中的:
IComponent
IComponentData
IExtendContextMenu
IExtendControlbar
IExtendPropertySheet2
ISnapinAbout
MMC的ATL实现支持类简介
Sample的模型图
模型图 ATL MMC Snapin.gif
ATL实现了几乎全部的接口,提供了默认的处理代码。ATL Wizzard生成的代码提供了基本的编程框架,Snapin的特性实现依赖于对CmySnapinData的某些函数的重载来修改默认行为。
上图中,CMySnapinComponent的基类IExtendContextMenuImpl,IExtendContextPropertySheet,也同CMySnapin的一样,依赖于对CMySnapinData的几个同名函数的调用,只是因为线条太乱才没有画出。
Snapin DLL Sample的代码生成Step by Step
1,    新建ATL工程,如果需要使用MFC,可以使用Wizzard选项支持MFC工程命名test6;
2,    “New ATL Object”,选择“MMC Snapin”;
3,    命名“MySnapin”,并在第二个属性页“MMC Snapin”上,选择IextendContextMenu,IextendControlbar,IextendPropertySheet,IsnapinAbout;并且去掉对持久性的支持;
4,    确定后,ATL Wizzard为我们生成了CMySnapin, CCMySnapinComponent, CMySnapinData,CMySnapinAbout, CMySnapinPage;
5,    编译;然后运行mmc.exe,添加一个管理单元“MySnapin”,另存为MySnapin.msc;
代码简介
CMySnapin实现了IComponentData,IExtendContextMenu,,IExtendPropertySheet三个接口。CMySnapinComponent实现了IComponent,IExtendContextMenu,IExtendControlbar,IExtendPropertySheet 四个接口,CMySnapinAbout则实现了ISnapinAbout接口。
DLL向外部暴露了CMySnapin和CMySnapinAbout两个对象。这样MMC就可以找到ISnapinAbout和IComponentData,IExtendContextMenu,,IExtendPropertySheet三个接口,然后MMC通过IComponentData的CreateComponent方法创建了CMySnapinComponent对象,从而又提供了CMySnapinComponent的IComponent,IExtendContextMenu,IExtendControlbar,IExtendPropertySheet 四个接口。
从图中可以看到,ATL的接口实现类实现了部分方法的默认行为,然后把几个重要方法如Notify等传递到CMySnapinData对象的同名函数,让其继续处理。
CMySnapinData从CSnapinItemImpl继承,CSnapinItemImpl实现了CSnapinItem接口,该接口定义了Item对象(左边的节点(scope pane item)还有右边的项(result pane item))的所有行为。
CMySnapin在构造函数里创建了CMySnapinData作为根结点。一个Item的所有行为都可以通过重载某些方法来修改默认行为。比如在根结点下面添加几个子节点,可以在重载的Notify方法中处理MMCN_EXPAND消息等等。
MSDN中的MMC Snap-In Wizard
MMC Snap-In Wizard讲了MMC Snap-In FAQ:
1.    How Do I Add a Toolbar Resource to the Snap-In Object?
2.    How Do I Add Menu Items, Control Bar Buttons, and a Property Sheet to the Snap-In Object?
3.    How Do I Enumerate the Child Items of the Snap-In Object?
4.    How Do I Add Custom Item Types to the Snap-In Object?
以上内容请自行参考msdn,按照以上的方法,可以做出一个完整功能的Snapin了。但是,非常遗憾的是,ATL Wizzard提供的无论是菜单、工具栏还是属性页都是所有的Item公用的,无论是Scope Item还是Result Item。特别是在有多个不同种类的节点的时候,这样几乎是不合适宜的。
按需定制的Item实现QA
如何生成子节点(Scope Item)?
    在按照以上步骤生成代码框架以后,运行MySnapin.msc可以看到只有一个根结点,名字是MySnapin。修改这个根结点的名字,只需要修改MySnapin.cpp文件中
const OLECHAR* CMySnapinData::m_SZDISPLAY_NAME = OLESTR("MySnapin");
这一行即可。
    前面讲过ATL把Item抽象成CSnapinItem接口,CSnapinItemImpl类实现了这个接口的大部分默认行为,因此,所有的Item都应该从这个类继承。考虑到CMySnapinData作为我们的根结点,ATL已经为我们生成了一些代码,从CMySnapinData继承是更好的选择。(能够重用的代码其实只有CMySnapinData构造函数中的初始化代码,不过从CMySnapinData继承的最大好处是可以将公共的实现放在CMySnapinData类中,而不需要每个Item类都实现一份相同的代码。),本文将从CMySnapinData类继承,也由于CMySnapinData将作为基类实现,因此,我们需要另外做一个根结点。
    接下来我们将生成三个一级子节点,分别为类似“服务”、“事件查看器”、“帐户管理”,然后在“事件查看器”和“帐户管理”中再生成二级子节点,基本上包含了定制菜单、属性页、工具栏等。
    分别从CMySnapinData继承,生成CItemRoot, CServicesContainer, CEventsContainer, CAccountsContainer。注意,在MySnapin.h文件中加入一行 #include "test6.h"。
    在CMySnapin的构造函数里,我们把根结点改为CItemRoot。
    在CItemRoot类中,重载Notify方法,增加代码处理MMCN_EXPAND,这个消息给了我们添加子节点(Scope Item)的机会。
    case MMCN_EXPAND:
        {
            CComQIPtr<IConsoleNameSpace, &IID_IConsoleNameSpace>
spConsoleNameSpace(spConsole);
            
            m_pServicesContainer->m_scopeDataItem.mask |= SDI_PARENT;
            m_pServicesContainer->m_scopeDataItem.relativeID = param;
            spConsoleNameSpace->InsertItem(&m_pServicesContainer->m_scopeDataItem);

            m_pEventsContainer->m_scopeDataItem.mask |= SDI_PARENT;
            m_pEventsContainer->m_scopeDataItem.relativeID = param;
            spConsoleNameSpace->InsertItem(&m_pEventsContainer->m_scopeDataItem);

            m_pAccountsContainer->m_scopeDataItem.mask |= SDI_PARENT;
            m_pAccountsContainer->m_scopeDataItem.relativeID = param;
            spConsoleNameSpace->InsertItem(&m_pAccountsContainer->m_scopeDataItem);
            
            hr = S_OK;
        }
        break;
如何生成结果栏的项(Result Item)
    从CMySnapinData继承,生成CEventEntry类,表示一个事件内容。在CEvent类中修改Notify方法的MMCN_SHOW消息,这个消息给了我们添加Result Item的机会。
如何修改子节点的名字?
    每一个结点都从CMySnapinData继承,其父类CSnapinItemImpl有一个成员变量CComBSTR m_bstrDisplayName。
MMC调用IComponentData或者IComponent 的GetDisplayInfo来获得显示信息,包括结点名字,GetDisplayInfo把调用传递到GetScopePaneInfo或者GetResultPaneInfo函数,GetScopePaneInfo和GetResultPaneInfo函数默认返回m_bstrDisplayName。
因此只要在构造函数里修改m_bstrDisplayName的值即可达到目的。
如何修改子节点的图标?
    在CMySnapinData中实现Notify方法的MMCN_ADD_IMAGES消息,这这里我们把所有的图标全部加载。这样其他的Item类就不需要再实现这部分代码了,只要把Notify中没有处理的消息让CMySnapinData的Notify方法处理一下即可。
    对于每个Snapin都有一个IImageList接口可供使用,MMC利用这个图标列表来保存所有需要用到的图标,以后每个Item只需要指出它的图标在图标列表的索引即可:
m_scopeDataItem.nImage = 2;
m_scopeDataItem.nOpenImage = 2;
    但是Scope栏中的图标却不是通过MMCN_ADD_IMAGES消息来加载的,而必须在CMySnapin类的Initialize方法中首先加载所有必要的图标。
    还有,以上的方法对根结点的图标都没有作用。根结点的图标的修改必须通过修改CMySnapinAbout类GetStaticFolderImage方法才可以。也可以顺便为About对话框添加一个ICON。    
如何修改子节点在结果栏中的默认显示?
    Scope Item在Result pane中默认仅仅显示一个名称。比如,在选中“MySnapin”时,默认行为是在Result pane中显示一级子节点。下面我们让“事件查看器”显示更详尽的信息。
    在CEventsContainer的Notify方法中修改MMCN_SHOW消息:
case MMCN_SHOW:
        {
            CComQIPtr<IResultData, &IID_IResultData> spResultData(spConsole);
            
            spHeader->InsertColumn(0, L"日志", LVCFMT_LEFT, 100);
            spHeader->InsertColumn(1, L"描述", LVCFMT_LEFT, 200);

            hr = S_OK;
        }
        break;
    然后在CEvent中重载GetResultPaneColInfo方法,提供每一列的显示字符串。
    由于GetResultPaneColInfo是非虚函数,因此我们还得在CEvent重载GetResultPaneInfo函数。或者修改CMySnapinData的GetResultPaneColInfo函数为虚函数,那么就可以不用再重载GetResultPaneInfo了。
如何给某一个子节点添加自己独特的菜单?
    由于从CSnapinItemImpl以模版方式实现,因此从CMySnapinData继承的Item类,将需要重载相应的处理函数,而不能最大限度地重用CSnapinItemImpl的实现。
    所以,我们让CService等几个需要更多功能的类从CSnapinItemImpl<CService>继承。

给“服务”项目添加“启动”、“停止”菜单。
1,    在菜单资源中添加菜单IDR_MYSNAPIN_MENU1,添加菜单项“启动”、“停止”到第一个下拉菜单中,如果需要在其他菜单项上,也可以添加到其他的下拉菜单中;
2,    使用宏SNAPINMENUID(IDR_MYSNAPIN_MENU1)来告诉ATL菜单资源的ID;
3,    使用宏
BEGIN_SNAPINCOMMAND_MAP(CService, FALSE)
            SNAPINCOMMAND_ENTRY(IDM_START, OnStart)
            SNAPINCOMMAND_ENTRY(IDM_STOP, OnStop)
    END_SNAPINCOMMAND_MAP()
    来接收命令消息。
4,    并使用
HRESULT OnStart(bool& bHandled, CSnapInObjectRootBase* pObj);
    HRESULT OnStop(bool& bHandled, CSnapInObjectRootBase* pObj);
来处理消息。
5,    如有必要,重载UpdateMenuState函数修改菜单状态;
如何给某一个子节点添加自己独特的工具栏?
给“服务”项目添加“启动”、“停止”工具栏按钮。
1,    资源中添加工具栏,添加按钮“启动”、“停止”;
2,    使用宏
BEGIN_SNAPINTOOLBARID_MAP(CService)
            SNAPINTOOLBARID_ENTRY(IDR_TOOLBAR1)
    END_SNAPINTOOLBARID_MAP()
    来接收命令消息。
3,    如有必要,重载UpdateToolbarButton函数修改按钮状态;
4,    如有必要,在处理消息后,可以通过IToolbar接口修改工具栏按钮状态;
如何给某一个子节点添加自己独特的属性页?
给“帐户”添加属性页。
1,    在CAccount类中重载Notify方法。
2,    在Notify方法中处理MMCN_SELECT消息:
CComPtr<IConsoleVerb> spConsoleVerb;
            if(spConsole->QueryConsoleVerb(&spConsoleVerb) != S_OK)
            {
                ATLTRACE("==>Query ConsoleVerb faild./n");
                return S_FALSE;
            }
            else
            {
                spConsoleVerb->SetVerbState(MMC_VERB_PROPERTIES, ENABLED,
TRUE);
                hr = S_OK;
        }
3,    重载CreatePropertyPages、QueryPagesFor方法,创建属性页,可以使用ATL Wizzard为我们生成的CMySnapinPage,也可以自行定制一个类似的类。
4,    如有必要,可以在属性页的OnApply函数中发出属性改变通知CAccout;
5,    CAccout相应地更新自己的显示。
注意点:
SCOPEDATAITEM/RESULTDATAITEM 结构的lParam,ATL特殊用法
    lParam在ATL中有特殊意义,IComponentImpl和IComponentDataImpl的GetDisplayInfo函数都假设SCOPEDATAITEM/RESULTDATAITEM 结构的lParam就是CSnapInItem对象,因此,CMySnapinData的构造函数中有m_scopeDataItem.lParam = (LPARAM) this;和m_resultDataItem.lParam = (LPARAM) this;
    因此,如果我们的Item类不从CMySnapinData继承的话,那么也要同样做这些工作。
QueryPagesFor方法
    如果Snapin支持属性页,那么必须在Root结点上提供一个QureyPagesFor的方法来支持,否则无法通过MMC控制台“增加”这个管理结点。

正文完

附件:

ROS机器人开发-第 02 章 开源的边界:哪些能抄,哪些要自己造 逆向任何产品的第一步不是拆东西,而是。这一章就是干这件事:Microduck 到底开源了什么、没开源什么、官方为什么这么说、复刻仓库自己是怎么栽了跟头又纠正过来的。边界划对,后面 34 章才不会在"这个件到底有没有官方资料"上反复打转。imu_to_dxlmicroduckelec_图 2-1 15 个部件沿运动链炸开的爆炸图(由 MJCF 自动渲染,每个部件标注名称与质量)。这张图本身就是"软件全开"的产物:没有官方装配图,复刻仓库用仿真模型自己画了出来。 阅读详情

相关推荐

YOLO26算法保龄球馆保龄球目标检测+训练好的模型+743张数据集+pyqt可视化界面.zip

数据集可视化效果可参见下方展示。 【数据集概况】 · 检测类别(中文):[保龄球(bowling)] · 训练集:594 张 · 验证集:75 张 · 测试集:74 张 · 总计:743 张 该数据集聚焦于室内保龄球馆场景,系统性采集了多角度、多姿态下保龄球在不同运动阶段的视觉特征,为保龄球运动过程中的球体识别与轨迹分析提供了高质量标注样本,具有明确的体育训练与智能辅助系统开发价值。... 【训练曲线与评估图】 【模型训练配置】 参数 | 值 模型 | yolo26n 训练轮数 | 100 epochs 输入尺寸 | 640x640 批次大小 | 24 优化器 | auto 初始学习率 | 0.01 训练设备 【关键指标汇总】 训练了 100 个 epoch,最终轮指标: 指标 | 数值 mAP50 | **0.9938** mAP50-95 | 0.6966 Precision | 0.9740 Recall | 0.9974 train/box_loss | 0.9113 train/cls_loss | 0.2862 val/box_loss | 1.1516 val/cls_loss | 0.3116 【训练过程分析】 100 轮训练后 mAP50 达到 0.9938,模型收敛良好。Loss 曲线前段快速下降,后段趋于平稳,val_loss 无反弹,没有明显过拟合。但 mAP50-95 为 0.6966,和 mAP50 差距 0.30,定位精度仍有优化空间。 【模型性能评估】 Precision 0.9740、Recall 0.9974,精召双高,模型对保龄球的检测能力强。 【预测效果展示】 验证集预测效果较好,检测框基本准确覆盖保龄球,置信度整体偏高。 【改进建议】 1. 丰富场景多样性:补充不同光照、背景和遮挡条件下的样本。 2. 提升输入分辨率:640 ...

ATL编写MMC SnapinSample

 MMC相关的编程接口MMC 实现了下面的接口:IColumnData (new in MMC 1.2) IConsole2 IConsoleNameSpace2 IConsoleVerb IContextMenuCallback IContextMenuProvider IControlbar IDisplayHelp IHeaderCtrl2 (new in MMC 1.2) IImage

flashsj的专栏 1086

goose 是一款在您的设备上运行的通用型 AI 代理

一款开源、可扩展的AI代理,功能远超代码建议——支持安装、执行、编辑以及与任何大型语言模型(LLM)进行测试。

MMC Snap In应用程序开发

MMC Snap In Development Starting Guide 目录 MMC Technology Summary Keywords MMC Programming Elements In this topic How to test the MMC program MMC Basic Class MMC Sample Code 抱歉:由于本人的英文能...

weixin_30332705的博客 319

用C# 创建 MMC Snapin

下载示例 - 102 Kb 绪论The article/code snippet helps in creation of MMC Snapin using C#. 背景The framework for building management consoles for Windows NT/2000 is developed by Jim. Jim is the author for ironr

江湖·郎中·路 1820

解禁注册表,启用MMC

       公司租用了远端主机(系统为WIN2003+SP2),需要设定组策略进行管制,在设定当中,先后把命令提示符、注册表、桌面、资源管理器等禁用,因一时大意,竟把MMC平台也设为禁用。退出系统后重新登陆,想再次进入组策略编辑器,才发生MMC不能使用了,唯一庆幸的是“开始=》运行”还未设为禁用,但在“运行”中输入“CMD”或“REGEDIT”,系统提示“命令提示符已被管理员禁用”等。试了N种方

ggw128的专栏 3275

ATL开发复合控件

 转载:http://www.vckbase.com/index.php/wv/1110 本文讲述了如何用ATL建立复合控件,以及如何响应连接点事件。考虑到代码很简单,程序中没有加注释,如有不清楚请参看MSDN,代码仓促中完成,不免有疏漏,见谅。 声明:本文仅适合初级中的初级读者。 步骤一:建立ATL项目,取名为AtlSample 步骤二:选择默认选项,点击F

myiszjf的专栏 955

如何使用Microsoft Management Console编写Snap-in(一)

1. 安装WindowsXP-KB907265-x86-ENU.exe,安装之后会在"C:\Windows\System32\"目录下多出两个文件:microsoft.managementconsole.dll。4. 在编译目录运行installutil TestMMC3.dll命令,如果没有将mmcfxcommon.dll加入GAC,就需要将TestMMC3.dll放到"C:\Windows\System32\"中。如果你要使用.NET 1.1编写对于MMC2的Snap-in,可以参考MMC.NET。

biyusr的专栏 1028

Mmc编程

SV的界面使用到mmc(Microsoft Management Console) Mmc编程中:通过调用启动*.mmc文件,插件以dll文件形式存在(这里是在代码的lib库中),通过编程编译形成dll文件(这里是:lib/jcenv/libjcenvJPN) MmcMMC为插件提供通用的宿主环境,这些插件可以是由微软或第三方软件供应商提供的。插件提供实际的管理行为,MMC自身并不提供任何管...

weixin_30651273的博客 543

mmc管理控制台是做什么的!?

看看这个网站吧 很全的 http://www.microsoft.com/technet/prodtechnol/windowsserver2003/zh-chs/library/ServerHelp/cd4d1a55-f5f9-4257-9a7b-b43f1737fd80.mspx?mfr=true 使用 MMC 控制台 可能需要使用预配置的 MMC 控制台(一般称为“保存的控制台”,这些控制台

ptrunner的专栏 9910

MFC CPtrArray的用法

CPtrArray是,在,专门用来存放。和你刚才看同事手写的那个CPtrArray目标一模一样,同事 2004 年就是模仿 MFC 这个类手写的简易版本。

谢谢大家的关注和点赞!这里只有纯纯的知识干货,没有一句废话。希望能实实在在帮到大家~要是觉得有用,别忘了给我点支持哟,你 251

基于GTK的简易MFC对话框兼容层 -- MfcToGTK

本文介绍了一种将Windows MFC对话框程序移植至Linux的轻量级兼容方案。通过解析MFC资源字符串,利用GTK库实现窗口控件的动态创建与布局,结合自定义CDialog基类和CStringW等MFC兼容类型,使原有基于MFC的测试工具在少量修改后即可在Linux上编译运行。该方案支持静态文本、编辑框、按钮、复选框等常见控件,并实现了模态对话框、数据交换(DDX)及文件选择对话框等功能,有效降低了跨平台移植成本。

lif12345的专栏 234

MFC 嵌入WPF控件

regasm UserControlLib.dll /regfile:UserControlLib.reg # 生成.Net Com 库的注册信息,可以将注册键HKEY_CLASSES_ROOT改为HKEY_CURRENT_USER\Software\Classes,执行reg import UserControlLib.reg将信息注册到当前用户,避免需要管理员权限。(基于.Net Framework创建的COM库,无法使用manifest进行免注册,因为clrCalss无法被WinSxS正确解析)。

yuanshenqiang的博客 120

PaddleOCRApi面向 Windows 与 Linux 的轻量级 OCR 与YOLO目标检测 HTTP 服务

PaddleOCR 与YOLO目标检测 HTTP 服务。 项目通过 PaddleOCROnnx 原生库集成 OnnxRuntime加速能力,围绕 ONNX 模型部署, 以统一接口提供图像文字识别、YOLO 目标检测和 Tensor 数据输出。 功能概览 文字识别:支持图片 Base64、multipart/form-data 上传,以及文本和 JSON 结果。 目标检测:支持 YOLO 图片检测,返回检测框 JSON 或原始 Tensor。 浏览器演示:访问服务根地址,上传图片并切换 OCR、YOLO 模式。 健康检查:通过 /health 查看服务及 OCR、YOLO 引擎初始化状态。 并发处理:通过 OCR 引擎实例池处理并发请求,可调整实例数量。 体验与调用 启动后访问: 入口 地址 浏览器演示 http://localhost:5000/ 健康检查 http://localhost:5000/health 原生依赖 Windows:优先从 runtimes/win-x64/native/ 加载原生 DLL;该目录没有 PaddleOCROnnx.dll 时,尝试从可执行文件所在目录加载。主 DLL 与对应后端依赖应放在同一原生目录中,不要将同一组依赖分散到多个目录。 Linux:原生运行时位于 runtimes/linux-x64/native/,程序使用相对于可执行文件的运行时搜索路径查找随包部署的依赖。 后端选择:CoreOCROnnx 支持 ONNX Runtime、OpenVINO、TensorRT 后端。请使用与平台、进程架构、硬件和后端匹配的一整套运行时,不要混用不同后端或版本的依赖。

丧尸枪战_1.0

丧尸枪战1.0这是一款我自己做的游戏2d版本的这个游戏我以后会更新

上一篇: 使用C#返回系统特殊路径.txt
下一篇: 用C# 创建 MMC Snapin
ycl111
博客等级 码龄22年 25粉丝 275原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值