<!-- Search Google -->
输入您的搜索字词 提交搜索表单
|
<!-- Search Google -->
集成开发环境中各个窗口的行为都是事先实现的,比如,文档编辑窗口对应着多文档类的视图窗口,负责对用户的输入进行响应,更新窗口的内容,主窗口负责调度各个视图窗口。Visual Studio的集成开发环境(IDE)没有给我们提供任何接口实现在IDE中添加一个窗口,并且这个窗口能够和IDE中其他窗口分享消息的功能,也就是说正常情况下插件无法干涉IDE环境中窗口的正常行为。但是,这并不意味着我们只能老老实实的作些本分工作,因为通过窗口的子类化技术(Subclassing),我们一样可以Hook窗口的消息。Visual Studio的插件是工作在IDE的进程空间的,这就给我们提供了Hook IDE内任何窗口的机会。从理论上讲,我们可以使用自己的窗口消息处理过程代替IDE中各个窗口的标准窗口消息处理过程,完成对特定消息的响应,甚至完全改变某个窗口的行为。著名的VC商业插件软件Visual Assist就是替换了文档编辑的视图窗口,从而使其比默认的文档编辑窗口提供更多的便利功能。
Visual Studio的IDE环境有很多窗口,我们关心的只有三个(类)窗口,一个是主框架窗口,一个是MDI子框架窗口,一个是文档窗口。TabBars的标签栏其实并不依赖主框架窗口的消息约束自己的行为,子类化主框架窗口主要是为了处理WM_GETTEXT消息。当用户在不同的文档窗口之间切换时,主框架窗口就会相应的改变窗口标题栏上显示的文字,Hook WM_GETTEXT消息可以使Tabbars插件自己创建的窗口能够在第一时间获得这个消息并做出相应的处理。子类化MDI子框架窗口有两个主要目的,一个是截获窗口大小和位置变更的消息以便能够适时的调整标签栏的大小和位置;另一个是向文档窗口报告MDI子框架窗口新的客户区位置,新客户区排除了标签栏窗口占用的位置,如果不处理这个消息,框架窗口会将文档窗口会按照默认的位置摆放,这会遮挡标签栏窗口。子类化文档窗口是为了处理WM_DESTROY消息,以便能够在用户关闭文档窗口时有机会更新标签栏上的按钮。下图是TabBars插件的窗口类关系图:
图1. Tabbars窗口类关系图
关系图中的核心是CTabManagerWindow类,这个类虽然名为TabManager,但是并不直接管理标签栏,它通过CTabBarsWnd管理标签栏。CTabBarsWnd是一个MFC的CWnd派生类,他的作用有两个,一个是周期的产生定时器事件,驱动TabBars插件完成文件自动保存之类的工作;另一个作用就是作为容器窗口承载一个Table控件。
子类化窗口的关键是找到窗口的句柄,Visual Studio的内置插件接口没有提供获取这些窗口句柄的方法,TabBars使用了很多小的Trick来达到这个目的,首先是hook主框架窗口,先看下面的代码:
pApp->put_Active(VARIANT_FALSE);
pApp->put_Active(VARIANT_TRUE);
hWnd = ::GetActiveWindow();
while (hWnd && hWnd != hDesktopWnd)
{
hDevStudioWnd = hWnd;
hWnd = ::GetParent(hWnd);
}
g_pDevStudioWnd = new CDevStudioWnd(hDevStudioWnd); //CWnd::FromHandle(hDevStudioWnd);
put_Active是操作IApplication接口的Active属性,确保Visual Studio的IDE窗口是当前活动窗口,紧跟着调用GetActiveWindow获得这个窗口。不过,GetActiveWindow通常得到的是IDE下的活动子窗口,所以通过向上查找父窗口最终可以得到真正的主框架窗口。
得到主框架窗口之后就可以顺藤摸瓜得到MDI子框架窗口,MDI子框架窗口使用了固定的类名:MDIClient,所以遍历主框架窗口的所有子窗口就可以找到MDI客户区窗口:
char cClassName[256];
hMDIWnd = g_pDevStudioWnd->GetTopWindow()->m_hWnd;
::GetClassName(hMDIWnd, (LPTSTR)cClassName, sizeof(cClassName));
while (strcmp(cClassName, "MDIClient") != 0)
{
hMDIWnd = ::GetNextWindow(hMDIWnd, GW_HWNDNEXT);
ASSERT(hMDIWnd);
GetClassName(hMDIWnd, (LPTSTR)cClassName, sizeof(cClassName));
}
子类化这些关键窗口,使得TabBars插件自己创建的窗口可以hook适当的消息,通过响应这些消息,TabBars插件可以调整标签栏的位置,更新标签栏并通知其他窗口MDI客户区的改变,从而使TabBars窗口能够融入到Visual Studio的集成开发环境(IDE)中。
分享到:
相关推荐
微信小程序——自定义tabbar(截图+源码).zip 微信小程序——自定义tabbar(截图+源码).zip 微信小程序——自定义tabbar(截图+源码).zip 微信小程序——自定义tabbar(截图+源码).zip 微信小程序——自定义...
IOS应用源码——TabBar+Table+UISearchDisplayController.rar
2001年的时候我在网上见到了一款名为“WndTab”的VC插件,它提供了一个集成在编辑窗口的table标签栏,每个打开的文档对应一个标签栏的按钮,通过鼠标点击按钮可以在文件之间快速切换,大大方便了代码查看和编辑,除...
这是一个自定义的Android导航栏,使用方便,可以通过调用里面的方法去设置自己的风格 。 Android TabBar 导航栏
自定义tabBar,移除系统的tabBar
一句代码调用,自定义tabbar
几代码实现导航栏透明渐变、实现TabBar中间凸起;可自定义
IOS应用源码——TabBarCustom (所有TabBar——间切换).zip
IOS应用源码——TabBarCustom (所有TabBar——间切换).rar
小程序源码 自定义tabbar (代码+截图)小程序源码 自定义tabbar (代码+截图)小程序源码 自定义tabbar (代码+截图)小程序源码 自定义tabbar (代码+截图)小程序源码 自定义tabbar (代码+截图)小程序源码 自定义tabbar ...
源代码:网站制作自定义tabbar
Flutter TabBar SliverAppBar PageView NestedScrollView
iphone开发技巧UI篇之自定义TabBar iphone开发技巧UI篇之自定义TabBar iphone开发技巧UI篇之自定义TabBar
iOS开发,常用页面架构之tabbar与navigation控制器关系图
微信小程序源码(含截图)自定义tabbar微信小程序源码(含截图)自定义tabbar微信小程序源码(含截图)自定义tabbar微信小程序源码(含截图)自定义tabbar微信小程序源码(含截图)自定义tabbar微信小程序源码(含...
纯代码实现的TabBar,可以根据需要修改TabBar的大小,图片,背影色,任意添加TabBarItem的个数
ios mvp架构封装导航栏与tabbar封装。。。。。。。。。。。。。。。。。。。。
iOS普通导航栏颜色,字体大小,字体颜色,图片导航栏,导航栏渐变。tabbar和自定义Tabbar
IOS应用源码——一个复杂的tabbar视图.zip