何とか高速に動かないものか?と考えていたら思い出しました。
以前、"Unofficial CATIA User Forum"の常連さんの所で記載し、一人で
ゴチャゴチャ書いた方法です。 もう十分時効なので記載します。
個人的な実感として、同じソースコードのマクロであれば、
ツールバーの登録し、呼び出した形が一番速度が速いです。
○独自のツールバー作成
「ツール」-「カスタマイズ」-「ツールバー」タブ-「新規作成」
○コマンドの登録
「ツール」-「カスタマイズ」-「コマンド」タブ-「マクロ」カテゴリ
これが出来ない場合もあるかと思います。例えば、ExcelのVBAを実行し
CATIAに対し、点や線を作成するような場合です。
偶然発見し根拠も良くわからないのですが、
実行時にシステムメニューを表示させた状態にすると、
マクロが高速で実行されます。
"システムメニューを表示させる"と言うのは、CATIAのWindowのタイトル
部分で右クリックしメニューを表示させた状態です。たったこれだけです。
手動で確認するのも良いですが、折角なのでマクロで再現させます。
VBAでは、こちらのコードを元に
レイヤーの扱いを考える5 - C#ATIA
SubCreateDatumPointメソッドは、そのままで上部の部分のみを
修正します。
'vba Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" _ (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" _ (ByVal Hwnd As Long, ByVal msg As Long, _ ByVal wParam As Long, ByVal lParam As Long) As Long 'Windows APIの構造体の定義 Private Type POINT X As Long Y As Long End Type 'マウスポインタ関係のAPI Private Declare Function GetCursorPos Lib "user32" _ (lpPoint As POINT) As Long Private Declare Function SetCursorPos Lib "user32" _ (ByVal X As Long, ByVal Y As Long) As Long 'マウスボタン関係のAPI Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Long, _ ByVal dx As Long, ByVal dy As Long, _ ByVal cButtons As Long, ByVal dwExtraInfo As Long) Private Const MOUSEEVENTF_LEFTUP As Integer = &H4 '左ボタンUP Private Const MOUSEEVENTF_LEFTDOWN As Integer = &H2 '左ボタンDown Private Const MOUSEEVENTF_RIGHTUP As Integer = &H10 '右ボタンUP Private Const MOUSEEVENTF_RIGHTDOWN As Integer = &H8 '右ボタンDown Public Sub MouseRIGHT(ByVal posLeft As Long, ByVal posTop As Long) '右クリック Call SetCursorPos(posLeft, posTop) Call mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0) Call mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0) End Sub Public Sub MouseLEFT(ByVal posLeft As Long, ByVal posTop As Long) '左クリック Call SetCursorPos(posLeft, posTop) Call mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0) Call mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) End Sub Sub CATMain() Dim T As Long Dim Left As Long, Top As Long Dim StartPos As POINT Left = CATIA.Left + 10 Top = CATIA.Top + 10 Call GetCursorPos(StartPos) T = timeGetTime Call MouseRIGHT(Left, Top) Call LayerStart Call MouseLEFT(StartPos.X, StartPos.Y) CATIA.RefreshDisplay = True MsgBox CDbl(timeGetTime - T) / 1000 & "秒" End Sub
右クリックを再現するには、C#でもAPIを使用するしかなさそうです。
C#では、こちらのコードを元に
レイヤーの扱いを考える6 - C#ATIA
"LayerTest_CSクラス"と"CatiaContainerクラス"と"CatExtensionクラス"は
そのままで、他の部分を以下の様に修正します。
//cs namespace catLeyTest { using System.Linq; using System.Diagnostics; using System.Windows.Forms; using System.Runtime.InteropServices;//COMオフ゛シ゛ェクトを操作するために必要 using INFITF;//Catiaのライブラリ using MECMOD;//Catiaのライブラリ using HybridShapeTypeLib;//Catiaのライブラリ using System; using System.Drawing; using System.Threading; static class Program { static void Main() { var catia = (INFITF.Application)Marshal .GetActiveObject("CATIA.Application"); var test = new LayerTest_CS(catia); SystemMenu.State = CatExtension.State; Thread.Sleep(100); SystemMenu.SystemMenuShow(); Stopwatch sw = new Stopwatch(); sw.Start(); test.StartTest(); sw.Stop(); SystemMenu.SystemMenuHide(); MessageBox.Show(string.Format("{0}秒", sw.Elapsed)); } } static class SystemMenu { [DllImport("user32.dll")] static extern void mouse_event( uint dwFlags,uint dx, uint dy, uint dwData,int dwExtraInfo); const uint MOUSEEVENTF_LEFTDOWN = 0x0002; const uint MOUSEEVENTF_LEFTUP = 0x0004; const uint MOUSEEVENTF_RIGHTDOWN = 0x0008; const uint MOUSEEVENTF_RIGHTUP = 0x0010; public static CatiaContainer State { get; set; } private static System.Drawing.Point StartPos { get; set; } public static void SystemMenuShow() { StartPos = Cursor.Position; Cursor.Position = new System.Drawing.Point( (int)State.Catia.Left + 10, (int)State.Catia.Top + 10); MouseRIGHT(); Cursor.Position = StartPos; } public static void SystemMenuHide() { Cursor.Position = StartPos; MouseLEFT(); } //右クリック private static void MouseRIGHT() { mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0); Thread.Sleep(100); mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0); } //左クリック private static void MouseLEFT() { mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0); Thread.Sleep(100); mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); } } }
システムメニューを直接表示する方法も試しましたが、効果ありませんでした。
あくまで右クリックで表示です。
又、実行中はシステムメニューが、表示されたままにしなければなりません。
他のソフトを使用してシステムメニューが消えてしまうとダメです。
なので基本、放置です。
「レイヤーの扱いを考える6」で使用したものと同一データでの
程のものでの比較です。
4MB弱 | C#ノーマル | C#システムメニュー表示 |
---|---|---|
1回目 | 10.24秒 | 7.94秒 |
2回目 | 10.21秒 | 6.49秒 |
3回目 | 10.23秒 | 6.37秒 |
22MB | C#ノーマル | C#システムメニュー表示 |
---|---|---|
1回目 | 187.24秒 | 82.43秒 |
2回目 | 185.91秒 | 82.32秒 |
どうでしょう、たったこれだけで処理時間が半分以下になる場合も
有ります。(もちろん手動でも)
全てのマクロで効果が出るものと思いますが、恐らく、画面上での描写が
多いものほど効果があるのではないかと思います。
但し、最初のツールバーへの登録ほど高速にはなりませんし、ツールバーへ登録
するマクロではやらない方がよいです。(最後に変な動きをするかもです)
・アウトプロセスなマクロ
・開発中にテストする際のエディタからの実行
ぐらいしか活用できませんが、手動でも機能します。(が、あくまで放置です)