2 using System.Collections.Generic;
3 using System.ComponentModel;
8 using System.Text.RegularExpressions;
9 using System.Windows.Forms;
11 using System.Runtime.InteropServices;
15 public partial class AutoMODIMainForm : Form
18 const int MARGIN_UNDER_CLICK = 2; // 次の行までの空白
20 const int WM_COPYDATA = 0x4A;
21 const int WM_APP = 0x8000;
22 const int WM_AMODI = (WM_APP + 0x400);
23 const int WM_EXEC_OCR = (WM_APP + 0x410);
25 // WM_COPYDATA command
26 const int WMCD_EXISTCHECK = 0x4000;
27 const int WMCD_SETPOINT = 0x4001;
28 const int WMCD_RESTORE_WINDOW = 0x4002;
31 //[StructLayout(LayoutKind.Sequential)]
32 private struct COPYDATASTRUCT
39 public struct COPYDATASTRUCT_send {
40 public Int32 dwData; //送信する32ビット値
41 public Int32 cbData; //lpDataのバイト数
42 public string lpData; //送信するデータへのポインタ(0も可能)
45 [DllImport("user32.dll", SetLastError = true)]
46 private static extern int PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
47 [DllImport("user32.dll", SetLastError = true)]
48 private static extern int SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, ref COPYDATASTRUCT_send lparam);
49 [DllImport("User32.dll", EntryPoint = "FindWindow")]
50 public static extern Int32 FindWindow(String lpClassName, String lpWindowName);
53 System.IO.FileSystemWatcher fsw;
54 Queue<string> FileNameQue;
57 int CurLoc; // mouse cursor position in text.
59 public AutoMODIMainForm()
61 InitializeComponent();
62 md = new MODI.Document();
63 FileNameQue = new Queue<string>();
66 string exepath = System.IO.Path.GetTempPath();
71 System.IO.Directory.Delete(exepath);
73 System.IO.Directory.CreateDirectory(exepath);
75 string exepath = Application.StartupPath;
76 lbFileName.Text = "Watching... - " + exepath;
78 fsw = new System.IO.FileSystemWatcher();
80 fsw.IncludeSubdirectories = false;
81 fsw.SynchronizingObject = this;
82 fsw.Changed += new System.IO.FileSystemEventHandler(watcher_Changed);
83 fsw.EnableRaisingEvents = true;
87 fsw.EnableRaisingEvents = false;
92 private void btnDoOCR_Click(object sender, EventArgs e)
94 DoOCR(tbFileName.Text);
97 private bool DoingOCR = false;
98 bool DoOCR(string filename)
100 if (DoingOCR) return false;
103 bool capture_page = miCapturePage.Checked;
105 ParseFileName(filename);
107 lbStatus.Text = "Recognizing... " + filename;
110 for (int i = 0; i < 10; i++){
114 tbInfo.AppendText("MODI Create failure: " + filename + "\r\n");
115 DBW("MODI Create file failure: " + filename);
116 System.Threading.Thread.Sleep(30);
123 if (miUseDefLang.Checked){
124 md.OCR(MODI.MiLANGUAGES.miLANG_SYSDEFAULT, true, true);
126 md.OCR(MODI.MiLANGUAGES.miLANG_ENGLISH, true, true);
129 DBW("MODI OCR Error: " + filename);
132 lbStatus.Text = "OCR Error: " + filename;
136 DBW("DoOCR:Completed");
137 const int UnderGap = MARGIN_UNDER_CLICK; // 単語のある領域より少し下のpointでも検索対象と認識する空白部分(Y方向)
141 lbPoint.Text = "" + CursorPoint.X + "," + CursorPoint.Y;
142 tbInfo.AppendText("Page:" + md.Images.Count + " pt:" + CursorPoint.X + "," + CursorPoint.Y + "\r\n");
143 for (int i = 0; i < md.Images.Count; i++)
145 MODI.Image image = (MODI.Image)md.Images[i];
146 MODI.Layout layout = image.Layout;
147 bool outok = capture_page;
148 string prevWord = "";
149 for (int j = 0; j < layout.Words.Count; j++)
151 MODI.Word word = (MODI.Word)layout.Words[j];
153 bool curLocSet = false;
155 for (int k = 0; k < word.Rects.Count; k++)
157 MODI.MiRect rc = (MODI.MiRect)word.Rects[k];
158 int h = rc.Bottom - rc.Top;
159 int w = rc.Right - rc.Left;
162 //tbText.AppendText(word.Text + " (" + rc.Left + "," + rc.Top+ ")\r\n");
163 if (CursorPoint.Y >= rc.Top && CursorPoint.Y <= rc.Bottom+UnderGap){
167 if (CursorPoint.X < rc.Left) {
171 if (prevWord.Length != 0) {
172 tbText.AppendText(prevWord + " ");
173 CurLoc = prevWord.Length + 1;
176 if (CursorPoint.X >= rc.Left && CursorPoint.X <= rc.Right){
179 if (prevWord.Length != 0) {
180 tbText.AppendText(prevWord + " ");
181 CurLoc = prevWord.Length + 1;
184 prevWord = word.Text;
192 tbInfo.AppendText(word.Text + " (" + w + "x" + h + ":" + rc.Left + "," + rc.Top + ")\r\n");
195 if (last_x > rc.Left){
205 tbText.AppendText("\r\n");
207 CurLoc += 2; // CR+LF
210 tbText.AppendText(word.Text + " ");
215 lbStatus.Text = "Done. " + filename;
219 private void ParseFileName(string filename)
221 Regex r = new Regex(@"\((?<x>\d+),(?<y>\d+)\)");
222 Match m = r.Match(filename);
225 CursorPoint.X = int.Parse(m.Groups["x"].Value);
226 CursorPoint.Y = int.Parse(m.Groups["y"].Value);
231 private void watcher_Changed(System.Object source,
232 System.IO.FileSystemEventArgs e)
234 switch (e.ChangeType)
236 case System.IO.WatcherChangeTypes.Changed:
237 string ext = System.IO.Path.GetExtension(e.FullPath);
238 if (ext==".gif" || ext==".jpg" || ext==".png" || ext==".tif" || ext==".bmp" || ext==".dib")
243 // case System.IO.WatcherChangeTypes.Created:
245 // case System.IO.WatcherChangeTypes.Deleted:
250 private void PostOCR(string filename)
252 FileNameQue.Enqueue(filename);
253 PostMessage(this.Handle, WM_EXEC_OCR, IntPtr.Zero, IntPtr.Zero);
256 private void ExecOCR(string filename)
258 if (DoOCR(filename)) {
259 string textname = filename + ".txt";
260 for (int i = 0; i < 10; i++) {
262 StreamWriter writer = new StreamWriter(textname, false, System.Text.Encoding.GetEncoding("utf-16"));
263 writer.WriteLine(CurLoc.ToString());
264 writer.Write(tbText.Text);
267 tbInfo.AppendText("Write Error:" + textname + "\r\n");
268 System.Threading.Thread.Sleep(30);
274 if (!miDebugMode.Checked) {
276 System.IO.File.Delete(filename);
280 // 連続して.bmpファイルが作られているため
281 tbInfo.AppendText("Delete Error:" + filename + "\r\n");
286 private void miExit_Click(object sender, EventArgs e)
302 unsafe static Point int2point(IntPtr param)
304 POINT pt = (POINT)Marshal.PtrToStructure((IntPtr)param, typeof(POINT));
305 Point p = new Point();
310 // interface for external app
311 protected override void WndProc(ref Message m)
313 if (m.Msg == WM_AMODI)
315 switch ((AMODI_CMD)m.WParam)
317 case AMODI_CMD.QUERY:
318 m.Result = (IntPtr)m.LParam;
320 case AMODI_CMD.PAGE_CAPTURE:
321 m.Result = (IntPtr)(miCapturePage.Checked ? 1 : 0);
327 if (m.Msg == WM_EXEC_OCR) {
328 string filename = "";
329 while (FileNameQue.Count()!=0) {
330 filename = FileNameQue.Dequeue();
332 if (filename != "") {
336 if (m.Msg == WM_COPYDATA)
338 COPYDATASTRUCT cds = new COPYDATASTRUCT();
339 cds = (COPYDATASTRUCT)Marshal.PtrToStructure(m.LParam, typeof(COPYDATASTRUCT));
340 if (cds.dwData == (IntPtr)WMCD_EXISTCHECK)
342 m.Result = (IntPtr)1;
345 if (cds.dwData == (IntPtr)WMCD_SETPOINT){
346 CursorPoint = int2point(cds.lpData);
347 Console.WriteLine("Cursor:" + CursorPoint.X + "," + CursorPoint.Y);
350 if (cds.dwData == (IntPtr)WMCD_RESTORE_WINDOW)
357 byte[] data = new byte[cds.cbData];
358 Marshal.Copy(cds.lpData, data, 0, cds.cbData);
359 //あとは data に COPYDATA の内容が入ってるので適宜処理
361 m.Result = (IntPtr)1;
367 private void miCapturePage_Click(object sender, EventArgs e)
369 miCapturePage.Checked = !miCapturePage.Checked;
372 private void AutoMODIMainForm_Activated(object sender, EventArgs e)
377 private void miDebugMode_Click(object sender, EventArgs e)
379 miDebugMode.Checked = !miDebugMode.Checked;
382 private void miUseDefLang_Click(object sender, EventArgs e)
384 miUseDefLang.Checked = !miUseDefLang.Checked;
388 void DBW( string msg )
391 hWin = FindWindow( "TDbgMsgForm", "Debug Messenger" );
392 if ( hWin==0 ) return;
394 byte[] bytearray = System.Text.Encoding.Default.GetBytes(msg);
395 int len = bytearray.Length;
396 COPYDATASTRUCT_send cds;
397 cds.dwData = 1; // Indicate String
398 cds.cbData = len + 1;
400 SendMessage( (IntPtr)hWin, WM_COPYDATA, IntPtr.Zero, ref cds );