1 //---------------------------------------------------------------------------
8 //---------------------------------------------------------------------------
9 const char *AppName = "DokoPop";
10 const char *StrVersion = "Ver.2.0.25";
11 int VersionValue = 0x020019; // xxyyzz -> xx.yy.zz x=major y=minor(0-255) z=release(0-255)
13 #pragma package(smart_init)
16 const char APPNAME[] = {"DokoPop/Unicode"};
18 const char APPNAME[] = {"DokoPop"};
21 const char *AMODI_EXE_PATH = "amodi.exe";
22 //const char *AMODI_EXE_PATH = "\\src\\amodi\\amodi\\bin\\Debug\\amodi.exe";
24 const char *EXMODIST_EXE_PATH = "ExMODIst.exe";
26 bool WindowsNT = false;
31 HKEY OpenKey( HKEY hkey, const char *keyname )
34 if ( RegOpenKeyEx( hkey, keyname, 0, KEY_ALL_ACCESS, &newkey ) == ERROR_SUCCESS ){
40 HKEY CreateKey( HKEY hkey, const char *keyname )
44 if ( RegCreateKeyEx( hkey, keyname, 0, (LPTSTR)keyname, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, &result ) == ERROR_SUCCESS ){
49 DWORD GetValueLength( HKEY hkey, const char *name )
52 if ( RegQueryValueEx( hkey, (LPTSTR)name, 0, NULL, NULL, &len ) == ERROR_SUCCESS ){
58 DWORD ReadInteger( HKEY hkey, const char *name, DWORD val )
60 DWORD len = sizeof(DWORD);
62 if ( RegQueryValueEx( hkey, (LPTSTR)name, 0, NULL, (LPBYTE)&v, &len ) == ERROR_SUCCESS ){
67 AnsiString ReadString( HKEY hkey, const char *name, const char *def )
69 DWORD len = GetValueLength( hkey, name );
71 char *buf = new char[ len ];
72 if ( RegQueryValueEx( hkey, (LPTSTR)name, 0, NULL, (LPBYTE)buf, &len ) == ERROR_SUCCESS ){
81 TMyIni::TMyIni( HKEY root, const char *soft, bool can_create )
83 hroot = can_create ? CreateKey( root, soft ) : OpenKey( root, soft );
91 void TMyIni::WriteInteger( const char *section, const char *key, int val )
93 HKEY hkey = CreateKey( hroot, section );
95 RegSetValueEx( hkey, (LPCTSTR)key, 0, REG_DWORD, (LPBYTE)&val, sizeof(DWORD) );
99 int TMyIni::ReadInteger( const char *section, const char *key, int val )
101 HKEY hkey = OpenKey( hroot, section );
103 DWORD len = sizeof(DWORD);
105 if ( RegQueryValueEx( hkey, (LPTSTR)key, 0, NULL, (LPBYTE)&v, &len ) == ERROR_SUCCESS ){
111 void TMyIni::WriteString( const char *section, const char *key, const char *str )
115 hkey = CreateKey( hroot, section );
116 if ( !section || hkey ){
117 RegSetValueEx( hkey, (LPCTSTR)key, 0, REG_SZ, (LPBYTE)str, lstrlen(str)+1 );
121 AnsiString TMyIni::ReadString( const char *section, const char *key, const char *str )
125 hkey = OpenKey( hroot, section );
126 if ( !section || hkey ){
127 DWORD len = GetValueLength( hkey, key );
129 char *buf = new char[ len ];
130 if ( RegQueryValueEx( hkey, (LPTSTR)key, 0, NULL, (LPBYTE)buf, &len ) == ERROR_SUCCESS ){
141 #define NAMEBUFFSIZE 512
142 BOOL QueryInfoKey( HKEY hkey, DWORD *maxvalue, DWORD *maxdata );
143 BOOL EnumValue( HKEY hkey, DWORD index, AnsiString &name, void *pbuffer=NULL, DWORD *maxlen=NULL, DWORD *type=NULL );
145 void TMyIni::ReadValues( const char *section, TStrings *strs )
149 HKEY hkey = OpenKey( hroot, section );
153 if ( !QueryInfoKey( hkey, &maxvaluename, &maxvaluedata ) ){
154 //
\93®
\82©
\82È
\82¢
\81I
\81I
\81I
156 maxvaluedata = 4096; //
\93K
\93\96\81I
\81I
160 char *buf = new char[ maxvaluedata + 1 ];
161 for ( int i=0;;i++ ){
162 DWORD maxlen = maxvaluedata + 1;
163 if ( !EnumValue( hkey, i, _entry, buf, &maxlen ) )
175 :super(HKEY_CURRENT_USER, REG_PDICEXE, false)
179 super::super(HKEY_CURRENT_USER, REG_PDICEXE, false);
184 const char *sLeft = "Left";
185 const char *sTop = "Top";
186 const char *sWidth = "Width";
187 const char *sHeight = "Height";
189 void LoadForm( const char *section, TForm *form, HWND hwnd )
193 GetWindowRect( hwnd, &rc );
195 rc.left = rc.top = 0;
197 form->Left = Ini->ReadInteger(section, sLeft, form->Left) + rc.left;
198 form->Top = Ini->ReadInteger(section, sTop, form->Top ) + rc.top;
200 GetScreenSize(form->Handle?form->Handle:hwnd, &rcScr);
201 int sx = rcScr.right - rcScr.left;
202 int sy = rcScr.bottom - rcScr.top;
204 switch ( form->BorderStyle ){
208 form->Width = Ini->ReadInteger( section, sWidth, form->Width );
209 form->Height = Ini->ReadInteger( section, sHeight, form->Height );
212 //
\89æ
\96Ê
\82Ì
\8aO
\82©
\82Ç
\82¤
\82©
\81H
213 if (form->Left+form->Width >= sx){
215 form->Left = sx - form->Width;
217 if (form->Left < rcScr.left){
219 form->Left = rcScr.left;
221 if (form->Top+form->Height >= sy){
223 form->Top = sy - form->Height;
225 if (form->Top < rcScr.top){
227 form->Top = rcScr.top;
230 void SaveForm( const char *section, TForm *form, HWND hwnd )
234 GetWindowRect( hwnd, &rc );
236 rc.left = rc.top = 0;
238 Ini->WriteInteger( section, sLeft, form->Left - rc.left );
239 Ini->WriteInteger( section, sTop, form->Top - rc.top );
240 switch ( form->BorderStyle ){
244 Ini->WriteInteger( section, sWidth, form->Width );
245 Ini->WriteInteger( section, sHeight, form->Height );
250 BOOL QueryInfoKey( HKEY hkey, DWORD *maxvalue, DWORD *maxdata )
252 char *classname = new char[ 512 ]; //
\82±
\82ñ
\82È
\82à
\82ñ
\82Å
\82¢
\82¢
\82©
\82È
\82\9f\81H
253 DWORD classnamesize = 512;
260 DWORD SecurityDescriptor;
261 FILETIME LastWriteTime;
262 if ( ::RegQueryInfoKey( hkey, classname, &classnamesize,
272 ) != ERROR_SUCCESS ){
277 *maxvalue = MaxValueName;
279 *maxdata = MaxValueData;
283 BOOL EnumValue( HKEY hkey, DWORD index, AnsiString &name, void *pbuffer, DWORD *maxlen, DWORD *type )
285 char *buffer = new char[ NAMEBUFFSIZE ];
286 DWORD buflen = NAMEBUFFSIZE;
287 if ( RegEnumValue( hkey, index, buffer, &buflen, 0, type, (LPBYTE)pbuffer, maxlen ) == ERROR_SUCCESS ){
295 bool CheckPassword( const char *str )
301 s = Ini->ReadString( "Main", "PW", "" );
307 typedef BOOL WINAPI (*FNIsWow64Process)(HANDLE hProcess, PBOOL Wow64Process);
309 FNIsWow64Process _IsWow64Process = (FNIsWow64Process)GetProcAddress(GetModuleHandle("kernel32"),"IsWow64Process");
310 if (_IsWow64Process){
312 if (_IsWow64Process(GetCurrentProcess(), &flag)){
317 void MoveToTop( HWND hwnd )
319 if ( IsIconic( hwnd ) )
320 ShowWindow( hwnd, SW_RESTORE );
324 HMODULE hUser32 = GetModuleHandle("user32");
326 typedef void (WINAPI *PROCSWITCHTOTHISWINDOW) (HWND, BOOL);
327 PROCSWITCHTOTHISWINDOW SwitchToThisWindow = (PROCSWITCHTOTHISWINDOW)GetProcAddress(hUser32, TEXT("SwitchToThisWindow"));
328 if ( SwitchToThisWindow ){
329 SwitchToThisWindow( hwnd, true );
330 FreeLibrary( hUser32 );
335 FreeLibrary( hUser32 );
338 /*BOOL changed = */ SystemParametersInfo( SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &locktimeout, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE );
339 SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, NULL, SPIF_UPDATEINIFILE);
340 SetForegroundWindow(hwnd);
341 SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, locktimeout, NULL, SPIF_UPDATEINIFILE);
343 // window(hwnd)
\82ðhwndParent
\82Ìcenter
\82Ö
\88Ú
\93®
344 // screen
\82Ì
\8aO
\82Ö
\8fo
\82é
\8fê
\8d\87\82Í
\92²
\90®
\82·
\82é
345 void MoveCenter( HWND hwnd, HWND hwndParent )
350 hwndParent = hwndMain; // parent
\82ª
\82È
\82¯
\82ê
\82Îmain window
354 if ( IsIconic(hwndParent) ){
355 GetScreenSize(hwndParent, &rc);
359 ::GetWindowRect( hwndParent, &rc );
362 GetScreenSize(hwnd, &rc);
365 GetScreenSize(hwnd, &rcScr);
366 ::GetWindowRect( hwnd, &rd );
367 int width = rd.right - rd.left;
368 int height = rd.bottom - rd.top;
369 int left = rc.left + ( ( rc.right - rc.left ) - width )/2;
370 int top = rc.top + ( ( rc.bottom - rc.top ) - height )/2;
371 if ( left < rcScr.left ){
374 if ( top < rcScr.top ){
377 if ( left + width > rcScr.right ){
378 left = rcScr.right - (rd.right - rd.left);
380 if ( top + height > rcScr.bottom ){
381 top = rcScr.bottom - (rd.bottom - rd.top);
383 ::SetWindowPos( hwnd, (HWND)NULL, left & ~7, top, 0, 0, SWP_NOSIZE | SWP_NOZORDER );
385 void GetScreenSize(HWND hwndBase, RECT *rcWork, RECT *rcScreen)
390 MLFXPC_CMN_ASSERT(false);
392 SetRect(rcScreen, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
395 SystemParametersInfo(SPI_GETWORKAREA, 0, rcWork, 0);
400 //__assert(hwndMain!=NULL);
401 HMONITOR hMonitor = MonitorFromWindow(hwndBase ? hwndBase : (hwndMain ? hwndMain : GetActiveWindow()), MONITOR_DEFAULTTONEAREST);
402 //__assert(hMonitor!=NULL);
404 memset(&mi, 0, sizeof(mi));
405 mi.cbSize = sizeof(mi);
406 GetMonitorInfo(hMonitor, &mi);
408 *rcScreen = mi.rcMonitor;
414 bool _WinExec( const char *cmd, int show, int waittime, const char *dir)
417 memset( &sui, 0, sizeof(STARTUPINFO) );
418 sui.cb = sizeof(STARTUPINFO);
419 sui.dwFlags = STARTF_USESHOWWINDOW;
420 sui.wShowWindow = (WORD)show;
421 sui.lpTitle = (LPTSTR)"";
422 PROCESS_INFORMATION pi;
423 if ( !CreateProcess( NULL, (LPTSTR)cmd, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, dir, &sui, &pi ) )
427 // DWORD startTime = GetTickCount();
428 int r = WaitForInputIdle( pi.hProcess, waittime );
431 dbw("CreateProcess: %d, 0x%X", r, GetLastError());
433 // dbw("CreateProcess: %d", GetTickCount() - startTime);
436 CloseHandle( pi.hProcess );
439 static const char *MyWinTitle = "<Processing...>";
440 HANDLE WinExecEx( const char *cmd, int show, const char *dir, const char *title )
443 memset( &sui, 0, sizeof(STARTUPINFO) );
444 sui.cb = sizeof(STARTUPINFO);
445 sui.dwFlags = STARTF_USESHOWWINDOW;
446 sui.wShowWindow = (WORD)show;
447 sui.lpTitle = (LPTSTR)(title ? title : MyWinTitle);
448 PROCESS_INFORMATION pi;
449 if ( !CreateProcess( NULL, (LPTSTR)cmd, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, dir, &sui, &pi ) )
455 TAppIni *ini = new TAppIni;
461 AnsiString s = ini->ReadString( PFS_COMMON, PFS_PATH, "" );
463 if ( s.Length() == 0 )
468 return _WinExec( s.c_str(), SW_SHOWNOACTIVATE|SW_MINIMIZE, 500 );
472 HANDLE h = WinExecEx(EXMODIST_EXE_PATH, SW_HIDE);
474 dbw("ExMODist exec error: %d", GetLastError());
477 WaitForSingleObject(h, INFINITE);
479 BOOL r = GetExitCodeProcess(h, &exitCode);
482 return exitCode ? true : false;
488 return MODIInstalled() && GetDNFVersion()>=451;
492 if (!AMODIRunable()) return false;
496 SW_SHOWNOACTIVATE|SW_MINIMIZE;
500 if (!_WinExec( AMODI_EXE_PATH, show, 300))
504 for (int i=0;i<10;i++){
512 void TerminateAMODI()
514 HWND hwnd = FindAMODI();
516 PostMessage(hwnd, WM_CLOSE, 0, 0);
521 HWND hwnd = FindAMODI();
523 ShowWindow(hwnd, SW_SHOW);
524 ShowWindow(hwnd, SW_RESTORE);
527 static HWND hwndFind;
528 static const char *findClass = NULL;
529 static const char *findWindow = NULL;
530 static const char *findAppName = NULL;
531 static BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam )
536 if ( !GetClassName( hwnd, buf, sizeof(buf)-1 ) ) return TRUE;
537 //DBW("class: %s", buf);
538 if (strcmp( buf, findClass )) return TRUE;
541 if (GetWindowText(hwnd, buf, sizeof(buf))<0){
544 //DBW("wnd: %s", buf);
545 if (strcmp(buf, findWindow)){ return TRUE; }
550 cd.dwData = WMCD_EXISTCHECK;
551 cd.lpData = (void*)findAppName;
552 cd.cbData = strlen(findAppName)+1;
553 if ( SendMessage( hwnd, WM_COPYDATA, 0, (LPARAM)&cd ) ){
564 HWND FindApp(const char *clsname, const char *wndname, const char *appname)
568 findWindow = wndname;
569 findAppName = appname;
570 EnumWindows( (FARPROC)EnumWindowsProc, 0 );
575 return FindApp("TDCHookMainForm", NULL, APPNAME);
577 int CheckVersion(HWND hwnd)
579 int ver = SendMessage(hwnd, WM_GET_VERSION, 0, 0);
580 if (ver==0){ return -1; } // older than ver.2.0
581 return ver - VersionValue;
585 static const char APPNAME_AMODI[] = "Auto MODI";
586 return FindApp(NULL, APPNAME_AMODI, APPNAME_AMODI);
588 static HWND hwndFound;
589 static BOOL CALLBACK EnumWindowsProcPS( HWND hwnd, LPARAM lParam )
592 if ( !GetClassName( hwnd, clsname, sizeof(clsname)-1 ) ) return TRUE;
593 if ( strcmp( clsname, "PSPOPUPWIN" )
594 && strcmp( clsname, "PSMENU" ) ) return TRUE;
600 // PDIC
\82Ìpopup window
\82ð
\92T
\82·
601 HWND FindPopupWindow( )
604 EnumWindows( (WNDENUMPROC)EnumWindowsProcPS, 0 );
608 void ShowManual(HWND hwnd)
610 AnsiString dir = ExtractFileDir( Application->ExeName );
611 ShellExecute( hwnd, "open", NAME_DKPPTXT, NULL, dir.c_str(), SW_SHOW );
614 void ShowLatestVersion()
617 const char *url = "http://pdic.la.coocan.jp/unicode/dev.html";
619 const char *url = "http://dokopop.osdn.jp/";
621 ShellExecute( NULL, _T("open"), url, NULL, NULL, SW_SHOW );
625 // https://msdn.microsoft.com/ja-jp/library/hh925568(v=vs.110).aspx#net_d
626 // http://www.atmarkit.co.jp/ait/articles/1210/26/news086.html
627 unsigned GetDNFVersion()
630 if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\NET Framework Setup\\NDP", 0, KEY_READ, &dnfKey ) == ERROR_SUCCESS ){
633 if ( RegOpenKeyEx( dnfKey, "v4.0", 0, KEY_READ, &verKey ) == ERROR_SUCCESS ){
636 if ( RegOpenKeyEx( dnfKey, "v4", 0, KEY_READ, &verKey ) == ERROR_SUCCESS ){
638 if ( RegOpenKeyEx( verKey, "Full", 0, KEY_READ, &fullKey ) == ERROR_SUCCESS ){
639 DWORD dwType = REG_DWORD;
642 if ( RegQueryValueEx( fullKey, "Release", NULL, &dwType, (BYTE*)&dwValue, &dwByte) == ERROR_SUCCESS){
644 if (dwValue >= 394254){
647 if (dwValue >= 393295){
650 if (dwValue >= 379893){
654 if (dwValue >= 378675){
657 if (dwValue >= 378389){
661 RegCloseKey( fullKey );
663 RegCloseKey( verKey );
666 if ( RegOpenKeyEx( dnfKey, "v3.5", 0, KEY_READ, &verKey ) == ERROR_SUCCESS ){
676 static HWND hWin = NULL;
677 static const char *clsname = "TDbgMsgForm";
678 static const char *winname = "Debug Messenger";
679 void dbw( const char *format, ... )
682 hWin = FindWindowA( clsname, winname );
686 va_start( ap, format );
688 wvsprintf( buf, format, ap );
690 cds.dwData = 1; // Indicate String
691 cds.cbData = strlen(buf);
693 SendMessage( hWin, WM_COPYDATA, NULL, (LPARAM)&cds );