IVsTextManager::GetActiveView(true, null, ...) returns 非焦点视图
IVsTextManager::GetActiveView(true, null, ...) returns non-focused view
我正在尝试创建一个 Visual Studio 文本编辑命令。我已经创建了一个包,绑定命令,将它放入菜单中。但是我不能以 Microsoft 推荐的方式做的是弄清楚是否有应该应用该命令的活动文本视图。
我正在按照 the VSSDK tutorial 中的步骤进行操作(向下滚动至 使用菜单命令添加评论装饰 )。从菜单中选择命令后,就可以调用 mt 命令处理程序。但是,当执行以下确切的教程代码时,我得到的结果是不一致的。
IVsTextManager txtMgr = (IVsTextManager)GetService(typeof(SVsTextManager));
IVsTextView vTextView = null;
int mustHaveFocus = 1;
txtMgr.GetActiveView(mustHaveFocus, null, out vTextView);
现在,如果只有文本视图,一切都会如您所愿:返回活动文本视图。但是在图片中抛出另一个视图(我使用的是位图编辑器),GetActiveView
返回的视图似乎是最后一个活动文本视图。即,如果我切换选项卡以将位图视图显示在先前活动的视图 fileA 上,则会返回 fileA 的相同视图。换句话说,我无法确定文本视图是否获得焦点。
现在,这似乎与 IVsTextManager::GetActiveView()
的 documentation 不一致(尽管很差)。它必须说明函数的第一个参数:if true,则返回当前 UI 活动视图。 Am I正确阅读?我观察到的行为似乎对应于另一种情况:if false,则返回最后一个活动视图,无论该视图当前是否 UI 活跃.
我可以想出另一种将命令绑定到视图的方法,即连接视图创建。让我担心的是,我显然无法以 Microsoft 推荐的方式处理命令。
好吧,对于令人困惑的文档,我深表歉意,但我不会为你的案例推荐这个演练(我是 VS 编辑器团队的开发人员)。
正如您所指出的,您可以通过 IVsTextViewCreationListener 连接命令过滤器来更简单地处理命令,这实际上是更常见和更好的方式,请参阅 Walkthrough: Using a Shortcut Key with an Editor Extension(这也是一个令人困惑的标题 :( )
VS 编辑团队的开发人员使用不同方法的答案可能适用于提出原始问题的人,但对于出于其他原因想要使用 GetActiveView 的我们来说,问题仍然存在:如何获得只有文本 windows 有焦点,而不是最后一个文本 window 有焦点?不可靠的文档(这表明 mustHaveFocus 是一个布尔值,即使它是一个 int)似乎具有误导性,因为将值设置为 0 或 1(或 -1)似乎导致最后一个文本 window 焦点是回来。
如果 pBuffer
是 null
,GetActiveView(fMustHaveFocus, pBuffer, out ppView)
显然会忽略 fMustHaveFocus
。如果它不是 null
,它会按照记录工作。
因此,您可以通过使用第一次返回的视图的缓冲区再次调用 GetActiveView
来获取 active-and-must-have-focus 视图。
IVsTextView vsTextView;
IVsTextLines vsTextLines;
// `GetActiveView` apparently ignores `fMustHaveFocus` if `pBuffer` is null, so call
// it a second time with the buffer from the view it returned the first time to find
// out if the view actually has focus.
if (textManager.GetActiveView(1, null, out vsTextView) == VSConstants.S_OK &&
vsTextView.GetBuffer(out vsTextLines) == VSConstants.S_OK &&
textManager.GetActiveView(1, vsTextLines, out vsTextView) == VSConstants.S_OK)
{
// vsTextView has focus.
}
我正在尝试创建一个 Visual Studio 文本编辑命令。我已经创建了一个包,绑定命令,将它放入菜单中。但是我不能以 Microsoft 推荐的方式做的是弄清楚是否有应该应用该命令的活动文本视图。
我正在按照 the VSSDK tutorial 中的步骤进行操作(向下滚动至 使用菜单命令添加评论装饰 )。从菜单中选择命令后,就可以调用 mt 命令处理程序。但是,当执行以下确切的教程代码时,我得到的结果是不一致的。
IVsTextManager txtMgr = (IVsTextManager)GetService(typeof(SVsTextManager));
IVsTextView vTextView = null;
int mustHaveFocus = 1;
txtMgr.GetActiveView(mustHaveFocus, null, out vTextView);
现在,如果只有文本视图,一切都会如您所愿:返回活动文本视图。但是在图片中抛出另一个视图(我使用的是位图编辑器),GetActiveView
返回的视图似乎是最后一个活动文本视图。即,如果我切换选项卡以将位图视图显示在先前活动的视图 fileA 上,则会返回 fileA 的相同视图。换句话说,我无法确定文本视图是否获得焦点。
现在,这似乎与 IVsTextManager::GetActiveView()
的 documentation 不一致(尽管很差)。它必须说明函数的第一个参数:if true,则返回当前 UI 活动视图。 Am I正确阅读?我观察到的行为似乎对应于另一种情况:if false,则返回最后一个活动视图,无论该视图当前是否 UI 活跃.
我可以想出另一种将命令绑定到视图的方法,即连接视图创建。让我担心的是,我显然无法以 Microsoft 推荐的方式处理命令。
好吧,对于令人困惑的文档,我深表歉意,但我不会为你的案例推荐这个演练(我是 VS 编辑器团队的开发人员)。
正如您所指出的,您可以通过 IVsTextViewCreationListener 连接命令过滤器来更简单地处理命令,这实际上是更常见和更好的方式,请参阅 Walkthrough: Using a Shortcut Key with an Editor Extension(这也是一个令人困惑的标题 :( )
VS 编辑团队的开发人员使用不同方法的答案可能适用于提出原始问题的人,但对于出于其他原因想要使用 GetActiveView 的我们来说,问题仍然存在:如何获得只有文本 windows 有焦点,而不是最后一个文本 window 有焦点?不可靠的文档(这表明 mustHaveFocus 是一个布尔值,即使它是一个 int)似乎具有误导性,因为将值设置为 0 或 1(或 -1)似乎导致最后一个文本 window 焦点是回来。
pBuffer
是 null
,GetActiveView(fMustHaveFocus, pBuffer, out ppView)
显然会忽略 fMustHaveFocus
。如果它不是 null
,它会按照记录工作。
因此,您可以通过使用第一次返回的视图的缓冲区再次调用 GetActiveView
来获取 active-and-must-have-focus 视图。
IVsTextView vsTextView;
IVsTextLines vsTextLines;
// `GetActiveView` apparently ignores `fMustHaveFocus` if `pBuffer` is null, so call
// it a second time with the buffer from the view it returned the first time to find
// out if the view actually has focus.
if (textManager.GetActiveView(1, null, out vsTextView) == VSConstants.S_OK &&
vsTextView.GetBuffer(out vsTextLines) == VSConstants.S_OK &&
textManager.GetActiveView(1, vsTextLines, out vsTextView) == VSConstants.S_OK)
{
// vsTextView has focus.
}