OSDN Git Service

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