启动VNC Shell扩展

下载source files - 18.3 Kb
Introduction
我们使用RealVNC来远程控制我们的网络中的pc机,VNC是一个伟大的产品,但如果不记住计算机名称,它可以是乏味的,在网络邻里找到计算机,然后复制计算机名称到VNC连接屏幕,所以我开发了这个Shell扩展。
VNC是什么?
从RealVNC网站:

VNC代表虚拟网络计算。它是一种远程控制软件,允许你使用一个简单的程序(“查看器”)在互联网上任何地方的另一台计算机上查看和交互一台计算机(“服务器”)。这两台计算机甚至不必是同一类型的,因此,您可以使用VNC来查看您家里的Windows PC上的office Linux计算机。VNC是免费和公开可用的,并在广泛活跃使用的数百万人在整个工业,学术界和私人。
RealVNC可以在这里下载。
创建一个扩展
首先我要感谢Michael Dunn所做的一切努力,特别是他的教程:编写Shell扩展的完整傻瓜指南第一部分。我将它作为我的扩展的起点。
我按照他的步骤创建了他的扩展演示,然后更改了他的初始化接口代码来处理网络资源,而不是文件名。
CFSTR_NETRESOURCES
在传输网络资源(如域或服务器)时使用此格式标识符。数据是一个包含全局内存对象的STGMEDIUM结构。结构的hGlobal成员指向一个NRESARRAY结构。该结构的nr成员表示一个NETRESOURCE结构,其lpRemoteName成员包含一个以null结尾的字符串来标识网络资源。
我们必须使用RegisterClipboardFormat API函数(提供CFSTR_NETRESOURCES作为参数)来获得用于网络资源的shell注册剪贴板格式。然后我们可以在NRESARRAY结构的nr成员中从第一个NETRESOURCE结构中提取所选项目的名称。
我们检查资源的类型,因为我们只对服务器感兴趣。成员dwDisplayType包含资源的类型。隐藏,复制Codeif(pNtary->nr[0].dwDisplayType == RESOURCEDISPLAYTYPE_SERVER)
NETRESOURCE结构中的字符串成员包含偏移量而不是地址!
因此,我们通过将结构转换为char指针来获得所选的名字,然后向指针添加偏移量,然后将其转换为WCHAR指针。隐藏,复制CodeWCHAR* pwchRemoteName = (WCHAR*)((char*)pNtary +
int(pNtary->nr[0].lpRemoteName));
我们从返回名称的开头删除\,并将其存储在m_szPCName成员变量中以供以后使用。隐藏,收缩,复制CodeSTDMETHODIMP CVNCShell::Initialize(LPCITEMIDLIST pIDFolder,
IDataObject *pDataObj,
HKEY hRegKey)
{
HRESULT hr;

if (pDataObj)
{
STGMEDIUM medium;
FORMATETC fe;
fe.cfFormat = RegisterClipboardFormat(CFSTR_NETRESOURCES);
fe.ptd = NULL;
fe.dwAspect = DVASPECT_CONTENT;
fe.lindex = -1;
fe.tymed = TYMED_HGLOBAL;

  hr = pDataObj->GetData(&fe, &medium);
  if(SUCCEEDED(hr))
  {
    LPVOID lpv = GlobalLock(medium.hGlobal); 
    if (lpv)
    {
      LPNRESARRAY pNtary = (NRESARRAY*)lpv;

      m_bShowMenuItem = false; 
      
      if(pNtary->nr[0].dwDisplayType == RESOURCEDISPLAYTYPE_SERVER)
      {
         m_bShowMenuItem = true;

         // The string members in the structure 
         // contain offsets instead of addresses!
         WCHAR* pwchRemoteName =  (WCHAR*)((char*)pNtary +
            int(pNtary->nr[0].lpRemoteName)); 

         // Copy name, minus \\ at begining of name, to local variable
         lstrcpynW (m_szPCName, pwchRemoteName + 2, 
               lstrlenW(pwchRemoteName) * sizeof(TCHAR));
      }
            
      GlobalUnlock(medium.hGlobal);
    }
    else
      hr = E_UNEXPECTED;
    
    ReleaseStgMedium(&medium);
  }

}
return hr;
}
我也改变了InvokeCommand界面显示一个对话框的代码替换为VNC程序执行的代码,这个假设VNC提供程序是安装在固定的路径,在本例中它总是安装,我们通过m_szPCName成员变量包含我们之前存储的电脑名称。隐藏,复制CodeShellExecute (pCmdInfo->hwnd, _T(“open”),
_T(“C:\Program Files\RealVNC\vncviewer.exe”),
m_szPCName, NULL, SW_SHOWNORMAL);

return S_OK;
注册shell扩展
Shell在HKEY_CLASSES_ROOT下定义了其他对象,可以按照与文件类型相同的方式扩展这些对象。
我们唯一感兴趣的是网络\Type\2子键:
HKEY_CLASSES_ROOT \网络\ \ 2 \ ShellEx \ ContextMenuHandlers \ VNCShellExt类型
从MSDN:

"对于Network\Type#, "#"是十进制的网络提供程序类型代码。网络提供者类型代码是网络类型的高级字。网络类型的列表在Winnetwk.h头文件中给出(WNNC_NET_* values)。
所以我把注册表资源从文本文件改为:复制CodeNoRemove Network
{
NoRemove Type
{
NoRemove 2
{
NoRemove ShellEx
{
NoRemove ContextMenuHandlers
{
ForceRemove VNCShellExt = s ‘{B9442EFE-9815-4046-B6FF-4F3606291D8E}’
}
}
}
}
}
就这样,这是我第一次尝试写这篇文章,而且我用c++编程的时间很短,请不要客气:)
参考文献

Michael Dunn的教程:完整的白痴指南编写Shell扩展-第一部分&第二部分
创建Shell扩展处理程序,Shell剪贴板格式

本文转载于:http://www.diyabc.com/frontweb/news29763.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值