我正在使用VBIDE API,并且不能假设主机应用程序是Excel或任何Office应用程序.
所以我所知道的是,我正在看着它VBComponent
,而且它Type
是vbext_ct_document
.
在VBE的即时窗格中,我可以获得此输出:
?TypeName(Application.VBE.ActiveVBProject.VBComponents("Sheet1"))
VBComponent
?TypeName(Sheet1)
Worksheet
Run Code Online (Sandbox Code Playgroud)
但是该Sheet1
对象仅存在于运行时环境中,所以如果我是C#加载项,我甚至都看不到它.
那得到任何接近我所需要的,唯一的一点是通过Parent
和Next
组件的属性:
?TypeName(Application.VBE.ActiveVBProject.VBComponents("Sheet1").Properties("Parent").Object)
Workbook
?TypeName(Application.VBE.ActiveVBProject.VBComponents("Sheet1").Properties("Next").Object)
Worksheet
Run Code Online (Sandbox Code Playgroud)
这让我得到了我追求的类型名称......但错误的组件!对于ThisWorkbook
,这是顶级文档对象,我得到的Application
对象为Parent
:
?TypeName(Application.VBE.ActiveVBProject.VBComponents("ThisWorkbook").Properties("Parent").Object)
Application
Run Code Online (Sandbox Code Playgroud)
这种方法可能很有用,但前提是硬编码特定于主机的逻辑,该逻辑知道哪个组件具有"应用程序"类型的"父"属性是Workbook
主机应用程序是Excel时的实例...并且不能保证其他主机中的其他文档模块甚至会有"父"属性,所以我非常难过.
几乎任何东西都是开放的- 从p/invoke调用和低级COM"反射"魔术(ITypeInfo
魔法)到...到......我不知道 - unsafe
带有时髦指针的代码需要// here be dragons
注释-任何导线,可以潜在地结束了一个可行的解决方案是值得欢迎的.
据我所知的VBE加载生活在同一个进程中的主机,这样的地方有一个指针ThisWorkbook
,并Sheet1
和任何其他文件类型的VBComponent
VBA项目.
?ObjPtr(ThisWorkbook)
161150920
Run Code Online (Sandbox Code Playgroud)
我想我只需要以某种方式抓住指针,我将成为我需要的地方.
在C/C++中,当我有一堆函数(指针)时,我可以将它们存储在数组或向量中,并按特定顺序将它们中的一些调用在一起.可以在VBA中做类似的事情吗?
谢谢!
我有一个问题,我的COM加载项拖了几个月,我无法弄清楚为什么.
该IDTExtensibility2
实施已经由Carlos Quintero(MZ-Tools背后的人)进行了同行评审,并且被认为是正确的.
根据他的建议,OnBeginShutdown
实现设置了一个签入的标志OnDisconnection
,以确保ShutdownAddIn
只运行一次(某些VBE主机应用程序不调用OnBeginShutdown
,这就是原因):
public void OnBeginShutdown(ref Array custom)
{
_isBeginShutdownExecuted = true;
ShutdownAddIn();
}
Run Code Online (Sandbox Code Playgroud)
我的插件使用Ninject进行DI/IoC,我的ShutdownAddIn
方法归结为调用Dispose
Ninject IKernel
实例,然后释放所有COM对象Marshal.ReleaseComObject
:
private void ShutdownAddIn()
{
if (_kernel != null)
{
_kernel.Dispose();
_kernel = null;
}
_ide.Release();
_isInitialized = false;
}
Run Code Online (Sandbox Code Playgroud)
我想不出更早的时间来运行这段代码.然而,当Dispose
我的命令栏和菜单包装奔跑,我发现了一个InvalidCastException
在StopEvents
当命令栏/菜单尝试拆卸他们的控制:
public void HandleEvents()
{
// register the unmanaged click events
((Microsoft.Office.Core.CommandBarButton)Target).Click += Target_Click;
}
public void StopEvents()
{
// unregister …
Run Code Online (Sandbox Code Playgroud) 如何在自己的页面上为每个子或函数编目,索引和/或打印VB6源代码..?如果可能的话,我想使用免费或包含Visual Studio插件这样做,但我并不反对自己写一些东西.我熟悉"Microsoft Office Visual Basic for Applications Extensibility",似乎VB6有一个类似的模块,这可能允许我通过代码模块集合简单地"For Each"并将打印机扔到打印机上时间.它可能需要10-15行代码.
我的首要任务是打印,最好是在自己的页面上使用每个子/功能,但是使用IDE的常规打印功能,所有代码在一个长打印输出中一起运行.接下来,我想在每个VBP中创建每个子,函数,变量和常量的名称的索引/ toc.我们有Visual Studio 6.0企业版,但似乎没有任何东西可以用来做这些事情.
你可能会笑,并问,"为什么VB6 .. ?? LOL !!".这是因为我的任务是升级和更改运行工厂的大型软件系统的VB6源代码.它位于一个与外部世界没有联系的孤立网络上,它已经运行了14年,但现在他们想要开始升级一些东西.该系统由许多VBP文件组成,每个文件都有许多模块和表单.
编辑:我确实尝试谷歌搜索的答案,但事实证明这是不可能的.我得到的只是关于用VB6编写的应用程序打印的编码样本,而不是从IDE打印源代码.
默认的Viso文档具有CodeName,ThisDocument
与其他Office文档不同,该ThisDocument
组件CodeName
似乎是只读的.
如果我有信任访问VBE,那么我可以用这样的行重命名组件:
ThisDocument.vbProject.vbComponents("ThisDocument").Name = "FooBar"
Run Code Online (Sandbox Code Playgroud)
从那时起,我可以将对象称为FooBar
而不是ThisDocument
但是,据推测,CodeName是只读的有一个原因.到目前为止,我找不到重命名对象的任何问题,但我不确定是否会有一些意想不到的后果.
重命名ThisDocument
组件是否安全/明智?
在VBA和VB6外接对象模型(VBIDE)暴露CommandBarEvents
有一个对象Click
的事件,而该事件的签名是:
Dim WithEvents CmdBarEvents As CommandBarEvents
Private Sub CmdBarEvents_Click(ByVal CommandBarControl As Object, handled As Boolean, CancelDefault As Boolean)
并且CommandBarControl
传递给a的引用以VBE.Events.CommandBarEvents
注册该事件处理程序CommaneBarControl
:
Set CmdBarEvents = Application.VBE.Events.CommandBarEvents(CmdBarItem)
该办公室的对象模型定义有自己单独的命令栏控件Click
的事件,例如,CommandBarControl
其中有一个对象Click
的事件,而签名是:
Dim WithEvents CmdBarBtn As CommandBarButton
Private Sub CmdBarBtn_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean)
并且CommandBarButton
对该WithEvents
对象分配了对a的引用:
Set CmdBarButton = myButton
为什么会有差异,我应该选择哪个?
我将事件附加到VBE的CommandBars上的控件(而不是主机应用程序中的CommandBars).
Office CommandBars无权访问CommandBarEvents
对象,因此我假设他们必须使用该CommandBarButton.Click
事件.但是VBE(在任何Office主机下)都可以访问CommandBarButton …
如何以编程方式在VB6 Addin中打印源代码..?我在对象浏览器中找不到VBIDE的打印或预览方法.
我在Google上搜索过高低,而且在VBIDE代码模块打印方面缺乏信息.我为PrettyPrint获得了很多热门,但就是这样.缺乏是如此之大,以至于我想知道是否存在一些我完全缺失的基本概念.
我害怕Herb在/sf/answers/2872394801/中提到的O'Reilly书的副本,它没有提到源代码的打印.我能看到的唯一方法是将代码导出到文本文件,并通过与VBIDE无关的常用方法打印它们.
我还在http://www.cpearson.com/excel/vbe.aspx上查看了Chip Pearson的VBE指南,它几乎与VBIDE相同,甚至没有打印代码的线索,除了我提到的想法.保存到文本文件然后打印.
**理想情况下,我想使用现有的VB6文件>打印对话框,并添加一个额外的复选框.我意识到在现有对话框中添加控件是另一个主题,我不反对创建我自己的打印对话框版本.