OSDN Git Service

3893171a6f21e3c11b4c9625db480fe094328fec
[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         if (fWow64)
189                 tmReInit64->Enabled = true;
190 }
191 //---------------------------------------------------------------------------
192 void __fastcall TDCHookMainForm::FormCloseQuery(TObject *Sender,
193           bool &CanClose)
194 {
195         if (AMODIAvail){
196                 TerminateAMODI();
197         }
198         if (OCRTextForm){
199                 OCRTextForm->Visible = false;
200                 delete OCRTextForm;
201                 OCRTextForm = NULL;
202         }
203         RegisterTrayIcon( false );
204 #ifdef _DEBUG
205         WINDOWPLACEMENT wp;
206         wp.length = sizeof(WINDOWPLACEMENT);
207         GetWindowPlacement( Handle, &wp );
208         RECT &rc = wp.rcNormalPosition;
209         Ini->WriteInteger( PFS_MAIN, "Left", rc.left );
210         Ini->WriteInteger( PFS_MAIN, "Top", rc.top );
211         Ini->WriteInteger( PFS_MAIN, "Width", rc.right - rc.left );
212         Ini->WriteInteger( PFS_MAIN, "Height", rc.bottom - rc.top );
213 #endif
214
215         miUnhookClick( this );
216
217         delete Ini;
218         if (PopupText){
219                 delete[] PopupText;
220                 PopupText = NULL;
221         }
222 }
223 //---------------------------------------------------------------------------
224 void __fastcall TDCHookMainForm::FormKeyPress(TObject *Sender, char &Key)
225 {
226 #ifndef _DEBUG
227         if ( Key == 0x1b ){
228                 Key = 0;
229                 Start();
230         }
231 #endif
232 }
233 #if 0
234 void __fastcall TDCHookMainForm::IdleHandler(TObject *sender, bool &done)
235 {
236         if (NotifyAMODIEnabled){
237                 NotifyAMODIEnabled = false;
238                 NotifyAMODI();
239         }
240 }
241 #endif
242 //---------------------------------------------------------------------------
243 // Menu event
244 //---------------------------------------------------------------------------
245 void __fastcall TDCHookMainForm::miDicGroup(TObject *Sender)
246 {
247         // \8e«\8f\91\83O\83\8b\81[\83v
248         AnsiString name = ((TMenuItem*)Sender)->Caption;
249         if ( name.Length() ){
250                 OpenDicGroup( name.c_str() );
251         }
252 }
253 //---------------------------------------------------------------------------
254 void __fastcall TDCHookMainForm::miClickOnlyClick(TObject *Sender)
255 {
256         miClickOnly->Checked = !miClickOnly->Checked;
257         EnableClickOnly( miClickOnly->Checked );
258         MenuClosed();
259 }
260 //---------------------------------------------------------------------------
261 void __fastcall TDCHookMainForm::miIncSearchClick(TObject *Sender)
262 {
263         miIncSearch->Checked = !miIncSearch->Checked;
264         MouseIncSrch = miIncSearch->Checked;
265         Ini->WriteInteger( PFS_CONFIG, PFS_INCSRCH, MouseIncSrch );
266         SetupConfig2();
267         if (MouseIncSrch){
268                 HWND hwnd = FindPdic();
269                 if (hwnd){
270                         MoveToTop(hwnd);
271                 }
272         }
273 }
274 //---------------------------------------------------------------------------
275 #if 0   // change capture mode
276         if (!AMODIAvail && (CaptureMode & CM_IMAGE)){
277                 InitAMODI();
278         }
279         if (AMODIAvail){
280                 SetupConfig2();
281         } else {
282                 NotifyAMODI();
283         }
284
285         MenuClosed();
286 #endif
287 //---------------------------------------------------------------------------
288 void __fastcall TDCHookMainForm::miEnablePopupClick(TObject *Sender)
289 {
290         if ( miEnablePopup->Checked ){
291                 miUnhookClick( this );
292                 EnablePopup = false;
293         } else {
294                 miHookClick( this );
295                 EnablePopup = true;
296         }
297         MenuClosed();
298 }
299 //---------------------------------------------------------------------------
300 void __fastcall TDCHookMainForm::miOCRTextClick(TObject *Sender)
301 {
302         if (!OCRTextForm) OCRTextForm = new TOCRTextForm(this);
303         OCRTextForm->Visible = true;
304 }
305 //---------------------------------------------------------------------------
306 void __fastcall TDCHookMainForm::miOptionClick(TObject *Sender)
307 {
308         if (PopupConfigDlg){
309                 MoveToTop(PopupConfigDlg->Handle);
310                 return;
311         }
312
313         // Configuration //
314         PopupConfigDlg = new TPopupConfigDlg( this );
315         PopupConfigDlg->cbGroupOpen->Checked = GroupOpen;
316         PopupConfigDlg->edGroupName->Text = GroupName;
317         PopupConfigDlg->SetPopupKey( Ini->ReadInteger( PFS_CONFIG, PFS_POPUPKEY, DEF_POPUPKEY ) );
318         PopupConfigDlg->SetToggleKey( Ini->ReadInteger( PFS_CONFIG, PFS_TOGGLEKEY, DEF_TOGGLEKEY ) );
319         PopupConfigDlg->cbCtrlClose->Checked = CtrlClose;
320         PopupConfigDlg->cbIgnoreJ->Checked = IgnoreJ;
321         PopupConfigDlg->cbBanner->Checked = Banner;
322         bool useAMODI = CaptureMode & CM_IMAGE ? true : false;
323         PopupConfigDlg->SetCaptureMode( CaptureMode );
324         PopupConfigDlg->SetScaler( Ini->ReadInteger(PFS_CONFIG, PFS_SCALE, 0) );
325         PopupConfigDlg->edAMODIPath->Text = AMODIPath;
326         PopupConfigDlg->SetMODIAvail( AMODIAvail );
327         bool use64 = Ini->ReadInteger(PFS_CONFIG, PFS_USE64, DEF_USE64);
328         PopupConfigDlg->cbUse64->Checked = use64;
329         SetForegroundWindow( PopupConfigDlg->Handle );
330         if ( PopupConfigDlg->ShowModal() == IDOK ){
331                 GroupOpen = PopupConfigDlg->cbGroupOpen->Checked;
332                 GroupName = PopupConfigDlg->edGroupName->Text;
333                 CtrlClose = PopupConfigDlg->cbCtrlClose->Checked;
334                 IgnoreJ = PopupConfigDlg->cbIgnoreJ->Checked;
335                 Banner = PopupConfigDlg->cbBanner->Checked;
336                 AMODIPath = PopupConfigDlg->edAMODIPath->Text;
337                 Ini->WriteInteger( PFS_CONFIG, PFS_POPUPKEY,
338                         PopupConfigDlg->GetPopupKey() );
339                 Ini->WriteInteger( PFS_CONFIG, PFS_TOGGLEKEY,
340                         PopupConfigDlg->GetToggleKey() );
341                 CaptureMode = PopupConfigDlg->GetCaptureMode();
342                 Ini->WriteInteger( PFS_CONFIG, PFS_CAPTURE_MODE, CaptureMode );
343                 Ini->WriteInteger( PFS_CONFIG, PFS_SCALE, PopupConfigDlg->GetScaler() );
344                 Ini->WriteString(PFS_CONFIG, PFS_AMODIPATH, AMODIPath.c_str());
345                 Ini->WriteInteger(PFS_CONFIG, PFS_USE64, PopupConfigDlg->cbUse64->Checked);
346                 SaveConfig();
347                 SetupConfig();
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::tmReInit64Timer(TObject *Sender)
586 {
587         // \8f\89\89ñ\8bN\93®\8e\9e\82Ì\82Ý\82±\82Ì\8f\88\97\9d\82ð\82µ\82È\82¢\82Æpopup\82µ\82È\82¢
588         // \8dÄ\83\8d\83O\83C\83\93\8e\9e\82Í\95s\97v
589         tmReInit64->Enabled = false;
590         Unhook();
591         bool use64 = Ini->ReadInteger(PFS_CONFIG, PFS_USE64, false);
592         Ini->WriteInteger(PFS_CONFIG, PFS_USE64, !use64);
593         Hook();
594         Ini->WriteInteger(PFS_CONFIG, PFS_USE64, use64);
595 }
596 //---------------------------------------------------------------------------
597 // Mouse Events
598 //---------------------------------------------------------------------------
599 void __fastcall TDCHookMainForm::ImageMouseDown(TObject *Sender,
600           TMouseButton Button, TShiftState Shift, int X, int Y)
601 {
602         if ( BootUp ) return;
603         Capturing = true;
604         SetCapture( Handle );
605         CapPoint.x = X;
606         CapPoint.y = Y;
607 }
608 //---------------------------------------------------------------------------
609 void __fastcall TDCHookMainForm::ImageMouseMove(TObject *Sender,
610           TShiftState Shift, int X, int Y)
611 {
612         if ( Capturing ){
613                 POINT pt;
614                 GetCursorPos( &pt );
615                 Left = pt.x - CapPoint.x;
616                 Top = pt.y - CapPoint.y;
617         }
618 }
619 //---------------------------------------------------------------------------
620 void __fastcall TDCHookMainForm::ImageMouseUp(TObject *Sender,
621           TMouseButton Button, TShiftState Shift, int X, int Y)
622 {
623         if ( BootUp )
624                 Start();
625         Capturing = false;
626 }
627 //---------------------------------------------------------------------------
628 // User Functions
629 //---------------------------------------------------------------------------
630 void TDCHookMainForm::InitAMODI()
631 {
632         AMODIPath = Ini->ReadString(PFS_CONFIG, PFS_AMODIPATH, AMODIPath.c_str());
633         SetupAMODI();
634 }
635 void TDCHookMainForm::Start()
636 {
637         BootTimer->Enabled = false;
638 #ifndef _DEBUG
639         ShowWindow( Application->Handle, SW_HIDE );
640         Visible = false;
641         Width = 0;
642 #endif
643         if ( BootUp ){
644                 RegisterTrayIcon( true );
645                 miHookClick( this );
646                 BootUp = false;
647         }
648 }
649 //---------------------------------------------------------------------------
650 bool TDCHookMainForm::Hook()
651 {
652         if ( hDll ){
653                 DBW("Already hooked");
654                 return true;    // already loaded
655         }
656
657         bool use64 = Ini->ReadInteger(PFS_CONFIG, PFS_USE64, DEF_USE64);
658         hDll = new TDCHookLoader(use64);
659         if (!hDll->LoadHook(Handle)){
660                 DBW("Load failed");
661                 delete hDll;
662                 hDll = NULL;
663                 return false;
664         }
665
666         miHook->Enabled = false;
667         miUnhook->Enabled = true;
668
669         if (hDll->IsReady()){
670                 SetupConfig();
671                 extern HWND hwnd64;
672                 PostMessage(Handle, UM_SHORTCUT, SCINX_NOTIFY64, (LPARAM)hwnd64);
673         }
674
675         DBW("Hook OK");
676         
677         return true;
678 }
679 void TDCHookMainForm::Unhook()
680 {
681         if ( !hDll ) return;
682
683         hDll->UnloadHook();
684         delete hDll;
685         hDll = NULL;
686
687         miHook->Enabled = true;
688         miUnhook->Enabled = false;
689 }
690 //---------------------------------------------------------------------------
691 #ifdef _DEBUG
692 // 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·
693 int GetTextFromPoint( HDC hdc, const char *text, int pos )
694 {
695         int len = lstrlen(text);
696         int left = 0;
697         int right = len;
698         SIZE sz;
699         int loc;
700         for(;;){
701                 loc = (right + left)/2;
702                 if ( right - left <= 1 ){
703                         break;
704                 }
705                 GetTextExtentPoint32A( hdc, text, loc, &sz );
706 //              DBW("%08X %d %d %d %d", hdc, left, right, loc, sz.cx);
707                 if ( pos < sz.cx ){
708                         right = loc;
709                 } else {
710                         left = loc;
711                 }
712         }
713         return (right+left)/2;
714 }
715 int GetTextFromPoint( HDC hdc, const wchar_t *text, int pos )
716 {
717         int len = lstrlenW(text);
718         int left = 0;
719         int right = len;
720         SIZE sz;
721         int loc;
722         for(;;){
723                 loc = (right + left)/2;
724                 if ( right - left <= 1 ){
725                         break;
726                 }
727                 GetTextExtentPoint32W( hdc, text, loc, &sz );
728 //              DBW("%08X %d %d %d %d", hdc, left, right, loc, sz.cx);
729                 if ( pos < sz.cx ){
730                         right = loc;
731                 } else {
732                         left = loc;
733                 }
734         }
735         return (right+left)/2;
736 }
737 #endif
738 void TDCHookMainForm::EvCopyData(TMessage& msg )
739 {
740         COPYDATASTRUCT *cds = (COPYDATASTRUCT*)msg.LParam;
741         if ( !cds ){ return; }
742         switch ( cds->dwData ){
743                 case DCH_MOVESEND:
744                         //DBW("DCH_MOVESEND");
745                         // mouse move message
746                         EvMoveSend(msg.WParam==0);
747                         break;
748                 case DCH_START:
749                         CursorPoint = *(POINT*)cds->lpData;
750 #ifdef _DEBUG
751                         PaintBox->Canvas->FillRect( PaintBox->Canvas->ClipRect );
752 #endif
753                         if (PopupText){
754                                 delete[] PopupText;
755                                 PopupText = NULL;
756                         }
757                         break;
758                 case DCH_END:
759                 case DCH_END | DCH_MOVESEND:
760                         if ( PopupText ){
761                                 PopupMoveSend = cds->dwData & DCH_MOVESEND ? true : false;
762                                 PostMessage( Handle, WM_POPUP, PopupLoc | (PopupMoveSend ? FLG_MOVESEND : 0), (LPARAM)PopupText );
763                                 if (OCRTextForm) OCRTextForm->SetText(PopupText);
764                                 PopupText = NULL;       // release ownership
765                         }
766                         break;
767                 case DCH_HITTEXT1:      // single char
768                 {
769                         DBW("DCH_HITTEXT1");
770                         if (PopupText)
771                                 delete[] PopupText;
772 #ifdef USE_UNICODE
773                         // ANSI -> Unicode
774                         //*+++ \93®\8dì\96¢\8am\94F 2002.12.4
775                         PopupText = new tchar[ cds->cbData*2 + 1 ];
776                         // \91O\94¼\95\94\95ª
777                         PopupLoc = MultiByteToWideChar( CP_ACP, 0,
778                                 (LPCSTR)cds->lpData, msg.WParam, PopupText, cds->cbData*2 );
779                         // \8cã\94¼\95\94\95ª
780                         int r = MultiByteToWideChar( CP_ACP, 0,
781                                 &((char*)cds->lpData)[msg.WParam], cds->cbData-msg.WParam, &PopupText[PopupLoc], cds->cbData-PopupLoc );
782                         PopupText[PopupLoc+r] = '\0';
783 #else   // !USE_UNICODE
784                         PopupText = new tchar[ cds->cbData + 1 ];
785                         memcpy( PopupText, cds->lpData, cds->cbData );
786                         PopupText[cds->cbData] = '\0';
787                         PopupLoc = msg.WParam;
788 #ifdef _DEBUG
789                         Memo->Lines->Add( PopupText );
790                         edFound->Text = PopupText + msg.WParam;
791                         TestTimer->Enabled = true;
792                         if ( DCDebug ){
793                                 char *p = (char*)DCDebug( );
794                                 memcpy( share, p, COMPSIZE );
795                         }
796 #endif
797 #endif
798                 }
799                         break;
800                 case DCH_HITTEXT2:      // wide char
801                 {
802                         DBW("DCH_HITTEXT2");
803                         if (PopupText)
804                                 delete[] PopupText;
805 #ifdef USE_UNICODE
806                         PopupText = new tchar[ cds->cbData + 1 ];
807                         memcpy( PopupText, cds->lpData, cds->cbData );
808                         PopupText[cds->cbData/sizeof(tchar)] = '\0';
809                         PopupLoc = msg.WParam;
810 #else   // !USE_UNICODE
811                         // Unicode -> ANSI
812                         //*+++ \93®\8dì\96¢\8am\94F 2002.12.4
813                         PopupText = new tchar[ cds->cbData + 1 ];
814                         // \91O\94¼\95\94\95ª
815                         BOOL defchar;
816                         PopupLoc = WideCharToMultiByte( CP_ACP, 0,
817                                 (wchar_t*)cds->lpData, msg.WParam,
818                                 PopupText, cds->cbData, 0, &defchar );
819                         // \8cã\94¼\95\94\95ª
820                         int r = WideCharToMultiByte( CP_ACP, 0,
821                                 &((wchar_t*)cds->lpData)[msg.WParam], (cds->cbData>>1)-msg.WParam,
822                                 &PopupText[PopupLoc], cds->cbData-PopupLoc, 0, &defchar );
823                         PopupText[PopupLoc+r] = '\0';
824 #endif
825                 }
826                         break;
827 #ifdef _DEBUG
828                 case DCH_EXTTEXTOUTA:
829                 case DCH_EXTTEXTOUTW:
830                 {
831                         EMREXTTEXTOUTW *emr = (EMREXTTEXTOUTW*)cds->lpData;
832                         wchar_t *p = (wchar_t*) ( ((char*)emr) + emr->emrtext.offString );
833                         char *buf = NULL;
834 #if 0
835                         char b[200];
836                         sprintf(b,"exScale=%f eyScale=%f ptlReference=(%d,%d)",emr->exScale, emr->eyScale, emr->emrtext.ptlReference.x, emr->emrtext.ptlReference.y );
837                         DBW(b);
838 #endif
839                         if ( cds->dwData == DCH_EXTTEXTOUTW ){
840                                 buf = new char[ emr->emrtext.nChars * 2 ];
841                                 memset( buf, 0, emr->emrtext.nChars*2 );
842                                 WideCharToMultiByte( CP_ACP, 0, p, emr->emrtext.nChars, buf, emr->emrtext.nChars * 2, NULL, NULL );
843                         }
844                         const char *text = buf ? buf : (char*)p;
845                         Memo->Lines->Add( text );
846                         PaintBox->Canvas->TextOut( emr->rclBounds.left, emr->rclBounds.top, text );
847
848                         if ( PtInRect( (RECT*)&emr->rclBounds, CursorPoint ) ){
849                                 int loc = GetTextFromPoint( (HDC)msg.WParam, text, CursorPoint.x - emr->rclBounds.left );
850                                 if ( loc != -1 ){
851                                         edFound->Text = text + loc;
852                                 }
853                         }
854                         if ( buf )
855                                 delete[] buf;
856                 }
857                         break;
858 #endif
859                 case DCH_MENU:
860                         DokoPopMenu( false );
861                         break;
862                 case DCH_TOGGLE:
863                         PostMessage( Handle, WM_TOGGLE, 0, 0 );
864                         break;
865                 case WMCD_EXISTCHECK:   // exist check
866                         if ( cds->cbData != strlen(APPNAME)+1 ){
867                                 msg.Result = false;
868                                 return;
869                         }
870                         msg.Result = (memcmp( cds->lpData, APPNAME, strlen(APPNAME)+1 ) == 0);
871                         return;
872                 case DCH_LAUNCH_AMODI:
873                         SetupAMODI();
874                         //Reboot();             // AMODI.exe\8dÄ\8bN\93®\82Å\82Í\89ð\8c\88\82Å\82«\82È\82¢\82½\82ß
875                         break;
876         }
877         return;
878 }
879 //---------------------------------------------------------------------------
880 bool WaitTransaction( TDdeClientConv *dde )
881 {
882 #if 1
883         for ( int i=0;i<100000;i++ ){
884                 Application->ProcessMessages();
885                 if ( !dde->WaitStat ){
886 //                      DBW("DCHook:Wait OK");
887                         return true;
888                 }
889         }
890         DBW("DCHook:Wait failure");
891         return false;
892 #else
893         return true;
894 #endif
895 }
896 // ANSI\82Å\93n\82·\8fê\8d\87
897 bool DdePoke( TDdeClientConv *dde, AnsiString Item, AnsiString Data )
898 {
899 #ifdef USE_UNICODE
900         int ansilen = Data.Length();
901         wchar_t *buf = new wchar_t[ansilen*2+1];
902         int len = MultiByteToWideChar( CP_ACP, 0,
903                 (LPCSTR)Data.c_str(), ansilen, buf, ansilen*2 );
904         buf[len] = '\0';
905         bool r = DdePoke( dde, Item, (wchar_t*)buf );
906         delete[] buf;
907         return r;
908 #else   // !USE_UNICODE
909         HSZ hszItem = DdeCreateStringHandle(ddeMgr->DdeInstId, Item.c_str(), CP_WINANSI );
910         if ( !hszItem ) return false;
911         HDDEDATA hszDat = DdeCreateDataHandle( ddeMgr->DdeInstId, Data.c_str(), Data.Length() + 1,
912                 0, hszItem, dde->DdeFmt, 0);
913         bool r = false;
914         if ( hszDat ){
915                 HDDEDATA hdata = DdeClientTransaction( (LPBYTE)hszDat, (DWORD)-1, (HCONV)dde->Conv, hszItem,
916                 dde->DdeFmt, XTYP_POKE, 10000, NULL);
917                 r = hdata ? true : false;
918         }
919         DdeFreeStringHandle (ddeMgr->DdeInstId, hszItem);
920         return r;
921 #endif
922 }
923 #ifdef USE_UNICODE
924 // Unicode\82Å\93n\82·\8fê\8d\87
925 bool DdePoke( TDdeClientConv *dde, AnsiString Item, const wchar_t *Data )
926 {
927         // Item\96¼\82ÍANSI\81A\83f\81[\83^\82ÍUNICODE //
928         int ddeFmt = /*dde->DdeFmt*/CF_UNICODETEXT;
929         HSZ hszItem = DdeCreateStringHandle(ddeMgr->DdeInstId, Item.c_str(), CP_WINANSI );
930         if ( !hszItem ) return false;
931         HDDEDATA hszDat = DdeCreateDataHandle( ddeMgr->DdeInstId, (LPBYTE)Data, (_tcslen(Data)+1)*sizeof(wchar_t),
932                 0, hszItem, ddeFmt, 0);
933         bool r = false;
934         if ( hszDat ){
935                 HDDEDATA hdata = DdeClientTransaction( (LPBYTE)hszDat, (DWORD)-1, (HCONV)dde->Conv, hszItem,
936                 ddeFmt, XTYP_POKE, 10000, NULL);
937                 r = hdata ? true : false;
938         }
939         DdeFreeStringHandle (ddeMgr->DdeInstId, hszItem);
940         return r;
941 }
942 #endif
943 TDdeClientConv *TDCHookMainForm::OpenPdic( const char *topic )
944 {
945         TDdeClientConv *PdicDde = new TDdeClientConv( this );
946
947         PdicDde->ConnectMode = ddeManual;
948         static int entry = 0;
949         PdicDde->Name = AnsiString("PdicDde") + (++entry);
950         PdicDde->ServiceApplication = DDE_SERVICE_NAME;
951         if ( !PdicDde->SetLink( DDE_SERVICE_NAME, topic ) ){
952                 DBW("DCHook:Cannot SetLink");
953                 delete PdicDde;
954                 return NULL;
955         }
956         if ( !PdicDde->OpenLink( ) ){   // \82±\82±\82ª\92x\82¢\81I\81I
957                 // PDIC auto launch
958                 if ( LaunchPdic() ){
959                         for(int i=0;i<OPEN_RETRY;i++){
960                                 if ( PdicDde->OpenLink() ){
961                                         return PdicDde;
962                                 }
963                                 Sleep(OPEN_WAITTIME);
964                         }
965                 }
966                 DBW("PDIC\82ª\8c©\82Â\82©\82è\82Ü\82¹\82ñ(OpenPdic)");
967                 Application->MessageBox( "PDIC\82ª\8c©\82Â\82©\82è\82Ü\82¹\82ñ(OpenPdic)", APPNAME, MB_OK );
968                 delete PdicDde;
969                 return NULL;
970         }
971         return PdicDde;
972 }
973 #ifdef USE_UNICODE
974 static const TCHAR *clsname = TEXT("TPdicMain.UnicodeClass");
975 #else
976 static const TCHAR *clsname = TEXT(DDE_SERVICE_NAME);
977 #endif
978 static const TCHAR *winname = NULL;
979 HWND TDCHookMainForm::FindPdic( )
980 {
981         HWND hWin = FindWindow( clsname, winname );
982         if ( !hWin ){
983                 // PDIC auto launch
984                 if ( LaunchPdic() ){
985                         hWin = FindWindow( clsname, winname );
986                         if ( !hWin ){
987                                 DBW("PDIC\82ª\8c©\82Â\82©\82è\82Ü\82¹\82ñ(FindPdic)");
988                                 Application->MessageBox( "PDIC\82ª\8c©\82Â\82©\82è\82Ü\82¹\82ñ(FindPdic)", APPNAME, MB_OK );
989                                 return NULL;
990                         }
991                 }
992         }
993         return hWin;
994 }
995 #if !USE_DDE
996 LRESULT TDCHookMainForm::SendCopyData( HWND hwnd, int message, const char *str )
997 {
998         COPYDATASTRUCT cds;
999         cds.dwData = message;
1000         cds.lpData = (LPSTR)str;
1001         cds.cbData = lstrlen(str)+1;
1002         SendMessage( hwnd, WM_COPYDATA, (WPARAM)Handle, (LPARAM)&cds );
1003 }
1004 #endif
1005 void TDCHookMainForm::ClosePdic( TDdeClientConv *dde )
1006 {
1007         dde->CloseLink();
1008         delete dde;
1009 }
1010 bool TDCHookMainForm::DoPopup( const tchar *text, const tchar *prevtext, bool movesend )
1011 {
1012         static int ct = 0;
1013         if ( ct >= 1 ){
1014                 if (PopupText){
1015                         // already pending
1016                         DBW("Reentrant!!!!!");
1017                         return true;
1018                 }
1019                 HWND hwnd = FindPopupWindow( );
1020                 if (hwnd){
1021                         HWND hwndParent = GetParent( hwnd );
1022                         if (hwndParent){
1023                                 DBW("Parent exist!!!!");
1024                                 hwnd = hwndParent;
1025                         }
1026                         DBW("Retry again:%d:%08X",ct,hwnd);
1027                         // \95K\82¸PostMessage()\82Åclose\82·\82é\82±\82Æ\81B
1028                         // CloseWindow()\82Å\82ÍPopup Winodow\82Ì\8f\89\8aú\89»\92\86\82É
1029                         // close\8f\88\97\9d\82ð\8eÀ\8ds\82µ\82Ä\82µ\82Ü\82¢\81A
1030                         // popup window\82ª\82¨\82©\82µ\82È\8fó\91Ô\82É\82Í\82¢\82Á\82Ä\82µ\82Ü\82¤\8fê\8d\87\82ª\82 \82é
1031                         PostMessage( hwnd, WM_CLOSE, 0, 0 );
1032                         return false;
1033                 } else {
1034                         if (ct >= 1 ){
1035                                 DBW("Not found popup window");
1036                                 if (DoPopupRetry++ > 10){
1037                                         DoPopupRetry = 0;
1038                                         return true;    // abort
1039                                 } else {
1040                                         return false;   // retry
1041                                 }
1042                         }
1043                 }
1044         }
1045         DoPopupRetry = 0;
1046         ct++;
1047
1048 #if USE_DDE
1049         // Windows9x\82Å\82Í\81ADDE transaction\82ª\92x\82¢\82Æ\82«\82ª\82 \82é
1050         // why? - because of 24bit OS:-)
1051         // ->\82Æ\8ev\82Á\82Ä\81AWM_COPYDATA version\82ð\8dì\82Á\82Ä\82¢\82½\82ç\91¬\82­\82È\82Á\82½\81H\81H\81H
1052         // ->WM_COPYDATA\89» project\82Í\92\86\92f
1053         TDdeClientConv *PdicDde;
1054         bool r;
1055
1056         if (movesend){
1057                 // incremental search
1058                 PdicDde = OpenPdic("Simulate");
1059                 if (!PdicDde){
1060                         ct--;
1061                         return true;
1062                 }
1063                 r = DdePoke(PdicDde, "InputWord3", text);
1064                 if (!r){
1065                         DBW("PDIC DDE : InputWord3 failure");
1066                         delete PdicDde;
1067                         ct--;
1068                         return true;
1069                 }
1070         } else {
1071                 // popup
1072                 if (GroupOpen){
1073                         PdicDde = OpenPdic( "Simulate" );
1074                         if (PdicDde){
1075                                 DdePoke( PdicDde, "Open", GroupName );
1076                                 PdicDde->CloseLink();
1077                                 delete PdicDde;
1078                         }
1079                 }
1080                 PdicDde = OpenPdic( "Dictionary" );
1081                 if ( !PdicDde ){
1082                         ct--;
1083                         return true;
1084                 }
1085
1086                 r = DdePoke( PdicDde, "Open", "" );
1087                 if ( !r ){
1088                         DBW("PDIC DDE : Open failure");
1089                         PdicDde->CloseLink();
1090                         delete PdicDde;
1091                         ct--;
1092                         if ( GroupOpen ){
1093                                 static int ct = 0;
1094                                 ct++;
1095                                 if ( ct == 1 ){
1096                                         Application->MessageBox(
1097                                                 "\8e«\8f\91\83O\83\8b\81[\83v\82ª\8aJ\82¯\82Ü\82¹\82ñ\r"
1098                                                 "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"
1099                                                 "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"
1100                                                 "\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"
1101                                                 "\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·"
1102                                                 ,
1103                                                 APPNAME, MB_OK );
1104                                 } else {
1105                                         SetForegroundWindow( Handle );
1106                                 }
1107                                 ct--;
1108                         }
1109                         return true;
1110                 }
1111                 if ( CtrlClose )
1112                         DdePoke( PdicDde, "PopupSearchConfig", "c1" );  // Ctrl close
1113         //      Sleep(1000);
1114                 DdePoke( PdicDde, "PopupSearchConfig", "o1w1" );        // overlap window and no wait transaction
1115                 if ( prevtext && (prevtext != text) ){
1116                         //DBW("prevtext="FMTS,prevtext);
1117                         DdePoke( PdicDde, "PopupSearch2", (tchar*)prevtext );
1118         //              ExecuteMacro( "PopupSearch2", true );
1119                         WaitTransaction( PdicDde );
1120                 } else {
1121                         //DBW("text="FMTS,text);
1122                         DdePoke( PdicDde, "PopupSearch", (tchar*)text );
1123         //              PdicDde->ExecuteMacro( "PopupSearch", true );
1124                         WaitTransaction( PdicDde );
1125                 }
1126                 DdePoke( PdicDde, "Close", "" );
1127         }
1128         ClosePdic( PdicDde );
1129 #else   // !USE_DDE
1130                 // WM_COPYDATA\82É\82æ\82é\95û\96@(\82Ü\82¾document\89»\82³\82ê\82Ä\82¢\82È\82¢\95û\96@(Ver.4.30)
1131                 // PDIC/W32 Ver.4.22\81`\82É\91Î\89\9e
1132                 // \82½\82¾\82µ\81AVer.4.29\82Ü\82Å\82Í\81AWMCD_POPUPSEARCH\82ÆWMCD_POPUPSEARCH2\82Í\93¯\82
1133
1134         // WM_COPYDATA code //
1135         // \88È\89º\82Ì\90\94\92l\82Í\8f«\97\88\95Ï\82í\82é\89Â\94\\90«\82ª\82 \82é(undocumented) //
1136         #define WMCD_GETVERSION         0x0001
1137         #define WMCD_CHECKOPEN          0x0010
1138         #define WMCD_AUTOSEARCH         0x0020
1139         #define WMCD_AUTOSEARCHMODE     0x0021
1140
1141         #define WMCD_ISOPENED                   0x0080
1142         #define WMCD_CLOSE                              0x0081
1143
1144         #define WMCD_POPUPSEARCH                0x0100
1145         #define WMCD_POPUPSEARCH2               0x0101
1146         #define WMCD_POPUPSEARCHPOINT   0x0102
1147         #define WMCD_POPUPSEARCHCONFIG  0x0103
1148         #define WMCD_POPUPSEARCHDIALOG  0x0104
1149         #define WMCD_POPUPSEARCHWINDOW  0x0105
1150
1151         #define WMCD_SPELLCHECK                 0x0110
1152
1153         HWND hwnd = FindPdic();
1154         if ( !hwnd ){
1155                 ct--;
1156                 return;
1157         }
1158
1159         bool r;
1160         if ( CtrlClose )
1161                 SendCopyData( hwnd, WMCD_POPUPSEARCHCONFIG, "c1" );
1162         POINT pt;
1163         GetCursorPos( &pt );
1164         char buf[20];
1165         wsprintf( buf, "%d,%d", pt.x, pt.y );
1166         SendCopyData( hwnd, WMCD_POPUPSEARCHPOINT, buf );
1167         if ( prevtext && (prevtext != text) ){
1168                 DBW("prevtext=%s",prevtext);
1169                 SendCopyData( hwnd, WMCD_POPUPSEARCH2, prevtext );
1170         } else {
1171                 DBW("text=%s",text);
1172                 SendCopyData( hwnd, WMCD_POPUPSEARCH, text );
1173         }
1174         SendCopyData( hwnd, WMCD_CLOSE, "" );
1175 #endif  // !USE_DDE
1176         ct--;
1177         DBW("DCHook:Exit Popup:%d",ct);
1178
1179 #if DETACHRELEASE
1180         if ( EnablePopup ){
1181                 miUnhookClick( this );
1182                 miHookClick( this );
1183         }
1184 #endif
1185         return true;
1186 }
1187 //---------------------------------------------------------------------------
1188 // EvPopup
1189 // WParam : text location & FLG_MOVESEND
1190 // LParam : text pointer (must be freed when done)
1191 void TDCHookMainForm::EvPopup(TMessage &msg)
1192 {
1193         //DBW("EvPopup");
1194         if (!msg.LParam)
1195                 return;
1196
1197         tchar *text = (tchar*)msg.LParam;
1198         int loc = msg.WParam & ~FLG_MOVESEND;
1199         bool movesend = msg.WParam & FLG_MOVESEND ? true : false;
1200         
1201         int start, end;
1202         int prevstart;
1203         if ( !GetWord( text, loc, start, end, prevstart, true, 10, true, IgnoreJ ) ){
1204                 // no words
1205                 delete[] text;
1206                 return;
1207         }
1208 #ifdef _DEBUG
1209         edWord->Text = text + start;
1210         edPrev->Text = loc + prevstart;
1211 #endif
1212
1213         if (DoPopup( text + start, text + prevstart, movesend )){
1214                 // done
1215                 delete[] text;
1216         } else {
1217                 // retry again
1218                 if (PopupText)
1219                         delete[] PopupText;     // \82 \82Æ\82É\97\88\82½\82Ù\82¤\82ð\97D\90æ\82·\82é
1220                 PopupText = text;
1221                 PopupLoc = loc;
1222                 PopupMoveSend = movesend;
1223                 tmPopup->Enabled = true;        // start timer for delayed popup
1224         }
1225         //DBW("EvPopup - end");
1226 }
1227 void TDCHookMainForm::EvMoveSend(TMessage &msg)
1228 {
1229         EvMoveSend(msg.WParam==0);
1230 }
1231 void TDCHookMainForm::EvMoveSend(bool enable)
1232 {
1233         tmMouseMove->Enabled = false;
1234         if (enable){
1235                 tmMouseMove->Enabled = true;
1236         }
1237 }
1238 void TDCHookMainForm::RegisterTrayIcon( bool flag )
1239 {
1240   NOTIFYICONDATA m_tnid;  //\82±\82ê\82Í*.h\82Å\92è\8b`\82µ\82Ä\82¨\82­
1241
1242   m_tnid.cbSize = sizeof(NOTIFYICONDATA);
1243   m_tnid.hWnd = Handle;
1244   m_tnid.uID = 1;
1245   m_tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
1246   m_tnid.uCallbackMessage = WM_NOTIFYICON;
1247   // Get small icon from me
1248   HICON hIconSm;
1249   HICON hIcon;
1250   ExtractIconEx( Application->ExeName.c_str(), -2, &hIcon, &hIconSm, 1 );
1251   m_tnid.hIcon = hIconSm;
1252   lstrcpy(m_tnid.szTip, APPNAME );
1253   Shell_NotifyIcon( flag ? NIM_ADD : NIM_DELETE, &m_tnid);
1254 }
1255 void TDCHookMainForm::EvNotifyIcon(TMessage &msg)
1256 {
1257         //UINT uID = (UINT) msg.WParam;
1258         UINT uMouseMsg = (UINT) msg.LParam;
1259         if (uMouseMsg == WM_LBUTTONDBLCLK)
1260         {
1261                 miOptionClick( this );
1262         }
1263         else if (uMouseMsg == WM_RBUTTONDOWN)
1264         {
1265                 DokoPopMenu( true );
1266         }
1267 }
1268 //---------------------------------------------------------------------------
1269 void TDCHookMainForm::SaveConfig()
1270 {
1271         Ini->WriteInteger( PFS_CONFIG, PFS_GROUPOPEN, GroupOpen );
1272         Ini->WriteString( PFS_CONFIG, PFS_GROUPNAME, GroupName.c_str() );
1273         Ini->WriteInteger( PFS_CONFIG, PFS_CTRLCLOSE, CtrlClose );
1274         Ini->WriteInteger( PFS_CONFIG, PFS_IGNOREJ, IgnoreJ );
1275         Ini->WriteInteger( PFS_CONFIG, PFS_BANNER, Banner );
1276 }
1277 void TDCHookMainForm::OpenDicGroup( const char *name )
1278 {
1279         TDdeClientConv *dde = OpenPdic( PFS_PDIC );
1280         if ( !dde )
1281                 return;
1282         // \8e«\8f\91\83O\83\8b\81[\83v\83I\81[\83v\83\93\8f\88\97\9d //
1283         if ( name[0] == '&' )
1284                 name++;
1285         DdePoke(dde, "OpenGroup", (tchar*)mustr(name));
1286         ClosePdic( dde );
1287 }
1288 //---------------------------------------------------------------------------
1289 // DokoPop\82Ì\90Ý\92è
1290 void TDCHookMainForm::SetupConfig()
1291 {
1292         EnableClickOnly( miClickOnly->Checked );
1293         if (hDll){
1294                 hDll->Config( -1, KA_POPUP,
1295                         Ini->ReadInteger( PFS_CONFIG, PFS_POPUPKEY, DEF_POPUPKEY ) );
1296                 hDll->Config( -1, KA_TOGGLE,
1297                         Ini->ReadInteger( PFS_CONFIG, PFS_TOGGLEKEY, DEF_TOGGLEKEY ) );
1298
1299                 SetupConfig2();
1300         }
1301         SetupAMODI();
1302 }
1303 void TDCHookMainForm::SetupConfig2()
1304 {
1305         if (!hDll)
1306                 return;
1307
1308         TDCHConfig cfg;
1309         memset(&cfg, 0, sizeof(cfg));
1310         cfg.UseAMODI = AMODIAvail && (CaptureMode & CM_IMAGE);
1311         cfg.OnlyAMODI = AMODIAvail && !(CaptureMode & CM_TEXT);
1312         cfg.MoveSend = MouseIncSrch;
1313         //cfg.OnlyImage = 1;    //TODO:
1314         if (AMODIPath.data()){
1315                 strncpy(cfg.AMODIPath, AMODIPath.c_str(), sizeof(cfg.AMODIPath)-1);
1316         }
1317
1318         int dpiDetect = Ini->ReadInteger(PFS_CONFIG, PFS_DPI_DETECT, 1);
1319         if (dpiDetect){
1320 #if DPI_DETECT
1321                 cfg.ScaleX = GetMonitorScale();
1322 #endif
1323         } else {
1324                 cfg.ScaleX = Ini->ReadInteger(PFS_CONFIG, PFS_SCALE, 0);
1325         }
1326         cfg.ScaleY = cfg.ScaleX;
1327         hDll->Config2(&cfg);
1328 }
1329 void TDCHookMainForm::SetupAMODI()
1330 {
1331         if (AMODIPath.data()){
1332                 AMODIAvail = true;
1333         } else {
1334                 HWND hwnd = FindAMODI();
1335                 if (hwnd){
1336                         AMODIAvail = true;
1337                 } else {
1338                         AMODIAvail = LaunchAMODI();
1339                         if (!AMODIAvail){
1340                                 HWND hwnd = FindAMODI();
1341                                 if (hwnd)
1342                                         AMODIAvail = true;
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