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 string prevWord2 = "";
150 for (int j = 0; j < layout.Words.Count; j++)
152 MODI.Word word = (MODI.Word)layout.Words[j];
154 bool curLocSet = false;
156 for (int k = 0; k < word.Rects.Count; k++)
158 MODI.MiRect rc = (MODI.MiRect)word.Rects[k];
159 int h = rc.Bottom - rc.Top;
160 int w = rc.Right - rc.Left;
163 //tbText.AppendText(word.Text + " (" + rc.Left + "," + rc.Top+ ")\r\n");
164 if (CursorPoint.Y >= rc.Top && CursorPoint.Y <= rc.Bottom+UnderGap){
168 if (CursorPoint.X < rc.Left // cursorを飛び越えた
169 || (CursorPoint.X >= rc.Left && CursorPoint.X <= rc.Right) // cursorが矩形内
173 if (prevWord.Length != 0) {
174 if (NumPrevWords >= 2 && prevWord2.Length != 0){
175 tbText.AppendText(prevWord2 + " " + prevWord + " ");
176 CurLoc = prevWord2.Length + 1 + prevWord.Length + 1;
178 tbText.AppendText(prevWord + " ");
179 CurLoc = prevWord.Length + 1;
183 prevWord2 = prevWord;
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);
228 r = new Regex(@"-n(?<n>\d+)");
229 m = r.Match(filename);
232 NumPrevWords = int.Parse(m.Groups["n"].Value);
237 private void watcher_Changed(System.Object source,
238 System.IO.FileSystemEventArgs e)
240 switch (e.ChangeType)
242 case System.IO.WatcherChangeTypes.Changed:
243 string ext = System.IO.Path.GetExtension(e.FullPath);
244 if (ext==".gif" || ext==".jpg" || ext==".png" || ext==".tif" || ext==".bmp" || ext==".dib")
249 // case System.IO.WatcherChangeTypes.Created:
251 // case System.IO.WatcherChangeTypes.Deleted:
256 private void PostOCR(string filename)
258 FileNameQue.Enqueue(filename);
259 PostMessage(this.Handle, WM_EXEC_OCR, IntPtr.Zero, IntPtr.Zero);
262 private void ExecOCR(string filename)
264 if (DoOCR(filename)) {
265 string textname = filename + ".txt";
266 for (int i = 0; i < 10; i++) {
268 StreamWriter writer = new StreamWriter(textname, false, System.Text.Encoding.GetEncoding("utf-16"));
269 writer.WriteLine(CurLoc.ToString());
270 writer.Write(tbText.Text);
273 tbInfo.AppendText("Write Error:" + textname + "\r\n");
274 System.Threading.Thread.Sleep(30);
280 if (!miDebugMode.Checked) {
282 System.IO.File.Delete(filename);
286 // 連続して.bmpファイルが作られているため
287 tbInfo.AppendText("Delete Error:" + filename + "\r\n");
292 private void miExit_Click(object sender, EventArgs e)
308 unsafe static Point int2point(IntPtr param)
310 POINT pt = (POINT)Marshal.PtrToStructure((IntPtr)param, typeof(POINT));
311 Point p = new Point();
316 int NumPrevWords = 1;
317 // interface for external app
318 protected override void WndProc(ref Message m)
320 if (m.Msg == WM_AMODI)
322 switch ((AMODI_CMD)m.WParam)
324 case AMODI_CMD.QUERY:
325 m.Result = (IntPtr)m.LParam;
327 case AMODI_CMD.PAGE_CAPTURE:
328 m.Result = (IntPtr)(miCapturePage.Checked ? 1 : 0);
334 if (m.Msg == WM_EXEC_OCR) {
335 string filename = "";
336 while (FileNameQue.Count()!=0) {
337 filename = FileNameQue.Dequeue();
339 if (filename != "") {
343 if (m.Msg == WM_COPYDATA)
345 COPYDATASTRUCT cds = new COPYDATASTRUCT();
346 cds = (COPYDATASTRUCT)Marshal.PtrToStructure(m.LParam, typeof(COPYDATASTRUCT));
347 if (cds.dwData == (IntPtr)WMCD_EXISTCHECK)
349 m.Result = (IntPtr)1;
352 if (cds.dwData == (IntPtr)WMCD_SETPOINT){
353 CursorPoint = int2point(cds.lpData);
354 Console.WriteLine("Cursor:" + CursorPoint.X + "," + CursorPoint.Y);
357 if (cds.dwData == (IntPtr)WMCD_RESTORE_WINDOW)
364 byte[] data = new byte[cds.cbData];
365 Marshal.Copy(cds.lpData, data, 0, cds.cbData);
366 //あとは data に COPYDATA の内容が入ってるので適宜処理
368 m.Result = (IntPtr)1;
374 private void miCapturePage_Click(object sender, EventArgs e)
376 miCapturePage.Checked = !miCapturePage.Checked;
379 private void AutoMODIMainForm_Activated(object sender, EventArgs e)
384 private void miDebugMode_Click(object sender, EventArgs e)
386 miDebugMode.Checked = !miDebugMode.Checked;
389 private void miUseDefLang_Click(object sender, EventArgs e)
391 miUseDefLang.Checked = !miUseDefLang.Checked;
395 void DBW( string msg )
398 hWin = FindWindow( "TDbgMsgForm", "Debug Messenger" );
399 if ( hWin==0 ) return;
401 byte[] bytearray = System.Text.Encoding.Default.GetBytes(msg);
402 int len = bytearray.Length;
403 COPYDATASTRUCT_send cds;
404 cds.dwData = 1; // Indicate String
405 cds.cbData = len + 1;
407 SendMessage( (IntPtr)hWin, WM_COPYDATA, IntPtr.Zero, ref cds );