如何:支持工具箱拖放功能

备注

建议使用此方法的方式将自定义控件添加到工具箱将使用随 Visual Studio 10 SDK,包括拖放支持的工具箱控件模板。本主题仅保留以备向后兼容和用于现有控件一起使用。

有关使用该模板创建的工具箱控件的更多信息,请参见 如何:创建使用 windows 窗体的一个工具箱控件如何:使用 WPF 创建一个工具箱控件

,如果它们是使用 工具箱 文档中的控件视图 (例如,编辑器或设计器, Vspackage 必须实现拖放支持。

默认情况下,从 Control 派生的所有 .NET Framework 对象自动和透明地提供使用 工具箱 控件支持,因此,下面介绍的过程是不必要的。 这种基本功能可以通过创建设计器扩展。

有关更多信息,请参见Windows 窗体概述扩展设计时支持

实现基本拖放功能

  1. 提供拖放通过实现在视图对象的 IDropTarget 支持。 这使个控件的视图具有 OLE 拖放功能和序列化。

    有关实现拖放功能的更多信息,请参见 拖放 (OLE)

    放置能在设计器或控件放置的剪贴板项。 有关 Visual Studio 支持的标准剪贴板格式的信息工具箱,请参见 工具箱 (Visual Studio SDK)

  2. 提供 IVsToolboxUser 接口的基本实现在文档视图。

    当用户尝试工具箱控件拖动到视图中时, Visual Studio shell 查询视图的 VSPackage 来查看它是否实现 IVsToolboxUser 接口。

    1. 实现返回放置目标支持的一些 工具箱 格式的 S_OKIsSupported 。 在将检查下面的示例数据对象是否以自定义剪贴板格式 (CF_CUSTOM_FORMAT),并且对象是 Activex 控件。

      STDMETHODIMP CustTbxUser::IsSupported(IDataObject* pDO)
      {
          HRESULT hr;
          STGMEDIUM stm;
          if (!pDO)
          return E_POINTER;
          // Determine if the data object is in the Custom clip board format
          // fetc is the dialog editor toolbox item template.
          FORMATETC fetc = { 
            m_CF_CUSTOM_FORMAT, //Value set with RegisterClipboardFormat
            NULL, 
            DVASPECT_CONTENT, // DVASCPECT_ICON might be better
            -1, 
            TYMED_HGLOBAL 
          };
          if (FAILED(hr = pDO->GetData(&fetc, &stm)))
          {
              // Determine if the object is in the class-id clipboard format ... this
              // would be the case if the control is an activeX toolbox item.
              FORMATETC xfetc = 
              { 
                m_CF_CLSID,
                NULL, 
                DVASPECT_CONTENT, // DVASCPECT_ICON might be better
                -1, 
                TYMED_HGLOBAL 
              };
              if (SUCCEEDED(hr = pDO->GetData(&xfetc,&stm)))
              {
                  USES_CONVERSION;
                  GUID guid;
                  LPSTR pData = (LPSTR)GlobalLock(stm.hGlobal);
                  if (pData)
                  {
                      // Convert from the string format to a binary GUID.
                      if (CLSIDFromString(A2W(pData), &guid) != S_OK)
                          return E_FAIL;
      
                      // HTML data objects could have CLSID format ... so any data object could 
                      // be returned as a NULL guid ... fail on null guid, obviously they are 
                      // not active X controls.
                      if (guid == GUID_NULL)
                          return E_FAIL;
                  }
              }    
          }
      
          return hr;
      }
      

      IDE 检查该信息,则视图的窗口第一个加载和视图窗口的每启动遵循 工具箱 的重置中用户通过 IDE 的 自定义工具箱 对话框。 通常, 工具箱 不显示不支持的 工具箱 项目。

      用户可以设置选项始终显示所有工具箱页。 在这种情况下,该环境不查询 IsSupported的编辑器。 有关如何用户的信息可以通过 IDE 中配置 工具箱 ,请参见 How to: Manipulate Toolbox Tabs

    2. IDropTarget 实现 (如中所描述的上面) 成功处理后一个放置的元素,视图对象必须通过调用 DataUsed发现此的 Visual Studio 环境 

    如果需要, VSPackage 中扩展其拖放通过扩展其 IVsToolboxUser 实现支持。

  3. IVsToolboxUser 实现可以支持拖动 工具箱 项添加到窗口通过选择而不是鼠标事件。 即拖动项,当用户双击 工具箱 项目或单击时然后按 enter。 具体方法为:

    1. 实现 ItemPicked 方法。

      此方法,调用由 IDE 通过单击进行选择,或者按 enter。

      方法如果插入 工具箱 项目到目标窗口。

    2. 如果不希望通过选择支持实现,该方法应返回 S_FALSE

      在下面的示例中, ItemPicked 方法的实现检查选定的对象是否支持,,并且,如果这样将到代码:

      STDMETHODIMP CustTbxUser::ItemPicked(IDataObject* pDataObject)
      {
          if (!pDataObject)
              return E_POINTER;
      
          UINT nIDTool;
          if (IsSupported(pDataObject) == S_OK)
          {
              SetToolCursor();
              m_pDataObject = pDataObject;
              nIDTool = DeserializeObject();
              // Get the focus back
              m_pResObject->m_spWndFrame->Show();
              return S_OK;
          }
      }
      
  4. 执行以下步骤以确保适当的焦点为应用程序中维护:

    1. 如果编辑器窗口实现两个不同窗格中,不存在两种不同视图,则调用 UpdateToolboxUI 方法,当您切换到编辑器窗口中的窗格启动。 只有您知道启动更改时在窗口内。

    2. 正确激活窗口和确保正确更新命令传送,则必须对该元素的 Show 方法。 此操作,则将焦点设置为组件窗口,例如编辑器中,创建或修改涉及工具箱时,的拖放操作必须执行。

VSPackage 在拖动操作可能需要干预并将 IVsToolboxActiveUserHook 界面修改该删除的项目。

例如,而不是显式添加新的 工具箱 控件。 工具箱, VSPackage 可能截获标准 工具箱 ,则继承和用自定义实现替换它。

动态修改工具箱控件

  1. 实现 IVsToolboxActiveUserHook 方法。

    每当 工具箱 项选择或放置, 工具箱 查询放置目标查看它是否支持 IVsToolboxActiveUserHook 接口和,如果调用 InterceptDataObject 方法。

  2. InterceptDataObject 方法必须返回要使用的新 IDataObject 对象而不是原始 IDataObject

    如果放置目标不需要重写数据对象,它将返回其输入。

VSPackage 可以允许用户通过剪贴板的内容循环通过按 CTRL+SHIFT+V。

支持剪贴板循环

  1. 实现 CMDIDPasteNextTBXCBItem 命令的处理程序使用:

  2. 在命令处理程序中,执行 AreDataObjectsAvailable 方法确定是否通过对循环的任何剪贴板对象。

    1. 如果在工具箱剪贴板的项目,则该环境检查系统剪贴板查看是否已的任何项目。

    2. 如果在系统剪贴板的项目,但是,不在工具箱中剪贴板,则剪贴板循环填充系统项目。

    3. 若要选择列表中的下一项,实现调用 GetAndSelectNextDataObject 方法。

    4. 若要返回到剪贴板循环的开头,调用 BeginCycle 方法。

请参见

任务

高级工具箱控件开发

概念

如何:使用互操作程序集,提供自定义工具箱项

注册工具箱支持功能

管理工具箱

其他资源

工具箱 (Visual Studio SDK)