OSDN Git Service

amodiからの文字位置情報が二桁以上あると正しく取得できていなかった
[dokopop/dokopop.git] / DCHookTest / DCHookMain.cpp
1 //---------------------------------------------------------------------------
2 #include <vcl.h>
3 #pragma hdrstop
4 #include <tchar.h>
5 #include "DCHookMain.h"
6 #include <stdio.h>
7 #include <shellapi.h>
8 #include "StringLib.h"
9 #include "PopupConfig.h"
10 #include "Notify.h"
11 #include "DCHookLoader.h"
12 #include "prgprof.h"
13 #include "MODINotifyDlg.h"
14 #include "prgconfig.h"
15 #include "OCRTextFrm.h"
16 #include "MonitorScale.h"
17 //---------------------------------------------------------------------------
18 #pragma package(smart_init)
19
20 /*------------------------------------------*/
21 /*              Configuration                                           */
22 /*------------------------------------------*/
23 // Popup\82Ì\82½\82Ñ\82ÉDLL\82ðUnload/Load\82·\82é
24 // \94½\89\9e\82µ\82È\82­\82È\82Á\82½\82Æ\82«\82Ì\82½\82ß\82Ì\91Î\8fÇ\97Ã\96@
25 // Note: 2013.3.12
26 //      inc.srch ON\82Ì\82Æ\82«\81AMoveSent\82ª\8fí\82Éreset\82³\82ê\82Ä\82µ\82Ü\82¤\82½\82ß\81A
27 //      mouse\82ªstill\8fó\91Ô\82Å\82 \82Á\82Ä\82à\89½\93x\82àinc.srch\82Ì\83\8a\83N\83G\83X\83g\82ª\82â\82Á\82Ä\82­\82é\81B
28 //      \82Ù\82©\81Apopup/inc.srch\82ð\82â\82é\82½\82Ñ\82ÉDLL\93à\82Ì\95Ï\90\94\82ªreset\82³\82ê\82é\82½\82ß\82±\82ê\82Í\82æ\82ë\82µ\82­\82È\82¢\81B
29 #define DETACHRELEASE           0
30
31 #define MIGROUP_INDEX           1               // \8e«\8f\91\83O\83\8b\81[\83v\95Ï\8dX\83\81\83j\83\85\81[\82Ìindex
32
33 // PDIC\8bN\93®\8cã\82ÌOpenLink()\8e¸\94s\8e\9e\82Ìretry\82¨\82æ\82Ñwaittime
34 #define OPEN_RETRY                      5
35 #define OPEN_WAITTIME           500             // [mSec]
36
37 #define DPI_DETECT                      0               // DPI Detect in main (monitor\82²\82Æ\82Ì\90Ý\92è\82ª\82Å\82«\82È\82¢\82½\82ßdebug\97p)
38
39 #define DEF_USE64                       (fWow64)
40
41 /*------------------------------------------*/
42 /*              Definitions                                                     */
43 /*------------------------------------------*/
44 #define URL_MODI_INSTALL        "http://support.microsoft.com/kb/982760"
45
46 #define DEF_POPUPKEY            (KF_CONTROL)
47 #define DEF_TOGGLEKEY           (KF_CONTROL+KF_MENU)
48
49 #define WM_AMODI                        (WM_APP+0x400)  // app communication message with AMODI
50
51 #define FLG_MOVESEND            0x40000000      // mouse move send
52
53 #pragma resource "*.dfm"
54 TDCHookMainForm *DCHookMainForm;
55
56 #define COMPANYNAME     "Software\\DokoPopProject\\"
57
58 bool Reboot = false;
59
60 /*------------------------------------------*/
61 /*              Prototypes                                                      */
62 /*------------------------------------------*/
63 bool DdePoke( TDdeClientConv *dde, AnsiString Item, AnsiString Data );
64 #ifdef USE_UNICODE
65 // Unicode\82Å\93n\82·\8fê\8d\87
66 bool DdePoke( TDdeClientConv *dde, AnsiString Item, const wchar_t *Data );
67 #endif;
68 void GetGroupList(TMyIni &ini, TStringList &list);
69
70 //---------------------------------------------------------------------------
71 __fastcall TDCHookMainForm::TDCHookMainForm(TComponent* Owner)
72         : TForm(Owner)
73 {
74         hDll = NULL;
75         EnablePopup = true;
76
77 #if 0
78         WindowsNT = false;
79
80         OSVERSIONINFO VersionInfo;
81         VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
82         GetVersionEx(&VersionInfo);
83         switch (VersionInfo.dwPlatformId){
84                 case VER_PLATFORM_WIN32_NT:
85                         WindowsNT = true;
86                         break;
87         }
88 #endif
89         CheckWOW64();
90         BootUp = true;
91         Capturing = false;
92         PopupText = NULL;
93         DoPopupRetry = 0;
94         CaptureMode = CM_TEXT | CM_IMAGE;
95         AMODIAvail = false;
96         MouseIncSrch = false;
97 }
98 //---------------------------------------------------------------------------
99 void __fastcall TDCHookMainForm::FormCreate(TObject *Sender)
100 {
101         Ini = new TMyIni( HKEY_CURRENT_USER, COMPANYNAME APPREGNAME, true );
102 //      DBW("Handle=%08X",Handle);
103
104 #ifdef _DEBUG
105         Left = Ini->ReadInteger( PFS_MAIN, "Left", Left );
106         Top = Ini->ReadInteger( PFS_MAIN, "Top", Top );
107         Width = Ini->ReadInteger( PFS_MAIN, "Width", Width );
108         Height = Ini->ReadInteger( PFS_MAIN, "Height", Height );
109 #endif
110
111         GroupOpen = Ini->ReadInteger( PFS_CONFIG, PFS_GROUPOPEN, false );
112         GroupName = Ini->ReadString( PFS_CONFIG, PFS_GROUPNAME, "" );
113         CtrlClose = Ini->ReadInteger( PFS_CONFIG, PFS_CTRLCLOSE, false );
114         IgnoreJ   = Ini->ReadInteger( PFS_CONFIG, PFS_IGNOREJ, true );
115         Banner    = Ini->ReadInteger( PFS_CONFIG, PFS_BANNER, true );
116
117 #ifndef _DEBUG
118         BorderStyle = bsNone;
119
120         Memo->Visible = false;
121         Panel1->Visible = false;
122         Splitter1->Visible = false;
123         Menu->Items->Delete( 0 );
124         Image->Visible = true;
125 //      Title->Caption = Title->Caption + "   " + StrVersion;
126 //      Title->Align = alBottom;
127 #if 0
128         Title->Visible = true;
129 #endif
130
131         AnsiString bmp = ExtractFilePath( Application->ExeName );
132         bmp += NAME_BMPFILE;
133         if ( FileExists( bmp ) ){
134                 Image->Picture->Bitmap->LoadFromFile( bmp );
135         }
136
137         Width = Image->Picture->Width;
138         Height = Image->Picture->Height;
139
140         // To center
141         Left += ( ( ( GetSystemMetrics( SM_CXSCREEN ) - ( Width ) ) / 2 + 4 ) & ~7 ) - Left;
142         Top += ( ( GetSystemMetrics( SM_CYSCREEN ) - ( Height ) ) / 2 ) - Top;
143 #endif
144
145         SavedWidth = Width;
146
147 #ifdef _DEBUG
148         BootTimer->Interval = 100;
149         Width = SavedWidth;
150         WindowState = wsNormal;
151 #else
152         if ( !Banner ){
153                 BootTimer->Interval = 10;
154                 // \82È\82ñ\82ÆVisible = false;\82É\82·\82é\82Æ\81A
155                 // \83A\83C\83R\83\93\89»\82µ\82½\82Æ\82«\81E\81E\81E\83A\83C\83R\83\93\82ª\95\\8e¦\82³\82ê\82é
156                 // \83A\83C\83R\83\93\89»\82µ\82È\82¢\82Æ\82«\81E\81E\83A\83C\83R\83\93\82Í\8fo\82Ä\82±\82È\82¢
157                 // \95Ï\82È\8ed\97l\81H
158                 // \82Æ\82¢\82¤\82í\82¯\82Å\95\9d\82ð\83[\83\8d\82É\82µ\82ÄWindow\82ð\94ñ\95\\8e¦\89»\82Æ\82¤\82¢\8e×\93¹\82È\95û\96@
159                 // \8dÅ\8f\89\82©\82ç\82¸\82Á\82ÆVisible=false\82Æ\82¢\82¤\95û\96@\82à\82 \82é\82ª\81A
160                 // VCL\82ªMainWindow\82ð\95K\82¸visible\82É\82·\82é\8f\88\97\9d\82ð\8ds\82Á\82Ä\82¢\82é\82½\82ß\95s\89Â\94\
161                 // \82Ù\82©\82É\82¢\82¢\95û\96@\82ª\82 \82Á\82½\82æ\82¤\82È\8bC\82ª\82·\82é\82ª\81A\81A\81A\81
162                 Width = 0;
163         } else {
164                 Visible = true; // \8dÅ\8f¬\89»\82Å\8bN\93®\82·\82é\82Æ\81A\83A\83C\83R\83\93\95\\8e¦\82ª\8fÁ\82¦\82È\82¢\82½\82ß\81B
165                                                 // \82±\82Ì\95û\96@\82ª\93K\93\96\82Å\82 \82é\82©\82Ç\82¤\82©\90[\82­\8dl\82¦\82Ä\82¢\82È\82¢\81E\81E
166                                                 // (\82½\82Ü\82½\82Ü\82¤\82Ü\82­\93®\82¢\82½:-)
167                 Width = SavedWidth;
168                 WindowState = wsNormal;
169         }
170 #endif
171
172         //TODO: default=ON\82É\82·\82é\82Æ\95s\88À\92è\82É\82È\82é\82Ì\82Å\82µ\82Î\82ç\82­def=false
173         //MouseIncSrch = Ini->ReadInteger( PFS_CONFIG, PFS_INCSRCH, MouseIncSrch );
174         CaptureMode = Ini->ReadInteger( PFS_CONFIG, PFS_CAPTURE_MODE, CaptureMode );
175         InitAMODI();
176         btnOK->Left = (SavedWidth - btnOK->Width)>>1;
177         btnOK->Top = Height - btnOK->Height - 8;
178         lbVersion->Caption = StrVersion;
179         lbVersion->Left = btnOK->Left + btnOK->Width + 4;
180         lbVersion->Top = btnOK->Top;
181         
182         BootTimer->Enabled = true;
183
184         if (!AMODIAvail && (CaptureMode & CM_IMAGE)){
185                 tmMODINotify->Enabled = true;
186         }
187
188 //      Application->OnIdle = IdleHandler;
189 }
190 //---------------------------------------------------------------------------
191 void __fastcall TDCHookMainForm::FormCloseQuery(TObject *Sender,
192           bool &CanClose)
193 {
194         if (AMODIAvail){
195                 TerminateAMODI();
196         }
197         if (OCRTextForm){
198                 OCRTextForm->Visible = false;
199                 delete OCRTextForm;
200                 OCRTextForm = NULL;
201         }
202         RegisterTrayIcon( false );
203 #ifdef _DEBUG
204         WINDOWPLACEMENT wp;
205         wp.length = sizeof(WINDOWPLACEMENT);
206         GetWindowPlacement( Handle, &wp );
207         RECT &rc = wp.rcNormalPosition;
208         Ini->WriteInteger( PFS_MAIN, "Left", rc.left );
209         Ini->WriteInteger( PFS_MAIN, "Top", rc.top );
210         Ini->WriteInteger( PFS_MAIN, "Width", rc.right - rc.left );
211         Ini->WriteInteger( PFS_MAIN, "Height", rc.bottom - rc.top );
212 #endif
213
214         miUnhookClick( this );
215
216         delete Ini;
217         if (PopupText){
218                 delete[] PopupText;
219                 PopupText = NULL;
220         }
221 }
222 //---------------------------------------------------------------------------
223 void __fastcall TDCHookMainForm::FormKeyPress(TObject *Sender, char &Key)
224 {
225 #ifndef _DEBUG
226         if ( Key == 0x1b ){
227                 Key = 0;
228                 Start();
229         }
230 #endif
231 }
232 #if 0
233 void __fastcall TDCHookMainForm::IdleHandler(TObject *sender, bool &done)
234 {
235         if (NotifyAMODIEnabled){
236                 NotifyAMODIEnabled = false;
237                 NotifyAMODI();
238         }
239 }
240 #endif
241 //---------------------------------------------------------------------------
242 // Menu event
243 //---------------------------------------------------------------------------
244 void __fastcall TDCHookMainForm::miDicGroup(TObject *Sender)
245 {
246         // \8e«\8f\91\83O\83\8b\81[\83v
247         AnsiString name = ((TMenuItem*)Sender)->Caption;
248         if ( name.Length() ){
249                 OpenDicGroup( name.c_str() );
250         }
251 }
252 //---------------------------------------------------------------------------
253 void __fastcall TDCHookMainForm::miClickOnlyClick(TObject *Sender)
254 {
255         miClickOnly->Checked = !miClickOnly->Checked;
256         EnableClickOnly( miClickOnly->Checked );
257         MenuClosed();
258 }
259 //---------------------------------------------------------------------------
260 void __fastcall TDCHookMainForm::miIncSearchClick(TObject *Sender)
261 {
262         miIncSearch->Checked = !miIncSearch->Checked;
263         MouseIncSrch = miIncSearch->Checked;
264         Ini->WriteInteger( PFS_CONFIG, PFS_INCSRCH, MouseIncSrch );
265         SetupConfig2();
266         if (MouseIncSrch){
267                 HWND hwnd = FindPdic();
268                 if (hwnd){
269                         MoveToTop(hwnd);
270                 }
271         }
272 }
273 //---------------------------------------------------------------------------
274 #if 0   // change capture mode
275         if (!AMODIAvail && (CaptureMode & CM_IMAGE)){
276                 InitAMODI();
277         }
278         if (AMODIAvail){
279                 SetupConfig2();
280         } else {
281                 NotifyAMODI();
282         }
283
284         MenuClosed();
285 #endif
286 //---------------------------------------------------------------------------
287 void __fastcall TDCHookMainForm::miEnablePopupClick(TObject *Sender)
288 {
289         if ( miEnablePopup->Checked ){
290                 miUnhookClick( this );
291                 EnablePopup = false;
292         } else {
293                 miHookClick( this );
294                 EnablePopup = true;
295         }
296         MenuClosed();
297 }
298 //---------------------------------------------------------------------------
299 void __fastcall TDCHookMainForm::miOCRTextClick(TObject *Sender)
300 {
301         if (!OCRTextForm) OCRTextForm = new TOCRTextForm(this);
302         OCRTextForm->Visible = true;
303 }
304 //---------------------------------------------------------------------------
305 void __fastcall TDCHookMainForm::miOptionClick(TObject *Sender)
306 {
307         if (PopupConfigDlg){
308                 MoveToTop(PopupConfigDlg->Handle);
309                 return;
310         }
311
312         // Configuration //
313         PopupConfigDlg = new TPopupConfigDlg( this );
314         PopupConfigDlg->cbGroupOpen->Checked = GroupOpen;
315         PopupConfigDlg->edGroupName->Text = GroupName;
316         PopupConfigDlg->SetPopupKey( Ini->ReadInteger( PFS_CONFIG, PFS_POPUPKEY, DEF_POPUPKEY ) );
317         PopupConfigDlg->SetToggleKey( Ini->ReadInteger( PFS_CONFIG, PFS_TOGGLEKEY, DEF_TOGGLEKEY ) );
318         PopupConfigDlg->cbCtrlClose->Checked = CtrlClose;
319         PopupConfigDlg->cbIgnoreJ->Checked = IgnoreJ;
320         PopupConfigDlg->cbBanner->Checked = Banner;
321         bool useAMODI = CaptureMode & CM_IMAGE ? true : false;
322         PopupConfigDlg->SetCaptureMode( CaptureMode );
323         PopupConfigDlg->SetScaler( Ini->ReadInteger(PFS_CONFIG, PFS_SCALE, 0) );
324         PopupConfigDlg->edAMODIPath->Text = AMODIPath;
325         PopupConfigDlg->SetMODIAvail( AMODIAvail );
326         bool use64 = Ini->ReadInteger(PFS_CONFIG, PFS_USE64, DEF_USE64);
327         PopupConfigDlg->cbUse64->Checked = use64;
328         SetForegroundWindow( PopupConfigDlg->Handle );
329         if ( PopupConfigDlg->ShowModal() == IDOK ){
330                 GroupOpen = PopupConfigDlg->cbGroupOpen->Checked;
331                 GroupName = PopupConfigDlg->edGroupName->Text;
332                 CtrlClose = PopupConfigDlg->cbCtrlClose->Checked;
333                 IgnoreJ = PopupConfigDlg->cbIgnoreJ->Checked;
334                 Banner = PopupConfigDlg->cbBanner->Checked;
335                 AMODIPath = PopupConfigDlg->edAMODIPath->Text;
336                 Ini->WriteInteger( PFS_CONFIG, PFS_POPUPKEY,
337                         PopupConfigDlg->GetPopupKey() );
338                 Ini->WriteInteger( PFS_CONFIG, PFS_TOGGLEKEY,
339                         PopupConfigDlg->GetToggleKey() );
340                 CaptureMode = PopupConfigDlg->GetCaptureMode();
341                 Ini->WriteInteger( PFS_CONFIG, PFS_CAPTURE_MODE, CaptureMode );
342                 Ini->WriteInteger( PFS_CONFIG, PFS_SCALE, PopupConfigDlg->GetScaler() );
343                 Ini->WriteString(PFS_CONFIG, PFS_AMODIPATH, AMODIPath.c_str());
344                 Ini->WriteInteger(PFS_CONFIG, PFS_USE64, PopupConfigDlg->cbUse64->Checked);
345                 SaveConfig();
346                 SetupConfig();
347                 tmReInit->Enabled = false;
348                 if (!useAMODI && (CaptureMode & CM_IMAGE) && !AMODIAvail){
349                         // AMODI off->ON \82©\82 AMODI\82ª\82¢\82È\82¢\8fê\8d\87
350                         NotifyAMODI();
351                 }
352                 if (PopupConfigDlg->cbUse64->Checked != use64){
353                         // 64bit hook \95Ï\8dX\8e\9e
354                         Unhook();
355                         Hook();
356                 }
357         }
358         delete PopupConfigDlg;
359         PopupConfigDlg = NULL;
360 }
361 void __fastcall TDCHookMainForm::miReadMeClick(TObject *Sender)
362 {
363         ShowManual(Handle);
364 }
365 //---------------------------------------------------------------------------
366 void __fastcall TDCHookMainForm::miAboutClick(TObject *Sender)
367 {
368         // show version dialog
369 #if 1
370         Width = SavedWidth;
371         btnOK->Visible = true;
372         btnOK->SetFocus();
373         Visible = true;
374 #else
375         VersionDlg = new TVersionDlg( this );
376         VersionDlg->ShowModal();
377         delete VersionDlg;
378 #endif
379 }
380 //---------------------------------------------------------------------------
381 void __fastcall TDCHookMainForm::miCheckLatestClick(TObject *Sender)
382 {
383         ShowLatestVersion();
384 }
385 //---------------------------------------------------------------------------
386 void __fastcall TDCHookMainForm::miCloseClick(TObject *Sender)
387 {
388         MenuClosed();
389 }
390 //---------------------------------------------------------------------------
391 void __fastcall TDCHookMainForm::miReloadClick(TObject *Sender)
392 {
393         // \8dÄ\8bN\93®
394         Unhook();
395         Hook();
396         MenuClosed();
397 }
398 //---------------------------------------------------------------------------
399 void __fastcall TDCHookMainForm::miHookClick(TObject *Sender)
400 {
401         if ( !Hook() ){
402                 Application->MessageBox( "DLL\82ð\8f\89\8aú\89»\82·\82é\82±\82Æ\82ª\82Å\82«\82Ü\82¹\82ñ\r\8fI\97¹\82µ\82Ü\82·", APPNAME, MB_OK );
403                 Close();
404         }
405 }
406 //---------------------------------------------------------------------------
407 void __fastcall TDCHookMainForm::miUnhookClick(TObject *Sender)
408 {
409         Unhook();
410 }
411 //---------------------------------------------------------------------------
412 void __fastcall TDCHookMainForm::miConfigClick(TObject *Sender)
413 {
414         miOptionClick(Sender);
415 }
416 //---------------------------------------------------------------------------
417 void __fastcall TDCHookMainForm::miDdeTestClick(TObject *Sender)
418 {
419 #ifdef _DEBUG
420         DoPopup( _t("test"), NULL, false );
421 #endif
422 }
423 //---------------------------------------------------------------------------
424 void __fastcall TDCHookMainForm::miTestClick(TObject *Sender)
425 {
426 #ifdef _DEBUG
427 #if 1
428         hDll->Init32(Handle);
429 #endif
430 #if 0
431         NotifyAMODI();
432 #endif
433 #if 0
434         miIncSearchClick(Sender);
435 #endif
436 #if 0
437         if (hDll){
438                 hDll->Capture();
439         }
440 #endif
441 #endif  // _DEBUG
442 }
443 //---------------------------------------------------------------------------
444 void __fastcall TDCHookMainForm::miExitClick(TObject *Sender)
445 {
446         Close();
447 }
448 //---------------------------------------------------------------------------
449 // Popup on tray icon //
450 void __fastcall TDCHookMainForm::pmTrayIconPopup(TObject *Sender)
451 {
452         // Add group names to menu
453         TAppIni ini;
454         if ( !ini.hroot ){
455                 return;
456         }
457
458         int sel = ini.ReadInteger( PFS_COMMON, PFS_GRPSEL, -1 );
459
460         TStringList *strs = new TStringList;
461         TMenuItem *sub = pmTrayIcon->Items->Items[MIGROUP_INDEX];
462         for ( ;sub->Count;){
463                 sub->Delete(0);
464         }
465         GetGroupList(ini, *strs);
466         int index = 0;
467         for ( int i=0;i<strs->Count;i++ ){
468                 AnsiString name = strs->Strings[i];
469                 if (name.IsEmpty() || name.AnsiPos("::")==1){
470                         continue;       // Ignore the group.
471                 }
472                 TMenuItem *item = new TMenuItem( this );
473                 item->Caption = name;
474                 item->OnClick = miDicGroup;
475                 sub->Add( item );
476                 // Check current group name //
477                 if ( sel == index ){
478                         item->Checked = true;
479                 }
480                 index++;
481         }
482         delete strs;
483         miGroup->Visible = sub->Count != 0;
484         // Check enable popup item //
485         miIncSearch->Checked = MouseIncSrch;
486         miEnablePopup->Checked = EnablePopup;
487
488         miOCRText->Visible = CaptureMode & CM_IMAGE ? true : false;
489 }
490 //---------------------------------------------------------------------------
491 void __fastcall TDCHookMainForm::btnOKClick(TObject *Sender)
492 {
493 #ifndef _DEBUG
494         Width = 0;
495 #endif
496         MenuClosed();
497 }
498 //---------------------------------------------------------------------------
499 // Timers
500 //---------------------------------------------------------------------------
501 void __fastcall TDCHookMainForm::TestTimerTimer(TObject *Sender)
502 {
503 #ifdef _DEBUG
504 #if 0
505         if ( DCDebug ){
506                 char *p = (char*)DCDebug( );
507                 if ( memcmp( share, p, COMPSIZE ) ){
508                         DBW("Different");
509                         for ( int i=0;i<COMPSIZE;i++ ){
510                                 DBW("[%02X:%02X]", (unsigned char)share[i],(unsigned char)p[i]);
511                         }
512                         memcpy( share, p, COMPSIZE );
513                 }
514         }
515 #endif
516 #endif
517 }
518 //---------------------------------------------------------------------------
519 void __fastcall TDCHookMainForm::BootTimerTimer(TObject *Sender)
520 {
521         Start();
522 }
523 //---------------------------------------------------------------------------
524 // \82±\82ê\82ð\82â\82ç\82È\82¢\82Æ\81A\81h\83\81\83j\83\85\81[\82ð\95Â\82\82é\81h\82ð\8eÀ\8ds\8cã\81A
525 // \83A\83C\83R\83\93\82ª\83^\83X\83N\83o\81[\82É\8ec\82Á\82Ä\82µ\82Ü\82¤\81B\82È\82º\81H\81H
526 void __fastcall TDCHookMainForm::tmMenuCloseTimer(TObject *Sender)
527 {
528         Visible = true;
529         Visible = false;
530         ShowWindow( Application->Handle, SW_HIDE );
531         tmMenuClose->Enabled = false;
532 }
533 //---------------------------------------------------------------------------
534 void __fastcall TDCHookMainForm::tmNotifyTimer(TObject *Sender)
535 {
536         if ( NotifyForm ){
537                 tmNotify->Enabled = false;
538                 delete NotifyForm;
539                 NotifyForm = NULL;
540         }
541 }
542 //---------------------------------------------------------------------------
543 void __fastcall TDCHookMainForm::tmPopupTimer(TObject *Sender)
544 {
545         PostMessage( Handle, WM_POPUP, PopupLoc | (PopupMoveSend ? FLG_MOVESEND :  0), (LPARAM)PopupText );
546         PopupText = NULL;       // release ownership
547         tmPopup->Enabled = false;       // stop timer
548 }
549 //---------------------------------------------------------------------------
550 void __fastcall TDCHookMainForm::tmMouseMoveTimer(TObject *Sender)
551 {
552         tmMouseMove->Enabled = false;
553
554         if (!hDll)
555                 return;
556         //hDll->Capture();
557         hDll->CaptureAsync();
558 }
559 //---------------------------------------------------------------------------
560 void __fastcall TDCHookMainForm::tmMODIInstallCheckTimer(TObject *Sender)
561 {
562         if (MODIInstalled()){
563 #if 0
564                 Reboot();
565 #else
566                 // \8dÅ\8f\89\82Ìpopup\82Å\97\8e\82¿\82Ä\82µ\82Ü\82¤\81H
567                 if (!AMODIAvail && (CaptureMode & CM_IMAGE)){
568                         InitAMODI();
569                 }
570                 if (AMODIAvail){
571                         SetupConfig2();
572                 }
573 #endif
574         }
575 }
576 //---------------------------------------------------------------------------
577 void __fastcall TDCHookMainForm::tmMODINotifyTimer(TObject *Sender)
578 {
579         tmMODINotify->Enabled = false;
580         if (!AMODIRunable()){
581                 NotifyAMODI();
582         }
583 }
584 //---------------------------------------------------------------------------
585 void __fastcall TDCHookMainForm::tmReInitTimer(TObject *Sender)
586 {
587         // amodi.exe\82Ìlaunch\82É\94ñ\8fí\82É\8e\9e\8aÔ\82ª\82©\82©\82é\8fê\8d\87\82ª\82 \82é
588         // ex.\8cÃ\82¢PC\82Åstartup\82É\93o\98^\82µ\82Ä\82¢\82é\8fê\8d\87
589         //    \81¨input idle\82É\82È\82Á\82Ä\82àmain window\82Ì\90\90¬\82É\8e\9e\8aÔ\82ª\82©\82©\82Á\82Ä\82¢\82é\82Ì\82©\82à\82µ\82ê\82È\82¢
590         // AMODIAvail\82ªtrue\82É\82È\82é\82Ü\82Å\8f\89\8aú\89»\82ð\91±\82¯\82é
591         tmReInit->Enabled = false;
592         SetupAMODI();
593         if (AMODIAvail){
594                 SetupConfig2();
595         }
596 }
597 //---------------------------------------------------------------------------
598 // Mouse Events
599 //---------------------------------------------------------------------------
600 void __fastcall TDCHookMainForm::ImageMouseDown(TObject *Sender,
601           TMouseButton Button, TShiftState Shift, int X, int Y)
602 {
603         if ( BootUp ) return;
604         Capturing = true;
605         SetCapture( Handle );
606         CapPoint.x = X;
607         CapPoint.y = Y;
608 }
609 //---------------------------------------------------------------------------
610 void __fastcall TDCHookMainForm::ImageMouseMove(TObject *Sender,
611           TShiftState Shift, int X, int Y)
612 {
613         if ( Capturing ){
614                 POINT pt;
615                 GetCursorPos( &pt );
616                 Left = pt.x - CapPoint.x;
617                 Top = pt.y - CapPoint.y;
618         }
619 }
620 //---------------------------------------------------------------------------
621 void __fastcall TDCHookMainForm::ImageMouseUp(TObject *Sender,
622           TMouseButton Button, TShiftState Shift, int X, int Y)
623 {
624         if ( BootUp )
625                 Start();
626         Capturing = false;
627 }
628 //---------------------------------------------------------------------------
629 // User Functions
630 //---------------------------------------------------------------------------
631 void TDCHookMainForm::InitAMODI()
632 {
633         AMODIPath = Ini->ReadString(PFS_CONFIG, PFS_AMODIPATH, AMODIPath.c_str());
634         SetupAMODI();
635 }
636 void TDCHookMainForm::Start()
637 {
638         BootTimer->Enabled = false;
639 #ifndef _DEBUG
640         ShowWindow( Application->Handle, SW_HIDE );
641         Visible = false;
642         Width = 0;
643 #endif
644         if ( BootUp ){
645                 RegisterTrayIcon( true );
646                 miHookClick( this );
647                 BootUp = false;
648         }
649 }
650 //---------------------------------------------------------------------------
651 bool TDCHookMainForm::Hook()
652 {
653         if ( hDll ){
654                 DBW("Already hooked");
655                 return true;    // already loaded
656         }
657
658         bool use64 = Ini->ReadInteger(PFS_CONFIG, PFS_USE64, DEF_USE64);
659         hDll = new TDCHookLoader(use64);
660         if (!hDll->LoadHook(Handle)){
661                 DBW("Load failed");
662                 delete hDll;
663                 hDll = NULL;
664                 return false;
665         }
666
667         miHook->Enabled = false;
668         miUnhook->Enabled = true;
669
670         if (hDll->IsReady()){
671                 SetupConfig();
672                 extern HWND hwnd64;
673                 PostMessage(Handle, UM_SHORTCUT, SCINX_NOTIFY64, (LPARAM)hwnd64);
674         }
675
676         DBW("Hook OK");
677         
678         return true;
679 }
680 void TDCHookMainForm::Unhook()
681 {
682         if ( !hDll ) return;
683
684         hDll->UnloadHook();
685         delete hDll;
686         hDll = NULL;
687
688         miHook->Enabled = true;
689         miUnhook->Enabled = false;
690 }
691 //---------------------------------------------------------------------------
692 #ifdef _DEBUG
693 // text\82Ì\90æ\93ª\82ð(0,0)\82Æ\82µ\82½\8dÀ\95W\82Å\81Apos\82Ì\88Ê\92u\82É\82 \82étext\82Ì\95\8e\9a\88Ê\92u\82ð\95Ô\82·
694 int GetTextFromPoint( HDC hdc, const char *text, int pos )
695 {
696         int len = lstrlen(text);
697         int left = 0;
698         int right = len;
699         SIZE sz;
700         int loc;
701         for(;;){
702                 loc = (right + left)/2;
703                 if ( right - left <= 1 ){
704                         break;
705                 }
706                 GetTextExtentPoint32A( hdc, text, loc, &sz );
707 //              DBW("%08X %d %d %d %d", hdc, left, right, loc, sz.cx);
708                 if ( pos < sz.cx ){
709                         right = loc;
710                 } else {
711                         left = loc;
712                 }
713         }
714         return (right+left)/2;
715 }
716 int GetTextFromPoint( HDC hdc, const wchar_t *text, int pos )
717 {
718         int len = lstrlenW(text);
719         int left = 0;
720         int right = len;
721         SIZE sz;
722         int loc;
723         for(;;){
724                 loc = (right + left)/2;
725                 if ( right - left <= 1 ){
726                         break;
727                 }
728                 GetTextExtentPoint32W( hdc, text, loc, &sz );
729 //              DBW("%08X %d %d %d %d", hdc, left, right, loc, sz.cx);
730                 if ( pos < sz.cx ){
731                         right = loc;
732                 } else {
733                         left = loc;
734                 }
735         }
736         return (right+left)/2;
737 }
738 #endif
739 void TDCHookMainForm::EvCopyData(TMessage& msg )
740 {
741         COPYDATASTRUCT *cds = (COPYDATASTRUCT*)msg.LParam;
742         if ( !cds ){ return; }
743         switch ( cds->dwData ){
744                 case DCH_MOVESEND:
745                         //DBW("DCH_MOVESEND");
746                         // mouse move message
747                         EvMoveSend(msg.WParam==0);
748                         break;
749                 case DCH_START:
750                         CursorPoint = *(POINT*)cds->lpData;
751 #ifdef _DEBUG
752                         PaintBox->Canvas->FillRect( PaintBox->Canvas->ClipRect );
753 #endif
754                         if (PopupText){
755                                 delete[] PopupText;
756                                 PopupText = NULL;
757                         }
758                         break;
759                 case DCH_END:
760                 case DCH_END | DCH_MOVESEND:
761                         if ( PopupText ){
762                                 PopupMoveSend = cds->dwData & DCH_MOVESEND ? true : false;
763                                 PostMessage( Handle, WM_POPUP, PopupLoc | (PopupMoveSend ? FLG_MOVESEND : 0), (LPARAM)PopupText );
764                                 if (OCRTextForm) OCRTextForm->SetText(PopupText);
765                                 PopupText = NULL;       // release ownership
766                         }
767                         break;
768                 case DCH_HITTEXT1:      // single char
769                 {
770                         DBW("DCH_HITTEXT1");
771                         if (PopupText)
772                                 delete[] PopupText;
773 #ifdef USE_UNICODE
774                         // ANSI -> Unicode
775                         //*+++ \93®\8dì\96¢\8am\94F 2002.12.4
776                         PopupText = new tchar[ cds->cbData*2 + 1 ];
777                         // \91O\94¼\95\94\95ª
778                         PopupLoc = MultiByteToWideChar( CP_ACP, 0,
779                                 (LPCSTR)cds->lpData, msg.WParam, PopupText, cds->cbData*2 );
780                         // \8cã\94¼\95\94\95ª
781                         int r = MultiByteToWideChar( CP_ACP, 0,
782                                 &((char*)cds->lpData)[msg.WParam], cds->cbData-msg.WParam, &PopupText[PopupLoc], cds->cbData-PopupLoc );
783                         PopupText[PopupLoc+r] = '\0';
784 #else   // !USE_UNICODE
785                         PopupText = new tchar[ cds->cbData + 1 ];
786                         memcpy( PopupText, cds->lpData, cds->cbData );
787                         PopupText[cds->cbData] = '\0';
788                         PopupLoc = msg.WParam;
789 #ifdef _DEBUG
790                         Memo->Lines->Add( PopupText );
791                         edFound->Text = PopupText + msg.WParam;
792                         TestTimer->Enabled = true;
793                         if ( DCDebug ){
794                                 char *p = (char*)DCDebug( );
795                                 memcpy( share, p, COMPSIZE );
796                         }
797 #endif
798 #endif
799                 }
800                         break;
801                 case DCH_HITTEXT2:      // wide char
802                 {
803                         DBW("DCH_HITTEXT2");
804                         if (PopupText)
805                                 delete[] PopupText;
806 #ifdef USE_UNICODE
807                         PopupText = new tchar[ cds->cbData + 1 ];
808                         memcpy( PopupText, cds->lpData, cds->cbData );
809                         PopupText[cds->cbData/sizeof(tchar)] = '\0';
810                         PopupLoc = msg.WParam;
811 #else   // !USE_UNICODE
812                         // Unicode -> ANSI
813                         //*+++ \93®\8dì\96¢\8am\94F 2002.12.4
814                         PopupText = new tchar[ cds->cbData + 1 ];
815                         // \91O\94¼\95\94\95ª
816                         BOOL defchar;
817                         PopupLoc = WideCharToMultiByte( CP_ACP, 0,
818                                 (wchar_t*)cds->lpData, msg.WParam,
819                                 PopupText, cds->cbData, 0, &defchar );
820                         // \8cã\94¼\95\94\95ª
821                         int r = WideCharToMultiByte( CP_ACP, 0,
822                                 &((wchar_t*)cds->lpData)[msg.WParam], (cds->cbData>>1)-msg.WParam,
823                                 &PopupText[PopupLoc], cds->cbData-PopupLoc, 0, &defchar );
824                         PopupText[PopupLoc+r] = '\0';
825 #endif
826                 }
827                         break;
828 #ifdef _DEBUG
829                 case DCH_EXTTEXTOUTA:
830                 case DCH_EXTTEXTOUTW:
831                 {
832                         EMREXTTEXTOUTW *emr = (EMREXTTEXTOUTW*)cds->lpData;
833                         wchar_t *p = (wchar_t*) ( ((char*)emr) + emr->emrtext.offString );
834                         char *buf = NULL;
835 #if 0
836                         char b[200];
837                         sprintf(b,"exScale=%f eyScale=%f ptlReference=(%d,%d)",emr->exScale, emr->eyScale, emr->emrtext.ptlReference.x, emr->emrtext.ptlReference.y );
838                         DBW(b);
839 #endif
840                         if ( cds->dwData == DCH_EXTTEXTOUTW ){
841                                 buf = new char[ emr->emrtext.nChars * 2 ];
842                                 memset( buf, 0, emr->emrtext.nChars*2 );
843                                 WideCharToMultiByte( CP_ACP, 0, p, emr->emrtext.nChars, buf, emr->emrtext.nChars * 2, NULL, NULL );
844                         }
845                         const char *text = buf ? buf : (char*)p;
846                         Memo->Lines->Add( text );
847                         PaintBox->Canvas->TextOut( emr->rclBounds.left, emr->rclBounds.top, text );
848
849                         if ( PtInRect( (RECT*)&emr->rclBounds, CursorPoint ) ){
850                                 int loc = GetTextFromPoint( (HDC)msg.WParam, text, CursorPoint.x - emr->rclBounds.left );
851                                 if ( loc != -1 ){
852                                         edFound->Text = text + loc;
853                                 }
854                         }
855                         if ( buf )
856                                 delete[] buf;
857                 }
858                         break;
859 #endif
860                 case DCH_MENU:
861                         DokoPopMenu( false );
862                         break;
863                 case DCH_TOGGLE:
864                         PostMessage( Handle, WM_TOGGLE, 0, 0 );
865                         break;
866                 case WMCD_EXISTCHECK:   // exist check
867                         if ( cds->cbData != strlen(APPNAME)+1 ){
868                                 msg.Result = false;
869                                 return;
870                         }
871                         msg.Result = (memcmp( cds->lpData, APPNAME, strlen(APPNAME)+1 ) == 0);
872                         return;
873                 case DCH_LAUNCH_AMODI:
874                         SetupAMODI();
875                         //Reboot();             // AMODI.exe\8dÄ\8bN\93®\82Å\82Í\89ð\8c\88\82Å\82«\82È\82¢\82½\82ß
876                         break;
877         }
878         return;
879 }
880 //---------------------------------------------------------------------------
881 bool WaitTransaction( TDdeClientConv *dde )
882 {
883 #if 1
884         for ( int i=0;i<100000;i++ ){
885                 Application->ProcessMessages();
886                 if ( !dde->WaitStat ){
887 //                      DBW("DCHook:Wait OK");
888                         return true;
889                 }
890         }
891         DBW("DCHook:Wait failure");
892         return false;
893 #else
894         return true;
895 #endif
896 }
897 // ANSI\82Å\93n\82·\8fê\8d\87
898 bool DdePoke( TDdeClientConv *dde, AnsiString Item, AnsiString Data )
899 {
900 #ifdef USE_UNICODE
901         int ansilen = Data.Length();
902         wchar_t *buf = new wchar_t[ansilen*2+1];
903         int len = MultiByteToWideChar( CP_ACP, 0,
904                 (LPCSTR)Data.c_str(), ansilen, buf, ansilen*2 );
905         buf[len] = '\0';
906         bool r = DdePoke( dde, Item, (wchar_t*)buf );
907         delete[] buf;
908         return r;
909 #else   // !USE_UNICODE
910         HSZ hszItem = DdeCreateStringHandle(ddeMgr->DdeInstId, Item.c_str(), CP_WINANSI );
911         if ( !hszItem ) return false;
912         HDDEDATA hszDat = DdeCreateDataHandle( ddeMgr->DdeInstId, Data.c_str(), Data.Length() + 1,
913                 0, hszItem, dde->DdeFmt, 0);
914         bool r = false;
915         if ( hszDat ){
916                 HDDEDATA hdata = DdeClientTransaction( (LPBYTE)hszDat, (DWORD)-1, (HCONV)dde->Conv, hszItem,
917                         dde->DdeFmt, XTYP_POKE, 10000, NULL);
918                 if (hdata || DdeGetLastError(ddeMgr->DdeInstId) != DMLERR_NO_ERROR){
919                         r = true;
920                         if (hdata)
921                                 DdeFreeDataHandle( hdata );
922                 }
923         }
924         DdeFreeStringHandle(ddeMgr->DdeInstId, hszItem);
925         return r;
926 #endif
927 }
928 #ifdef USE_UNICODE
929 // Unicode\82Å\93n\82·\8fê\8d\87
930 bool DdePoke( TDdeClientConv *dde, AnsiString Item, const wchar_t *Data )
931 {
932         // Item\96¼\82ÍANSI\81A\83f\81[\83^\82ÍUNICODE //
933         int ddeFmt = /*dde->DdeFmt*/CF_UNICODETEXT;
934         HSZ hszItem = DdeCreateStringHandle(ddeMgr->DdeInstId, Item.c_str(), CP_WINANSI );
935         if ( !hszItem ) return false;
936         HDDEDATA hszDat = DdeCreateDataHandle( ddeMgr->DdeInstId, (LPBYTE)Data, (_tcslen(Data)+1)*sizeof(wchar_t),
937                 0, hszItem, ddeFmt, 0);
938         bool r = false;
939         if ( hszDat ){
940                 HDDEDATA hdata = DdeClientTransaction( (LPBYTE)hszDat, (DWORD)-1, (HCONV)dde->Conv, hszItem,
941                         ddeFmt, XTYP_POKE, 10000, NULL);
942                 if (hdata || DdeGetLastError(ddeMgr->DdeInstId) != DMLERR_NO_ERROR){
943                         r = true;
944                         if (hdata)
945                                 DdeFreeDataHandle( hdata );
946                 }
947         }
948         }
949         DdeFreeStringHandle(ddeMgr->DdeInstId, hszItem);
950         return r;
951 }
952 #endif
953 TDdeClientConv *TDCHookMainForm::OpenPdic( const char *topic )
954 {
955         TDdeClientConv *PdicDde = new TDdeClientConv( this );
956
957         PdicDde->ConnectMode = ddeManual;
958         static int entry = 0;
959         PdicDde->Name = AnsiString("PdicDde") + (++entry);
960         PdicDde->ServiceApplication = DDE_SERVICE_NAME;
961         if ( !PdicDde->SetLink( DDE_SERVICE_NAME, topic ) ){
962                 DBW("DCHook:Cannot SetLink");
963                 delete PdicDde;
964                 return NULL;
965         }
966         if ( !PdicDde->OpenLink( ) ){   // \82±\82±\82ª\92x\82¢\81I\81I
967                 // PDIC auto launch
968                 if ( LaunchPdic() ){
969                         for(int i=0;i<OPEN_RETRY;i++){
970                                 if ( PdicDde->OpenLink() ){
971                                         return PdicDde;
972                                 }
973                                 Sleep(OPEN_WAITTIME);
974                         }
975                 }
976                 DBW("PDIC\82ª\8c©\82Â\82©\82è\82Ü\82¹\82ñ(OpenPdic)");
977                 Application->MessageBox( "PDIC\82ª\8c©\82Â\82©\82è\82Ü\82¹\82ñ(OpenPdic)", APPNAME, MB_OK );
978                 delete PdicDde;
979                 return NULL;
980         }
981         return PdicDde;
982 }
983 #ifdef USE_UNICODE
984 static const TCHAR *clsname = TEXT("TPdicMain.UnicodeClass");
985 #else
986 static const TCHAR *clsname = TEXT(DDE_SERVICE_NAME);
987 #endif
988 static const TCHAR *winname = NULL;
989 HWND TDCHookMainForm::FindPdic( )
990 {
991         HWND hWin = FindWindow( clsname, winname );
992         if ( !hWin ){
993                 // PDIC auto launch
994                 if ( LaunchPdic() ){
995                         hWin = FindWindow( clsname, winname );
996                         if ( !hWin ){
997                                 DBW("PDIC\82ª\8c©\82Â\82©\82è\82Ü\82¹\82ñ(FindPdic)");
998                                 Application->MessageBox( "PDIC\82ª\8c©\82Â\82©\82è\82Ü\82¹\82ñ(FindPdic)", APPNAME, MB_OK );
999                                 return NULL;
1000                         }
1001                 }
1002         }
1003         return hWin;
1004 }
1005 #if !USE_DDE
1006 LRESULT TDCHookMainForm::SendCopyData( HWND hwnd, int message, const char *str )
1007 {
1008         COPYDATASTRUCT cds;
1009         cds.dwData = message;
1010         cds.lpData = (LPSTR)str;
1011         cds.cbData = lstrlen(str)+1;
1012         SendMessage( hwnd, WM_COPYDATA, (WPARAM)Handle, (LPARAM)&cds );
1013 }
1014 #endif
1015 void TDCHookMainForm::ClosePdic( TDdeClientConv *dde )
1016 {
1017         dde->CloseLink();
1018         delete dde;
1019 }
1020 bool TDCHookMainForm::DoPopup( const tchar *text, const tchar *prevtext, bool movesend )
1021 {
1022         static int ct = 0;
1023         if ( ct >= 1 ){
1024                 if (PopupText){
1025                         // already pending
1026                         DBW("Reentrant!!!!!");
1027                         return true;
1028                 }
1029                 HWND hwnd = FindPopupWindow( );
1030                 if (hwnd){
1031                         HWND hwndParent = GetParent( hwnd );
1032                         if (hwndParent){
1033                                 DBW("Parent exist!!!!");
1034                                 hwnd = hwndParent;
1035                         }
1036                         DBW("Retry again:%d:%08X",ct,hwnd);
1037                         // \95K\82¸PostMessage()\82Åclose\82·\82é\82±\82Æ\81B
1038                         // CloseWindow()\82Å\82ÍPopup Winodow\82Ì\8f\89\8aú\89»\92\86\82É
1039                         // close\8f\88\97\9d\82ð\8eÀ\8ds\82µ\82Ä\82µ\82Ü\82¢\81A
1040                         // popup window\82ª\82¨\82©\82µ\82È\8fó\91Ô\82É\82Í\82¢\82Á\82Ä\82µ\82Ü\82¤\8fê\8d\87\82ª\82 \82é
1041                         PostMessage( hwnd, WM_CLOSE, 0, 0 );
1042                         return false;
1043                 } else {
1044                         if (ct >= 1 ){
1045                                 DBW("Not found popup window");
1046                                 if (DoPopupRetry++ > 10){
1047                                         DoPopupRetry = 0;
1048                                         return true;    // abort
1049                                 } else {
1050                                         return false;   // retry
1051                                 }
1052                         }
1053                 }
1054         }
1055         DoPopupRetry = 0;
1056         ct++;
1057
1058 #if USE_DDE
1059         // Windows9x\82Å\82Í\81ADDE transaction\82ª\92x\82¢\82Æ\82«\82ª\82 \82é
1060         // why? - because of 24bit OS:-)
1061         // ->\82Æ\8ev\82Á\82Ä\81AWM_COPYDATA version\82ð\8dì\82Á\82Ä\82¢\82½\82ç\91¬\82­\82È\82Á\82½\81H\81H\81H
1062         // ->WM_COPYDATA\89» project\82Í\92\86\92f
1063         TDdeClientConv *PdicDde;
1064         bool r;
1065
1066         if (movesend){
1067                 // incremental search
1068                 PdicDde = OpenPdic("Simulate");
1069                 if (!PdicDde){
1070                         ct--;
1071                         return true;
1072                 }
1073                 r = DdePoke(PdicDde, "InputWord3", text);
1074                 if (!r){
1075                         DBW("PDIC DDE : InputWord3 failure");
1076                         delete PdicDde;
1077                         ct--;
1078                         return true;
1079                 }
1080         } else {
1081                 // popup
1082                 if (GroupOpen){
1083                         PdicDde = OpenPdic( "Simulate" );
1084                         if (PdicDde){
1085                                 DdePoke( PdicDde, "Open", GroupName );
1086                                 PdicDde->CloseLink();
1087                                 delete PdicDde;
1088                         }
1089                 }
1090                 PdicDde = OpenPdic( "Dictionary" );
1091                 if ( !PdicDde ){
1092                         ct--;
1093                         return true;
1094                 }
1095
1096                 r = DdePoke( PdicDde, "Open", "" );
1097                 if ( !r ){
1098                         DBW("PDIC DDE : Open failure");
1099                         PdicDde->CloseLink();
1100                         delete PdicDde;
1101                         ct--;
1102                         if ( GroupOpen ){
1103                                 static int ct = 0;
1104                                 ct++;
1105                                 if ( ct == 1 ){
1106                                         Application->MessageBox(
1107                                                 "\8e«\8f\91\83O\83\8b\81[\83v\82ª\8aJ\82¯\82Ü\82¹\82ñ\r"
1108                                                 "DokoPop!\82Å\81u\8e«\8f\91\83O\83\8b\81[\83v\8ew\92è\81v\82ð\97L\8cø\82É\82µ\82Ä\82¢\82é\8fê\8d\87\82Í\81A\82·\82Å\82ÉPDIC\96{\91Ì\82Å\83I\81[\83v\83\93\82³\82ê\82Ä\82¢\82é\8e«\8f\91\82Æ\8b¤\97L\88á\94½\82ð\8bN\82±\82µ\82Ä\82¢\82é\89Â\94\\90«\82ª\82 \82è\82Ü\82·\r"
1109                                                 "DokoPop!\82ÆPDIC\96{\91Ì\82Å\8eg\97p\82µ\82Ä\82¢\82é\8e«\8f\91\82É\93¯\88ê\82Ì\82à\82Ì\82ª\82È\82¢\82©\92²\82×\82Ä\82­\82¾\82³\82¢\r"
1110                                                 "\82à\82µ\82 \82Á\82½\8fê\8d\87\82Í\93o\98^\8bÖ\8e~\82È\82Ç\8b¤\97L\82Å\82«\82é\82æ\82¤\82È\8fó\91Ô\82É\82µ\82Ä\82­\82¾\82³\82¢\r"
1111                                                 "\82±\82Ì\83\81\83b\83Z\81[\83W\82Ì\88Ó\96¡\82ª\82í\82©\82ç\82È\82¢\8fê\8d\87\82Í\81A\81u\8e«\8f\91\83O\83\8b\81[\83v\8ew\92è\81v\8b@\94\\82ð\8eg\82í\82È\82¢\82Ù\82¤\82ª\88À\91S\82Å\82·"
1112                                                 ,
1113                                                 APPNAME, MB_OK );
1114                                 } else {
1115                                         SetForegroundWindow( Handle );
1116                                 }
1117                                 ct--;
1118                         }
1119                         return true;
1120                 }
1121                 if ( CtrlClose )
1122                         DdePoke( PdicDde, "PopupSearchConfig", "c1" );  // Ctrl close
1123         //      Sleep(1000);
1124                 DdePoke( PdicDde, "PopupSearchConfig", "o1w1" );        // overlap window and no wait transaction
1125                 if ( prevtext && (prevtext != text) ){
1126                         //DBW("prevtext="FMTS,prevtext);
1127                         DdePoke( PdicDde, "PopupSearch2", (tchar*)prevtext );
1128         //              ExecuteMacro( "PopupSearch2", true );
1129                         WaitTransaction( PdicDde );
1130                 } else {
1131                         //DBW("text="FMTS,text);
1132                         DdePoke( PdicDde, "PopupSearch", (tchar*)text );
1133         //              PdicDde->ExecuteMacro( "PopupSearch", true );
1134                         WaitTransaction( PdicDde );
1135                 }
1136                 DdePoke( PdicDde, "Close", "" );
1137         }
1138         ClosePdic( PdicDde );
1139 #else   // !USE_DDE
1140                 // WM_COPYDATA\82É\82æ\82é\95û\96@(\82Ü\82¾document\89»\82³\82ê\82Ä\82¢\82È\82¢\95û\96@(Ver.4.30)
1141                 // PDIC/W32 Ver.4.22\81`\82É\91Î\89\9e
1142                 // \82½\82¾\82µ\81AVer.4.29\82Ü\82Å\82Í\81AWMCD_POPUPSEARCH\82ÆWMCD_POPUPSEARCH2\82Í\93¯\82
1143
1144         // WM_COPYDATA code //
1145         // \88È\89º\82Ì\90\94\92l\82Í\8f«\97\88\95Ï\82í\82é\89Â\94\\90«\82ª\82 \82é(undocumented) //
1146         #define WMCD_GETVERSION         0x0001
1147         #define WMCD_CHECKOPEN          0x0010
1148         #define WMCD_AUTOSEARCH         0x0020
1149         #define WMCD_AUTOSEARCHMODE     0x0021
1150
1151         #define WMCD_ISOPENED                   0x0080
1152         #define WMCD_CLOSE                              0x0081
1153
1154         #define WMCD_POPUPSEARCH                0x0100
1155         #define WMCD_POPUPSEARCH2               0x0101
1156         #define WMCD_POPUPSEARCHPOINT   0x0102
1157         #define WMCD_POPUPSEARCHCONFIG  0x0103
1158         #define WMCD_POPUPSEARCHDIALOG  0x0104
1159         #define WMCD_POPUPSEARCHWINDOW  0x0105
1160
1161         #define WMCD_SPELLCHECK                 0x0110
1162
1163         HWND hwnd = FindPdic();
1164         if ( !hwnd ){
1165                 ct--;
1166                 return;
1167         }
1168
1169         bool r;
1170         if ( CtrlClose )
1171                 SendCopyData( hwnd, WMCD_POPUPSEARCHCONFIG, "c1" );
1172         POINT pt;
1173         GetCursorPos( &pt );
1174         char buf[20];
1175         wsprintf( buf, "%d,%d", pt.x, pt.y );
1176         SendCopyData( hwnd, WMCD_POPUPSEARCHPOINT, buf );
1177         if ( prevtext && (prevtext != text) ){
1178                 DBW("prevtext=%s",prevtext);
1179                 SendCopyData( hwnd, WMCD_POPUPSEARCH2, prevtext );
1180         } else {
1181                 DBW("text=%s",text);
1182                 SendCopyData( hwnd, WMCD_POPUPSEARCH, text );
1183         }
1184         SendCopyData( hwnd, WMCD_CLOSE, "" );
1185 #endif  // !USE_DDE
1186         ct--;
1187         DBW("DCHook:Exit Popup:%d",ct);
1188
1189 #if DETACHRELEASE
1190         if ( EnablePopup ){
1191                 miUnhookClick( this );
1192                 miHookClick( this );
1193         }
1194 #endif
1195         return true;
1196 }
1197 //---------------------------------------------------------------------------
1198 // EvPopup
1199 // WParam : text location & FLG_MOVESEND
1200 // LParam : text pointer (must be freed when done)
1201 void TDCHookMainForm::EvPopup(TMessage &msg)
1202 {
1203         //DBW("EvPopup");
1204         if (!msg.LParam)
1205                 return;
1206
1207         tchar *text = (tchar*)msg.LParam;
1208         int loc = msg.WParam & ~FLG_MOVESEND;
1209         bool movesend = msg.WParam & FLG_MOVESEND ? true : false;
1210         
1211         int start, end;
1212         int prevstart;
1213         if ( !GetWord( text, loc, start, end, prevstart, true, 10, true, IgnoreJ ) ){
1214                 // no words
1215                 delete[] text;
1216                 return;
1217         }
1218 #ifdef _DEBUG
1219         edWord->Text = text + start;
1220         edPrev->Text = loc + prevstart;
1221 #endif
1222
1223         if (DoPopup( text + start, text + prevstart, movesend )){
1224                 // done
1225                 delete[] text;
1226         } else {
1227                 // retry again
1228                 if (PopupText)
1229                         delete[] PopupText;     // \82 \82Æ\82É\97\88\82½\82Ù\82¤\82ð\97D\90æ\82·\82é
1230                 PopupText = text;
1231                 PopupLoc = loc;
1232                 PopupMoveSend = movesend;
1233                 tmPopup->Enabled = true;        // start timer for delayed popup
1234         }
1235         //DBW("EvPopup - end");
1236 }
1237 void TDCHookMainForm::EvMoveSend(TMessage &msg)
1238 {
1239         EvMoveSend(msg.WParam==0);
1240 }
1241 void TDCHookMainForm::EvMoveSend(bool enable)
1242 {
1243         tmMouseMove->Enabled = false;
1244         if (enable){
1245                 tmMouseMove->Enabled = true;
1246         }
1247 }
1248 void TDCHookMainForm::RegisterTrayIcon( bool flag )
1249 {
1250   NOTIFYICONDATA m_tnid;  //\82±\82ê\82Í*.h\82Å\92è\8b`\82µ\82Ä\82¨\82­
1251
1252   m_tnid.cbSize = sizeof(NOTIFYICONDATA);
1253   m_tnid.hWnd = Handle;
1254   m_tnid.uID = 1;
1255   m_tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
1256   m_tnid.uCallbackMessage = WM_NOTIFYICON;
1257   // Get small icon from me
1258   HICON hIconSm;
1259   HICON hIcon;
1260   ExtractIconEx( Application->ExeName.c_str(), -2, &hIcon, &hIconSm, 1 );
1261   m_tnid.hIcon = hIconSm;
1262   lstrcpy(m_tnid.szTip, APPNAME );
1263   Shell_NotifyIcon( flag ? NIM_ADD : NIM_DELETE, &m_tnid);
1264 }
1265 void TDCHookMainForm::EvNotifyIcon(TMessage &msg)
1266 {
1267         //UINT uID = (UINT) msg.WParam;
1268         UINT uMouseMsg = (UINT) msg.LParam;
1269         if (uMouseMsg == WM_LBUTTONDBLCLK)
1270         {
1271                 miOptionClick( this );
1272         }
1273         else if (uMouseMsg == WM_RBUTTONDOWN)
1274         {
1275                 DokoPopMenu( true );
1276         }
1277 }
1278 //---------------------------------------------------------------------------
1279 void TDCHookMainForm::SaveConfig()
1280 {
1281         Ini->WriteInteger( PFS_CONFIG, PFS_GROUPOPEN, GroupOpen );
1282         Ini->WriteString( PFS_CONFIG, PFS_GROUPNAME, GroupName.c_str() );
1283         Ini->WriteInteger( PFS_CONFIG, PFS_CTRLCLOSE, CtrlClose );
1284         Ini->WriteInteger( PFS_CONFIG, PFS_IGNOREJ, IgnoreJ );
1285         Ini->WriteInteger( PFS_CONFIG, PFS_BANNER, Banner );
1286 }
1287 void TDCHookMainForm::OpenDicGroup( const char *name )
1288 {
1289         TDdeClientConv *dde = OpenPdic( PFS_PDIC );
1290         if ( !dde )
1291                 return;
1292         // \8e«\8f\91\83O\83\8b\81[\83v\83I\81[\83v\83\93\8f\88\97\9d //
1293         if ( name[0] == '&' )
1294                 name++;
1295         DdePoke(dde, "OpenGroup", (tchar*)mustr(name));
1296         ClosePdic( dde );
1297 }
1298 //---------------------------------------------------------------------------
1299 // DokoPop\82Ì\90Ý\92è
1300 void TDCHookMainForm::SetupConfig()
1301 {
1302         EnableClickOnly( miClickOnly->Checked );
1303         if (hDll){
1304                 hDll->Config( -1, KA_POPUP,
1305                         Ini->ReadInteger( PFS_CONFIG, PFS_POPUPKEY, DEF_POPUPKEY ) );
1306                 hDll->Config( -1, KA_TOGGLE,
1307                         Ini->ReadInteger( PFS_CONFIG, PFS_TOGGLEKEY, DEF_TOGGLEKEY ) );
1308
1309                 SetupConfig2();
1310         }
1311         SetupAMODI();
1312 }
1313 void TDCHookMainForm::SetupConfig2()
1314 {
1315         if (!hDll)
1316                 return;
1317
1318         TDCHConfig cfg;
1319         memset(&cfg, 0, sizeof(cfg));
1320         cfg.UseAMODI = AMODIAvail && (CaptureMode & CM_IMAGE);
1321         cfg.OnlyAMODI = AMODIAvail && !(CaptureMode & CM_TEXT);
1322         cfg.MoveSend = MouseIncSrch;
1323         //cfg.OnlyImage = 1;    //TODO:
1324         if (AMODIPath.data()){
1325                 strncpy(cfg.AMODIPath, AMODIPath.c_str(), sizeof(cfg.AMODIPath)-1);
1326         }
1327
1328         int dpiDetect = Ini->ReadInteger(PFS_CONFIG, PFS_DPI_DETECT, 1);
1329         if (dpiDetect){
1330 #if DPI_DETECT
1331                 cfg.ScaleX = GetMonitorScale();
1332 #endif
1333         } else {
1334                 cfg.ScaleX = Ini->ReadInteger(PFS_CONFIG, PFS_SCALE, 0);
1335         }
1336         cfg.ScaleY = cfg.ScaleX;
1337         hDll->Config2(&cfg);
1338 }
1339 void TDCHookMainForm::SetupAMODI()
1340 {
1341         if (AMODIPath.data()){
1342                 AMODIAvail = true;
1343         } else {
1344                 HWND hwnd = FindAMODI();
1345                 if (hwnd){
1346                         AMODIAvail = true;
1347                 } else {
1348                         AMODIAvail = LaunchAMODI();
1349                         if (!AMODIAvail){
1350                                 HWND hwnd = FindAMODI();
1351                                 if (hwnd)
1352                                         AMODIAvail = true;
1353                                 else
1354                                         tmReInit->Enabled = true;       // retry later
1355                         }
1356                 }
1357         }
1358         if (AMODIAvail){
1359                 tmMODIInstallCheck->Enabled = false;
1360         }
1361 }
1362 void TDCHookMainForm::EnableClickOnly( bool enable )
1363 {
1364         if (hDll)
1365                 hDll->Config( enable, 0, 0 );
1366 }
1367 void TDCHookMainForm::DokoPopMenu( bool all )
1368 {
1369 //      Width = 0;
1370         SetForegroundWindow( Handle );
1371         POINT pt;
1372         GetCursorPos( &pt );
1373         miEnablePopup->Visible = all;
1374         miReload->Visible = !all;
1375         miClose->Visible = !all;
1376         miExit2->Visible = all;
1377         pmTrayIcon->TrackButton = tbRightButton;
1378         pmTrayIcon->Popup( pt.x, pt.y );
1379         MoveToTop( Handle );
1380 //      MoveToTop( pmTrayIcon->WindowHandle );
1381 }
1382 void TDCHookMainForm::MenuClosed()
1383 {
1384         Visible = false;
1385         ShowWindow( Application->Handle, SW_HIDE );
1386         tmMenuClose->Enabled = true;
1387 }
1388 void TDCHookMainForm::EvToggle( TMessage &msg )
1389 {
1390         miClickOnlyClick( this );
1391         ShowNotify();
1392 }
1393 void TDCHookMainForm::EvShortcut( TMessage &msg )
1394 {
1395         switch (msg.WParam){
1396                 case SCINX_NOTIFY64:
1397                         DBW("SCINX_NOTIFY64:%08X %08X", msg.LParam, hDll);
1398                         if (hDll){
1399                                 hDll->Notify64(msg.LParam);
1400                                 SetupConfig();
1401                         }
1402                         break;
1403         }
1404 }
1405 void TDCHookMainForm::EvGetVersion( TMessage &msg )
1406 {
1407         msg.Result = VersionValue;
1408 }
1409 //---------------------------------------------------------------------------
1410 // \89E\83N\83\8a\83b\83N\8c\9f\8dõON/OFF\95\\8e¦
1411 void TDCHookMainForm::ShowNotify()
1412 {
1413         POINT pt;
1414         GetCursorPos( &pt );
1415         if ( !NotifyForm ){
1416                 NotifyForm = new TNotifyForm( this );
1417         } else {
1418                 NotifyForm->Visible = false;
1419         }
1420         NotifyForm->enable = miClickOnly->Checked;
1421         NotifyForm->Left = pt.x + 8;
1422         NotifyForm->Top = pt.y + 8;
1423         NotifyForm->Setup();
1424         NotifyForm->Show();
1425         SetWindowPos( Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE );
1426         SetWindowPos( NotifyForm->Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE );
1427         tmNotify->Enabled = false;
1428         tmNotify->Enabled = true;
1429 }
1430 void TDCHookMainForm::NotifyAMODI()
1431 {
1432         MODINotifyDialog = new TMODINotifyDialog(this);
1433         MODINotifyDialog->ShowModal();
1434         if (MODINotifyDialog->LinkClicked || AMODIRunable()){
1435                 tmMODIInstallCheck->Enabled = true;
1436         }
1437         delete MODINotifyDialog;
1438 }
1439 void TDCHookMainForm::Reboot()
1440 {
1441         ::Reboot = true;
1442         Close();
1443 }
1444 void GetGroupList(TMyIni &ini, TStringList &list)
1445 {
1446         AnsiString s = ini.ReadString("Group", "::GroupNames::", "");
1447         if (s.IsEmpty()){
1448                 // for old version (not work correctly)
1449                 ini.ReadValues( "Group", &list);
1450         } else {
1451                 const TCHAR *p = _tcstok(s.c_str(), _T("\t"));
1452                 while (p){
1453                         list.Add( p );
1454                         p = _tcstok(NULL, _T("\t"));
1455                 }
1456         }
1457 }
1458