浩子

在.NET的世界里徜徉

导航

用自动化接口控制 Virsual Studio .NET 2003 的工具箱

做了一套ASP.NET的自定义控件,本想把这些控件加到Virsual Studio .NET 2003 的工具箱中,看了一下MSDN,自己做代码试了一下,竟然不好使。搞了半天,查了N多资料,才知道是Virsual Studio .NET 2003的Bug,好在总算解决了。下面是源码,发出来以免大家碰到同样问题是浪费时间。

中间有几行代码可能你会觉得没必要,但如果没有,你会发现就不好用,经验之谈,希望对大家有所帮助!

控制台程序的主单元:

using System;
using EnvDTE;

namespace SuperToolboxCS
{
/// <summary>
/// ClassMain 的摘要说明。
/// </summary>
class ClassMain
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
Type latestDTE = Type.GetTypeFromProgID("VisualStudio.DTE");
EnvDTE.DTE dte = Activator.CreateInstance(latestDTE) as EnvDTE.DTE;

MessageFilter.Register();

if (dte != null)
Installer.AddToolBoxTab(dte);

MessageFilter.Revoke();
}
}

sealed class Installer
{
public static void AddToolBoxTab(EnvDTE.DTE dte)
{
if (dte == null)
return;

Window win = dte.Windows.Item(EnvDTE.Constants.vsWindowKindToolbox);

ToolBox box = win.Object as ToolBox;

if (box == null)
return;

ToolBoxTabs tabs = box.ToolBoxTabs;

if (tabs == null)
return;

foreach (ToolBoxTab t in tabs)
{
if (t.Name == TabName)
t.Delete();
}

ToolBoxTab tab = tabs.Add(TabName);

if (tab == null)
return;

dte.ExecuteCommand("View.PropertiesWindow", "");

tab.Activate();
tab.ToolBoxItems.Item(1).Select();

string fullpath = LookupSuperServerObjectFileName();

if (fullpath == "")
return;

tab.ToolBoxItems.Add(@"Unused?", fullpath, vsToolBoxItemFormat.vsToolBoxItemFormatDotNETComponent);

System.Console.Write("SuperLib Web 窗体工具箱创建成功!");
}

private static string LookupSuperServerObjectFileName()
{
string KeyName = "";

Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.LocalMachine;
rk = rk.OpenSubKey(KeyName, false);

if (rk == null)
{

return "";
}

string fullpath = (string)rk.GetValue(null);
fullpath += @"\SuperLib.ServerObject.dll";

if (!System.IO.File.Exists(fullpath))
{

return "";
}

return fullpath;
}

private const string TabName = @"SuperLib Web 窗体";
private const string KeyName = @"SOFTWARE\Microsoft\VisualStudio\7.1\AssemblyFolders\SuperLibV2.4.2003";
}
}

MessageFilter 类

using System;
using System.Runtime.InteropServices;

namespace SuperToolboxCS
{
/// <summary>
/// MessageFilter 的摘要说明。
/// </summary>
public class MessageFilter : IOleMessageFilter
{
public static void Register()
{
IOleMessageFilter newfilter = new MessageFilter();

IOleMessageFilter oldfilter = null;
CoRegisterMessageFilter(newfilter, out oldfilter);
}

public static void Revoke()
{
IOleMessageFilter oldfilter = null;
CoRegisterMessageFilter(null, out oldfilter);
}

//
// IOleMessageFilter impl

int IOleMessageFilter.HandleInComingCall(int dwCallType, System.IntPtr hTaskCaller, int dwTickCount, System.IntPtr lpInterfaceInfo)
{
System.Diagnostics.Debug.WriteLine("IOleMessageFilter::HandleInComingCall");

return 0; //SERVERCALL_ISHANDLED
}

int IOleMessageFilter.RetryRejectedCall(System.IntPtr hTaskCallee, int dwTickCount, int dwRejectType)
{
System.Diagnostics.Debug.WriteLine("IOleMessageFilter::RetryRejectedCall");

if (dwRejectType == 2 ) //SERVERCALL_RETRYLATER
{
System.Diagnostics.Debug.WriteLine("Retry call later");
return 99; //retry immediately if return >=0 & <100
}
return -1; //cancel call
}

int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee, int dwTickCount, int dwPendingType)
{
System.Diagnostics.Debug.WriteLine("IOleMessageFilter::MessagePending");

return 2; //PENDINGMSG_WAITDEFPROCESS
}

//
// Implementation
[DllImport("Ole32.dll")]
private static extern int CoRegisterMessageFilter(IOleMessageFilter newfilter, out IOleMessageFilter oldfilter);
}

[ComImport(), Guid("00000016-0000-0000-C000-000000000046"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
interface IOleMessageFilter // deliberately renamed to avoid confusion w/ System.Windows.Forms.IMessageFilter
{
[PreserveSig]
int HandleInComingCall(
int dwCallType,
IntPtr hTaskCaller,
int dwTickCount,
IntPtr lpInterfaceInfo);

[PreserveSig]
int RetryRejectedCall(
IntPtr hTaskCallee,
int dwTickCount,
int dwRejectType);

[PreserveSig]
int MessagePending(
IntPtr hTaskCallee,
int dwTickCount,
int dwPendingType);
}
}

同样有 VB.NET 版本的实现,不贴了。
需要发消息。

参考 BLOG:
http://weblogs.asp.net/savanness/archive/2003/04/24/6012.aspx
http://weblogs.asp.net/savanness/archive/2003/04/15/5701.aspx
http://weblogs.asp.net/savanness/archive/2003/04/10/5352.aspx
http://weblogs.asp.net/savanness/archive/2003/03/18/4019.aspx

posted on 2004-10-14 22:03  浩子  阅读(920)  评论(1编辑  收藏  举报