1 //---------------------------------------------------------------------------
9 //---------------------------------------------------------------------------
10 const char *AppName = "DokoPop";
11 const char *StrVersion = "Ver.2.0.27";
12 int VersionValue = 0x02001B; // xxyyzz -> xx.yy.zz x=major y=minor(0-255) z=release(0-255)
14 #pragma package(smart_init)
17 const char APPNAME[] = {"DokoPop/Unicode"};
19 const char APPNAME[] = {"DokoPop"};
22 const char *AMODI_EXE_PATH = "amodi.exe";
23 //const char *AMODI_EXE_PATH = "\\src\\amodi\\amodi\\bin\\Debug\\amodi.exe";
25 const char *EXMODIST_EXE_PATH = "ExMODIst.exe";
27 bool WindowsNT = false;
32 HKEY OpenKey( HKEY hkey, const char *keyname )
35 if ( RegOpenKeyEx( hkey, keyname, 0, KEY_ALL_ACCESS, &newkey ) == ERROR_SUCCESS ){
41 HKEY CreateKey( HKEY hkey, const char *keyname )
45 if ( RegCreateKeyEx( hkey, keyname, 0, (LPTSTR)keyname, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, &result ) == ERROR_SUCCESS ){
50 DWORD GetValueLength( HKEY hkey, const char *name )
53 if ( RegQueryValueEx( hkey, (LPTSTR)name, 0, NULL, NULL, &len ) == ERROR_SUCCESS ){
59 DWORD ReadInteger( HKEY hkey, const char *name, DWORD val )
61 DWORD len = sizeof(DWORD);
63 if ( RegQueryValueEx( hkey, (LPTSTR)name, 0, NULL, (LPBYTE)&v, &len ) == ERROR_SUCCESS ){
68 AnsiString ReadString( HKEY hkey, const char *name, const char *def )
70 DWORD len = GetValueLength( hkey, name );
72 char *buf = new char[ len ];
73 if ( RegQueryValueEx( hkey, (LPTSTR)name, 0, NULL, (LPBYTE)buf, &len ) == ERROR_SUCCESS ){
82 TMyIni::TMyIni( HKEY root, const char *soft, bool can_create )
84 hroot = can_create ? CreateKey( root, soft ) : OpenKey( root, soft );
92 void TMyIni::WriteInteger( const char *section, const char *key, int val )
94 HKEY hkey = CreateKey( hroot, section );
96 RegSetValueEx( hkey, (LPCTSTR)key, 0, REG_DWORD, (LPBYTE)&val, sizeof(DWORD) );
100 int TMyIni::ReadInteger( const char *section, const char *key, int val )
102 HKEY hkey = OpenKey( hroot, section );
104 DWORD len = sizeof(DWORD);
106 if ( RegQueryValueEx( hkey, (LPTSTR)key, 0, NULL, (LPBYTE)&v, &len ) == ERROR_SUCCESS ){
112 void TMyIni::WriteString( const char *section, const char *key, const char *str )
116 hkey = CreateKey( hroot, section );
117 if ( !section || hkey ){
118 RegSetValueEx( hkey, (LPCTSTR)key, 0, REG_SZ, (LPBYTE)str, lstrlen(str)+1 );
122 AnsiString TMyIni::ReadString( const char *section, const char *key, const char *str )
126 hkey = OpenKey( hroot, section );
127 if ( !section || hkey ){
128 DWORD len = GetValueLength( hkey, key );
130 char *buf = new char[ len ];
131 if ( RegQueryValueEx( hkey, (LPTSTR)key, 0, NULL, (LPBYTE)buf, &len ) == ERROR_SUCCESS ){
142 #define NAMEBUFFSIZE 512
143 BOOL QueryInfoKey( HKEY hkey, DWORD *maxvalue, DWORD *maxdata );
144 BOOL EnumValue( HKEY hkey, DWORD index, AnsiString &name, void *pbuffer=NULL, DWORD *maxlen=NULL, DWORD *type=NULL );
146 void TMyIni::ReadValues( const char *section, TStrings *strs )
150 HKEY hkey = OpenKey( hroot, section );
154 if ( !QueryInfoKey( hkey, &maxvaluename, &maxvaluedata ) ){
155 //
\93®
\82©
\82È
\82¢
\81I
\81I
\81I
157 maxvaluedata = 4096; //
\93K
\93\96\81I
\81I
161 char *buf = new char[ maxvaluedata + 1 ];
162 for ( int i=0;;i++ ){
163 DWORD maxlen = maxvaluedata + 1;
164 if ( !EnumValue( hkey, i, _entry, buf, &maxlen ) )
176 :super(HKEY_CURRENT_USER, REG_PDICEXE, false)
180 super::super(HKEY_CURRENT_USER, REG_PDICEXE, false);
185 const char *sLeft = "Left";
186 const char *sTop = "Top";
187 const char *sWidth = "Width";
188 const char *sHeight = "Height";
190 void LoadForm( const char *section, TForm *form, HWND hwnd )
194 GetWindowRect( hwnd, &rc );
196 rc.left = rc.top = 0;
198 form->Left = Ini->ReadInteger(section, sLeft, form->Left) + rc.left;
199 form->Top = Ini->ReadInteger(section, sTop, form->Top ) + rc.top;
201 GetScreenSize(form->Handle?form->Handle:hwnd, &rcScr);
202 int sx = rcScr.right - rcScr.left;
203 int sy = rcScr.bottom - rcScr.top;
205 switch ( form->BorderStyle ){
209 form->Width = Ini->ReadInteger( section, sWidth, form->Width );
210 form->Height = Ini->ReadInteger( section, sHeight, form->Height );
213 //
\89æ
\96Ê
\82Ì
\8aO
\82©
\82Ç
\82¤
\82©
\81H
214 if (form->Left+form->Width >= sx){
216 form->Left = sx - form->Width;
218 if (form->Left < rcScr.left){
220 form->Left = rcScr.left;
222 if (form->Top+form->Height >= sy){
224 form->Top = sy - form->Height;
226 if (form->Top < rcScr.top){
228 form->Top = rcScr.top;
231 void SaveForm( const char *section, TForm *form, HWND hwnd )
235 GetWindowRect( hwnd, &rc );
237 rc.left = rc.top = 0;
239 Ini->WriteInteger( section, sLeft, form->Left - rc.left );
240 Ini->WriteInteger( section, sTop, form->Top - rc.top );
241 switch ( form->BorderStyle ){
245 Ini->WriteInteger( section, sWidth, form->Width );
246 Ini->WriteInteger( section, sHeight, form->Height );
251 BOOL QueryInfoKey( HKEY hkey, DWORD *maxvalue, DWORD *maxdata )
253 char *classname = new char[ 512 ]; //
\82±
\82ñ
\82È
\82à
\82ñ
\82Å
\82¢
\82¢
\82©
\82È
\82\9f\81H
254 DWORD classnamesize = 512;
261 DWORD SecurityDescriptor;
262 FILETIME LastWriteTime;
263 if ( ::RegQueryInfoKey( hkey, classname, &classnamesize,
273 ) != ERROR_SUCCESS ){
278 *maxvalue = MaxValueName;
280 *maxdata = MaxValueData;
284 BOOL EnumValue( HKEY hkey, DWORD index, AnsiString &name, void *pbuffer, DWORD *maxlen, DWORD *type )
286 char *buffer = new char[ NAMEBUFFSIZE ];
287 DWORD buflen = NAMEBUFFSIZE;
288 if ( RegEnumValue( hkey, index, buffer, &buflen, 0, type, (LPBYTE)pbuffer, maxlen ) == ERROR_SUCCESS ){
296 bool CheckPassword( const char *str )
302 s = Ini->ReadString( "Main", "PW", "" );
308 typedef BOOL WINAPI (*FNIsWow64Process)(HANDLE hProcess, PBOOL Wow64Process);
310 FNIsWow64Process _IsWow64Process = (FNIsWow64Process)GetProcAddress(GetModuleHandle("kernel32"),"IsWow64Process");
311 if (_IsWow64Process){
313 if (_IsWow64Process(GetCurrentProcess(), &flag)){
318 void MoveToTop( HWND hwnd )
320 if ( IsIconic( hwnd ) )
321 ShowWindow( hwnd, SW_RESTORE );
325 HMODULE hUser32 = GetModuleHandle("user32");
327 typedef void (WINAPI *PROCSWITCHTOTHISWINDOW) (HWND, BOOL);
328 PROCSWITCHTOTHISWINDOW SwitchToThisWindow = (PROCSWITCHTOTHISWINDOW)GetProcAddress(hUser32, TEXT("SwitchToThisWindow"));
329 if ( SwitchToThisWindow ){
330 SwitchToThisWindow( hwnd, true );
331 FreeLibrary( hUser32 );
336 FreeLibrary( hUser32 );
339 /*BOOL changed = */ SystemParametersInfo( SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &locktimeout, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE );
340 SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, NULL, SPIF_UPDATEINIFILE);
341 SetForegroundWindow(hwnd);
342 SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, locktimeout, NULL, SPIF_UPDATEINIFILE);
344 // window(hwnd)
\82ðhwndParent
\82Ìcenter
\82Ö
\88Ú
\93®
345 // screen
\82Ì
\8aO
\82Ö
\8fo
\82é
\8fê
\8d\87\82Í
\92²
\90®
\82·
\82é
346 void MoveCenter( HWND hwnd, HWND hwndParent )
351 hwndParent = hwndMain; // parent
\82ª
\82È
\82¯
\82ê
\82Îmain window
355 if ( IsIconic(hwndParent) ){
356 GetScreenSize(hwndParent, &rc);
360 ::GetWindowRect( hwndParent, &rc );
363 GetScreenSize(hwnd, &rc);
366 GetScreenSize(hwnd, &rcScr);
367 ::GetWindowRect( hwnd, &rd );
368 int width = rd.right - rd.left;
369 int height = rd.bottom - rd.top;
370 int left = rc.left + ( ( rc.right - rc.left ) - width )/2;
371 int top = rc.top + ( ( rc.bottom - rc.top ) - height )/2;
372 if ( left < rcScr.left ){
375 if ( top < rcScr.top ){
378 if ( left + width > rcScr.right ){
379 left = rcScr.right - (rd.right - rd.left);
381 if ( top + height > rcScr.bottom ){
382 top = rcScr.bottom - (rd.bottom - rd.top);
384 ::SetWindowPos( hwnd, (HWND)NULL, left & ~7, top, 0, 0, SWP_NOSIZE | SWP_NOZORDER );
386 void GetScreenSize(HWND hwndBase, RECT *rcWork, RECT *rcScreen)
391 MLFXPC_CMN_ASSERT(false);
393 SetRect(rcScreen, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
396 SystemParametersInfo(SPI_GETWORKAREA, 0, rcWork, 0);
401 //__assert(hwndMain!=NULL);
402 HMONITOR hMonitor = MonitorFromWindow(hwndBase ? hwndBase : (hwndMain ? hwndMain : GetActiveWindow()), MONITOR_DEFAULTTONEAREST);
403 //__assert(hMonitor!=NULL);
405 memset(&mi, 0, sizeof(mi));
406 mi.cbSize = sizeof(mi);
407 GetMonitorInfo(hMonitor, &mi);
409 *rcScreen = mi.rcMonitor;
415 bool _WinExec( const char *cmd, int show, int waittime, const char *dir)
418 memset( &sui, 0, sizeof(STARTUPINFO) );
419 sui.cb = sizeof(STARTUPINFO);
420 sui.dwFlags = STARTF_USESHOWWINDOW;
421 sui.wShowWindow = (WORD)show;
422 sui.lpTitle = (LPTSTR)"";
423 PROCESS_INFORMATION pi;
424 if ( !CreateProcess( NULL, (LPTSTR)cmd, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, dir, &sui, &pi ) )
428 // DWORD startTime = GetTickCount();
429 int r = WaitForInputIdle( pi.hProcess, waittime );
432 dbw("CreateProcess: %d, 0x%X", r, GetLastError());
434 // dbw("CreateProcess: %d", GetTickCount() - startTime);
437 CloseHandle( pi.hProcess );
440 static const char *MyWinTitle = "<Processing...>";
441 HANDLE WinExecEx( const char *cmd, int show, const char *dir, const char *title )
444 memset( &sui, 0, sizeof(STARTUPINFO) );
445 sui.cb = sizeof(STARTUPINFO);
446 sui.dwFlags = STARTF_USESHOWWINDOW;
447 sui.wShowWindow = (WORD)show;
448 sui.lpTitle = (LPTSTR)(title ? title : MyWinTitle);
449 PROCESS_INFORMATION pi;
450 if ( !CreateProcess( NULL, (LPTSTR)cmd, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, dir, &sui, &pi ) )
456 TAppIni *ini = new TAppIni;
462 AnsiString s = ini->ReadString( PFS_COMMON, PFS_PATH, "" );
464 if ( s.Length() == 0 )
469 return _WinExec( s.c_str(), SW_SHOWNOACTIVATE|SW_MINIMIZE, 500 );
473 HANDLE h = WinExecEx(EXMODIST_EXE_PATH, SW_HIDE);
475 dbw("ExMODist exec error: %d", GetLastError());
478 WaitForSingleObject(h, INFINITE);
480 BOOL r = GetExitCodeProcess(h, &exitCode);
483 return exitCode ? true : false;
489 return MODIInstalled() && GetDNFVersion()>=451;
493 if (!AMODIRunable()) return false;
497 SW_SHOWNOACTIVATE|SW_MINIMIZE;
501 if (!_WinExec( AMODI_EXE_PATH, show, 300))
505 for (int i=0;i<10;i++){
513 void TerminateAMODI()
515 HWND hwnd = FindAMODI();
517 PostMessage(hwnd, WM_CLOSE, 0, 0);
522 HWND hwnd = FindAMODI();
524 ShowWindow(hwnd, SW_SHOW);
525 ShowWindow(hwnd, SW_RESTORE);
528 static HWND hwndFind;
529 static const char *findClass = NULL;
530 static const char *findWindow = NULL;
531 static const char *findAppName = NULL;
532 static BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam )
537 if ( !GetClassName( hwnd, buf, sizeof(buf)-1 ) ) return TRUE;
538 //DBW("class: %s", buf);
539 if (strcmp( buf, findClass )) return TRUE;
542 if (GetWindowText(hwnd, buf, sizeof(buf))<0){
545 //DBW("wnd: %s", buf);
546 if (strcmp(buf, findWindow)){ return TRUE; }
551 cd.dwData = WMCD_EXISTCHECK;
552 cd.lpData = (void*)findAppName;
553 cd.cbData = strlen(findAppName)+1;
554 if ( SendMessage( hwnd, WM_COPYDATA, 0, (LPARAM)&cd ) ){
565 HWND FindApp(const char *clsname, const char *wndname, const char *appname)
569 findWindow = wndname;
570 findAppName = appname;
571 EnumWindows( (FARPROC)EnumWindowsProc, 0 );
576 return FindApp("TDCHookMainForm", NULL, APPNAME);
578 int CheckVersion(HWND hwnd)
580 int ver = SendMessage(hwnd, WM_GET_VERSION, 0, 0);
581 if (ver==0){ return -1; } // older than ver.2.0
582 return ver - VersionValue;
586 static const char APPNAME_AMODI[] = "Auto MODI";
587 return FindApp(NULL, APPNAME_AMODI, APPNAME_AMODI);
589 static HWND hwndFound;
590 static BOOL CALLBACK EnumWindowsProcPS( HWND hwnd, LPARAM lParam )
593 if ( !GetClassName( hwnd, clsname, sizeof(clsname)-1 ) ) return TRUE;
594 if ( strcmp( clsname, "PSPOPUPWIN" )
595 && strcmp( clsname, "PSMENU" ) ) return TRUE;
601 // PDIC
\82Ìpopup window
\82ð
\92T
\82·
602 HWND FindPopupWindow( )
605 EnumWindows( (WNDENUMPROC)EnumWindowsProcPS, 0 );
609 void ShowManual(HWND hwnd)
611 AnsiString dir = ExtractFileDir( Application->ExeName );
612 ShellExecute( hwnd, "open", NAME_DKPPTXT, NULL, dir.c_str(), SW_SHOW );
615 void ShowLatestVersion()
618 const char *url = "http://pdic.la.coocan.jp/unicode/dev.html";
620 const char *url = "http://dokopop.osdn.jp/";
622 ShellExecute( NULL, _T("open"), url, NULL, NULL, SW_SHOW );
626 // https://msdn.microsoft.com/ja-jp/library/hh925568(v=vs.110).aspx#net_d
627 // http://www.atmarkit.co.jp/ait/articles/1210/26/news086.html
628 unsigned GetDNFVersion()
631 if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\NET Framework Setup\\NDP", 0, KEY_READ, &dnfKey ) == ERROR_SUCCESS ){
634 if ( RegOpenKeyEx( dnfKey, "v4.0", 0, KEY_READ, &verKey ) == ERROR_SUCCESS ){
637 if ( RegOpenKeyEx( dnfKey, "v4", 0, KEY_READ, &verKey ) == ERROR_SUCCESS ){
639 if ( RegOpenKeyEx( verKey, "Full", 0, KEY_READ, &fullKey ) == ERROR_SUCCESS ){
640 DWORD dwType = REG_DWORD;
643 if ( RegQueryValueEx( fullKey, "Release", NULL, &dwType, (BYTE*)&dwValue, &dwByte) == ERROR_SUCCESS){
645 if (dwValue >= 394254){
648 if (dwValue >= 393295){
651 if (dwValue >= 379893){
655 if (dwValue >= 378675){
658 if (dwValue >= 378389){
662 RegCloseKey( fullKey );
664 RegCloseKey( verKey );
667 if ( RegOpenKeyEx( dnfKey, "v3.5", 0, KEY_READ, &verKey ) == ERROR_SUCCESS ){
677 static HWND hWin = NULL;
678 static const char *clsname = "TDbgMsgForm";
679 static const char *winname = "Debug Messenger";
680 void dbw( const char *format, ... )
683 hWin = FindWindowA( clsname, winname );
687 va_start( ap, format );
689 wvsprintf( buf, format, ap );
691 cds.dwData = 1; // Indicate String
692 cds.cbData = strlen(buf);
694 SendMessage( hWin, WM_COPYDATA, NULL, (LPARAM)&cds );