如何将Mindjet的宏放到自定义功能区
如何將Mindjet的宏放到自定義功能區
雖然很早就接觸了思維軟件Mindjet Manager,但最近才用得比較頻繁。現在軟件已發布到Mindjet15版,官方原版終于支持中文了,但我還是比較習慣11版,原因很簡單,15版還沒有破解。大家可以很輕松地在網上下載到Mindjet 11破解版,也可以直接在我的百度網盤下載。
網盤鏈接: http://pan.baidu.com/s/18XRv4 密碼: b9nj
我先總結一下使用感受:
- 比較容易上手
- 內置甘特圖,與任務板配合使用,非常適合作計劃
- 支持表格、數據庫,圖片、備注、附件自然也支持
- 可以自定義宏,可惜不能錄制宏
- 文件格式從11版到15版沒有變化,即用15版制作的用11版也能打開
一、Mindjet Macro使用經歷
平時用Excel VBA的時間比較多,發現Mindjet也支持宏后,我就把Excel VBA的那一套照搬過去,發現它們使用完全一樣的語言,只是對象不一樣。比如,Excel里用得最多的是Range對象,Mindjet里則是Topic對象。不過,Excel VBA要流行得多,至少可以在網上找到很多的教程,而且其自帶的幫助文檔也很詳細,有說明有實例。相比之下,Mindjet Macro就麻煩多了,想找點中文教程真是難,只好硬著頭皮去Google。好在找到一些例子,不然,我可能現在連Topic對象都還不會用。CSDN里必定有牛人會Mindjet宏,但我找了半天也沒有找到教程。也許是用的人少,討論少了點,所以我在此拋磚引玉,希望大家來交流交流經驗。
摸索出一些簡單對象的用法后,我先編寫了幾個宏,增強一下mindjet任務模塊的功能,比如批量添加進度、查找當天的任務等。后來發現在組織宏時,可以把宏添加到一些下拉菜單、右鍵彈出菜單,確實方便了不少。但還是不能和excel的相比,人家可以把任意sub放在自定義功能區的任何位置。于是我琢磨著,能不能讓mindjet也做到這樣?折騰了兩天,總算弄出來了。先上一個效果圖:
二、使用的軟件及文件
Mindjet Manager用的是11.1.353專業版,此版為英文版,須使用漢化補丁。
你如果用過11版,一定注意到了新建界面有些不一樣。沒錯,這里面是15版的導圖模板。文章開頭的時候我說過,11版和15版的文件格式是一樣的,他們的模板可以通用。只需把15版的模板復制到11版就行了,大概是在這個位置:
C:\Users\Administrator\AppData\Local\Mindjet\MindManager\11\Library\ENU\Templates
另外還需要VS2010,其他版本應該也可以,但我沒試過。
1.處理思路
首先說說思想來源。我在www.Activeityowner.com上找到一篇文章,作者提供了一個Addin,可以把某文件夾下的宏全部添加到一個主選項卡。效果如圖:
這個mymapmacros插件有3個版本,最新的是2012版,即10版。安裝后發現,我的11版不能用。順便說一下,我之前說的例子,有些就是從這里來的,有興趣的可以去看看——MindManager Macro Library,另外還有這里——
于是,我繼續找,從Yahoo Group里找到這個How to Create a MindManager 7 Add-in Using Visual Basic .NET (VB)
看了一下,好像看懂了(我之前從沒寫過插件,所以知道的不多)。于是,我決定自己寫一個Addin。
在寫的過程中,查看了一下注冊表,發現mymapmacros把注冊信息寫到了Mindjet/10/Addins/下面,果斷把它導出來,把10改成11再導回去。居然可以用了!其他版本應該也可以這樣弄。
我本想就此停住,但我關閉軟件時,突然彈了個網頁出來,是作者的網站。于是我又繼續研究寫插件。
2.用VS2010寫一個HelloWorld
這似乎是程序員慣例吧,先用HelloWorld試下水。
其實,基本就照網上說的就行了。可能有的人不習慣看英文,所以我大致翻譯一下。
(1).下載注冊表文件,給vs2010添加Mindjet 插件向導
原文件里,只有mindjet7、8、9,需要增加mindjet11及其他版本的注冊信息。這是原版,點擊下載。修改后的,下載。
主要修改2個地方:一個是”RegistryRoot”,可以在注冊表搜索mindjet(項,全字匹配),找到Addins項,看看是不是和Mindjet選項里一樣的。因為我裝的64位系統,用的32位Mindjet,所以它在Software\Wow6432Node\
另一個地方是Microsoft\Shared Tools\AddinWizard的位置,還是用查找的方法,看你的vs2010的插件向導在哪里。
修改完后,導入注冊表即可。
(2).新建工程
我用的也是英文版VS2010,就直接用原圖說明了。
文件->新建工程->其他工程->擴展->共享插件(應該是這樣吧),在取名時最好一次取好,以后改麻煩。這里仍用Mm7HelloWorld_VB。
選擇VB語言。
如果在這里看到了Mindjet的選項,講明第1步成功了。若沒看到,就再改注冊表。
填插件名字、說明。
勾選隨程序啟動和所有用戶都可用。
新建完成。
(3).添加/刪除引用
在solution面板,右鍵工程,Add Reference添加引用。
在com選項里選擇Mindmanager 11 Type Library,其他版本類推。
再到工程屬性里,把名字改成插件名,不然生成的dll名字會是默認值。然后到Reference里把office的引用刪了。
(4).添加代碼
網站上說明很詳細,把高亮的代碼添加進去即可。但有個更簡單的方法,把你工程中的GuidAttribute那串數字,替換掉下面代碼中的GuidAttribute。如果插件名不一樣的話,也可以直接替換。然后把代碼全部復制進工程即可。
(5).編譯測試
然后Build 插件,以及插件的setup工程。網站上說Build之后就能在注冊表mindjet下看到有Mm7HelloWorld_VB,而且能在mindjet里出現helloworld按鈕。但我的好像沒有出現,我把setup編譯好后,安裝了一遍,才有的。Hello World插件就是在插件啟動、更新、斷開時用對話框進行提示。
然后,在VS2010里改代碼,關掉mindjet再build,重開mindjet就能看到變化。如果你已到了這一步,相信如果你會一些mindjet macro的話,就能進行自己的插件開發了。主要就是用ribbon對象、command對象。
3.MacroToRibbon插件
以下是將宏放到自定義功能區的MacroToRibbon插件代碼
Imports Extensibility Imports System.Runtime.InteropServices Imports Mindjet.MindManager.Interop#Region " Read me for Add-in installation and setup information. " ' When run, the Add-in wizard prepared the registry for the Add-in. ' At a later time, if the Add-in becomes unavailable for reasons such as: ' 1) You moved this project to a computer other than which is was originally created on. ' 2) You chose 'Yes' when presented with a message asking if you wish to remove the Add-in. ' 3) Registry corruption. ' you will need to re-register the Add-in by building the MacroToRibbonSetup project, ' right click the project in the Solution Explorer, then choose install. #End Region<GuidAttribute("C7BCF9F4-2ACB-4F6E-AF7E-7D748B811C1C"), ProgIdAttribute("MacroToRibbon.Connect")> _ Public Class ConnectImplements Extensibility.IDTExtensibility2Public Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Integer, ByVal lpFileName As String) As IntegerPublic Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal lpString As String, ByVal lpFileName As String) As LongDim applicationObject As Mindjet.MindManager.Interop.ApplicationPrivate addInInstance As ObjectDim WithEvents mmCommand As Mindjet.MindManager.Interop.CommandDim mycmd() As Mindjet.MindManager.Interop.CommandDim ribtb() As ribbonTabDim ribgp As RibbonGroupDim ctl As ControlDim ctn() As CmdBtnPrivate m_filename As String = "F:\backup\loadmacro.ini"Public Function GetiniValue(ByVal lpKeyName As String, ByVal strName As String) As StringDim strTmp As StringstrTmp = New String(" ", 256)Call GetPrivateProfileString(lpKeyName, strName, "", strTmp, Len(strTmp), m_filename)GetiniValue = Left$(strTmp, InStr(strTmp, vbNullChar) - 1)End FunctionPublic Sub OnBeginShutdown(ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnBeginShutdownEnd SubPublic Sub OnAddInsUpdate(ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnAddInsUpdateMsgBox("OnAddInsUpdate")End SubPublic Sub OnStartupComplete(ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnStartupCompleteEnd SubPublic Sub OnDisconnection(ByVal RemoveMode As Extensibility.ext_DisconnectMode, ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnDisconnection' MsgBox("OnDisconnection")' Release all objects'' Use ReleaseComObject() for event-handled objects' or else the application will not shut downDim i As IntegerFor i = 1 To UBound(mycmd)System.Runtime.InteropServices.Marshal.ReleaseComObject(mycmd(i))NextFor i = 1 To UBound(ribtb)ribtb(i).Delete()NextapplicationObject = NothingaddInInstance = Nothing' Make sure "garbage collection" is done, otherwise cached' objects might cause the application not to shut down.System.GC.Collect()End SubPublic Sub OnConnection(ByVal application As Object, ByVal connectMode As Extensibility.ext_ConnectMode, ByVal addInInst As Object, ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnConnectionapplicationObject = CType(application, Mindjet.MindManager.Interop.Application)addInInstance = addInInstReadSet()End SubPrivate Sub mmCommand_UpdateState(ByRef enabled As Boolean, ByRef checked As Boolean) _Handles mmCommand.UpdateState' Only enable command if a document is open enabled = applicationObject.Documents.Count > 0checked = FalseEnd SubPrivate Sub mmCommand_Click() Handles mmCommand.Click' Process the MindManager command and say hello' applicationObject.RunMacro("F:\backup\其他\全部添加完成度.mmbas")End SubPrivate Sub ReadSet()'下面是讀取INI文件中的數據()Dim ret As IntegerDim n As IntegerDim i As IntegerDim j As IntegerDim filename As StringDim section As StringDim name As StringDim image As StringDim bigimage As StringDim mtab() As StringDim ntab As IntegerDim group As StringDim mgroup As IntegerDim whenever As Booleanret = CInt(GetiniValue("set", "tabcount"))ReDim ribtb(ret), mtab(ret)For j = 1 To UBound(ribtb)mtab(j) = GetiniValue("tab" & j, "tabname")ribtb(j) = applicationObject.Ribbon.Tabs.Add(6, mtab(j), "DIYBYNIGHTMOON" & j)ret = CInt(GetiniValue("tab" & j, "groupcount"))For i = 1 To retgroup = GetiniValue("tab" & j, CStr(i))ribgp = ribtb(j).Groups.Add(0, group, "DIYTAB" & j & "GROUP" & i, "")NextNextn = CInt(GetiniValue("set", "count"))ReDim ctn(n), mycmd(n)section = "macro"For i = 1 To nsection = "macro" & iname = GetiniValue(section, "name")filename = GetiniValue(section, "filename")image = GetiniValue(section, "image")bigimage = GetiniValue(section, "bigimage")ntab = CInt(GetiniValue(section, "tab"))mgroup = CInt(GetiniValue(section, "group"))whenever = CBool(GetiniValue(section, "whenever"))mmCommand = applicationObject.Commands.Add("MacroToRibbon.Connect", "DIY_" & section)mmCommand.Caption = nameIf image <> "" Then mmCommand.ImagePath = imageIf bigimage <> "" Then mmCommand.LargeImagePath = bigimage'If ribgp.GroupControls.Count > mindex Then mindex = 0If GetiniValue(section, "onribbon") = "1" Thenctl = ribtb(ntab).Groups.Item(mgroup).GroupControls.AddButton(mmCommand)End Ifmycmd(i) = mmCommandctn(i) = New CmdBtnctn(i).Init(applicationObject, mmCommand, filename, whenever)NextEnd Sub End ClassPublic Class CmdBtnDim WithEvents mcmd As Mindjet.MindManager.Interop.CommandDim appObject As Mindjet.MindManager.Interop.ApplicationDim ss As StringDim documentcount As IntegerPublic Sub Init(ByRef app As Mindjet.MindManager.Interop.Application, ByVal mmcommand As Mindjet.MindManager.Interop.Command, ByVal filename As String, Optional ByVal whenever As Boolean = True)appObject = appmcmd = mmcommandss = filenameIf whenever = True Thendocumentcount = -1Elsedocumentcount = 0End IfEnd SubPrivate Sub mcmd_Click() Handles mcmd.Click'MsgBox("I am here")'MsgBox(ss)appObject.RunMacro(ss)End SubPrivate Sub mcmd_UpdateState(ByRef enabled As Boolean, ByRef checked As Boolean) Handles mcmd.UpdateStateenabled = appObject.Documents.Count > documentcountchecked = FalseEnd SubProtected Overrides Sub finalize()mcmd = NothingEnd SubPublic Sub New()End Sub End Class對應的ini文件內容為:
[set] count=3 tabcount=2[tab1] tabname=自定義 groupcount=2 1=MyMacro 2=Trial[tab2] tabname=自定義2 groupcount=2 1=MyMacro 2=Trial[macro1] name="全部添加完成度" filename=F:\backup\其他\全部添加完成度.mmbas image=F:\backup\其他\b.ico bigimage=F:\backup\其他\b.ico onribbon=1 tab=1 group=1 whenever=1[macro2] name="刷新完成情況" filename=F:\backup\其他\刷新完成情況.mmbas image=F:\backup\其他\b.ico bigimage= onribbon=1 tab=1 group=2 whenever=0插件啟動時,會按照ini文件里的配置將宏加載成插件命令,放到功能區。
ini文件的路徑為:F:\backup\loadmacro.ini
可以自己改,但注意路徑不要有中文,這然會出問題。
set下的count表示宏的數量,tabcount表示主選項卡的數量,對應tab1、tab2……
tab1下的name表示選項卡的名稱,groupcount表示分組數,1、2等對應組名。
macro1下的name表示按鈕名稱,filename表示宏文件位置,image為小圖標位置,bigimage為大圖標位置,onribbon為是否在功能區顯示,tab表示選項卡號,group表示組號,whenever表示是否沒打開map也有效。
支持mindjet 10、11、14、15,工程文件到這里下載。
時間倉促,有些難免有誤,請各位不吝指教!
拋磚引玉,望大家多多交流,將Mindjet VBA也開拓一下!
總結
以上是生活随笔為你收集整理的如何将Mindjet的宏放到自定义功能区的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JScript js数组去重
- 下一篇: lrzsz传输超过4G文件需要拆分(使用