無事東北ずん子もしゃべるものを作成。
喋ってる間に次の命令来たらどう対処すんべ、、、、ずん子はUIのステータスチャックで拾えるけど、結月ゆかりはどうしようかな
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; using System.Windows.Forms; namespace net.azworks.VoiceroidAccess { class Zunko { private Process getVoiceroidProcess() { Process[] proceses = Process.GetProcessesByName("VOICEROID"); if (proceses.Length == 0) throw new ApplicationInirializeException( "VOCALOID.exe プロセスが存在していません。"); foreach (Process process in proceses) { string processName = process.ProcessName; string windowTitle = process.MainWindowTitle; if (process.MainWindowTitle.StartsWith("VOICEROID+ 東北ずん子")) return process; } return null; } private Process process = null; private IntPtr getVoiceroidWindwHandle() { try { return process.MainWindowHandle; } catch (Exception e) { playButton = IntPtr.Zero; textbox = IntPtr.Zero; process = getVoiceroidProcess(); if (process == null) throw new ApplicationInirializeException( "VOICEROID+ 東北ずん子 が起動してないっぽいです。"); return process.MainWindowHandle; } } private IntPtr FindButton(List<IntPtr> tgts, String caption) { foreach (var p in tgts) { string className = Win32.GetWindowClassName(p); string captionText = Win32.GetWindowCaption(p); bool left = className.StartsWith("WindowsForms10.BUTTON"); bool right = captionText.Contains(caption); if (left && right) return p; } return IntPtr.Zero; } private IntPtr playButton = IntPtr.Zero; private IntPtr GetPlayButton() { if (playButton == IntPtr.Zero) { var children = Win32.GetChildWindows(getVoiceroidWindwHandle()); playButton = FindButton(children, "再生"); } return playButton; } private IntPtr textbox = IntPtr.Zero; private IntPtr GetTextbox() { if (textbox == IntPtr.Zero) { IntPtr current = Win32.GetWindow(getVoiceroidWindwHandle(), Win32.GW_CHILD); current = Win32.GetWindow(current, Win32.GW_CHILD); current = Win32.GetWindow(current, Win32.GW_HWNDNEXT); current = Win32.GetWindow(current, Win32.GW_CHILD); current = Win32.GetWindow(current, Win32.GW_CHILD); current = Win32.GetWindow(current, Win32.GW_CHILD); current = Win32.GetWindow(current, Win32.GW_CHILD); textbox = Win32.GetWindow(current, Win32.GW_CHILD); } return textbox; } IntPtr VK_DELETE = new IntPtr(46); public void Talk(String message, int delay = 10) { IntPtr textEdit = GetTextbox(); // コピペ IntPtr currentTextLength = Win32.SendMessage(textEdit, Win32.WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero); Win32.SendMessage(textEdit, Win32.EM_SETSEL, IntPtr.Zero, new IntPtr(currentTextLength.ToInt32())); Win32.SendMessage(textEdit, Win32.WM_KEYDOWN, new IntPtr(46), IntPtr.Zero); Clipboard.SetText(message); Win32.SendMessage(textEdit, Win32.WM_PASTE, IntPtr.Zero, IntPtr.Zero); } public void Play() { IntPtr playButton = GetPlayButton(); Win32.SendMessage(playButton, 245, IntPtr.Zero, IntPtr.Zero); } } }
ずん子の方が楽でした RichEdit コンポーネントとか使ってるっぽいので、Windowsメッセージをフルに投げて操作できる。
とはいえ、これで幾つか新しい情報が手に入ったのも事実。どっかでフィードバック居るかなぁ(;´Д`)
あと弄ってみてNGワードがあるのは気づいたが、どうもその処理は単語認識ではなく、単純な文字列一致としてNGらしい。
文章を扱うプログラムでその作りはどうなんだ?と思わなくもないが、まぁ要するにVOICEROIDに食わせる前にそれを伏字にすればいいだけの話ではある。