OSDN Git Service

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