WEB开发网
开发学院软件开发VC 编写控制面板程序的一个例子 阅读

编写控制面板程序的一个例子

 2009-10-24 20:31:26 来源:WEB开发网   
核心提示:一定要用DECLARE_DYNCREATE来声明对话框类和属性页类,如果不这样做Create会调用失败,编写控制面板程序的一个例子(3),而且可能还会有MFC的TRACE诊断错,除此之外,所以删除文件的时候一定要小心,如果哪位有更好的办法,还要记住重 写对话框和属性页的OnPostNcDestroy函数,加入代码&ld

一定要用DECLARE_DYNCREATE来声明对话框类和属性页类。如果不这样做Create会调用失败,而且可能还会有MFC的TRACE诊断错。除此之外,还要记住重 写对话框和属性页的OnPostNcDestroy函数,加入代码“delete this”。这是因为,通常创建对话框是在栈(stack)上进行的,代码如下:

CMyDialog dlg;
dlg.DoModal();

这种情况不用关心delete。而CPApplet是在堆(heap)上创建的对话框和属性页,在对话框和属性页被destroy掉以后,必须要进行delete操作,否则造成内存溢出。

综上所述,我们可以看到,使用CControlPanelApp 和 CCPApplet编写控制面扩展易如反掌。为了添加普通对话框或者基于属性页的面板应用,只需要重写CControlPanelApp::OnInit即可,然后实现相应的对话框代码和属性页代码。 表一概括地总结了框架处理各种CPL消息的方法和注释。

表一:控制面板消息和控制面板应用框架

CPlApplet 消息 框架 class::function 是否需要改写?
CPL_INIT CControlPanelApp::OnInit 是,每个控制面板程序都调用 AddApplet 添加
CPL_GETCOUNT 没有 否,CControlPanelApp 决定控制面板程序数量
CPL_INQUIRE CCPApplet:: OnInquire 很少用
CPL_NEWINQUIRE CCPApplet::OnNewInquire 很少用
CPL_DBLCLK CCPApplet::OnLaunch 很少用,仅用于没有对话框和属性页界面的情况
CPL_SELECT (已废掉) CCPApplet::OnSelect
CPL_STOP CCPApplet::OnStop 很少用,除非控制面板程序都进行垃圾收集,但这种情况最好在程序的析构函数中进行
CPL_EXIT CControlPanelApp::OnExit 很少用,用 ExitInstance 代替
CPL_STARTWPARAMS
(Windows 98 或者Windows NT 4.0)
CCPApplet::OnLaunch 很少用,仅用于没有对话框和属性页界面的情况

下面是编写控制面板程序需要注意的几件事情:首先是生成控制面板扩展后,它是一个*.dll文件,不要忘了把它的扩展名改为*.cpl。其次,运行*.cpl之前,必须将它拷贝到Windows的系统目录中,如C:\\Winnt\\System32,或者C:\\Windows\\System,根据你的操作系统安装目录决定。你可以通过“Project”=>“Setting”菜单将这一步添加到Post-Build步骤中。如果你想在自己的目录中保存一份DLL文件,那么可以通过安装程序在Windows的CONTROL.INI文件的[MMCPL]

段添加一行内容:

[MMCPL]

MyCtrlPanel=c:\utils\MyCtrlPanel\MyCtrlPanel.cpl

第三要注意的事情是当你生成控制面板程序时,可能会遇到下面的情况:如增加另一个面板应用、改变名字或者图标——而这些更改在控制面板中反映不出来。这是因为控制面板读取(CPL_INQUIRE)信息时,需要第一次与你的DLL见面后, 它才能将信息缓冲到磁盘。让控制面板重读新信息的一种比较保险的方法是改DLL名字。你也可以试一下在控制面板中按F5(Refresh),但这个方法不一定每次都奏效。在开发期间,你可以将CCPApplet::m_bDynamic 设置为 TRUE,让它告诉框架使用CPL_NEWINQUIRE(不缓冲信息)代替 CPL_INQUIRE (缓冲信息)。当你完成调试准备发行正式版时,再将CCPApplet::m_bDynamic置回(缺省值)FALSE。

说到调试,下面介绍两种调试控制面板应用程序的方法:一种是在调试器中启动控制面板程序;如果你觉得那太麻烦,那么还有另外一种方法是使用rundll32:

rundll32 shell32.dll,Control_RunDLL MyCtrlPanel.cpl

你可以在命令行上面的命令,也可以在VC++的Debug Settings菜单中进行设置。

相信很多人都没像这样用过 rundll32.exe 程序,它可以从命令行调用某个DLL中的某个函数。Control_RunDLL是shell32.dll中的一个特别的函数, 顾名思义,它运行一个控制面板程序;为了运行DLL中一个特定的控制面板程序,敲入:

rundll32 shell32.dll,Control_RunDLL MyCtrlPanel.cpl,@n

这里 n 是基于零的应用程序索引。如果你在末尾加一个串,它被传递到CPL_STARTWPARAMS,就象一个常规的Windows应用程序命令行一样。通常,这个串被用于启动一个基于属性页的控制面板应用, 并且定位到特定的属性页上。例如:为了调出显示器的“设置”属性页标签,敲入:

rundll32 shell32.dll,Control_RunDLL desk.cpl,,3

如果你以前不知道有些应用程序是怎么启动特定的控制面板应用的,现在你应该知道了。如果你使用本文提供的迷你框架,自己就不必写任何代码来解析这个参数;对于一个基于属性页的面板,CCPApplet自动将相关参数解释为一个属性页号。

LRESULT CCPApplet::OnLaunch(CWnd* pWndCpl, LPCSTR lpCmdLine)
{
  CWnd* pw = (CWnd*)m_pDialogClass->CreateObject();
  if (pw) {
   if (pw->IsKindOf(RUNTIME_CLASS(CPropertySheet))) {
     CPropertySheet* ps = (CPropertySheet*)pw;
     ps->SetActivePage(lpCmdLine ? atoi(lpCmdLine) : 0);
     ps->DoModal();
   } else if (pw->IsKindOf(RUNTIME_CLASS(CDialog))) {
        CDialog* pd = (CDialog*)pw;
        pd->DoModal();
      }
  }
  return pw==NULL;
}

最后,如果你不知道如何卸载控制面板程序,这里告诉你一个笨方法:重启机器,只要你不运行控制面板,Windows就不会加载那些.cpl文件,所以你可以直接到Windows系统目录 (比如c:\windows\sysytem或者c:\winnt\system32)下删除相应的.cpl文件。注意这样做的风险是——万一你删错了文件, 那么对应的控制面板程序图标将从控制面板中消失。所以删除文件的时候一定要小心。如果哪位有更好的办法,请告诉我。

希望本文的介绍和例子对大家开发控制面板程序有所帮助

上一页  1 2 3 

Tags:编写 控制 面板

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接