C:\home\SVGCats_src\src\winx.c
1|/************************************************************************** 2|* 1. <<< Windows API (WinX) >>> 3|*【参考】 4|*・http://www.kt.rim.or.jp/~yuta/prog/win32/ 5|*【API index】 6|*・GetSystemDirectory 7|***************************************************************************/ 8| 9|#ifdef UNDER_CE 10| #error not support for WinCE 11|#endif 12| 13|#include <windows.h> 14|// #pragma hdrstop 15|#ifdef USES_MXP_AUTOINC 16| #include "winx.ah" /* Auto include header, Look at mixer-... folder */ 17|#else 18| #include <all.h> 19|#endif 20| 21|/*#define WINX_ENABLE_DEBUG_MODE*/ 22| 23|#include <winreg.h> /* レジストリ関係 */ 24|#include <ddeml.h> /* DDE 通信関係 */ 25|#include <direct.h> 26|#include <limits.h> 27|#include <stdio.h> 28| 29|extern char WinX_dde_command[]; 30|extern char WinX_dde_service[]; 31|extern char WinX_dde_topic[]; 32| 33| 34| 35|/*------------------------------------------------------------------------*/ 36|/* 2. <<<< サブルーチン >>>> */ 37|/*------------------------------------------------------------------------*/ 38| 39|/************************************************************************** 40|* 2-1. <<< [WinX_error] エラーを発生させる(GetLastError 使用) >>> 41|***************************************************************************/ 42|void WinX_error(void) 43|{ 44| static char msg[256]; 45| int errcode = GetLastError(); 46| 47| FormatMessage( 48| FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 49| NULL, errcode, 50| MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // デフォルト言語 51| (LPTSTR) msg, sizeof(msg), NULL ); 52| error2_4( WinX_Err_API_Error, "API Error : %s, allcode = %08X (Facility=%d, Code=%d)", \ 53| msg, (errcode), ((errcode) & 0x0FFF0000) >> 16, ((errcode) & 0x0000FFFF) ); 54|} 55| 56| 57|/************************************************************************** 58|* 2-2. <<< [WinX_error2] エラーを発生させる(返り値使用) >>> 59|***************************************************************************/ 60|void WinX_error2( LONG code ) 61|{ 62| static char msg[256]; 63| 64| FormatMessage( 65| FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 66| NULL, code, 67| MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // デフォルト言語 68| (LPTSTR) msg, sizeof(msg), NULL ); 69| error2_1( WinX_Err_API_Error, "API Error : %s", msg ); 70|} 71| 72| 73|/************************************************************************** 74|* 2-3. <<< [WinX_throw_imp] API のエラーコード例外を投げる >>> 75|*【引数】 76|* ・int errcode エラーコード; 77|*【補足】 78|*・エラーコードの内容は、winerror.h(C:\Program Files\Microsoft Visual Studio\ 79|* VC98\Include\WINERROR.H) に書いてあります。 80|* ただし、エラーコードはビットフィールドによって複数の情報が入っていることに 81|* 注意してください。 82|***************************************************************************/ 83|#ifdef USES_EXCEPT2 84|void WinX_throw_imp( int errcode, char* file, int line ) 85|{ 86| throw( Except2_Str_newExcept2_f( "WinX: API Error in %s:%d\n" 87| "allcode = %08X ( Sev=%d, Facility=%d, Code=%d)", 88| file, line, errcode, (errcode & 0xC0000000) >> 30, 89| (errcode & 0x0FFF0000) >> 16, (errcode & 0x0000FFFF) ) ); 90|} 91|#else 92|void WinX_throw_imp( int errcode, char* file, int line ) 93|{ 94| static char msg[256]; 95| 96| FormatMessage( 97| FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 98| NULL, errcode, 99| MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // デフォルト言語 100| (LPTSTR) msg, sizeof(msg), NULL ); 101| sprintf( strchr( msg, '\0' ), ", allcode = %08X (Facility=%d, Code=%d)", 102| (errcode), ((errcode) & 0x0FFF0000) >> 16, ((errcode) & 0x0000FFFF) ); 103| error2_3( WinX_Err_API_Error, "API Error : %s in %s(%d)", \ 104| msg, file, line ); 105|} 106|#endif /* USES_EXCEPT2 */ 107| 108|/************************************************************************** 109|* 2-4. <<< [WinX_throwDde_imp] DDE のエラーコード例外を投げる >>> 110|*【引数】 111|* ・DWORD dde; DdeInitialize の第1引数と同じ 112|***************************************************************************/ 113|void WinX_throwDde_imp( DWORD dde, char* file, int line ) 114|{ 115| char* errstr; 116| 117| switch ( DdeGetLastError( dde ) ) { 118| case DMLERR_ADVACKTIMEOUT: 119| errstr = "DMLERR_ADVACKTIMEOUT"; break; 120| case DMLERR_BUSY: 121| errstr = "DMLERR_BUSY"; break; 122| case DMLERR_DATAACKTIMEOUT: 123| errstr = "DMLERR_DATAACKTIMEOUT"; break; 124| case DMLERR_DLL_NOT_INITIALIZED: 125| errstr = "DMLERR_NOT_INITIALIZED"; break; 126| case DMLERR_DLL_USAGE: 127| errstr = "DMLERR_DLL_USAGE"; break; 128| case DMLERR_EXECACKTIMEOUT: 129| errstr = "DMLERR_EXECACKTIMEOUT"; break; 130| case DMLERR_INVALIDPARAMETER: 131| errstr = "DMLERR_INVALIDPARAMETER"; break; 132| case DMLERR_LOW_MEMORY: 133| errstr = "DMLERR_LOW_MEMORY"; break; 134| case DMLERR_MEMORY_ERROR: 135| errstr = "DMLERR_MEMORY_ERROR"; break; 136| case DMLERR_NO_CONV_ESTABLISHED: 137| errstr = "DMLERR_NO_CONV_ESTABLISHED"; break; 138| case DMLERR_NOTPROCESSED: 139| errstr = "DMLERR_NOTPROCESSED"; break; 140| case DMLERR_POKEACKTIMEOUT: 141| errstr = "DMLERR_POKEACKTIMEOUT"; break; 142| case DMLERR_POSTMSG_FAILED: 143| errstr = "DMLERR_POSTMSG_FAILED"; break; 144| case DMLERR_REENTRANCY: 145| errstr = "DMLERR_REENTRANCY"; break; 146| case DMLERR_SERVER_DIED: 147| errstr = "DMLERR_SERVER_DIED"; break; 148| case DMLERR_SYS_ERROR: 149| errstr = "DMLERR_SYS_ERROR"; break; 150| case DMLERR_UNADVACKTIMEOUT: 151| errstr = "DMLERR_UNADVACKTIMEOUT"; break; 152| case DMLERR_UNFOUND_QUEUE_ID: 153| errstr = "DMLERR_UNFOUND_QUEUE_ID"; break; 154| default: 155| errstr = "unknown"; break; 156| } 157| 158| #ifdef USES_EXCEPT2 159| throw( Except2_Str_newExcept2_f( 160| "WinX: DDE Error : %s in %s:%d", 161| errstr, file, line ) ); 162| #else 163| error2_5( WinX_Err_DdeError, "WinX: DDE Error command=%s, service=%s, topic=%s: in %s:%d", 164| WinX_dde_command, WinX_dde_service, WinX_dde_topic, errstr, line ); 165| #endif /* USES_EXCEPT2 */ 166|} 167| 168| 169|/*------------------------------------------------------------------------*/ 170|/* 3. <<<< ◆ レジストリ関係 >>>> */ 171|/*------------------------------------------------------------------------*/ 172| 173| 174| 175|/************************************************************************** 176| 3-1. <<< [WinX_getReg] レジストリの値(任意の型)を取得する >>> 177|【引数】 178| ・HKEY baseKey; 基準キー(HKEY_CLASSES_ROOT など、サブキーでも可) 179| ・char* path; 基準キーからのパス 180| ・bool bDef; path は(標準または規定)のデータかどうか 181| ・WinX_RegData* data; レジストリ・データ 182|【補足】 183|・キーが HKEY_CLASSES_ROOT\Display\Settings の場合、 184| baseKey == HKEY_CLASSES_ROOT, path == "Display\\Settings" を指定します。 185|・path に指定したキーが無いときは、例外を発生します。 186|・キーは、レジストリエディタの左半分のツリーに表示されるフォルダアイコン、 187| データは、レジストリエディタの右半分に表示されるアイコンに相当します。 188|***************************************************************************/ 189|void WinX_getReg( HKEY baseKey, const char* path, bool bDef, WinX_RegData* data ) 190|{ 191| LONG ret; 192| HKEY key; 193| DWORD size = data->maxSize; 194| const char* keyPath; 195| char* dataName; 196| char s[512]; 197| 198| ERRORS_FUNC_START( WinX_getReg ); 199| 200| /* keyPath と namePath を設定する */ 201| if ( bDef ) { 202| keyPath = path; 203| dataName = NULL; 204| } 205| else { 206| if ( strlen( path ) >= sizeof( s ) ) 207| error2_1( WinX_Err_TooLongPath, "レジストリのパスが長すぎます(%s)", path ); 208| strcpy( s, path ); 209| keyPath = s; 210| dataName = StrX_RSearchC2( s, '\\' ) + 1; 211| *(dataName - 1) = '\0'; 212| } 213| 214| /* レジストリ・データを取得する */ 215| ret = RegOpenKeyEx( baseKey, keyPath, 0L, KEY_READ, &key ); 216| if ( ret != ERROR_SUCCESS ) { 217| if ( ret == 2 ) { 218| error2_1( WinX_Err_NoRegKey, "レジストリのキー「%s」が見つかりません。", 219| path ); 220| } 221| else 222| WinX_throw( ret ); 223| } 224| 225| ret = RegQueryValueEx( key, dataName, NULL, &data->type, data->data, &size ); 226| if ( ret != ERROR_SUCCESS ) { 227| RegCloseKey( key ); 228| if ( ret == ERROR_FILE_NOT_FOUND || ret == ERROR_MORE_DATA ) { 229| if ( dataName == NULL ) { 230| error2_1( WinX_Err_NoRegData, "レジストリのキー「%s」のデータ(標準)が見つかりません。", 231| path ); 232| } 233| else { 234| error2_2( WinX_Err_NoRegData, "レジストリのキー「%s」のデータ「%s」が見つかりません。", 235| path, dataName ); 236| } 237| } 238| else 239| WinX_throw( ret ); 240| } 241| data->size = size; 242| 243| ret = RegCloseKey( key ); 244| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 245| 246| ERRORS_FUNC_END( WinX_getReg ); 247|} 248| 249|/************************************************************************** 250| 3-2. <<< [WinX_setReg] レジストリの値(任意の型)を設定する >>> 251|【引数】 252| ・HKEY baseKey; 基準キー(HKEY_CLASSES_ROOT など、サブキーでも可) 253| ・char* path; 基準キーからのパス 254| ・bool bDef; path は(標準または規定)のデータかどうか 255| ・WinX_RegData* data; レジストリ・データ 256|【補足】 257|・キーが HKEY_CLASSES_ROOT\Display\Settings の場合、 258| baseKey == HKEY_CLASSES_ROOT, path == "Display\\Settings" を指定します。 259|・path のキーやデータが存在しないときは、新しく作成します。 260|・キーは、レジストリエディタの左半分のツリーに表示されるフォルダアイコン、 261| データは、レジストリエディタの右半分に表示されるアイコンに相当します。 262|***************************************************************************/ 263|void WinX_setReg( HKEY baseKey, const char* path, bool bDef, WinX_RegData* data ) 264|{ 265| LONG ret; 266| HKEY key; 267| const char* keyPath; 268| char* dataName; 269| char s[512]; 270| DWORD dwDisp; 271| 272| ERRORS_FUNC_START( WinX_setReg ); 273| 274| /* keyPath と namePath を設定する */ 275| if ( bDef ) { 276| keyPath = path; 277| dataName = NULL; 278| } 279| else { 280| if ( strlen( path ) >= sizeof( s ) ) 281| error2_1( WinX_Err_TooLongPath, "レジストリのパスが長すぎます(%s)", path ); 282| strcpy( s, path ); 283| keyPath = s; 284| dataName = StrX_RSearchC2( s, '\\' ) + 1; 285| *(dataName - 1) = '\0'; 286| } 287| 288| /* レジストリ・データを設定する */ 289| ret = RegCreateKeyEx( baseKey, keyPath, 0, 0, 290| REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dwDisp ); 291| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 292| 293| ret = RegSetValueEx( key, dataName, 0, 294| data->type, data->data, data->size ); 295| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 296| 297| ret = RegCloseKey( key ); 298| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 299| 300| ERRORS_FUNC_END( WinX_setReg ); 301|} 302| 303|/************************************************************************** 304| 3-3. <<< [WinX_delReg] レジストリのキーまたはデータを削除する >>> 305|【引数】 306| ・HKEY baseKey; 基準キー(HKEY_CLASSES_ROOT など、サブキーでも可) 307| ・char* path; 基準キーからのパス 308| ・bool bKey; path はキーかどうか 309|【補足】 310|・サブ・キーがあったときは、例外が発生します。 311|***************************************************************************/ 312|void WinX_delReg( HKEY baseKey, const char* path, bool bKey ) 313|{ 314| LONG ret; 315| 316| ERRORS_FUNC_START( WinX_delReg ); 317| 318| if ( bKey && StrX_strchr2( path, '\\' ) == NULL ) { 319| ret = RegDeleteKey( baseKey, path ); 320| if ( (ret & 0xFFFF) != ERROR_FILE_NOT_FOUND && ret != ERROR_SUCCESS ) 321| WinX_throw( ret ); 322| } 323| else { 324| HKEY key; 325| char path2[512]; 326| char name2[512]; 327| 328| StrX_cpyFolder( path2, path ); 329| StrX_cpyFName( name2, path ); 330| ret = RegOpenKeyEx( baseKey, path2, 0L, KEY_WRITE, &key ); 331| if ( (ret & 0xFFFF) != ERROR_FILE_NOT_FOUND ) { 332| if ( ret != ERROR_SUCCESS ) 333| WinX_throw( ret ); 334| 335| if ( bKey ) 336| ret = RegDeleteKey( key, name2 ); 337| else 338| ret = RegDeleteValue( key, name2 ); 339| if ( (ret & 0xFFFF) != ERROR_FILE_NOT_FOUND && ret != ERROR_SUCCESS ) 340| WinX_throw( ret ); 341| 342| ret = RegCloseKey( key ); 343| if ( ret != ERROR_SUCCESS ) 344| WinX_throw( ret ); 345| } 346| } 347| 348| ERRORS_FUNC_END( WinX_delReg ); 349|} 350| 351|/************************************************************************** 352| 3-4. <<< [WinX_delRegIfNoSub] サブキーが無ければ削除する >>> 353|【引数】 354| ・HKEY baseKey; 基準キー(HKEY_CLASSES_ROOT など、サブキーでも可) 355| ・char* path; 削除するキー、基準キーからのパス 356|***************************************************************************/ 357|void WinX_delRegIfNoSub( HKEY baseKey, const char* path ) 358|{ 359| LONG ret; 360| HKEY key; 361| char path2[512]; 362| char name1[512]; 363| char name2[512]; 364| int size; 365| 366| ERRORS_FUNC_START( WinX_delRegIfNoSub ); 367| 368| ret = RegOpenKeyEx( baseKey, path, 0L, KEY_ALL_ACCESS, &key ); 369| if ( (ret & 0xFFFF) != ERROR_FILE_NOT_FOUND ) { 370| if ( ret != ERROR_SUCCESS ) 371| WinX_throw( ret ); 372| 373| size = sizeof(name1); 374| ret = RegEnumKeyEx( key, 0, name1, &size, NULL, NULL, NULL, NULL ); 375| if ( ret != ERROR_SUCCESS ) { 376| 377| if ( StrX_strchr2( path, '\\' ) == NULL ) { 378| ret = RegDeleteKey( baseKey, path ); 379| if ( ret != ERROR_SUCCESS ) 380| WinX_throw( ret ); 381| } 382| else { 383| ret = RegCloseKey( key ); 384| if ( ret != ERROR_SUCCESS ) 385| WinX_throw( ret ); 386| 387| StrX_cpyFolder( path2, path ); 388| StrX_cpyFName( name2, path ); 389| ret = RegOpenKeyEx( baseKey, path2, 0L, KEY_ALL_ACCESS, &key ); 390| if ( ret != ERROR_SUCCESS ) 391| WinX_throw( ret ); 392| 393| ret = RegDeleteKey( key, name2 ); 394| if ( ret != ERROR_SUCCESS ) { 395| error2_4( WinX_Err_AccessDenied, "%s(%s,%s) を削除できません(%d)", 396| name2, path2, name1, ret ); /* レジストリを確認(保存) */ 397| } 398| } 399| } 400| ret = RegCloseKey( key ); 401| if ( ret != ERROR_SUCCESS ) 402| WinX_throw( ret ); 403| } 404| 405| ERRORS_FUNC_END( WinX_delRegIfNoSub ); 406|} 407| 408|/************************************************************************** 409| 3-5. <<< [WinX_isExistReg] レジストリのキーまたはデータが存在するかどうかを返す >>> 410|【引数】 411| ・HKEY baseKey; 基準キー(HKEY_CLASSES_ROOT など、サブキーでも可) 412| ・char* path; 基準キーからのパス 413| ・bool bKey; path はキーかどうか 414| ・bool bKeyOrData; path が、キーとデータの違いがあっても true を返すかどうか 415|***************************************************************************/ 416|bool WinX_isExistReg( HKEY baseKey, const char* path, bool bKey, bool bKeyOrData ) 417|{ 418| HKEY key; 419| LONG ret; 420| 421| ERRORS_FUNC_START( WinX_isExistReg ); 422| 423| /* キーが存在するかどうかを調べる */ 424| if ( bKey || bKeyOrData ) { 425| ret = RegOpenKeyEx( baseKey, path, 0L, KEY_QUERY_VALUE, &key ); 426| if ( ret == ERROR_SUCCESS ) { 427| RegCloseKey( key ); 428| ERRORS_FUNC_END( WinX_isExistReg ); 429| return true; 430| } 431| } 432| 433| /* データが存在するかどうかを調べる */ 434| if ( ! bKey || bKeyOrData ) { 435| char s[512]; 436| 437| StrX_cpyFolder( s, path ); 438| ret = RegOpenKeyEx( baseKey, s, 0L, KEY_READ, &key ); 439| if ( ret != ERROR_SUCCESS ) return false; 440| 441| ret = RegQueryValueEx( key, StrX_refFName( path ), NULL, NULL, NULL, 0 ); 442| 443| RegCloseKey( key ); 444| 445| ERRORS_FUNC_END( WinX_isExistReg ); 446| return ( ret == ERROR_SUCCESS ); 447| } 448| 449| ERRORS_FUNC_END( WinX_isExistReg ); 450| return false; 451|} 452| 453|/************************************************************************** 454| 3-6. <<< [WinX_getReg_s] レジストリの値(文字列)を取得する >>> 455|【引数】 456| ・HKEY baseKey; 基準キー(HKEY_CLASSES_ROOT など、サブキーでも可) 457| ・char* subKey; キーの残りの文字列 458| ・char* name; データの名前の文字列(標準の場合は NULL) 459| ・char* var; データ(文字列)を格納するアドレス 460| ・int var_size; var のメモリサイズ 461|【補足】 462|・WinX_getReg の説明を参照。 463|***************************************************************************/ 464|char* WinX_getReg_s( HKEY baseKey, const char* subKeyPath, 465| const char* name, char* var, int var_size ) 466|{ 467| LONG ret; 468| HKEY key; 469| DWORD type; 470| DWORD size = var_size; 471| 472| ERRORS_FUNC_START( WinX_getReg_s ); 473| 474| ret = RegOpenKeyEx( baseKey, subKeyPath, 0L, KEY_READ, &key ); 475| if ( ret != ERROR_SUCCESS ) { 476| if ( ret == 2 ) { 477| error2_1( WinX_Err_NoRegKey, "レジストリのキー「%s」が見つかりません。", 478| subKeyPath ); 479| } 480| else 481| WinX_throw( ret ); 482| } 483| 484| ret = RegQueryValueEx( key, name, NULL, &type, var, &size ); 485| if ( ret != ERROR_SUCCESS ) { 486| RegCloseKey( key ); 487| if ( ret == 2 ) { 488| error2_2( WinX_Err_NoRegData, "レジストリのキー「%s」のデータ「%s」が見つかりません。", 489| subKeyPath, name ); 490| } 491| else 492| WinX_throw( ret ); 493| } 494| if ( type != REG_SZ ) { 495| error2_2( WinX_Err_DifferentType, "レジストリのキー「%s」のデータ「%s」のタイプが異なります。", 496| subKeyPath, name ); 497| } 498| ASSERT( size <= (DWORD)var_size ); 499| 500| ret = RegCloseKey( key ); 501| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 502| 503| ERRORS_FUNC_END( WinX_getReg_s ); 504| return var; 505|} 506| 507| 508| 509|/************************************************************************** 510| 3-7. <<< [WinX_getReg_x] レジストリの値(バイナリ)を取得する >>> 511|【引数】 512| ・HKEY baseKey; 基準キー(HKEY_CLASSES_ROOT など、サブキーでも可) 513| ・char* subKey; キーの残りの文字列 514| ・char* name; データの名前の文字列(標準の場合は NULL) 515| ・char* var; データ(バイナリ)を格納するアドレス 516| ・int var_size; var のメモリサイズ 517|【補足】 518|・WinX_getReg の説明を参照。 519|・WinX_getReg_s との違いは、取得する値の型がバイナリであることのみです。 520|***************************************************************************/ 521|char* WinX_getReg_x( HKEY baseKey, const char* subKeyPath, 522| const char* name, void* var, int var_size ) 523|{ 524| LONG ret; 525| HKEY key; 526| DWORD type; 527| DWORD size = var_size; 528| 529| ERRORS_FUNC_START( WinX_getReg_x ); 530| 531| ret = RegOpenKeyEx( baseKey, subKeyPath, 0L, KEY_READ, &key ); 532| if ( ret != ERROR_SUCCESS ) { 533| if ( ret == 2 ) { 534| error2_1( WinX_Err_NoRegKey, "レジストリのキー「%s」が見つかりません。", 535| subKeyPath ); 536| } 537| else { 538| WinX_throw( ret ); 539| } 540| } 541| 542| ret = RegQueryValueEx( key, name, NULL, &type, var, &size ); 543| if ( ret == 2 ) { 544| error2_2( WinX_Err_NoRegData, "レジストリのキー「%s」のデータ「%s」が見つかりません。", 545| subKeyPath, name ); 546| } 547| else if ( ret != ERROR_SUCCESS ) { 548| WinX_throw( ret ); 549| } 550| if ( type != REG_BINARY ) { 551| error2_2( WinX_Err_DifferentType, "レジストリのキー「%s」のデータ「%s」のタイプが異なります。", 552| subKeyPath, name ); 553| } 554| ASSERT( size <= (DWORD)var_size ); 555| 556| ret = RegCloseKey( key ); 557| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 558| 559| ERRORS_FUNC_END( WinX_getReg_x ); 560| return var; 561|} 562| 563| 564| 565|/************************************************************************** 566| 3-8. <<< [WinX_copyRegNest] レジストリをサブキーを含めてコピーする >>> 567|【引数】 568| ・HKEY dstKey; コピー先のキー(HKEY_CLASSES_ROOT など) 569| ・char* dstPath; コピー先のパス(dstKey からの相対) 570| ・HKEY srcKey; コピー元のキー 571| ・char* dstPath; コピー元のパス(srcKey からの相対) 572|***************************************************************************/ 573|#ifdef USES_EXCEPT3 574|void WinX_copyRegNest( HKEY dstKey, const char* dstPath, 575| HKEY srcKey, const char* srcPath ) 576|{ 577| WinX_RegNest nest; 578| char dstPath2[256]; 579| WinX_RegData data; 580| bool bKey; 581| char dataX[256]; 582| 583| ERRORS_FUNC_START( WinX_copyRegNest ); 584| 585| WinX_RegData_init( &data, dataX, sizeof(dataX) ); 586| WinX_RegNest_init( &nest, srcKey, srcPath, true ); 587| 588| while ( WinX_RegNest_next( &nest ) ) { 589| 590| /* dstKey2, dstDataName2 を取得する */ 591| ASSERT( dstPath2[0] != '\0' ); 592| strcpy( dstPath2, dstPath ); strcat( dstPath2, "\\" ); 593| strcat( dstPath2, WinX_RegNest_getStepPath( &nest ) ); 594| StrX_cutLastOf( dstPath2, '\\' ); 595| bKey = WinX_RegNest_getIsKey( &nest ); 596| 597| /* データをコピーする */ 598| c_try { 599| WinX_RegNest_getData( &nest, &data ); 600| WinX_setReg( dstKey, dstPath2, bKey, &data ); 601| } 602| c_catch( Errors_Msg*, msg ) { 603| if ( msg->code != WinX_Err_NoRegData || !bKey ) 604| c_throw_again(); 605| } c_end_catch; 606| } 607| 608| WinX_RegNest_finish( &nest ); 609| ERRORS_FUNC_END( WinX_copyRegNest ); 610|} 611|#endif 612| 613| 614|/************************************************************************** 615| 3-9. <<< [WinX_delRegNest] レジストリのキーをサブキーも含めて削除する >>> 616|【引数】 617| ・HKEY baseKey; 基準キー(HKEY_CLASSES_ROOT など、サブキーでも可) 618| ・char* path; 基準キーからのパス(キーを指定してください) 619|【補足】 620|・キーが HKEY_CLASSES_ROOT\Display\Settings の場合、 621| baseKey == HKEY_CLASSES_ROOT, path == "Display\\Settings" を指定します。 622|・すでに存在しないときでも、例外は発生しません。 623|***************************************************************************/ 624|#ifdef USES_EXCEPT3 625|void WinX_delRegNest( HKEY baseKey, const char* path ) 626|{ 627| WinX_RegNest nest; 628| 629| ERRORS_FUNC_START( WinX_delRegNest ); 630| 631| WinX_RegNest_init( &nest, baseKey, path, true ); 632| 633| while ( WinX_RegNest_next( &nest ) ) { 634| WinX_delReg( baseKey, WinX_RegNest_getAbsPath( &nest ), 635| WinX_RegNest_getIsKey( &nest ) ); 636| } 637| WinX_RegNest_finish( &nest ); 638| 639| WinX_delReg( baseKey, path, true ); 640| ERRORS_FUNC_END( WinX_delRegNest ); 641|} 642|#endif 643| 644|/*------------------------------------------------------------------------*/ 645|/* 4. <<<< ◆(WinX_RegNest) サブキーを含めたレジストリの列挙 >>>> */ 646|/*------------------------------------------------------------------------*/ 647| 648|void WinX_RegNest_add( WinX_RegNest* ); 649| 650| 651| 652|/************************************************************************** 653| 4-1. <<< [WinX_RegNest_init] 初期化する >>> 654|【引数】 655| ・char* absPath; 列挙する基底のディレクトリ・パス 656| ・bool bFinishedDir; 探索が済んだディレクトリも列挙するかどうか 657|【補足】 658|・初期化しても、WinX_RegNest_next するまで、ファイル名を参照することはできません。 659|***************************************************************************/ 660|#ifdef USES_EXCEPT3 661|void WinX_RegNest_init( WinX_RegNest* m, HKEY baseKey, const char* absPath, 662| bool bFinishedDir ) 663|{ 664| int i; 665| 666| ERRORS_FUNC_START( WinX_RegNest_init ); 667| 668| m->fname = malloc( sizeof(char*) * WinX_RegNest_bufM ); 669| m->fname_memArea = (char*)malloc( sizeof(char) * WinX_RegNest_bufM * (WinX_RegNest_nameSize + 1) ); 670| for ( i = 0; i < WinX_RegNest_bufM; i++ ) 671| m->fname[i] = m->fname_memArea + i * (WinX_RegNest_nameSize + 1); 672| m->bFinishedDir = bFinishedDir; 673| 674| m->I = malloc( sizeof(int) * (WinX_nestM + 1) ); 675| 676| m->baseKey = baseKey; 677| strcpy( m->absPath, absPath ); 678| 679| m->nest = -1; 680| c_try { 681| WinX_RegNest_add( m ); 682| m->bKey = ( WinX_RegNest_getDataCount( m ) == 0 ); 683| } 684| c_catch ( Errors_Msg*, msg ) { 685| if ( msg->code != WinX_Err_CannotAddNest ) c_throw_again(); 686| m->nest= -1; 687| } c_end_catch; 688| m->I[1] ++; 689| 690| ERRORS_FUNC_END( WinX_RegNest_init ); 691|} 692|#endif 693| 694| 695|/************************************************************************** 696| 4-2. <<< [WinX_RegNest_finish] 後始末する >>> 697|***************************************************************************/ 698|void WinX_RegNest_finish( WinX_RegNest* m ) 699|{ 700| ERRORS_FUNC_START( WinX_RegNest_finish ); 701| free( m->fname_memArea ); 702| free( m->fname ); 703| free( m->I ); 704| ERRORS_FUNC_END( WinX_RegNest_finish ); 705|} 706| 707| 708| 709|/************************************************************************** 710| 4-3. <<< [WinX_RegNest_next] 次のファイルを参照する >>> 711|【引数】 712| ・返り値 : 次の候補があるか 713|【補足】 714|・最初、または次のファイルを参照するようにします。つまり、この関数を 715| 呼び出すたびに、WinX_RegNest_getName 関数、WinX_RegNest_getPath 関数、 716| WinX_RegNest_getAbsPath 関数によって参照されるキー名と、 717| WinX_RegNest_getVar 関数によって参照される値が変わります。 718|***************************************************************************/ 719|bool WinX_RegNest_next( WinX_RegNest* m ) 720|{ 721| bool r; 722| 723| ERRORS_FUNC_START( WinX_RegNest_next ); 724| 725| if ( m->nest <= 0 ) { r = false; goto ret; } 726| 727| /* 次のデータがすぐあれば返る */ 728| m->I[m->nest] --; 729| 730| if ( m->I[m->nest] >= m->I[m->nest - 1] ) { 731| { r = true; goto ret; } 732| } 733| 734| /* bFinishedDir のとき */ 735| if ( m->bKey ) { 736| m->nest --; 737| m->bKey = false; 738| } 739| 740| do { 741| 742| /* ルートのサブキーがあるとき */ 743| if ( m->nest == 1 ) { 744| if ( m->I[0] == 0 ) { r = false; goto ret; } 745| m->nest --; 746| m->I[0] --; 747| } 748| 749| /* ルートより下位のキーの... */ 750| else { 751| 752| /* サブキーがあるとき */ 753| if ( WinX_RegNest_getNotExpandSubKeyCount( m ) > 0 ) { 754| m->nest --; 755| m->I[m->nest] --; 756| } 757| 758| /* サブキーがもう無いとき */ 759| else { 760| 761| /* 処理済のキーを返すとき、そのキーを返す */ 762| if ( m->bFinishedDir ) { 763| m->bKey = true; 764| { r = true; goto ret; } 765| } 766| 767| /* 次のデータかキーまで親キーへ戻る */ 768| m->nest -= 2; 769| while ( m->I[m->nest] - 1 == m->I[m->nest - 1] ) { 770| if ( m->I[m->nest - 1] == 0 ) { r = false; goto ret; } 771| m->nest --; 772| } 773| m->I[m->nest] --; 774| } 775| } 776| 777| /* 次のサブキーとデータを格納する */ 778| WinX_RegNest_add( m ); 779| m->bKey = ( WinX_RegNest_getDataCount( m ) == 0 ); 780| 781| } while ( m->bKey ); 782| /* データが無いときは、次のキーの内容を格納する */ 783| r = true; 784| 785|ret: 786| ERRORS_FUNC_END( WinX_RegNest_next ); 787| return r; 788|} 789| 790| 791| 792| 793|/************************************************************************** 794| 4-4. <<< [WinX_RegNest_add] スタックに、あるキーが持つ、サブキー名とデータ名の列挙を追加する >>> 795|【補足】 796|・m->I[0] 〜 m->I[m->nest] から作られるパスのキーのサブキーと 797| データを取得します。 798|・サブ・キーまたはデータが無いときは追加しませんが、ネスト数(m->nest)は増えます。 799|***************************************************************************/ 800|void WinX_RegNest_add( WinX_RegNest* m ) 801|{ 802| LONG ret; 803| int i, n, first; 804| DWORD size; 805| char* path; 806| FILETIME dummyTime; 807| HKEY key; 808| 809| ERRORS_FUNC_START( WinX_RegNest_add ); 810| 811| strcpy( m->workPath, m->absPath ); 812| if ( m->nest >= 0 ) { 813| strcat( m->workPath, "\\" ); 814| for ( i = 0; i <= m->nest - 1; i++ ) { 815| strcat( m->workPath, m->fname[ m->I[i] ] ); 816| strcat( m->workPath, "\\" ); 817| } 818| strcat( m->workPath, m->fname[ m->I[i] ] ); 819| } 820| path = m->workPath; 821| 822| 823| ret = RegOpenKeyEx( m->baseKey, path, 0L, KEY_READ, &key ); 824| if ( ret != ERROR_SUCCESS ) 825| error2_1( WinX_Err_CannotAddNest, "レジストリ %s がありません", path ); 826| 827| /* m->I[m->nest] のサブキー名の列挙を読み込む */ 828| n = 0; 829| i = ( m->nest >= 0 ) ? m->I[m->nest] : -1; 830| first = i + 1; 831| for (;;) { 832| i++; size = WinX_RegNest_nameSize; 833| ret = RegEnumKeyEx( key, n, m->fname[i], &size, NULL, NULL, NULL, &dummyTime ); 834| if ( ret == ERROR_NO_MORE_ITEMS ) 835| break; 836| n++; 837| } 838| for ( i = 0; i < n / 2; i++ ) { 839| char* sw; 840| 841| sw = m->fname[first + i]; 842| m->fname[first + i] = m->fname[first + n - i - 1]; 843| m->fname[first + n - i - 1] = sw; 844| } 845| 846| m->I[m->nest + 1] = ( m->nest >= 0 ) ? m->I[m->nest] + n + 1: n; 847| m->nest ++; 848| 849| 850| /* データ名の列挙を読み込む */ 851| n = 0; 852| i = m->I[m->nest]; 853| first = i; 854| for (;;) { 855| do { 856| size = WinX_RegNest_nameSize; 857| ret = RegEnumValue( key, n, m->fname[i], &size, NULL, NULL, NULL, NULL ); 858| if ( ret == ERROR_NO_MORE_ITEMS ) 859| goto exit_for; 860| n++; 861| } while ( m->fname[i][0] == '\0' ); /*(標準)のデータは格納しない */ 862| i++; 863| } 864| exit_for: 865| n = i - m->I[m->nest]; 866| for ( i = 0; i < n / 2; i++ ) { 867| char* sw; 868| 869| sw = m->fname[first + i]; 870| m->fname[first + i] = m->fname[first + n - i - 1]; 871| m->fname[first + n - i - 1] = sw; 872| } 873| 874| m->I[m->nest + 1] = m->I[m->nest] + n - 1; 875| m->nest ++; 876| 877| ret = RegCloseKey( key ); 878| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 879| 880| ERRORS_FUNC_END( WinX_RegNest_add ); 881|} 882| 883| 884| 885| 886|/************************************************************************** 887| 4-5. <<< [WinX_RegNest_getName] 現在のファイル名を参照する >>> 888|【補足】 889|・フォルダの場所(絶対パス)を含まない、単独のファイル名を参照します。 890|・folder\sub\filename.txt の filename.txt が参照されます。 891|・m->absPath == "folder\" の場合、 892| WinX_RegNest_getName 関数では "filename.txt"、 893| WinX_RegNest_getPath 関数では "sub\filename.txt"、 894| WinX_RegNest_getAbsPath 関数では "folder\sub\filename.txt" が参照されます。 895|・参照しているファイル名は、変更しないでください。 896|***************************************************************************/ 897|char* WinX_RegNest_getName( WinX_RegNest* m ) 898|{ 899| return m->fname[ m->I[m->nest] ]; 900|} 901| 902| 903| 904|/************************************************************************** 905| 4-6. <<< [WinX_RegNest_getStepPath] 現在の相対パスを参照する >>> 906|【補足】 907|・WinX_RegNest_init 関数の absPath 引数に指定したパスからの相対パスを参照します。 908|・参照している相対パスは、WinX_RegNest_getPath() か WinX_RegNest_getAbsPath() 909| のどれかが再び呼び出されると変更されます。 910|***************************************************************************/ 911|char* WinX_RegNest_getStepPath( WinX_RegNest* m ) 912|{ 913| int i; 914| 915| ERRORS_FUNC_START( WinX_RegNest_getStepPath ); 916| 917| strcpy( m->workPath, "" ); 918| 919| if ( m->nest >= 0 ) { 920| for ( i = 0; i <= m->nest - 2; i++ ) { 921| strcat( m->workPath, m->fname[ m->I[i] ] ); 922| strcat( m->workPath, "\\" ); 923| } 924| if ( m->bKey ) 925| StrX_bs( m->workPath ); 926| else 927| strcat( m->workPath, m->fname[ m->I[m->nest] ] ); 928| } 929| 930| ERRORS_FUNC_END( WinX_RegNest_getStepPath ); 931| return m->workPath; 932|} 933| 934| 935| 936|/************************************************************************** 937| 4-7. <<< [WinX_RegNest_getAbsPath] 現在の絶対パスを参照する >>> 938|【補足】 939|・参照している相対パスは、WinX_RegNest_getPath() か WinX_RegNest_getAbsPath() 940| のどれかが再び呼び出されると変更されます。 941|***************************************************************************/ 942|char* WinX_RegNest_getAbsPath( WinX_RegNest* m ) 943|{ 944| char s[_MAX_PATH]; 945| 946| ERRORS_FUNC_START( WinX_RegNest_getAbsPath ); 947| 948| strcpy( s, WinX_RegNest_getStepPath( m ) ); 949| strcpy( m->workPath, m->absPath ); 950| if ( s[0] != '\0' ) { 951| strcat( m->workPath, "\\" ); 952| strcat( m->workPath, s ); 953| } 954| 955| ERRORS_FUNC_END( WinX_RegNest_getAbsPath ); 956| return m->workPath; 957|} 958| 959| 960| 961|/************************************************************************** 962| 4-8. <<< [WinX_RegNest_getData] 現在のレジストリ・データを取得する >>> 963|***************************************************************************/ 964|void WinX_RegNest_getData( WinX_RegNest* m, WinX_RegData* data ) 965|{ 966| ERRORS_FUNC_START( WinX_RegNest_getData ); 967| 968| WinX_getReg( m->baseKey, WinX_RegNest_getAbsPath( m ), 969| WinX_RegNest_getIsKey( m ), data ); 970| 971| ERRORS_FUNC_END( WinX_RegNest_getData ); 972|} 973| 974| 975|/************************************************************************** 976| 4-9. <<< [WinX_RegNest_getNotExpandSubKeyCount] 現在まだ展開していないサブキーの数を返す >>> 977|***************************************************************************/ 978|int WinX_RegNest_getNotExpandSubKeyCount( WinX_RegNest* m ) 979|{ 980| return m->I[m->nest - 1] - m->I[m->nest - 2] - 1; 981|} 982| 983| 984|/*------------------------------------------------------------------------*/ 985|/* 5. <<<< ◆パス関係 >>>> */ 986|/*------------------------------------------------------------------------*/ 987| 988|/************************************************************************** 989| 5-1. <<< [WinX_getWSHPath] WSH(Windws Scripting Host) のパスを返す >>> 990|【補足】 991|・WSH がインストールされていなかったら NULL を返します。 992| 5-2. <<< [WSH] Windws Scripting Host >>> 993|・WSH(Windows Scripting Host) は Win98 以降ならデフォルトで入っています。 994| Win95 でも、インストールすれば使えます。 995|***************************************************************************/ 996|#if defined(USES_FILEX) && defined(USES_EXCEPT3) 997|char* WinX_getWSHPath() 998|{ 999| static char path[_MAX_PATH]; 1000| 1001| StrX_cpyAbsPath( path, "WScript.exe", _MAX_PATH - 1, WinX_getWindowsPath() ); 1002| if ( FileX_isExist( path ) ) return path; 1003| 1004| StrX_cdFName( path, "system32" ); 1005| if ( FileX_isExist( path ) ) return path; 1006| 1007| return NULL; 1008|} 1009|#endif 1010| 1011|/************************************************************************** 1012| 5-3. <<< [WinX_getWindowsPath] Windowsフォルダのパスを返す >>> 1013|***************************************************************************/ 1014|char* WinX_getWindowsPath() 1015|{ 1016| return getenv( "windir" ); 1017|} 1018| 1019| 1020| 1021|/************************************************************************** 1022| 5-4. <<< [WinX_getSystemPath] Windows のシステムフォルダのパスを返す >>> 1023|***************************************************************************/ 1024|char* WinX_getSystemPath() 1025|{ 1026| static unsigned char var[_MAX_PATH]; 1027| unsigned long size = sizeof(var); 1028| 1029| GetSystemDirectory( var, size ); 1030| 1031|#if 0 1032| HKEY key; 1033| LONG ret; 1034| 1035| ret = RegOpenKeyEx( HKEY_LOCAL_MACHINE, 1036| "Software\\Microsoft\\Windows\\CurrentVersion\\Setup", 1037| 0L, KEY_READ, &key ); 1038| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 1039| 1040| ret = RegQueryValueEx( key, "SysDir", NULL, NULL, var, &size ); 1041| else if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 1042| 1043| RegCloseKey( key ); 1044| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 1045|#endif 1046| 1047| return (char*)var; 1048|} 1049| 1050| 1051| 1052|/************************************************************************** 1053| 5-5. <<< [WinX_getDesktopPath] デスクトップのパスを参照する >>> 1054|【補足】 1055|・通常、"c:\windows\デスクトップ" を参照します。 1056|***************************************************************************/ 1057|char* WinX_getDesktopPath() 1058|{ 1059| static unsigned char var[_MAX_PATH]; 1060| unsigned long size = sizeof(var); 1061| HKEY key; 1062| LONG ret; 1063| 1064| ret = RegOpenKeyEx( HKEY_CURRENT_USER, 1065| "Software\\Microsoft\\Windows\\CurrentVersion\\" 1066| "Explorer\\Shell Folders", 0L, KEY_READ, &key ); 1067| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 1068| 1069| ret = RegQueryValueEx( key, "Desktop", NULL, NULL, var, &size ); 1070| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 1071| 1072| RegCloseKey( key ); 1073| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 1074| 1075| return (char*)var; 1076|} 1077| 1078| 1079| 1080|/************************************************************************** 1081| 5-6. <<< [WinX_getProgramPath] Program Files のパスを参照する >>> 1082|【補足】 1083|・通常、"c:\Program Files\" を参照します。 1084|***************************************************************************/ 1085|char* WinX_getProgramPath() 1086|{ 1087| static unsigned char var[_MAX_PATH]; 1088| unsigned long size = sizeof(var); 1089| HKEY key; 1090| LONG ret; 1091| 1092| ret = RegOpenKeyEx( HKEY_LOCAL_MACHINE, 1093| "Software\\Microsoft\\Windows\\CurrentVersion", 0L, KEY_READ, &key ); 1094| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 1095| 1096| ret = RegQueryValueEx( key, "ProgramFilesDir", NULL, NULL, var, &size ); 1097| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 1098| 1099| RegCloseKey( key ); 1100| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 1101| 1102| return (char*)var; 1103|} 1104| 1105| 1106| 1107|/************************************************************************** 1108| 5-7. <<< [WinX_getSendToPath] 「送る」のパスを参照する >>> 1109|【補足】 1110|・通常、"c:\windows\sendto" を参照します。 1111|***************************************************************************/ 1112|char* WinX_getSendToPath() 1113|{ 1114| static unsigned char var[_MAX_PATH]; 1115| unsigned long size = sizeof(var); 1116| HKEY key; 1117| LONG ret; 1118| 1119| ret = RegOpenKeyEx( HKEY_CURRENT_USER, 1120| "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer", 1121| 0L, KEY_READ, &key ); 1122| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 1123| 1124| ret = RegQueryValueEx( key, "Shell Folders", NULL, NULL, var, &size ); 1125| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 1126| 1127| RegCloseKey( key ); 1128| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 1129| 1130| return (char*)var; 1131|} 1132| 1133| 1134| 1135|/************************************************************************** 1136| 5-8. <<< [WinX_getMyDocPath] My Documents のパスを参照する >>> 1137|【補足】 1138|・通常、"c:\My Documents\" を参照します。 1139|***************************************************************************/ 1140|char* WinX_getMyDocPath() 1141|{ 1142| static unsigned char var[_MAX_PATH]; 1143| unsigned long size = sizeof(var); 1144| HKEY key; 1145| LONG ret; 1146| 1147| ret = RegOpenKeyEx( HKEY_CURRENT_USER, 1148| "Software\\Microsoft\\Windows\\CurrentVersion\\" 1149| "Explorer\\Shell Folders", 0L, KEY_READ, &key ); 1150| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 1151| 1152| ret = RegQueryValueEx( key, "Personal", NULL, NULL, var, &size ); 1153| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 1154| 1155| RegCloseKey( key ); 1156| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 1157| 1158| return (char*)var; 1159|} 1160| 1161| 1162| 1163|/************************************************************************** 1164| 5-9. <<< [WinX_getStartupPath] スタートアップのパスを参照する >>> 1165|【補足】 1166|・通常、"C:\Documents and Settings\xxx\スタート メニュー\プログラム\スタートアップ" を参照します。 1167|***************************************************************************/ 1168|char* WinX_getStartupPath() 1169|{ 1170| static unsigned char var[_MAX_PATH]; 1171| unsigned long size = sizeof(var); 1172| HKEY key; 1173| LONG ret; 1174| 1175| ret = RegOpenKeyEx( HKEY_CURRENT_USER, 1176| "Software\\Microsoft\\Windows\\CurrentVersion\\" 1177| "Explorer\\Shell Folders", 0L, KEY_READ, &key ); 1178| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 1179| 1180| ret = RegQueryValueEx( key, "Startup", NULL, NULL, var, &size ); 1181| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 1182| 1183| RegCloseKey( key ); 1184| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 1185| 1186| 1187| return (char*)var; 1188|} 1189| 1190| 1191| 1192|/************************************************************************** 1193| 5-10. <<< [WinX_getTempPath] Win98 のクリーンアップに対応の TEMP パスを参照する >>> 1194|【補足】 1195|・通常、"c:\windows\TEMP\" を参照します。 1196|・クリーンアップが TEMP に作成したフォルダを認識しないことがあります。 1197|***************************************************************************/ 1198|#ifdef USES_STRX 1199|char* WinX_getTempPath() 1200|{ 1201| static unsigned char var[_MAX_PATH]; 1202| 1203| strcpy( var, getenv( "TEMP" ) ); 1204| StrX_cutLastOf2( var, '\\' ); 1205| 1206| return (char*)var; 1207|} 1208|#endif 1209| 1210| 1211|/*------------------------------------------------------------------------*/ 1212|/* 6. <<<< ◆ウィンドウ関係 >>>> */ 1213|/*------------------------------------------------------------------------*/ 1214| 1215|/*********************************************************************** 1216| 6-1. <<< [WinX_getWndRectN] ウィンドウの座標を得る(最大化などから元に戻したときの) >>> 1217|【引数】 1218| ・HWND hWnd; ウィンドウ 1219| ・RECT* rect; (出力)ウィンドウの座標 1220|【補足】 1221|・最大化したときに、ほぼ画面全体の座標を得るときは、APIの GetWindowRect 1222| を使ってください。 1223|************************************************************************/ 1224|void WinX_getWndRectN( HWND hWnd, RECT* rect ) 1225|{ 1226| WINDOWPLACEMENT a; 1227| RECT desktopWorkArea; 1228| 1229| GetWindowPlacement( hWnd, &a ); 1230| *rect = a.rcNormalPosition; 1231| SystemParametersInfo( SPI_GETWORKAREA, 0, &desktopWorkArea, 0 ); 1232| rect->left += desktopWorkArea.left; 1233| rect->right += desktopWorkArea.left; 1234| rect->top += desktopWorkArea.top; 1235| rect->bottom += desktopWorkArea.top; 1236|} 1237| 1238|/*********************************************************************** 1239| 6-2. <<< [WinX_setIme] 日本語 IME をオンまたはオフにする >>> 1240|【引数】 1241| ・HWND hWnd; ウィンドウ 1242| ・bool bOn; 日本語IMEをオンにするかどうか 1243|************************************************************************/ 1244|void WinX_setIme( HWND hWnd, bool bOn ) 1245|{ 1246| HIMC ime; 1247| 1248| ime = ImmGetContext( hWnd ); 1249| if ( ime ) { 1250| ImmSetOpenStatus( ime, bOn ); 1251| ImmReleaseContext( hWnd, ime ); 1252| } 1253|} 1254| 1255|/*********************************************************************** 1256| 6-3. <<< [WinX_getIme] 日本語 IME がオンかどうかを返す >>> 1257|【引数】 1258| ・HWND hWnd; ウィンドウ 1259| ・bool 返り値; 日本語IMEをオンにするかどうか 1260|************************************************************************/ 1261|bool WinX_getIme( HWND hWnd ) 1262|{ 1263| HIMC ime; 1264| bool ret = false; 1265| 1266| ime = ImmGetContext( hWnd ); 1267| if ( ime ) { 1268| ret = ImmGetOpenStatus( ime ); 1269| ImmReleaseContext( hWnd, ime ); 1270| } 1271| 1272| return ret; 1273|} 1274| 1275| 1276|/*********************************************************************** 1277| 6-4. <<< [WinX_getNumOfWnd] パソコン全体のウィンドウの数を返す >>> 1278|************************************************************************/ 1279|int WinX_getNumOfWnd() 1280|{ 1281| HWND wnd; 1282| int n = 0; 1283| 1284| for ( wnd = GetTopWindow( GetDesktopWindow() ); 1285| wnd != NULL; 1286| wnd = GetNextWindow( wnd, GW_HWNDNEXT ) ) { 1287| n++; 1288| } 1289| return n; 1290|} 1291| 1292| 1293|/*********************************************************************** 1294| 6-5. <<< [WinX_getAllAppHWnd] 指定のプログラムのウィンドウハンドルの一覧を取得する >>> 1295|【引数】 1296| ・HWND* hs; (出力)ウィンドウハンドルの集合 1297| ・int hs_size; hs のメモリサイズ 1298| ・char* exe_fname; 実行ファイル名 1299| ・int 返り値; 格納した要素数 1300|************************************************************************/ 1301|int WinX_getAllAppHWnd( HWND* hs, int hs_size, const char* exe_fname ) 1302|{ 1303| HWND wnd; 1304| HWND* hs_first = hs; 1305| HWND* hs_over = (HWND*)( (char*)hs + hs_size ); 1306| char path[_MAX_PATH]; 1307| 1308| 1309| for ( wnd = GetTopWindow( GetDesktopWindow() ); 1310| wnd != NULL; 1311| wnd = GetNextWindow( wnd, GW_HWNDNEXT ) ) { 1312| WinX_getExeFNameOfWnd( wnd, path ); 1313| if ( exe_fname == NULL || stricmp( path, exe_fname ) == 0 ) { 1314| *hs = wnd; 1315| hs++; 1316| if ( hs >= hs_over ) break; 1317| } 1318| } 1319| return hs - hs_first; 1320|} 1321| 1322|/*------------------------------------------------------------------------*/ 1323|/* 7. <<<< ◆ディスプレイ関係 >>>> */ 1324|/*------------------------------------------------------------------------*/ 1325| 1326|/************************************************************************** 1327| 7-1. <<< [WinX_setDisplayBppReturnValue] WinX_getDisplayBpp 関数の返り値を設定する >>> 1328|【補足】 1329|・WinX_getDisplayBpp 関数で自動判断ができないときに使います。 1330|・0 を指定すると、自動判定に戻します。 1331|***************************************************************************/ 1332|int WinX_displayBppReturnValue = 0; 1333| 1334|void WinX_setDisplayBppReturnValue( int bpp ) 1335|{ 1336| WinX_displayBppReturnValue = bpp; 1337|} 1338| 1339| 1340|/************************************************************************** 1341| 7-2. <<< [WinX_getDisplayBpp] ディスプレイの色のビット数を返す >>> 1342|【補足】 1343| ・Win2000 でも使えます。 1344|【旧バージョンの補足】 1345|・15Bpp(R5G5B5) のディスプレイの場合、16を返します。 1346| (判断する方法はありません) 1347|・Windows 2000 では使えません。その代わり、WinX_setDisplayBppReturnValue 1348| 関数を使って本関数の返り値を設定すれば、互換性を保つことができます。 1349|***************************************************************************/ 1350|int WinX_getDisplayBpp() 1351|{ 1352| int ret; 1353| HDC dc; 1354| 1355| dc = GetDC( NULL ); 1356| ret = GetDeviceCaps( dc, BITSPIXEL ); 1357| ReleaseDC( NULL, dc ); 1358| 1359| return ret; 1360| 1361|#if 0 1362| static unsigned char var[_MAX_PATH]; 1363| unsigned long size = sizeof(var); 1364| HKEY key; 1365| LONG ret; 1366| 1367| if ( WinX_displayBppReturnValue == 0 ) { 1368| 1369| ret = RegOpenKeyEx( HKEY_CURRENT_USER, "Display\\Settings", 0L, KEY_READ, &key ); 1370| if ( ret != ERROR_SUCCESS ) { 1371| ret = RegOpenKeyEx( HKEY_CURRENT_CONFIG, "Display\\Settings", 0L, KEY_READ, &key ); 1372| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 1373| } 1374| 1375| ret = RegQueryValueEx( key, "BitsPerPixel", NULL, NULL, var, &size ); 1376| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 1377| 1378| RegCloseKey( key ); 1379| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 1380| 1381| return atoi(var); 1382| } 1383| else 1384| return WinX_displayBppReturnValue; 1385|#endif 1386|} 1387| 1388| 1389| 1390|/*------------------------------------------------------------------------*/ 1391|/* 8. <<<< ◆プログラム実行関係 >>>> */ 1392|/*------------------------------------------------------------------------*/ 1393| 1394|/************************************************************************** 1395| 8-1. <<< [WinX_call] プログラムを呼び出し、終了するまで待つ >>> 1396|【引数】 1397| ・char* cmdline; コマンドライン(実行ファイルパス+パラメータ) 1398| ・int 返り値; 呼び出したプログラムの返り値 1399|***************************************************************************/ 1400|#if defined(USES_WINERR) && defined(USES_STRX) 1401|int WinX_call( const char* cmdline ) 1402|{ 1403| BOOL r; 1404| STARTUPINFO st; 1405| PROCESS_INFORMATION pi; 1406| DWORD ret; 1407| char path[_MAX_PATH]; 1408| 1409| GetStartupInfo( &st ); 1410| StrX_getSpacedPath( cmdline, path, NULL ); 1411| 1412| r = CreateProcess( path, (char*)cmdline, NULL, NULL, FALSE, 1413| 0, NULL, NULL, &st, &pi ); 1414| if ( r == 0 ) { 1415| ret = GetLastError(); 1416| if ( ret == 2 ) 1417| error2_1( WinX_Err_FileNotFound, "%s が見つかりません", path ); 1418| else 1419| error(); 1420| } 1421| 1422| WaitForSingleObject( pi.hProcess, INFINITE ); 1423| 1424| GetExitCodeProcess( pi.hProcess, &ret ); 1425| 1426| CloseHandle( pi.hProcess ); 1427| 1428| return (int)ret; 1429|} 1430|#endif 1431| 1432|/************************************************************************** 1433| 8-2. <<< [WinX_openHtml] HTML ページを開く >>> 1434|【機能】 1435|・デフォルトで使用するブラウザをレジストリから調べて、 1436| 必要ならブラウザを開いて HTML ページを表示させます。 1437|【引数】 1438| ・char* url; 開く HTML ページの URL 1439| ・bool bNewWnd; 新しいウィドウで開くかどうか 1440|【補足】 1441|・ローカル上、インターネット上どちらの HTML ページも開くことが出来ます。 1442|***************************************************************************/ 1443|#if defined(USES_BIGSTACK) && defined(USES_STRX) && defined(USES_EXCEPT3) 1444|#if defined(USES_FILEX) 1445|void WinX_openHtml_sub( const char* url, bool bNewWnd, int browser ); 1446| 1447|void WinX_openHtml( const char* url, bool bNewWnd ) 1448|{ 1449| WinX_openHtml_sub( url, bNewWnd, 0 ); 1450|} 1451| 1452| 1453|/* browser: 0=標準のブラウザ, 1=IE(for ActiveX) */ 1454|void WinX_openHtml_sub( const char* url, bool bNewWnd, int browser ) 1455|{ 1456| enum { size = 512 }; 1457| char* subName; 1458| char url2[size]; 1459| char command[size]; 1460| char data[size]; 1461| char service[size]; 1462| char topic[size]; 1463| 1464| ERRORS_FUNC_START( WinX_openHtml ); 1465| 1466| /* # 付きのパスなら、サブ・ネーム付きの URL とみなす */ 1467| subName = StrX_refURLSubName( url ); 1468| strcpy( url2, url ); 1469| if ( *subName == '\0' ) { 1470| strcpy( url2, url ); 1471| } 1472| else { 1473| FILE* f; 1474| char regularURL[_MAX_PATH]; 1475| 1476| if ( StrX_isUrl( url ) ) 1477| strcpy( regularURL, url ); 1478| else 1479| StrX_chgPathToUrl( regularURL, url ); 1480| 1481| FileX_getTmpPath3( NULL, "url", "htm", url2 ); 1482| f = fopen( url2, "wt" ); 1483| fputs( "<HTML>\n", f ); 1484| fputs( "<HEAD>\n", f ); 1485| fputs( " <META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html;CHARSET=x-sjis\">\n", f ); 1486| fputs( " <TITLE>移動中</TITLE>\n", f ); 1487| fputs( "</HEAD>\n", f ); 1488| fputs( "\n", f ); 1489| fputs( "<BODY onLoad=\"setTimeout('nextp()',1000)\" BGCOLOR=\"#ffffff\">\n", f ); 1490| fputs( "\n", f ); 1491| fputs( "<SCRIPT LANGUAGE=\"JavaScript\">\n", f ); 1492| fputs( "<!--\n", f ); 1493| fprintf( f, "function nextp(){location.href=\"%s\"}\n", regularURL ); 1494| fputs( "//-->\n", f ); 1495| fputs( "</SCRIPT>\n", f ); 1496| fputs( "\n", f ); 1497| fputs( "<P><CENTER></CENTER>\n", f ); 1498| fputs( "<CENTER>\n", f ); 1499| fputs( "\n", f ); 1500| fprintf( f, "<P><A href=\"%s\">ジャンプしています</A><P>\n", regularURL ); 1501| fputs( "\n", f ); 1502| fputs( "</CENTER>\n", f ); 1503| fputs( "</BODY>\n", f ); 1504| fputs( "</HTML>\n", f ); 1505| fclose( f ); 1506| } 1507| 1508| /* 標準のブラウザの情報を取得する */ 1509| if ( browser == 0 ) { 1510| c_try { 1511| WinX_getReg_s( HKEY_CLASSES_ROOT, "http\\shell\\open\\command", 1512| NULL, command, size ); 1513| WinX_getReg_s( HKEY_CLASSES_ROOT, "http\\shell\\open\\ddeexec", 1514| NULL, data, size ); 1515| WinX_getReg_s( HKEY_CLASSES_ROOT, "http\\shell\\open\\ddeexec\\Application", 1516| NULL, service, size ); 1517| WinX_getReg_s( HKEY_CLASSES_ROOT, "http\\shell\\open\\ddeexec\\Topic", 1518| NULL, topic, size ); 1519| } 1520| c_catch ( Errors_Msg*, msg ) { 1521| if ( msg->code == WinX_Err_NoRegKey ) bNewWnd = true; 1522| else c_throw_again(); 1523| } c_end_catch; 1524| } 1525| else if ( browser == 1 ) { 1526| strcpy( command, WinX_getWindowsPath() ); 1527| StrX_addFName( command, "explorer.exe \"%1\"" ); 1528| } 1529| 1530| 1531| /* 開く */ 1532| if ( bNewWnd ) { 1533| if ( strstr( command, "%1" ) != NULL ) 1534| StrX_rep( command, size, "%1", url2 ); 1535| else 1536| { strcat( command, " \"" ); strcat( command, url2 ); strcat( command, "\"" ); } 1537| WinExec( command, SW_SHOWNORMAL ); 1538| } 1539| else { 1540| StrX_rep( data, size, "%1", url2 ); 1541| WinX_sendDDE( command, service, topic, data, strlen( data ), WinX_Request ); 1542| } 1543| 1544| ERRORS_FUNC_END( WinX_openHtml ); 1545|} 1546|#endif 1547|#endif 1548| 1549| 1550|/************************************************************************** 1551| 8-3. <<< [WinX_openIE] Internet Explorer を開く(AcriveX用) >>> 1552|***************************************************************************/ 1553|void WinX_openIE( const char* url ) 1554|{ 1555| WinX_openHtml_sub( url, true, 1 ); 1556|} 1557| 1558| 1559|/************************************************************************** 1560| 8-4. <<< [WinX_openByNotePad] メモ帳でファイルを開く >>> 1561|【引数】 1562| ・char* path; 開くファイルのパス 1563|***************************************************************************/ 1564|void WinX_openByNotepad( const char* path ) 1565|{ 1566| char cmd[_MAX_PATH*2]; 1567| 1568| sprintf( cmd, "%s\\notepad.exe \"%s\"", WinX_getWindowsPath(), path ); 1569| 1570| WinExec( cmd, SW_SHOWNORMAL ); 1571|} 1572| 1573| 1574|/************************************************************************** 1575| 8-5. <<< [WinX_openFile] ユーザ的にファイルを開く(ダブルクリック的) >>> 1576|【引数】 1577| ・char* path; ファイルパス 1578|【補足】 1579|・ファイルをダブルクリックしてファイルを開くことと同じことをします。 1580|【内部補足】 1581|・次の DDE コマンドには対応していません。(DDE を使わないで開きます) 1582| [FindFolder("%l", %I)] 1583| [ViewFolder("%l","%l",%S)] 1584| [ViewFolder(%l, %I, %S)] 1585| [ExploreFolder(%l, %I, %S)] 1586| [printto("%1","%2","%3","%4")] 1587| [ShellFile("%1","%1",%S)] 1588|・shellEx キーの内容には対応していません。 1589| (GUID は、HKEY_CLASSES_ROOT\CLSID にありますが) 1590|・WinX_Err_NoRegKey 例外が出ることがあります。 1591|***************************************************************************/ 1592|#ifdef USES_STRX 1593|#if defined(USES_BIGSTACK) && defined(USES_FILEX) && defined(USES_EXCEPT3) 1594|void WinX_openFile( const char* path ) 1595|{ 1596| HKEY shellKey; 1597| char keyPath[256]; 1598| char action[256]; 1599| DWORD type; 1600| DWORD size; 1601| DWORD index; 1602| LONG ret; 1603| 1604| ERRORS_FUNC_START( WinX_openFile ); 1605| 1606| ASSERT( ! FileX_isDir( path ) ); 1607| ASSERT( FileX_isExist( path ) ); 1608| 1609|#if 0 1610| char* p1; 1611| bool bDDE; 1612| char command[256]; 1613|#endif 1614| 1615| /* # 付きのパスなら、サブ・ネーム付きの URL とみなす */ 1616| { 1617| char* subName = StrX_refURLSubName( path ); 1618| if ( *subName != '\0' ) { 1619| WinX_openHtml( path, true ); 1620| return; 1621| } 1622| } 1623| 1624| /* HKEY_CLASSES_ROOT\.(ext)\(標準) のキーの値を keyPath に取得する */ 1625| c_try { 1626| WinX_getReg_s( HKEY_CLASSES_ROOT, StrX_refExt( path ) - 1, NULL, keyPath, sizeof(keyPath) ); 1627| 1628| } 1629| c_catch ( Errors_Msg*, msg ) { 1630| if ( msg->code == WinX_Err_NoRegKey ) strcpy( keyPath, "*" ); 1631| else c_throw_again(); 1632| } c_end_catch; 1633| 1634| /* HKEY_CLASSES_ROOT\(typeName)\shell キーを shellKey とする */ 1635| /* HKEY_CLASSES_ROOT\(typeName)\shell\(標準) のキーの値を action に取得する */ 1636| strcat( keyPath, "\\shell" ); 1637| ret = RegOpenKeyEx( HKEY_CLASSES_ROOT, keyPath, 0L, KEY_READ, &shellKey ); 1638| if ( ret != ERROR_SUCCESS ) WinX_error2( ret ); 1639| size = sizeof(action); 1640| ret = RegQueryValueEx( shellKey, NULL, NULL, &type, action, &size ); 1641| 1642| /* 上記キー(デフォルト・アクション)が無かったら */ 1643| if ( ret != ERROR_SUCCESS || action[0] == '\0' ) { 1644| 1645| /* HKEY_CLASSES_ROOT\(typeName)\shell\open キーがあれば action に open を代入する */ 1646| index = 0; 1647| do { 1648| ret = RegEnumKey( shellKey, index, action, sizeof(action) ); 1649| index++; 1650| } while ( strcmp( action, "open" ) != 0 && ret == ERROR_SUCCESS ); 1651| 1652| RegCloseKey( shellKey ); 1653| 1654| /* 上記キーが無ければ */ 1655| if ( ret != ERROR_SUCCESS ) { 1656| 1657| /* HKEY_CLASSES_ROOT\*\shell キーを shellKey とする */ 1658| /* HKEY_CLASSES_ROOT\*\shell\\(標準)キーに値があれば action に代入する */ 1659| strcpy( keyPath, "*\\shell" ); 1660| RegOpenKeyEx( HKEY_CLASSES_ROOT, keyPath, 0L, KEY_READ, &shellKey ); 1661| size = sizeof(action); 1662| if ( RegQueryValueEx( shellKey, NULL, NULL, &type, action, &size ) 1663| != ERROR_SUCCESS || *action == '\0' ) { 1664| 1665| /* 無ければ HKEY_CLASSES_ROOT\*\shell のサブキー名を action 代入する */ 1666| RegEnumKey( shellKey, 0, action, sizeof(action) ); 1667| } 1668| RegCloseKey( shellKey ); 1669| } 1670| } 1671| else 1672| RegCloseKey( shellKey ); 1673| 1674|#if 1 1675| ShellExecute( NULL, action, path, "", ".", SW_SHOWNORMAL ); 1676| 1677|#else /* 以下は、Word ファイルの DDE がうまくいかないため却下 */ 1678| 1679| /* 各種実行パラメータを取得する */ 1680| p1 = strchr( keyPath, '\0' ); 1681| bDDE = true; 1682| 1683| sprintf( p1, "\\%s\\command", action ); 1684| WinX_getReg_s( HKEY_CLASSES_ROOT, keyPath, NULL, command, sizeof(command) ); 1685| sprintf( p1, "\\%s", action ); 1686| 1687| /* 実行する */ 1688| WinX_openFile_sub( keyPath, command, path, action ); 1689|#endif 1690| 1691| ERRORS_FUNC_END( WinX_openFile ); 1692|} 1693|#endif 1694|#endif 1695| 1696| 1697| 1698|/************************************************************************** 1699| 8-6. <<< [WinX_openFile2] ユーザ的にファイルを開く(右クリック的) >>> 1700|【引数】 1701| ・char* path; ファイルパス 1702| ・char* action; アクション名("" または NULL で、デフォルトアクション) 1703| ・bool bAll; 対応する拡張子が無いときに全拡張子の情報を使って開くか 1704|【補足】 1705|・ファイルをダブルクリックしたり右クリックしてファイルを開くことと 1706| 同じことをします。 1707|***************************************************************************/ 1708|#if defined(USES_BIGSTACK) && defined(USES_FILEX) && defined(USES_EXCEPT3) 1709|void WinX_openFile2( const char* path, const char* action ) 1710|{ 1711|#if 1 1712| ShellExecute( NULL, action, path, "", ".", SW_SHOWNORMAL ); 1713| return; 1714|#else /* 以下は、Word ファイルの DDE がうまくいかないため却下 */ 1715| char keyPath[256]; 1716| char command[256]; 1717| char typeName[256]; 1718| 1719| ERRORS_FUNC_START( WinX_openFile2 ); 1720| 1721| /* デフォルトアクションを実行する */ 1722| if ( action == NULL || action[0] == '\0' ) { 1723| WinX_openFile( path ); 1724| ERRORS_FUNC_END( WinX_openFile2 ); 1725| return; 1726| } 1727| 1728| c_try { 1729| /* HKEY_CLASSES_ROOT\.(ext)\(標準) のキーの値を keyPath に取得する */ 1730| WinX_getReg_s( HKEY_CLASSES_ROOT, StrX_refExt( path ) - 1, NULL, typeName, sizeof(typeName) ); 1731| 1732| /* HKEY_CLASSES_ROOT\(typeName)\shell\(action) キーの名前を keyPath に取得する */ 1733| /* HKEY_CLASSES_ROOT\(typeName)\shell\(action)\command キーの値を command に取得する */ 1734| sprintf( keyPath, "%s\\shell\\%s\\command", typeName, action ); 1735| WinX_getReg_s( HKEY_CLASSES_ROOT, keyPath, NULL, command, sizeof(command) ); 1736| sprintf( keyPath, "%s\\shell\\%s", typeName, action ); 1737| } 1738| c_catch ( Errors_Msg*, msg ) { 1739| if ( msg->code == WinX_Err_NoRegKey ) 1740| command[0] = '\0'; 1741| else 1742| c_throw_again(); 1743| } c_end_catch; 1744| 1745| /* command に取得できなかったら */ 1746| if ( command[0] == '\0' && bAll ) { 1747| 1748| /* HKEY_CLASSES_ROOT\*\shell\(action) キーの名前を keyPath に取得する */ 1749| /* HKEY_CLASSES_ROOT\*\shell\(action)\command キーの値を command に取得する */ 1750| c_try { 1751| sprintf( keyPath, "*\\shell\\%s\\command", action ); 1752| WinX_getReg_s( HKEY_CLASSES_ROOT, keyPath, NULL, command, sizeof(command) ); 1753| sprintf( keyPath, "*\\shell\\%s", action ); 1754| } 1755| c_catch ( Errors_Msg*, msg ) { 1756| if ( msg->code == WinX_Err_NoRegKey ) 1757| command[0] = '\0'; 1758| else 1759| c_throw_again(); 1760| } c_end_catch; 1761| } 1762| 1763| /* command に取得できなかったらエラー */ 1764| if ( command[0] == '\0' ) { 1765| error2_2( WinX_Err_NotMatchActionName, 1766| "ファイル %s のアクション %s がありません。", path, action ); 1767| } 1768| 1769| /* 実行する */ 1770| WinX_openFile_sub( keyPath, command, path, action ); 1771| ERRORS_FUNC_END( WinX_openFile2 ); 1772|#endif 1773|} 1774|#endif 1775| 1776|/************************************************************************** 1777| 8-7. <<< [WinX_openFile_sub] WinX_openFile のサブルーチン >>> 1778|【引数】 1779| ・char* actionPath; アクションキーのパス(内部で書きかえられます、サイズは256以上) 1780| ・char* command; レジストリにあるコマンドデータ(内部で書きかえられます、サイズは256以上) 1781| ・char* path; ファイルパス 1782| ・char* action; アクション名 1783|***************************************************************************/ 1784|#if defined(USES_BIGSTACK) && defined(USES_FILEX) && defined(USES_EXCEPT3) 1785|void WinX_openFile_sub( char* actionPath, char* command, const char* path, 1786| const char* action ) 1787|{ 1788| char* p1 = strchr( actionPath, '\0' ); 1789| bool bDDE; 1790| char ifexec[256]; 1791| char data[256]; 1792| char service[256]; 1793| char topic[256]; 1794| char shortPath[_MAX_PATH]; 1795| char longPath[_MAX_PATH]; 1796| 1797| ERRORS_FUNC_START( WinX_openFile_sub ); 1798| 1799| bDDE = true; 1800| 1801| GetShortPathName( path, shortPath, sizeof(shortPath) ); 1802| StrX_toLongPath( longPath, shortPath ); 1803| if ( strstr( command, "%1" ) == NULL ) 1804| ;//{ strcat( command, " " ); strcat( command, shortPath ); } 1805| else 1806| StrX_rep( command, 256, "%1", shortPath ); 1807| 1808| c_try { 1809| strcpy( p1, "\\ddeexec" ); 1810| WinX_getReg_s( HKEY_CLASSES_ROOT, actionPath, NULL, data, sizeof(data) ); 1811| StrX_rep( data, sizeof(data), "%1", longPath ); 1812| if ( strstr( data, "%l" ) != NULL ) 1813| bDDE = false; 1814| } 1815| c_catch ( Errors_Msg*, msg ) { 1816| bDDE = false; 1817| } c_end_catch; 1818| 1819| /* DDE を実行する */ 1820| if ( bDDE ) { 1821| strcpy( p1, "\\ddeexec\\application" ); 1822| WinX_getReg_s( HKEY_CLASSES_ROOT, actionPath, NULL, service, sizeof(service) ); 1823| c_try { 1824| strcpy( p1, "\\ddeexec\\ifexec" ); 1825| WinX_getReg_s( HKEY_CLASSES_ROOT, actionPath, NULL, ifexec, sizeof(ifexec) ); 1826| } 1827| c_catch ( Errors_Msg*, msg ) { 1828| ifexec[0] = '\0'; 1829| } c_end_catch; 1830| strcpy( p1, "\\ddeexec\\topic" ); 1831| WinX_getReg_s( HKEY_CLASSES_ROOT, actionPath, NULL, topic, sizeof(topic) ); 1832| 1833| if ( ifexec[0] == '\0' ) { 1834| #if ERRORS_DEBUG_FALSE 1835| WS( command ); 1836| WS( data ); 1837| #endif 1838| WinX_sendDDE( command, service, topic, data, strlen( data ), WinX_Execute ); 1839| } 1840| else 1841| WinX_sendDDE( ifexec, service, topic, data, strlen( data ), WinX_Execute ); 1842| } 1843| 1844| /* コマンドを実行する */ 1845| else { 1846| WinExec( command, SW_SHOWNORMAL ); 1847| } 1848| ERRORS_FUNC_END( WinX_openFile_sub ); 1849|} 1850|#endif 1851| 1852|/************************************************************************** 1853| 8-8. <<< [WinX_openFolder] フォルダを開く >>> 1854|【引数】 1855| ・char* path; フォルダパス 1856|***************************************************************************/ 1857|void WinX_openFolder( const char* path ) 1858|{ 1859| char path2[_MAX_PATH*2]; 1860| 1861| ERRORS_FUNC_START( WinX_openFolder ); 1862| 1863| sprintf( path2, "%s\\explorer.exe \"%s\"", WinX_getWindowsPath(), path ); 1864| WinExec( path2, SW_SHOWNORMAL ); 1865| 1866| ERRORS_FUNC_END( WinX_openFolder ); 1867|} 1868| 1869|/************************************************************************** 1870| 8-9. <<< [WinX_openFolder2] フォルダを開く >>> 1871|【引数】 1872| ・char* path; 開くフォルダのパス 1873| ・bool bTree; フォルダツリーを表示するかどうか 1874| ・bool bRoot; path をツリーのルートとするかどうか(bTree==true のとき有効) 1875| ・char* selPath; 選択状態にするファイルパス(path からの相対)(NULL=選択しない) 1876|***************************************************************************/ 1877|void WinX_openFolder2( const char* path, bool bTree, bool bRoot, const char* selPath ) 1878|{ 1879| char path2[_MAX_PATH*2]; 1880| 1881| ERRORS_FUNC_START( WinX_openFolder2 ); 1882| 1883| ASSERT( selPath == NULL ); /* 未対応 */ 1884| 1885| if ( bTree && bRoot ) { 1886| sprintf( path2, "%s\\explorer.exe /e,/root,\"%s\"", WinX_getWindowsPath(), path ); 1887| WinExec( path2, SW_SHOWNORMAL ); 1888| } 1889| else { 1890| ( bTree ? WinX_openExplorer( path ) : WinX_openFolder( path ) ); 1891| } 1892| 1893| ERRORS_FUNC_END( WinX_openFolder2 ); 1894|} 1895| 1896| 1897| 1898|/************************************************************************** 1899| 8-10. <<< [WinX_openExplorer] エクスプローラを開く >>> 1900|【引数】 1901| ・char* path; フォルダパス 1902|***************************************************************************/ 1903|void WinX_openExplorer( const char* path ) 1904|{ 1905| char path2[_MAX_PATH*2]; 1906| 1907| ERRORS_FUNC_START( WinX_openExplorer ); 1908| 1909| sprintf( path2, "%s\\explorer.exe /e,\"%s\"", WinX_getWindowsPath(), path ); 1910| WinExec( path2, SW_SHOWNORMAL ); 1911| 1912| ERRORS_FUNC_END( WinX_openExplorer ); 1913|} 1914| 1915|/************************************************************************** 1916| 8-11. <<< [WinX_getExeFNameOfWnd] 指定ウィンドウの実行ファイルのパスを取得する >>> 1917|【引数】 1918| ・HWND hWnd; 調べるウィンドウハンドル 1919| ・char* exe_fname; (出力)実行ファイルのファイル名(メモリサイズは、_MAX_PATH) 1920| ・bool 返り値; 成功したかどうか 1921|【補足】 1922|・exe_fname は、パスではなくファイル名です。 1923|・Windows NT4.0以前では使えません。 1924|・参考 http://techtips.belution.com/ja/vc/0022/ 1925|***************************************************************************/ 1926|#include <tlhelp32.h> 1927| 1928|bool WinX_getExeFNameOfWnd( HWND wnd, char* exe_fname ) 1929|{ 1930| bool ret = false; 1931| DWORD wnd_procId; 1932| HANDLE snapshot; 1933| PROCESSENTRY32 proc; 1934| 1935| /* ToolHelp 関数ポインタ */ 1936| HANDLE (WINAPI *CreateSnapshot)( DWORD, DWORD ); 1937| BOOL (WINAPI *Process32First)( HANDLE, LPPROCESSENTRY32 ); 1938| BOOL (WINAPI *Process32Next)( HANDLE, LPPROCESSENTRY32 ); 1939| 1940| /* ウィンドウのプロセスIDを取得する */ 1941| GetWindowThreadProcessId( wnd , &wnd_procId ); 1942| 1943| /* DLL 関数のアドレスを取得する */ 1944| CreateSnapshot = (HANDLE(WINAPI*)(DWORD,DWORD)) GetProcAddress( 1945| GetModuleHandle("kernel32.dll"), "CreateToolhelp32Snapshot" ); 1946| Process32First= (BOOL(WINAPI*)(HANDLE,LPPROCESSENTRY32)) GetProcAddress( 1947| GetModuleHandle("kernel32.dll"), "Process32First" ); 1948| Process32Next= (BOOL(WINAPI*)(HANDLE,LPPROCESSENTRY32))GetProcAddress( 1949| GetModuleHandle("kernel32.dll"), "Process32Next" ); 1950| 1951| if ( !CreateSnapshot || !Process32First || !Process32Next ) 1952| return FALSE; 1953| 1954| 1955| /* 全プロセスから、一致するウィンドウを検索する */ 1956| snapshot = CreateSnapshot( TH32CS_SNAPPROCESS , 0 ); /* open */ 1957| if ( snapshot == (HANDLE)-1 ) error(); 1958| 1959| proc.dwSize = sizeof(PROCESSENTRY32); 1960| if ( Process32First( snapshot, &proc ) ) { 1961| do { 1962| if ( proc.th32ProcessID == wnd_procId ) { 1963| strcpy( exe_fname, proc.szExeFile ); 1964| ret = true; 1965| break; 1966| } 1967| } while ( Process32Next( snapshot, &proc ) ); 1968| } 1969| CloseHandle( snapshot ); 1970| 1971| return ret; 1972|} 1973| 1974|/************************************************************************** 1975| 8-12. <<< [WinX_sendMsgToExe] 指定の実行ファイルの全てのウィンドウにメッセージを送る >>> 1976|【引数】 1977| ・char* exe_path; 実行ファイルパス(フォルダパスは無視されます) 1978|***************************************************************************/ 1979|void WinX_sendPostMsgToExe( int op, const char* exe_path, UINT message, WPARAM wParam, LPARAM lParam ); 1980| 1981|void WinX_sendMsgToExe( const char* exe_path, UINT message, WPARAM wParam, LPARAM lParam ) 1982|{ 1983| WinX_sendPostMsgToExe( 0, exe_path, message, wParam, lParam ); 1984|} 1985| 1986|/************************************************************************** 1987| 8-13. <<< [WinX_postMsgToExe] 指定の実行ファイルの全てのウィンドウにメッセージを投げる >>> 1988|【引数】 1989| ・char* exe_path; 実行ファイルパス(フォルダパスは無視されます) 1990|***************************************************************************/ 1991|void WinX_postMsgToExe( const char* exe_path, UINT message, WPARAM wParam, LPARAM lParam ) 1992|{ 1993| WinX_sendPostMsgToExe( 1, exe_path, message, wParam, lParam ); 1994|} 1995| 1996|/************************************************************************** 1997| 8-14. <<< [WinX_sendPostMsgToExe] WinX_sendMsgToExe, WinX_postMsgToExe のサブルーチン >>> 1998|***************************************************************************/ 1999|void WinX_sendPostMsgToExe( int op, const char* exe_path, UINT message, WPARAM wParam, LPARAM lParam ) 2000|{ 2001| HWND wnd; 2002| HWND* wnds; 2003| int nWnd; 2004| int iWnd; 2005| char path[_MAX_PATH]; 2006| char* exe_fname = StrX_refFName( exe_path ); 2007| 2008| /* ウィンドウの数 nWnd を得る */ 2009| nWnd = 0; 2010| for ( wnd = GetTopWindow( GetDesktopWindow() ); 2011| wnd != NULL; 2012| wnd = GetNextWindow( wnd, GW_HWNDNEXT ) ) { 2013| nWnd ++; 2014| } 2015| 2016| wnds = malloc( sizeof(HWND) * nWnd ); 2017| 2018| /* 全ウィンドウのハンドルを集める(集めておくのはクローズへの対応) */ 2019| iWnd = 0; 2020| for ( wnd = GetTopWindow( GetDesktopWindow() ); 2021| wnd != NULL; 2022| wnd = GetNextWindow( wnd, GW_HWNDNEXT ) ) { 2023| wnds[iWnd] = wnd; 2024| iWnd++; 2025| } 2026| 2027| 2028| /* 対象となるウィンドウ全てにメッセージを送る */ 2029| for ( iWnd = 0; iWnd < nWnd; iWnd++ ) { 2030| WinX_getExeFNameOfWnd( wnds[iWnd], path ); 2031| if ( stricmp( path, exe_fname ) == 0 ) { 2032| if ( op == 0 ) SendMessage( wnds[iWnd], message, wParam, lParam ); 2033| if ( op == 1 ) PostMessage( wnds[iWnd], message, wParam, lParam ); 2034| } 2035| } 2036| 2037| free( wnds ); 2038|} 2039| 2040|/************************************************************************** 2041| 8-15. <<< [WinX_isRunning] 実行ファイルが実行中(開いている)かどうかを返す >>> 2042|【引数】 2043| ・char* exe_path; 実行ファイルパス(フォルダパスは無視されます) 2044|***************************************************************************/ 2045|bool WinX_isRunning( const char* exe_path ) 2046|{ 2047|#if 1 2048| bool ret = false; 2049| HANDLE snapshot; 2050| PROCESSENTRY32 proc; 2051| char* exe_fname = StrX_refFName( exe_path ); 2052| 2053| /* ToolHelp 関数ポインタ */ 2054| HANDLE (WINAPI *CreateSnapshot)( DWORD, DWORD ); 2055| BOOL (WINAPI *Process32First)( HANDLE, LPPROCESSENTRY32 ); 2056| BOOL (WINAPI *Process32Next)( HANDLE, LPPROCESSENTRY32 ); 2057| 2058| /* DLL 関数のアドレスを取得する */ 2059| CreateSnapshot = (HANDLE(WINAPI*)(DWORD,DWORD)) GetProcAddress( 2060| GetModuleHandle("kernel32.dll"), "CreateToolhelp32Snapshot" ); 2061| Process32First= (BOOL(WINAPI*)(HANDLE,LPPROCESSENTRY32)) GetProcAddress( 2062| GetModuleHandle("kernel32.dll"), "Process32First" ); 2063| Process32Next= (BOOL(WINAPI*)(HANDLE,LPPROCESSENTRY32))GetProcAddress( 2064| GetModuleHandle("kernel32.dll"), "Process32Next" ); 2065| 2066| if ( !CreateSnapshot || !Process32First || !Process32Next ) 2067| error(); 2068| 2069| snapshot = CreateSnapshot( TH32CS_SNAPPROCESS , 0 ); /* open */ 2070| if ( snapshot == (HANDLE)-1 ) error(); 2071| 2072| proc.dwSize = sizeof(PROCESSENTRY32); 2073| if ( Process32First( snapshot, &proc ) ) { 2074| do { 2075| if ( stricmp( exe_fname, proc.szExeFile ) == 0 ) { 2076| ret = true; 2077| break; 2078| } 2079| } while ( Process32Next( snapshot, &proc ) ); 2080| } 2081| CloseHandle( snapshot ); 2082| 2083| return ret; 2084|#else 2085| HWND targetWnd; 2086| char path[_MAX_PATH]; 2087| char* exe_fname = StrX_refFName( exe_path ); 2088| 2089| for ( targetWnd = GetTopWindow( GetDesktopWindow() ); 2090| targetWnd != NULL; 2091| targetWnd = GetNextWindow( targetWnd, GW_HWNDNEXT ) ) { 2092| 2093| WinX_getExeFNameOfWnd( targetWnd, path ); 2094| if ( stricmp( path, exe_fname ) == 0 ) { 2095| return true; 2096| } 2097| } 2098| return false; 2099|#endif 2100|} 2101| 2102|/*------------------------------------------------------------------------*/ 2103|/* 9. <<<< ◆エクスプローラメニュー関係 >>>> */ 2104|/*------------------------------------------------------------------------*/ 2105| 2106|void WinX_openFile_sub( char* shellPath, char* command, const char* path, 2107| const char* action ); 2108|int WinX_getFTypeInfos_sub( HKEY shellKey, int iSubKey, WinX_FType* type ); 2109| 2110| 2111|/************************************************************************** 2112| 9-1. <<< [WinX_setExtApp] 拡張子をアプリケーションに関連付けする >>> 2113|【引数】 2114| ・char* ext; 拡張子(3バイトまで) 2115| ・char* explain; ファイルタイプの説明 2116| ・char* actionName; アクション名(英語) 2117| ・char* actionTitle; アクション・表題(右クリック・メニューの項目) 2118| ・char* command; アクション・コマンド、実行するアプリケーション 2119| ・char* iconPath; アイコン・ファイル・パス 2120| ・int iconNum; iconPath 中のアイコン番号 2121| ・bool bDownChk; ダウンロード時に確認するかどうか 2122|【補足】 2123|・actionTitle に、アクセスキー(例:(&A))を指定できます。 2124|・actionName を "open" にしないと、WinX_setNewFile 関数によって、 2125| 新規作成を登録できなくなります。 2126|・command には、実行ファイルをフルパスで指定してください。 2127|・iconPath にアイコン・リソースを含む実行ファイルを指定した場合、 2128| iconNum に0以上の値を指定してください。 2129|・再起動するかフォルダオプションでアイコンを選択しない限り、 2130| アイコンの表示は変化しません。 2131|・すでに関連付けしてある場合、それまで関連付けしてあったアクションは、 2132| 残ります(右クリック・メニューによる)。 2133|【内部補足】 2134|・デフォルトではレジストリに、.拡張子と、拡張子+"file" という名前の 2135| サブ・キーが作られます。 2136| 例:「.ext」キーと、「extfile」キー 2137|***************************************************************************/ 2138|#ifdef USES_BIGSTACK 2139|void WinX_setExtApp( const char* ext, const char* explain, 2140| const char* actionName, const char* actionTitle, const char* command, 2141| const char* iconPath, int iconNum, bool bDefault, bool bDownChk ) 2142|{ 2143| enum { type_max = 2048 }; 2144| HKEY key; 2145| LONG ret; 2146| static char flags11[4] = { 0x00, 0x00, 0x00, 0x00 }; /* ダウンロード時に確認する */ 2147| static char flags10[4] = { 0x00, 0x00, 0x01, 0x00 }; /* ダウンロード時に確認しない */ 2148| static char flags2[4] = { 0x01, 0x00, 0x00, 0x00 }; 2149| char* type; 2150| int type_len; 2151| char* s; 2152| DWORD dwDisp; 2153| 2154| ERRORS_FUNC_START( WinX_setExtApp ); 2155| 2156| #ifdef WINX_ENABLE_DEBUG_MODE 2157| Errors_printf( "WinX_setExtApp():" ); 2158| Errors_printf( " ext = %s, explain = %s", ext, explain ); 2159| Errors_printf( " actionName = %s, actionTitle = %s, command = %s", 2160| actionName, actionTitle, command ); 2161| Errors_printf( " iconPath = %s, iconNum = %d, bDefault = %d, bDownChk = %d", 2162| iconPath, iconNum, bDefault, bDownChk ); 2163| #endif 2164| 2165| BigStack_start(); 2166| type = BigStack_alloc( type_max ); 2167| s = BigStack_alloc( type_max ); 2168| 2169| strcpy( s, "." ); strcat( s, ext ); 2170| ret = RegCreateKeyEx( HKEY_CLASSES_ROOT, s, 0, 0, 2171| REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dwDisp ); 2172| #ifdef WINX_ENABLE_DEBUG_MODE 2173| MARK(); WS( s ); WD( ret ); 2174| #endif 2175| if ( ret == ERROR_SUCCESS ) { 2176| type_len = type_max; 2177| ret = RegQueryValueEx( key, NULL, NULL, NULL, type, &type_len ); 2178| #ifdef WINX_ENABLE_DEBUG_MODE 2179| MARK(); WS( type ); WD( ret ); 2180| #endif 2181| if ( ret == 2 || type[0] == '\0' ) { 2182| strcpy( type, ext ); strcat( type, "file" ); 2183| type_len = strlen( type ); 2184| ret = RegSetValueEx( key, NULL, 0, REG_SZ, (WinX_DataPtr)type, type_len ); 2185| #ifdef WINX_ENABLE_DEBUG_MODE 2186| MARK(); WS( type ); WD( ret ); 2187| #endif 2188| } 2189| if ( RegCloseKey( key ) != ERROR_SUCCESS ) WinX_throw( ret ); 2190| } 2191| if ( ret != ERROR_SUCCESS ) { 2192| strcpy( type, ext ); strcat( type, "file" ); 2193| type_len = strlen( type ); 2194| 2195| ret = RegCreateKeyEx( HKEY_CLASSES_ROOT, s, 0, 0, 2196| REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dwDisp ); 2197| #ifdef WINX_ENABLE_DEBUG_MODE 2198| MARK(); WS( s ); WD( ret ); 2199| #endif 2200| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2201| ret = RegSetValueEx( key, NULL, 0, REG_SZ, (WinX_DataPtr)type, type_len ); 2202| #ifdef WINX_ENABLE_DEBUG_MODE 2203| WS( type ); WD( ret ); 2204| #endif 2205| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2206| ret = RegCloseKey( key ); 2207| #ifdef WINX_ENABLE_DEBUG_MODE 2208| WD( ret ); 2209| #endif 2210| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2211| } 2212| 2213| ret = RegCreateKeyEx( HKEY_CLASSES_ROOT, type, 0, 0, 2214| REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dwDisp ); 2215| #ifdef WINX_ENABLE_DEBUG_MODE 2216| MARK(); WS( type ); WD( ret ); 2217| #endif 2218| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2219| 2220| if ( explain != NULL ) { 2221| ret = RegSetValueEx( key, NULL, 0, REG_SZ, (WinX_DataPtr)explain, strlen(explain) ); 2222| #ifdef WINX_ENABLE_DEBUG_MODE 2223| MARK(); WS( explain ); WD( ret ); 2224| #endif 2225| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2226| } 2227| if ( bDownChk ) 2228| ret = RegSetValueEx( key, "EditFlags", 0, REG_BINARY, (WinX_DataPtr)flags11, sizeof(flags11) ); 2229| else 2230| ret = RegSetValueEx( key, "EditFlags", 0, REG_BINARY, (WinX_DataPtr)flags10, sizeof(flags10) ); 2231| #ifdef WINX_ENABLE_DEBUG_MODE 2232| MARK(); WD( ret ); 2233| #endif 2234| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2235| ret = RegCloseKey( key ); 2236| #ifdef WINX_ENABLE_DEBUG_MODE 2237| WD( ret ); 2238| #endif 2239| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2240| 2241| if ( iconNum != -1 ) { 2242| sprintf( s, "%s\\DefaultIcon", type ); 2243| ret = RegCreateKeyEx( HKEY_CLASSES_ROOT, s, 0, 0, 2244| REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dwDisp ); 2245| #ifdef WINX_ENABLE_DEBUG_MODE 2246| MARK(); WS( s ); WD( ret ); 2247| #endif 2248| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2249| sprintf( s, "%s,%d", iconPath, iconNum ); 2250| ret = RegSetValueEx( key, NULL, 0, REG_SZ, (WinX_DataPtr)s, strlen(s) ); 2251| #ifdef WINX_ENABLE_DEBUG_MODE 2252| WS( s ); WD( ret ); 2253| #endif 2254| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2255| ret = RegCloseKey( key ); 2256| #ifdef WINX_ENABLE_DEBUG_MODE 2257| WD( ret ); 2258| #endif 2259| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2260| } 2261| 2262| if ( bDefault ) { 2263| sprintf( s, "%s\\shell", type ); 2264| ret = RegCreateKeyEx( HKEY_CLASSES_ROOT, s, 0, 0, 2265| REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dwDisp ); 2266| #ifdef WINX_ENABLE_DEBUG_MODE 2267| MARK(); WS( s ); WD( ret ); 2268| #endif 2269| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2270| ret = RegSetValueEx( key, NULL, 0, REG_SZ, (WinX_DataPtr)actionName, strlen(actionName) ); 2271| #ifdef WINX_ENABLE_DEBUG_MODE 2272| WS( actionName ); WD( ret ); 2273| #endif 2274| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2275| RegCloseKey( key ); 2276| #ifdef WINX_ENABLE_DEBUG_MODE 2277| WD( ret ); 2278| #endif 2279| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2280| } 2281| 2282| sprintf( s, "%s\\shell\\%s", type, actionName ); 2283| ret = RegCreateKeyEx( HKEY_CLASSES_ROOT, s, 0, 0, 2284| REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dwDisp ); 2285| #ifdef WINX_ENABLE_DEBUG_MODE 2286| MARK(); WS( s ); WD( ret ); 2287| #endif 2288| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2289| ret = RegSetValueEx( key, NULL, 0, REG_SZ, (WinX_DataPtr)actionTitle, strlen(actionTitle) ); 2290| #ifdef WINX_ENABLE_DEBUG_MODE 2291| WS( actionTitle ); WD( ret ); 2292| #endif 2293| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2294| ret = RegSetValueEx( key, "EditFlags", 0, REG_BINARY, (WinX_DataPtr)flags2, sizeof(flags2) ); 2295| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2296| RegCloseKey( key ); 2297| #ifdef WINX_ENABLE_DEBUG_MODE 2298| WD( ret ); 2299| #endif 2300| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2301| 2302| sprintf( s, "%s\\shell\\%s\\command", type, actionName ); 2303| ret = RegCreateKeyEx( HKEY_CLASSES_ROOT, s, 0, 0, 2304| REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dwDisp ); 2305| #ifdef WINX_ENABLE_DEBUG_MODE 2306| WS( s ); WD( ret ); 2307| #endif 2308| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2309| ret = RegSetValueEx( key, NULL, 0, REG_SZ, (WinX_DataPtr)command, strlen(command) ); 2310| #ifdef WINX_ENABLE_DEBUG_MODE 2311| WS( command ); WD( ret ); 2312| #endif 2313| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2314| RegCloseKey( key ); 2315| #ifdef WINX_ENABLE_DEBUG_MODE 2316| WD( ret ); 2317| #endif 2318| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2319| 2320| BigStack_end(); 2321| 2322| ERRORS_FUNC_END( WinX_setExtApp ); 2323|} 2324|#endif /* USES_BIGSTACK */ 2325| 2326| 2327| 2328|/************************************************************************** 2329| 9-2. <<< [WinX_setFolderApp] フォルダをアプリケーションに関連付けする >>> 2330|【引数】 2331| ・char* actionName; アクション名(英語) 2332| ・char* actionTitle; アクション・表題(右クリック・メニューの項目) 2333| ・char* command; アクション・コマンド、実行するアプリケーション 2334|【補足】 2335|・actionTitle に、アクセスキー(例:(&A))を指定できます。 2336|・actionName を "open" にしないと、WinX_setNewFile 関数によって、 2337| 新規作成を登録できなくなります。 2338|・command には、実行ファイルをフルパスで指定してください。 2339|***************************************************************************/ 2340|#ifdef USES_BIGSTACK 2341|void WinX_setFolderApp( const char* actionName, const char* actionTitle, 2342| const char* command, bool bDefault ) 2343|{ 2344| HKEY key; 2345| LONG ret; 2346| static char flags[4] = { 0x01, 0x00, 0x00, 0x00 }; 2347| char* s; 2348| DWORD dwDisp; 2349| 2350| ERRORS_FUNC_START( WinX_setFolderApp ); 2351| 2352| BigStack_start(); 2353| s = BigStack_alloc( 2048 ); 2354| 2355| if ( bDefault ) { 2356| ret = RegCreateKeyEx( HKEY_CLASSES_ROOT, "Directory\\shell", 0, 0, 2357| REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dwDisp ); 2358| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2359| ret = RegSetValueEx( key, NULL, 0, REG_SZ, (WinX_DataPtr)actionName, strlen(actionName) ); 2360| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2361| RegCloseKey( key ); 2362| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2363| } 2364| 2365| sprintf( s, "Directory\\shell\\%s", actionName ); 2366| ret = RegCreateKeyEx( HKEY_CLASSES_ROOT, s, 0, 0, 2367| REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dwDisp ); 2368| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2369| ret = RegSetValueEx( key, NULL, 0, REG_SZ, (WinX_DataPtr)actionTitle, strlen(actionTitle) ); 2370| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2371| ret = RegSetValueEx( key, "EditFlags", 0, REG_BINARY, (WinX_DataPtr)flags, sizeof(flags) ); 2372| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2373| RegCloseKey( key ); 2374| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2375| 2376| sprintf( s, "Directory\\shell\\%s\\command", actionName ); 2377| ret = RegCreateKeyEx( HKEY_CLASSES_ROOT, s, 0, 0, 2378| REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dwDisp ); 2379| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2380| ret = RegSetValueEx( key, NULL, 0, REG_SZ, (WinX_DataPtr)command, strlen(command) ); 2381| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2382| RegCloseKey( key ); 2383| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2384| 2385| BigStack_end(); 2386| 2387| ERRORS_FUNC_END( WinX_setFolderApp ); 2388|} 2389|#endif /* USES_BIGSTACK */ 2390| 2391| 2392| 2393|/************************************************************************** 2394| 9-3. <<< [WinX_unsetExtApp] 拡張子とアプリケーションの関連付けを解除する >>> 2395|【引数】 2396| ・char* ext; 拡張子(3バイトまで) 2397| ・char* actionName; アクション名(英語) 2398|【補足】 2399|・WinX_setExtApp 関数によって設定された場合のみ正しく解除します。 2400|・他のアクションがある場合、それらは残ります。 2401|***************************************************************************/ 2402|#ifdef USES_BIGSTACK 2403|void WinX_unsetExtApp( const char* ext, const char* actionName ) 2404|{ 2405| enum { type_max = 2048 }; 2406| HKEY key; 2407| LONG ret; 2408| char* type; 2409| char* s; 2410| FILETIME time; 2411| int size = 2048; 2412| int type_len; 2413| 2414| ERRORS_FUNC_START( WinX_unsetExtApp ); 2415| 2416| BigStack_start(); 2417| type = BigStack_alloc( type_max ); 2418| s = BigStack_alloc( size ); 2419| 2420| /* タイプ名 type を取得する */ 2421| s[0]= '.'; strcpy( s + 1, ext ); 2422| ret = RegOpenKeyEx( HKEY_CLASSES_ROOT, s, 0L, KEY_ALL_ACCESS, &key ); 2423| if ( ret == 2 ) { BigStack_end(); return; } /* 既に関連付けが無い */ 2424| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2425| type_len = type_max; 2426| ret = RegQueryValueEx( key, NULL, NULL, NULL, type, &type_len ); 2427| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2428| ret = RegCloseKey( key ); 2429| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2430| 2431| /* アクションを削除する */ 2432| sprintf( s, "%s\\shell\\%s\\command", type, actionName ); 2433| ret = RegDeleteKey( HKEY_CLASSES_ROOT, s ); 2434| if ( (ret & 0xFFFF) == ERROR_FILE_NOT_FOUND ) return; /* なければ返る */ 2435| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2436| 2437| sprintf( s, "%s\\shell\\%s", type, actionName ); 2438| ret = RegDeleteKey( HKEY_CLASSES_ROOT, s ); 2439| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2440| 2441| /* open アクションをデフォルトに戻す */ 2442| sprintf( s, "%s\\shell", type ); 2443| ret = RegOpenKeyEx( HKEY_CLASSES_ROOT, s, 0L, KEY_ALL_ACCESS, &key ); 2444| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2445| ret = RegSetValueEx( key, NULL, 0, REG_SZ, (WinX_DataPtr)"open", 4 ); 2446| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2447| RegCloseKey( key ); 2448| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2449| 2450| /* 他のアクションがあるかどうか調べる */ 2451| sprintf( s, "%s\\shell", type ); 2452| ret = RegOpenKeyEx( HKEY_CLASSES_ROOT, s, 0L, KEY_ALL_ACCESS, &key ); 2453| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2454| 2455| /* 他のアクションが無ければ、ファイルタイプを削除する */ 2456| ret = RegEnumKeyEx( key, 0, s, &size, NULL, NULL, NULL, &time ); 2457| if ( ret == ERROR_NO_MORE_ITEMS ) { 2458| sprintf( s, "%s\\shell", type ); 2459| ret = RegDeleteKey( HKEY_CLASSES_ROOT, s ); 2460| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2461| 2462| sprintf( s, "%s\\DefaultIcon", type ); 2463| ret = RegDeleteKey( HKEY_CLASSES_ROOT, s ); 2464| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2465| 2466| ret = RegDeleteKey( HKEY_CLASSES_ROOT, type ); 2467| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2468| 2469| s[0]= '.'; strcpy( s + 1, ext ); 2470| ret = RegDeleteKey( HKEY_CLASSES_ROOT, s ); 2471| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2472| } 2473| else if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2474| 2475| BigStack_end(); 2476| 2477| ERRORS_FUNC_END( WinX_unsetExtApp ); 2478|} 2479|#endif /* USES_BIGSTACK */ 2480| 2481| 2482| 2483|/************************************************************************** 2484| 9-4. <<< [WinX_unsetFolderApp] フォルダとアプリケーションの関連付けを解除する >>> 2485|【引数】 2486| ・char* actionName; アクション名(英語) 2487|【補足】 2488|・WinX_setFolderApp 関数によって設定された場合のみ正しく解除します。 2489|***************************************************************************/ 2490|#ifdef USES_BIGSTACK 2491|void WinX_unsetFolderApp( const char* actionName ) 2492|{ 2493| LONG ret; 2494| char* s; 2495| int size = 2048; 2496| 2497| ERRORS_FUNC_START( WinX_unsetFolderApp ); 2498| 2499| BigStack_start(); 2500| s = BigStack_alloc( size ); 2501| 2502| /* アクションを削除する */ 2503| sprintf( s, "Directory\\shell\\%s\\command", actionName ); 2504| ret = RegDeleteKey( HKEY_CLASSES_ROOT, s ); 2505| if ( (ret & 0xFFFF) == ERROR_FILE_NOT_FOUND ) return; /* なければ返る */ 2506| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2507| 2508| sprintf( s, "Directory\\shell\\%s", actionName ); 2509| ret = RegDeleteKey( HKEY_CLASSES_ROOT, s ); 2510| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2511| 2512| BigStack_end(); 2513| 2514| ERRORS_FUNC_END( WinX_unsetFolderApp ); 2515|} 2516|#endif /* USES_BIGSTACK */ 2517| 2518| 2519| 2520|/************************************************************************** 2521| 9-5. <<< [WinX_setNewFile] 右クリックの新規作成に登録する >>> 2522|【引数】 2523| ・char* ext; 拡張子(3バイトまで) 2524| ・char* newFName; デフォルト・ファイルの名前(NULL 可)(補足参照) 2525|【補足】 2526|・ext には、WinX_setExtApp 関数でアプリケーションに関連付けした拡張子を 2527| 指定します。 2528|・WinX_setExtApp 関数で指定した actionName 引数は "open" にしてください。 2529|・newFName は、新規作成するときに作られるデータの入ったファイルの 2530| ファイル名を指定します。ただし、Windows\ShellNew フォルダ 2531| (WinX_getShellNewPath 関数で取得できます)に 2532| FileX_copy 関数などを用いてそのファイルを入れてください。 2533| newFName に NULL を指定すると、空(0バイト)のデータを作成するように 2534| 設定します。 2535|・右クリックメニューに表示される項目は、WinX_setExtApp 関数の explain 2536| 引数に指定したものを表示します。 2537|【参考】 2538|・http://www.saitou.com/windows/doc/dsk0001.htm 2539|***************************************************************************/ 2540|#if defined(USES_FILEX) && defined(USES_BIGSTACK) && defined(USES_EXCEPT3) 2541|void WinX_setNewFile( const char* ext, const char* newFName ) 2542|{ 2543| HKEY key; 2544| LONG ret; 2545| char* s; 2546| DWORD dwDisp; 2547| 2548| ERRORS_FUNC_START( WinX_setNewFile ); 2549| 2550| BigStack_start(); 2551| s = BigStack_alloc( 2048 ); 2552| 2553| if ( newFName == NULL ) { 2554| 2555| sprintf( s, ".%s\\ShellNew", ext ); 2556| ret = RegCreateKeyEx( HKEY_CLASSES_ROOT, s, 0, 0, 2557| REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dwDisp ); 2558| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2559| ret = RegSetValueEx( key, "NullFile", 0, REG_SZ, "", 0 ); 2560| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2561| ret = RegCloseKey( key ); 2562| 2563| } 2564| else { 2565| strcpy( s, WinX_getShellNewPath() ); 2566| StrX_addFName( s, newFName ); 2567| if ( ! FileX_isExist( s ) ) 2568| error2_1( Errors_Unofficial, "file not found in ShellNew Folder or new file (%s)", s ); 2569| 2570| sprintf( s, ".%s\\ShellNew", ext ); 2571| ret = RegCreateKeyEx( HKEY_CLASSES_ROOT, s, 0, 0, 2572| REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dwDisp ); 2573| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2574| ret = RegSetValueEx( key, "FileName", 0, REG_SZ, newFName, strlen(newFName) ); 2575| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2576| ret = RegCloseKey( key ); 2577| 2578| } 2579| BigStack_end(); 2580| 2581| ERRORS_FUNC_END( WinX_setNewFile ); 2582|} 2583|#endif 2584| 2585| 2586|/************************************************************************** 2587| 9-6. <<< [WinX_unsetNewFile] 右クリックの新規作成から外す >>> 2588|【引数】 2589| ・char* ext; 拡張子(3バイトまで) 2590|【補足】 2591|・ext には、アプリケーションに関連付け去れている拡張子のみ指定できます。 2592|・WinX_setNewFile 関数で設定したタイプのみ正常に動作します。 2593|***************************************************************************/ 2594|#ifdef USES_BIGSTACK 2595|void WinX_unsetNewFile( const char* ext ) 2596|{ 2597| LONG ret; 2598| char* s; 2599| 2600| ERRORS_FUNC_START( WinX_unsetNewFile ); 2601| 2602| BigStack_start(); 2603| s = BigStack_alloc( 2048 ); 2604| 2605| sprintf( s, ".%s\\ShellNew", ext ); 2606| ret = RegDeleteKey( HKEY_CLASSES_ROOT, s ); 2607| if ( (ret & 0xFFFF) != ERROR_FILE_NOT_FOUND && 2608| ret != ERROR_SUCCESS ) WinX_throw( ret ); 2609| 2610| BigStack_end(); 2611| 2612| ERRORS_FUNC_END( WinX_unsetNewFile ); 2613|} 2614|#endif 2615| 2616|/************************************************************************** 2617| 9-7. <<< [WinX_isNeedSecurity] ダウンロード時に開く確認をするかどうかを返す >>> 2618|【引数】 2619| ・char* ext; 拡張子 2620| ・bool 返り値; 確認をするかどうか 2621|【補足】 2622|・レジストリに登録されていない拡張子を指定したときは、true を返します。 2623|***************************************************************************/ 2624|#if defined(USES_EXCEPT3) 2625|bool WinX_isNeedSecurity( const char* ext ) 2626|{ 2627| bool r; 2628| HKEY key; 2629| char s1[256]; 2630| char s2[256]; 2631| DWORD type; 2632| DWORD size; 2633| LONG ret; 2634| 2635| ERRORS_FUNC_START( WinX_isNeedSecurity ); 2636| 2637| c_try { 2638| s2[0] = '.'; strcpy( s2 + 1, ext ); 2639| WinX_getReg_s( HKEY_CLASSES_ROOT, s2, NULL, s1, sizeof(s1) ); 2640| ret = RegOpenKeyEx( HKEY_CLASSES_ROOT, s1, 0L, KEY_READ, &key ); 2641| if ( ret != ERROR_SUCCESS ) { 2642| r = true; 2643| } 2644| else { 2645| size = sizeof(s2); 2646| ret = RegQueryValueEx( key, "EditFlags", NULL, &type, s2, &size ); 2647| if ( ret != ERROR_SUCCESS || *s2 == '\0' ) 2648| r = true; 2649| else 2650| r = ! s2[2]; 2651| } 2652| RegCloseKey( key ); 2653| } 2654| c_catch ( Errors_Msg*, msg ) { 2655| if ( msg->code == WinX_Err_NoRegKey ) 2656| r = true; 2657| } c_end_catch; 2658| 2659| ERRORS_FUNC_END( WinX_isNeedSecurity ); 2660| return r; 2661|} 2662|#endif 2663| 2664|/************************************************************************** 2665| 9-8. <<< [WinX_getShellNewPath] 新規作成用フォルダのパスを返す >>> 2666|【補足】 2667|・新規作成時に参照するテンプレートファイルの入ったフォルダのパスを 2668| 返します。 2669|***************************************************************************/ 2670|char* WinX_getShellNewPath() 2671|{ 2672| static unsigned char var[_MAX_PATH]; 2673| unsigned long size = sizeof(var); 2674| HKEY key; 2675| LONG ret; 2676| 2677| ERRORS_FUNC_START( WinX_getShellNewPath ); 2678| 2679| ret = RegOpenKeyEx( HKEY_CURRENT_USER, 2680| "Software\\Microsoft\\Windows\\CurrentVersion\\" 2681| "Explorer\\Shell Folders", 0L, KEY_READ, &key ); 2682| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2683| 2684| ret = RegQueryValueEx( key, "Templates", NULL, NULL, var, &size ); 2685| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2686| 2687| RegCloseKey( key ); 2688| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2689| 2690| ERRORS_FUNC_END( WinX_getShellNewPath ); 2691| return (char*)var; 2692|} 2693| 2694| 2695| 2696|/************************************************************************** 2697| 9-9. <<< [WinX_setIcon] ファイルタイプに関連したアイコンを登録する >>> 2698|【引数】 2699| ・char* ext; 拡張子(ピリオド不要) 2700| ・char* path; アイコンファイルのパス 2701| ・int iIcon; アイコンファイル中のアイコン番号(0〜) 2702|***************************************************************************/ 2703|void WinX_setIcon( const char* ext, const char* path, int iIcon ) 2704|{ 2705| HKEY key; 2706| char s[256]; 2707| char type[256]; 2708| int type_len; 2709| LONG ret; 2710| DWORD dwDisp; 2711| 2712| ERRORS_FUNC_START( WinX_setIcon ); 2713| 2714| strcpy( s, "." ); strcat( s, ext ); 2715| ret = RegOpenKeyEx( HKEY_CLASSES_ROOT, s, 0L, KEY_READ, &key ); 2716| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2717| type_len = sizeof(type); 2718| ret = RegQueryValueEx( key, NULL, NULL, NULL, type, &type_len ); 2719| if ( ret != ERROR_SUCCESS || type[0] == '\0' ) WinX_throw( ret ); 2720| ret = RegCloseKey( key ); 2721| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2722| 2723| sprintf( s, "%s\\DefaultIcon", type ); 2724| ret = RegCreateKeyEx( HKEY_CLASSES_ROOT, s, 0, 0, 2725| REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dwDisp ); 2726| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2727| sprintf( s, "%s,%d", path, iIcon ); 2728| ret = RegSetValueEx( key, NULL, 0, REG_SZ, (WinX_DataPtr)s, strlen(s) ); 2729| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2730| ret = RegCloseKey( key ); 2731| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2732| 2733| ERRORS_FUNC_END( WinX_setIcon ); 2734|} 2735| 2736| 2737|/************************************************************************** 2738| 9-10. <<< [WinX_getIcon] ファイルタイプに関連しているアイコンを取得する >>> 2739|【引数】 2740| ・char* ext; 拡張子(ピリオド不要) 2741| ・char* path; アイコンファイルのパス 2742| ・int* iIcon; アイコンファイル中のアイコン番号(0〜)を格納するアドレス 2743|【補足】 2744|・取得したアイコンは、ピクチャーコントロールのタイプをアイコンにして、 2745| ExtractIconEx, CStatic::SetIcon を使って表示できます。 2746|・アイコンが登録されていない場合、path="", iIcon=0 になります。 2747|***************************************************************************/ 2748|#ifdef USES_EXCEPT3 2749|#ifdef USES_FILEX 2750|void WinX_getIcon( const char* ext, char* path, int* iIcon ) 2751|{ 2752| HKEY key; 2753| char s[256]; 2754| char s2[256]; 2755| char type[256]; 2756| int len; 2757| char* p; 2758| LONG ret; 2759| bool bExeDefIcon = false; 2760| 2761| ERRORS_FUNC_START( WinX_getIcon ); 2762| 2763| c_try { 2764| 2765| strcpy( s, "." ); strcat( s, ext ); 2766| ret = RegOpenKeyEx( HKEY_CLASSES_ROOT, s, 0L, KEY_READ, &key ); 2767| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2768| len = sizeof(type); 2769| ret = RegQueryValueEx( key, NULL, NULL, NULL, type, &len ); 2770| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2771| type[len] = '\0'; 2772| ret = RegCloseKey( key ); 2773| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2774| 2775| /* DefaultIcon からアイコンのパスを取得する */ 2776| sprintf( s, "%s\\DefaultIcon", type ); 2777| ret = RegOpenKeyEx( HKEY_CLASSES_ROOT, s, 0L, KEY_READ, &key ); 2778| 2779| if ( ret == 2 ) bExeDefIcon = true; 2780| else if ( ret != ERROR_SUCCESS ) { WinX_throw( ret ); } 2781| else { 2782| ret = RegQueryValueEx( key, NULL, NULL, NULL, type, &len ); 2783| len = sizeof(s); 2784| ret = RegQueryValueEx( key, NULL, NULL, NULL, s, &len ); 2785| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2786| p = StrX_RSearchC2( s, ',' ); 2787| if ( p == NULL ) 2788| { strcpy( path, s ); *iIcon = 0; } 2789| else 2790| { *p = '\0'; strcpy( path, s ); *iIcon = atoi( p + 1 ); } 2791| 2792| ret = RegCloseKey( key ); 2793| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 2794| } 2795| 2796| /* Command からアイコンのパスを取得する */ 2797| if ( bExeDefIcon ) { 2798| sprintf( s, "%s\\Shell", type ); 2799| WinX_getReg_s( HKEY_CLASSES_ROOT, s, NULL, s2, sizeof(s2) ); 2800| sprintf( s, "%s\\Shell\\%s\\command", type, s2 ); 2801| WinX_getReg_s( HKEY_CLASSES_ROOT, s, NULL, s2, sizeof(s2) ); 2802| StrX_getSpacedPath( s2, path, NULL ); 2803| *iIcon = 0; 2804| } 2805| } 2806| c_catch ( Errors_Msg*, msg ) { 2807| if ( ret == 2 ) 2808| { path[0] = '\0'; iIcon = 0; } 2809| else c_throw_again(); 2810| } c_end_catch; 2811| 2812| ERRORS_FUNC_END( WinX_getIcon ); 2813|} 2814|#endif 2815|#endif 2816| 2817|/************************************************************************** 2818| 9-11. <<< [WinX_getFTypeInfos] レジストリにある拡張子に関する情報を得る >>> 2819|【引数】 2820| ・WinX_FType* types; 格納する配列領域の先頭アドレス 2821| ・int types_size; types のメモリサイズ 2822| ・bool bAll; 全拡張子に対する情報も加えるか 2823| ・WinX_FType** defType; 左ダブルクリックしたときに実行されるアクション(ポインタのアドレス) 2824| ・int 返り値; types に格納した配列要素数 2825|【補足】 2826|・エクスプローラでファイルを右クリックしたときに表示されるメニュー項目、 2827| つまり、レジストリの HKEY_CLASSES_ROOT\(ext)\shell にある情報を取得します。 2828|***************************************************************************/ 2829|#if defined(USES_EXCEPT3) 2830|int WinX_getFTypeInfos( const char* ext, WinX_FType* types, int types_size, 2831| bool bAll, WinX_FType** defType ) 2832|{ 2833| int i, j; 2834| int nSkip; 2835| HKEY shellKey; 2836| char subKeyPath[256]; 2837| char typeRootName[256]; 2838| char defName[64]; 2839| DWORD type; 2840| LONG ret; 2841| DWORD size; 2842| 2843| ERRORS_FUNC_START( WinX_getFTypeInfos ); 2844| 2845| i = 0; 2846| nSkip = 0; 2847| *defType = NULL; 2848| 2849| c_try { 2850| 2851| if ( bAll ) { 2852| 2853| /* HKEY_CLASSES_ROOT\*\shell キーを shellKey に */ 2854| ret = RegOpenKeyEx( HKEY_CLASSES_ROOT, "*\\shell", 0L, KEY_READ, &shellKey ); 2855| if ( ret != ERROR_SUCCESS ) 2856| { error2_0( WinX_Err_NoRegKey, "" ); } 2857| 2858| /* HKEY_CLASSES_ROOT\*\shell\標準 の値を defName に */ 2859| size = sizeof(defName); 2860| ret = RegQueryValueEx( shellKey, NULL, NULL, &type, defName, &size ); 2861| if ( ret != ERROR_SUCCESS ) defName[0] = '\0'; 2862| 2863| for ( j = 0; ; j++ ) { 2864| WinX_FType* type = &types[i + j - nSkip]; 2865| 2866| switch ( WinX_getFTypeInfos_sub( shellKey, j, type ) ) { 2867| case 0: break; 2868| case 1: goto exit_for2; 2869| case 2: nSkip++; break; 2870| } 2871| 2872| if ( strcmp( type->name, defName ) == 0 ) { 2873| /* リストの先頭へ持っていく */ 2874| WinX_FType t = *type; 2875| memmove( &types[1], &types[0], sizeof(WinX_FType) * (i + j - nSkip) ); 2876| types[0] = t; 2877| 2878| if ( *defType == NULL ) 2879| *defType = &types[0]; 2880| } 2881| } 2882| exit_for2: 2883| RegCloseKey( shellKey ); 2884| i += j; 2885| } 2886| } 2887| c_catch ( Errors_Msg*, msg ) { 2888| if ( msg->code != WinX_Err_NoRegKey ) c_throw_again(); 2889| } c_end_catch; 2890| 2891| c_try { 2892| 2893| /* HKEY_CLASSES_ROOT\.(ext)\標準 の値を typeRootName に */ 2894| if ( ext[0] == '\0' || strcmp( ext, "*" ) == 0 ) { 2895| strcpy( typeRootName, "*" ); 2896| bAll = false; 2897| } 2898| else { 2899| subKeyPath[0] = '.'; strcpy( subKeyPath + 1, ext ); 2900| WinX_getReg_s( HKEY_CLASSES_ROOT, subKeyPath, NULL, typeRootName, sizeof(typeRootName) ); 2901| } 2902| 2903| /* HKEY_CLASSES_ROOT\(typeRootName)\shell キーを shellKey に */ 2904| sprintf( subKeyPath, "%s\\shell", typeRootName ); 2905| ret = RegOpenKeyEx( HKEY_CLASSES_ROOT, subKeyPath, 0L, KEY_READ, &shellKey ); 2906| if ( ret != ERROR_SUCCESS ) 2907| { error2_0( WinX_Err_NoRegKey, "" ); } 2908| 2909| /* HKEY_CLASSES_ROOT\(typeRootName)\shell\標準 の値を defName に */ 2910| size = sizeof(defName); 2911| ret = RegQueryValueEx( shellKey, NULL, NULL, &type, defName, &size ); 2912| if ( ret != ERROR_SUCCESS ) defName[0] = '\0'; 2913| 2914| for ( j = 0; ; j++ ) { 2915| WinX_FType* type = &types[i + j - nSkip]; 2916| 2917| switch ( WinX_getFTypeInfos_sub( shellKey, j, type ) ) { 2918| case 0: break; 2919| case 1: goto exit_for; 2920| case 2: nSkip++; break; 2921| } 2922| 2923| if ( strcmp( type->name, defName ) == 0 || stricmp( type->name, "open" ) == 0 ) { 2924| /* リストの先頭へ持っていく */ 2925| WinX_FType t = *type; 2926| memmove( &types[1], &types[0], sizeof(WinX_FType) * (i + j - nSkip) ); 2927| types[0] = t; 2928| 2929| if ( *defType == NULL ) 2930| *defType = &types[0]; 2931| } 2932| } 2933| exit_for: 2934| RegCloseKey( shellKey ); 2935| i += j; 2936| } 2937| c_catch ( Errors_Msg*, msg ) { 2938| if ( msg->code != WinX_Err_NoRegKey ) c_throw_again(); 2939| } c_end_catch; 2940| 2941| 2942| i -= nSkip; 2943| ASSERT( *defType != NULL || i == 0 ); 2944| 2945| ERRORS_FUNC_END( WinX_getFTypeInfos ); 2946| return i; 2947|} 2948|#endif 2949| 2950|/************************************************************************** 2951|* 9-12. <<< [WinX_getFTypeInfos_sub] WinX_getFTypeInfos のサブルーチン >>> 2952|*【引数】 2953|* ・HKEY shellKey; HKEY_CLASSES_ROOT\(typeRootName)\shell のキー 2954|* ・int iSubKey; shellKey のサブキー番号(0〜返り値が1になるまで) 2955|* ・WinX_FType* type; 格納する領域の先頭アドレス 2956|* ・int 返り値; 0=成功、1=iSubKey が大きすぎる、2=type に格納する情報が無い 2957|***************************************************************************/ 2958|#if defined(USES_EXCEPT3) 2959|int WinX_getFTypeInfos_sub( HKEY shellKey, int iSubKey, WinX_FType* type ) 2960|{ 2961| DWORD size, size2; 2962| LONG ret; 2963| FILETIME time; 2964| char className[256]; 2965| char subKeyPath[256]; 2966| 2967| /* HKEY_CLASSES_ROOT\(typeRootName)\shell のサブキー名を type->name に */ 2968| size = sizeof(type->name); 2969| size2 = sizeof(className); 2970| ret = RegEnumKeyEx( shellKey, iSubKey, type->name, &size, NULL, 2971| className, &size2, &time ); 2972| if ( ret == ERROR_NO_MORE_ITEMS ) return 1; 2973| 2974| /* HKEY_CLASSES_ROOT\(typeRootName)\shell\(name)\標準 の値を type->caption に */ 2975| c_try { 2976| type->caption[0] = '\0'; 2977| WinX_getReg_s( shellKey, type->name, NULL, 2978| type->caption, sizeof(type->caption) ); 2979| } 2980| Errors_ignore_catch( case WinX_Err_NoRegData: ); 2981| if ( type->caption[0] == '\0' ) { 2982| if ( stricmp( type->name, "open" ) == 0 ) 2983| strcpy( type->caption, "開く(&O)" ); 2984| else if ( stricmp( type->name, "print" ) == 0 ) 2985| strcpy( type->caption, "印刷(&P)" ); 2986| else 2987| StrX_cpy( type->caption, type->name, sizeof( type->caption ) ); 2988| } 2989| 2990| /* HKEY_CLASSES_ROOT\(typeRootName)\shell\(name)\EditFlags の値を type->editFlags に */ 2991| c_try { 2992| WinX_getReg_x( shellKey, type->name, "EditFlags", 2993| &type->editFlags, sizeof(type->editFlags) ); 2994| } 2995| Errors_ignore_catch( case WinX_Err_NoRegData: ); 2996| 2997| /* HKEY_CLASSES_ROOT\(typeRootName)\shell\(name)\command\標準 の値を type->command に */ 2998| { 2999| bool bGet = false; 3000| c_try { 3001| sprintf( subKeyPath, "%s\\command", type->name ); 3002| WinX_getReg_s( shellKey, subKeyPath, NULL, 3003| type->command, sizeof(type->command) ); 3004| bGet = true; 3005| } 3006| c_catch( Errors_Msg*, msg ) { 3007| } c_end_catch; 3008| if ( ! bGet ) return 2; 3009| } 3010| 3011| /* HKEY_CLASSES_ROOT\(typeRootName)\shell\(name)\ddeExec\標準 の値を type->ddeMsg に */ 3012| type->bDDE = false; 3013| c_try { 3014| sprintf( subKeyPath, "%s\\ddeExec", type->name ); 3015| WinX_getReg_s( shellKey, subKeyPath, NULL, 3016| type->ddeMsg, sizeof(type->ddeMsg) ); 3017| sprintf( subKeyPath, "%s\\ddeExec\\application", type->name ); 3018| WinX_getReg_s( shellKey, subKeyPath, NULL, 3019| type->ddeApp, sizeof(type->ddeApp) ); 3020| sprintf( subKeyPath, "%s\\ddeExec\\ifexec", type->name ); 3021| WinX_getReg_s( shellKey, subKeyPath, NULL, 3022| type->ddeOpenCmd, sizeof(type->ddeOpenCmd) ); 3023| sprintf( subKeyPath, "%s\\ddeExec\\topic", type->name ); 3024| WinX_getReg_s( shellKey, subKeyPath, NULL, 3025| type->ddeTopic, sizeof(type->ddeTopic) ); 3026| type->bDDE = true; 3027| } 3028| c_catch( Errors_Msg*, msg ) { 3029| } c_end_catch; 3030| 3031| return 0; 3032|} 3033|#endif 3034| 3035|/*------------------------------------------------------------------------*/ 3036|/* 10. <<<< ◆ インストール関係 >>>> */ 3037|/*------------------------------------------------------------------------*/ 3038| 3039| 3040| 3041|/************************************************************************** 3042| 10-1. <<< [WinX_uninstallFolder] アンインストーラのあるフォルダを削除する >>> 3043|【引数】 3044| ・char* folderPath; 削除するフォルダのパス 3045| ・char* appName; アプリケーション名(ダイアログのタイトルに表示します) 3046| ・char* folderName; 削除するフォルダ名(誤った削除をしないため) 3047|【補足】 3048|・削除するフォルダのバックアップを取っておいて下さい。 3049|・アプリが終了する直前に実行してください。終了してから削除します。 3050|・WSH がある時は、それを使用して自動的に削除します(完了メッセージあり)。 3051| WSH が無いときは、削除するフォルダを開き、ユーザに削除するように 3052| メッセージを表示します。 3053|・folderName は、誤って別のフォルダを削除しないために用意しています。 3054| folderPath は、実行ファイルのパスなどから導いたものに対して、 3055| folderName は、アプリケーションのコードでダイレクトに文字列を指定します。 3056|・完全にフォルダが削除されるまで、フォルダの削除を何度もトライします。 3057| そのため、早いうちに、実行ファイルの実行を終了するようにしてください。 3058|***************************************************************************/ 3059| 3060|#if defined(USES_FILEX) && defined(USES_STRX) && defined(USES_EXCEPT3) 3061|bool WinX_uninstallFolder( const char* folderPath, const char* appName, 3062| const char* folderName ) 3063|{ 3064| FILE* f; 3065| char path[_MAX_PATH]; 3066| char path2[_MAX_PATH]; 3067| char s[_MAX_PATH*2]; 3068| char* wshPath = WinX_getWSHPath(); 3069| 3070| ERRORS_FUNC_START( WinX_uninstallFolder ); 3071| 3072| if ( wshPath == NULL ) { 3073| MessageBox( NULL, "アンインストールが完了しました。\r\n\r\n" 3074| "ただし、実行ファイルのある(次に表示される)フォルダは、" 3075| "手動で削除してください。", "アンインストール完了", MB_OK ); 3076| WinX_openExplorer( folderPath ); 3077| } 3078| else if ( stricmp( StrX_refFName( folderPath ), folderName ) != 0 ) { 3079| sprintf( s, "アンインストールが完了しました。\r\n\r\n" 3080| "ただし、削除するフォルダ名が、アプリケーションが想定した名前(%s)" 3081| "と異なるため削除しませんでした。\r\n" 3082| "次に表示されるフォルダを確認して、手動で削除してください。", folderName ); 3083| MessageBox( NULL, s, "アンインストール完了", MB_OK ); 3084| WinX_openExplorer( folderPath ); 3085| } 3086| else { 3087| #ifndef NDEBUG 3088| sprintf( s, "フォルダ %s を削除します。よろしいですか?", folderPath ); 3089| if ( MessageBox( NULL, s, "デバッグ版専用メッセージ", MB_YESNO ) == IDNO ) 3090| return false; 3091| #endif 3092| 3093| StrX_cpyAbsPath( path, "uninst.vbs", _MAX_PATH - 1, WinX_getTempPath() ); 3094| f = FileX_open( path, "wt" ); 3095| 3096| fputs( "Set fs = CreateObject( \"Scripting.FileSystemObject\" )\n", f ); 3097| fputs( "On Error Resume Next\n", f ); 3098| fputs( "Dim I\n", f ); 3099| fputs( "I = 0\n", f ); 3100| fputs( "Do\n", f ); 3101| fputs( " Err.Clear\n", f ); 3102| fprintf( f, " fs.DeleteFolder \"%s\", True\n", folderPath ); 3103| fputs( " If Err.Number = 76 Then\n", f ); 3104| fprintf( f, " MsgBox \"パスの指定が間違っています : %s\"\n", folderPath ); 3105| fputs( " End If\n", f ); 3106| fputs( " If Err.Number = 70 Then\n", f ); 3107| fputs( " I = I+ 1\n", f ); 3108| fputs( " If I = 2000 Then\n", f ); 3109| fprintf( f, " If MsgBox( \"削除が拒否されました。" 3110| "%s の中にあるファイルかプロンプトを閉じて「再試行」を押してください。\"," 3111| "vbRetryCancel + vbExclamation, \"アンインストール - %s\" )" 3112| " = vbCancel Then\n", 3113| folderPath, appName ); /* インストーラが終わっていない可能性があります */ 3114| fputs( " Exit Do\n", f ); 3115| fputs( " End If\n", f ); 3116| fputs( " I = 0\n", f ); 3117| fputs( " End If\n", f ); 3118| fputs( " End If\n", f ); 3119| fputs( "Loop While Err.Number = 70\n", f ); 3120| fputs( "If Err.Number = 0 Then\n", f ); 3121| fprintf( f, " MsgBox \"アンインストールが完了しました。\", vbOKOnly, " 3122| "\"アンインストール - %s\"\n", appName ); 3123| fputs( "Else\n", f ); 3124| fprintf( f, " MsgBox \"アンインストールは正常に完了しませんでした。\", vbOKOnly, " 3125| "\"アンインストール - %s\"\n", appName ); 3126| fputs( "End If\n", f ); 3127| fprintf( f, "fs.DeleteFile \"%s\", True\n", path ); 3128| 3129| fclose( f ); 3130| 3131| StrX_cpyFolder( path2, wshPath ); 3132| _chdir( path2 ); 3133| sprintf( s, "%s \"%s\"", wshPath, path ); 3134| WinExec( s, SW_SHOWNORMAL ); 3135| } 3136| 3137| ERRORS_FUNC_END( WinX_uninstallFolder ); 3138| return true; 3139|} 3140|#endif 3141| 3142|/************************************************************************** 3143| 10-2. <<< [WinX_setAppUninstall] アプリケーションの追加と削除に追加する >>> 3144|【引数】 3145| ・char* appName; アプリ名(識別子) 3146| ・char* title; アプリのリスト中に表示される内容 3147| ・char* command; 選択されたときのコマンド(アンインストーラのファイル名)) 3148|***************************************************************************/ 3149|void WinX_setAppUninstall( const char* appName, 3150| const char* title, const char* command ) 3151|{ 3152| static unsigned char s[_MAX_PATH]; 3153| HKEY key; 3154| LONG ret; 3155| DWORD dwDisp; 3156| 3157| ERRORS_FUNC_START( WinX_setAppUninstall ); 3158| 3159| sprintf( s, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s", 3160| appName ); 3161| ret = RegCreateKeyEx( HKEY_LOCAL_MACHINE, s, 0, 0, 3162| REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dwDisp ); 3163| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 3164| ret = RegSetValueEx( key, "DisplayName", 0, REG_SZ, 3165| (WinX_DataPtr)title, strlen(title) ); 3166| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 3167| ret = RegSetValueEx( key, "UninstallString", 0, REG_SZ, 3168| (WinX_DataPtr)command, strlen(command) ); 3169| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 3170| ret = RegCloseKey( key ); 3171| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 3172| 3173| ERRORS_FUNC_END( WinX_setAppUninstall ); 3174|} 3175| 3176| 3177| 3178|/************************************************************************** 3179| 10-3. <<< [WinX_unsetAppUninstall] アプリケーションの追加と削除から削除する >>> 3180|【引数】 3181| ・char* appName; アプリ名(識別子) 3182|***************************************************************************/ 3183|void WinX_unsetAppUninstall( const char* appName ) 3184|{ 3185| static unsigned char s[_MAX_PATH]; 3186| LONG ret; 3187| 3188| ERRORS_FUNC_START( WinX_unsetAppUninstall ); 3189| 3190| sprintf( s, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s", 3191| appName ); 3192| ret = RegDeleteKey( HKEY_LOCAL_MACHINE, s ); 3193| if ( (ret & 0xFFFF) == ERROR_FILE_NOT_FOUND ) return; /* なければ返る */ 3194| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 3195| 3196| ERRORS_FUNC_END( WinX_unsetAppUninstall ); 3197|} 3198| 3199| 3200| 3201|/************************************************************************** 3202| 10-4. <<< [WinX_isSetAppUninstall] アプリケーションの追加と削除に登録されているか >>> 3203|【引数】 3204| ・char* appName; アプリ名(識別子) 3205| ・bool 返り値; アプリケーションの追加と削除に登録されているかどうか 3206|***************************************************************************/ 3207|bool WinX_isSetAppUninstall( const char* appName ) 3208|{ 3209| char s[_MAX_PATH]; 3210| bool r; 3211| 3212| ERRORS_FUNC_START( WinX_unsetAppUninstall ); 3213| 3214| sprintf( s, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s", 3215| appName ); 3216| 3217| r = WinX_isExistReg( HKEY_LOCAL_MACHINE, s, true, false ) 3218| 3219| ERRORS_FUNC_END( WinX_unsetAppUninstall ); 3220| return r; 3221|} 3222| 3223| 3224| 3225|/************************************************************************** 3226| 10-5. <<< [WinX_throwToTrash] ファイルをごみ箱へ移動する >>> 3227|***************************************************************************/ 3228|void WinX_throwToTrash( HWND hWnd, const char* path ) 3229|{ 3230| SHFILEOPSTRUCT s; 3231| 3232| memset( &s, 0, sizeof(s) ); 3233| s.hwnd = hWnd; 3234| s.wFunc = FO_DELETE; 3235| s.pFrom = path; 3236| s.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION; 3237| s.fAnyOperationsAborted = TRUE; 3238| 3239| ((char*)path)[ strlen(path) + 1 ] = '\0'; 3240| 3241| SHFileOperation( &s ); 3242|} 3243| 3244|/*------------------------------------------------------------------------*/ 3245|/* 11. <<<< ◆(WinX_Inst) インストール関係 >>>> */ 3246|/*------------------------------------------------------------------------*/ 3247| 3248|void WinX_RegNest_add( WinX_RegNest* ); 3249| 3250| 3251|/************************************************************************** 3252| 11-1. <<< [WinX_Inst_install] レジストリ情報をインストールする >>> 3253|【引数】 3254| ・WinX_Inst* m; インストール情報 3255| ・char* exePath; メインとなる実行ファイルの絶対パス 3256| ・bool* enables; 拡張子別インストール許可・不許可(NULL=全部許可) 3257| ・bool bSplitByVer; 複数のバージョンを同居させるかどうか(現在falseのみ可) 3258|【補足】 3259|・(未対応)旧 open があれば、それを open2 にして、open を追加する 3260|・アンインストール情報:.(ext)\backup = .(ext) のバックアップ 3261|・(未対応)マージ・インストール, バージョンマージインストール or 修復 3262|・(未対応)(ext)file\shell\(各アプリ最初のコマンド)\DefCmd にバックアップ 3263|・(未対応)(ext)file\shell\(各アプリ最初のコマンド)\DefaultIcon にバックアップ 3264|***************************************************************************/ 3265|#ifdef USES_BIGSTACK 3266|void WinX_Inst_install( WinX_Inst* m, const char* exePath, bool* enables, 3267| bool bSplitByVer ) 3268|{ 3269| WinX_InstType* type; 3270| WinX_InstCmd* cmd; 3271| int typeKeyName_len; 3272| LONG ret; 3273| HKEY key; 3274| char s[256]; 3275| char typeKeyName[256]; 3276| WinX_RegData data; 3277| char x[256]; 3278| int len; 3279| int typeTmp; 3280| DWORD dwDisp; 3281| 3282| ERRORS_FUNC_START( WinX_Inst_install ); 3283| 3284| ASSERT( ! bSplitByVer ); 3285| WinX_RegData_init( &data, x, sizeof(x) ); 3286| 3287| /* WinX_InstType の設定をレジストリに設定する */ 3288| for ( type = m->types; strcmp( type->ext, "NULL" ) != 0; type++ ) { 3289| 3290| if ( enables != NULL && ! enables[ type - m->types ] ) 3291| continue; 3292| 3293| if ( strcmp( type->ext, "*" ) == 0 || stricmp( type->ext, "folder" ) == 0 ) { 3294| strcpy( typeKeyName, type->ext ); 3295| } 3296| 3297| /* HKEY_CLASSES_ROOT\.(ext)\標準 に (ext)file を設定する */ 3298| else { 3299| strcpy( s, "." ); strcat( s, type->ext ); 3300| 3301| ret = RegCreateKeyEx( HKEY_CLASSES_ROOT, s, 0, 0, 3302| REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dwDisp ); 3303| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 3304| 3305| strcpy( s, type->ext ); strcat( s, "file" ); 3306| typeKeyName_len = sizeof(typeKeyName); 3307| ret = RegQueryValueEx( key, NULL, NULL, NULL, typeKeyName, &typeKeyName_len ); 3308| if ( ret == ERROR_SUCCESS && typeKeyName[0] != '\0' ) { 3309| if ( stricmp( s, typeKeyName ) != 0 ) { 3310| 3311| WinX_copyRegNest( HKEY_CLASSES_ROOT, s, HKEY_CLASSES_ROOT, typeKeyName ); 3312| 3313| /* バックアップを取る */ 3314| data.type = REG_SZ; strcpy( data.data, typeKeyName ); 3315| data.size = strlen( typeKeyName ); 3316| sprintf( typeKeyName, ".%s\\backup", type->ext ); 3317| WinX_setReg( HKEY_CLASSES_ROOT, typeKeyName, false, &data ); 3318| 3319| /* リンク先を変える */ 3320| data.type = REG_SZ; 3321| sprintf( data.data, "%sfile", type->ext ); 3322| data.size = strlen( typeKeyName ); 3323| sprintf( typeKeyName, ".%s", type->ext ); 3324| WinX_setReg( HKEY_CLASSES_ROOT, typeKeyName, true, &data ); 3325| } 3326| } 3327| else { 3328| ret = RegSetValueEx( key, NULL, 0, REG_SZ, (WinX_DataPtr)s, strlen( s ) ); 3329| 3330| /* アンインストール時に消すようにする */ 3331| data.type = REG_SZ; strcpy( data.data, "" ); 3332| data.size = strlen( typeKeyName ); 3333| sprintf( typeKeyName, ".%s\\backup", type->ext ); 3334| WinX_setReg( HKEY_CLASSES_ROOT, typeKeyName, false, &data ); 3335| } 3336| strcpy( typeKeyName, s ); 3337| 3338| ret = RegCloseKey( key ); 3339| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 3340| } 3341| 3342| /* HKEY_CLASSES_ROOT\(ext)file を開く */ 3343| ret = RegCreateKeyEx( HKEY_CLASSES_ROOT, typeKeyName, 0, 0, 3344| REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dwDisp ); 3345| 3346| /* HKEY_CLASSES_ROOT\(ext)file\標準 に タイプの説明 を設定する */ 3347| if ( type->explain != NULL ) { 3348| ret = RegSetValueEx( key, NULL, 0, REG_SZ, (WinX_DataPtr)type->explain, strlen(type->explain) ); 3349| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 3350| } 3351| 3352| /* HKEY_CLASSES_ROOT\(ext)file\EditFlags にダウンロードの設定をする */ 3353| { 3354| static char flags11[4] = { 0x00, 0x00, 0x00, 0x00 }; /* ダウンロード時に確認する */ 3355| static char flags10[4] = { 0x00, 0x00, 0x01, 0x00 }; /* ダウンロード時に確認しない */ 3356| 3357| if ( type->bDownChk ) 3358| ret = RegSetValueEx( key, "EditFlags", 0, REG_BINARY, (WinX_DataPtr)flags11, sizeof(flags11) ); 3359| else 3360| ret = RegSetValueEx( key, "EditFlags", 0, REG_BINARY, (WinX_DataPtr)flags10, sizeof(flags10) ); 3361| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 3362| } 3363| 3364| /* HKEY_CLASSES_ROOT\(ext)file を閉じる */ 3365| ret = RegCloseKey( key ); 3366| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 3367| 3368| /* HKEY_CLASSES_ROOT\(ext)file\CLSID を CLSID_BK に変えて、レジストリの設定を有効にする */ 3369| { 3370| char from[512]; 3371| char to[512]; 3372| 3373| sprintf( from, "%s\\CLSID", typeKeyName ); 3374| if ( WinX_isExistReg( HKEY_CLASSES_ROOT, from, true, false ) ) { 3375| sprintf( to, "%s\\CLSID_BK", typeKeyName ); 3376| WinX_copyRegNest( HKEY_CLASSES_ROOT, to, HKEY_CLASSES_ROOT, from ); 3377| WinX_delRegNest( HKEY_CLASSES_ROOT, from ); 3378| } 3379| } 3380| 3381| /* HKEY_CLASSES_ROOT\(ext)file\DefaultIcon にアイコンのパスと番号を設定する */ 3382| if ( type->iIcon != -1 ) { 3383| 3384| { 3385| char from[512]; 3386| char to[512]; 3387| 3388| sprintf( from, "%s\\DefaultIcon", typeKeyName ); 3389| sprintf( to, "%s\\DefaultIcon_BK", typeKeyName ); 3390| if ( WinX_isExistReg( HKEY_CLASSES_ROOT, from, true, false ) && 3391| ! WinX_isExistReg( HKEY_CLASSES_ROOT, to, true, false ) ) { 3392| WinX_copyRegNest( HKEY_CLASSES_ROOT, to, HKEY_CLASSES_ROOT, from ); 3393| WinX_delRegNest( HKEY_CLASSES_ROOT, from ); 3394| } 3395| } 3396| 3397| sprintf( s, "%s\\DefaultIcon", typeKeyName ); 3398| ret = RegCreateKeyEx( HKEY_CLASSES_ROOT, s, 0, NULL, REG_OPTION_NON_VOLATILE, 3399| KEY_ALL_ACCESS, NULL, &key, NULL ); 3400| 3401| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 3402| 3403| if ( type->iconPath == NULL || strcmp( type->iconPath, "" ) == 0 ) 3404| strcpy( s, exePath ); 3405| else 3406| StrX_cpyAbsPath2( s, type->iconPath, sizeof(s), exePath ); 3407| sprintf( strchr( s, '\0' ), ",%d", type->iIcon ); 3408| ret = RegSetValueEx( key, NULL, 0, REG_SZ, (WinX_DataPtr)s, strlen(s) ); 3409| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 3410| 3411| ret = RegCloseKey( key ); 3412| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 3413| } 3414| 3415| for ( cmd = type->cmds; strcmp( cmd->name, "NULL" ) != 0; cmd++ ) { 3416| 3417| /* デフォルト・コマンドなら HKEY_CLASSES_ROOT\(ext)file\shell\標準 にコマンド名を設定する */ 3418| sprintf( s, "%s\\shell", typeKeyName ); 3419| ret = RegCreateKeyEx( HKEY_CLASSES_ROOT, s, 0, 0, 3420| REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dwDisp ); 3421| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 3422| 3423| len = sizeof(s); 3424| ret = RegQueryValueEx( key, NULL, NULL, &typeTmp, s, &len ); 3425| if ( ( cmd->defType == WinX_SubDef && ( ret == 2 || s[0] == '\0' ) ) || 3426| cmd->defType == WinX_Def ) { 3427| 3428| ret = RegSetValueEx( key, NULL, 0, REG_SZ, (WinX_DataPtr)cmd->name, strlen(cmd->name) ); 3429| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 3430| } 3431| else { 3432| ret = RegSetValueEx( key, NULL, 0, REG_SZ, (WinX_DataPtr)"", 0 ); 3433| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 3434| } 3435| ret = RegCloseKey( key ); 3436| if ( ret != ERROR_SUCCESS ) { Errors_printf_release( "%s", typeKeyName ); WinX_error(); } /* WinX_throw( ret ); */ 3437| 3438| /* HKEY_CLASSES_ROOT\(ext)file\shell\(cmd_name)\標準 にメニュー表示内容を設定する */ 3439| /* HKEY_CLASSES_ROOT\(ext)file\shell\(cmd_name)\EditFlags に設定する */ 3440| { 3441| static char flags2[4] = { 0x01, 0x00, 0x00, 0x00 }; 3442| DWORD flags; 3443| DWORD size; 3444| DWORD type; 3445| 3446| sprintf( s, "%s\\shell\\%s", typeKeyName, cmd->name ); 3447| ret = RegCreateKeyEx( HKEY_CLASSES_ROOT, s, 0, 0, 3448| REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dwDisp ); 3449| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 3450| 3451| ret = RegSetValueEx( key, NULL, 0, REG_SZ, (WinX_DataPtr)cmd->caption, strlen(cmd->caption) ); 3452| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 3453| 3454| ret = RegSetValueEx( key, "EditFlags", 0, REG_BINARY, (WinX_DataPtr)flags2, sizeof(flags2) ); 3455| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 3456| 3457| /* HKEY_CLASSES_ROOT\(ext)file\Shell\(cmd)\BrowserFlags と 〜\ExplorerFlags を改名する */ 3458| /* HKEY_CLASSES_ROOT\(ext)file\Shell\(cmd) にある DWORD 型 */ 3459| /* データ BrowserFlags(フォルダ), ExplorerFlags(エクスプローラ) の */ 3460| /* フラグ値 0x10 が立っていると、.zip 形式のときは、エクスプローラが展開します。 */ 3461| /* フラグ値 0x02 が立っていると、新規ウィンドウを開きます。 */ 3462| /* これらは、本関数で登録したインストール情報より優先されるため、データ名を */ 3463| /* BrowserFlaga_backup のように変えています。*/ 3464| ret = RegQueryValueEx( key, "BrowserFlags", 0, &type, (char*)&flags, &size ); 3465| if ( ret == ERROR_SUCCESS ) { 3466| if ( type != REG_DWORD ) error(); 3467| ret = RegSetValueEx( key, "BrowserFlags_backup", 0, REG_DWORD, (char*)&flags, sizeof(flags) ); 3468| WinX_delReg( key, "BrowserFlags", false ); 3469| } 3470| 3471| ret = RegQueryValueEx( key, "ExplorerFlags", 0, &type, (char*)&flags, &size ); 3472| if ( ret == ERROR_SUCCESS ) { 3473| if ( type != REG_DWORD ) error(); 3474| ret = RegSetValueEx( key, "ExplorerFlags_backup", 0, REG_DWORD, (char*)&flags, sizeof(flags) ); 3475| WinX_delReg( key, "ExplorerFlags", false ); 3476| } 3477| 3478| ret = RegCloseKey( key ); 3479| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 3480| } 3481| 3482| /* HKEY_CLASSES_ROOT\(ext)file\shell\(cmd_name)\ddeexec を改名する */ 3483| /* HKEY_CLASSES_ROOT\(ext)file\Shell\(cmd)\BrowserFlags と同じ理由による */ 3484| sprintf( s, "%s\\shell\\%s\\ddeexec", typeKeyName, cmd->name ); 3485| sprintf( x, "%s\\shell\\%s\\ddeexec_backup", typeKeyName, cmd->name ); 3486| if ( WinX_isExistReg( HKEY_CLASSES_ROOT, s, true, true ) ) { 3487| WinX_copyRegNest( HKEY_CLASSES_ROOT, x, HKEY_CLASSES_ROOT, s ); 3488| WinX_delRegNest( HKEY_CLASSES_ROOT, s ); 3489| } 3490| 3491| /* HKEY_CLASSES_ROOT\(ext)file\shell\(cmd_name)\command\標準 にコマンドを設定する */ 3492| { 3493| char cmdLine[512]; 3494| 3495| sprintf( s, "%s\\shell\\%s\\command", typeKeyName, cmd->name ); 3496| ret = RegCreateKeyEx( HKEY_CLASSES_ROOT, s, 0, 0, 3497| REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dwDisp ); 3498| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 3499| 3500| if ( cmd->exePath == NULL || cmd->exePath[0] == '\0' ) 3501| sprintf( cmdLine, "\"%s\" %s", exePath, cmd->command ); 3502| else { 3503| StrX_cpyAbsPath2( s, cmd->exePath, sizeof(s), exePath ); 3504| sprintf( cmdLine, "\"%s\" %s", s, cmd->command ); 3505| } 3506| ret = RegSetValueEx( key, NULL, 0, REG_SZ, (WinX_DataPtr)cmdLine, strlen(cmdLine) ); 3507| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 3508| 3509| RegCloseKey( key ); 3510| if ( ret != ERROR_SUCCESS ) WinX_throw( ret ); 3511| } 3512| } 3513| } 3514| ERRORS_FUNC_END( WinX_Inst_install ); 3515|} 3516|#endif 3517| 3518| 3519|/************************************************************************** 3520| 11-2. <<< [WinX_Inst_uninstall] レジストリ情報をアンインストールする >>> 3521|【引数】 3522| ・WinX_Inst* m; インストール時に使ったインストール情報 3523| ・char* exePath; メインとなる実行ファイルの絶対パス 3524| ・bool* enables; 拡張子別アンインストール許可・不許可(NULL=全部許可) 3525|【補足】 3526|・(未対応)アンインストールするときは、実行ファイル名をチェックして、 3527| 合っていなかったら、open2, open3, ... を調べる。 3528|***************************************************************************/ 3529|#ifdef USES_BIGSTACK 3530|void WinX_Inst_uninstall( WinX_Inst* m, const char* exePath, bool* enables ) 3531|{ 3532| WinX_InstType* type; 3533| WinX_InstCmd* cmd; 3534| char s[256]; 3535| char typeKeyName[256]; 3536| 3537| ERRORS_FUNC_START( WinX_Inst_uninstall ); 3538| 3539| /* WinX_InstType の設定をレジストリに設定する */ 3540| for ( type = m->types; strcmp( type->ext, "NULL" ) != 0; type++ ) { 3541| 3542| if ( enables != NULL && enables[ type - m->types ] ) 3543| continue; 3544| 3545| if ( strcmp( type->ext, "*" ) == 0 || stricmp( type->ext, "folder" ) == 0 ) { 3546| strcpy( typeKeyName, type->ext ); 3547| } 3548| else { 3549| /* HKEY_CLASSES_ROOT\.(ext)\標準 を typeKeyName に取得する */ 3550| c_try { 3551| strcpy( s, "." ); strcat( s, type->ext ); 3552| WinX_getReg_s( HKEY_CLASSES_ROOT, s, NULL, typeKeyName, sizeof(typeKeyName) ); 3553| } 3554| c_catch ( Errors_Msg*, msg ) { 3555| if ( msg->code != WinX_Err_NoRegKey ) c_throw_again(); 3556| typeKeyName[0] = '\0'; 3557| } c_end_catch; 3558| if ( typeKeyName[0] == '\0' ) continue; 3559| 3560| /* typeKeyName が標準名でなかったら、本モジュールがインストールしていないものとして何もしない */ 3561| sprintf( s, "%sfile", type->ext ); 3562| if ( strcmp( s, typeKeyName ) != 0 ) continue; 3563| } 3564| 3565| /* HKEY_CLASSES_ROOT\(ext)file\DefaultIcon を削除する */ 3566| /* sprintf( s, "%s\\DefaultIcon", typeKeyName ); */ 3567| /* WinX_delRegNest( HKEY_CLASSES_ROOT, s ); */ /* アンインストールを先にすると元々あったのさえ削除してしまう */ 3568| { 3569| char from[512]; 3570| char to[512]; 3571| 3572| sprintf( from, "%s\\DefaultIcon_BK", typeKeyName ); 3573| if ( WinX_isExistReg( HKEY_CLASSES_ROOT, from, true, false ) ) { 3574| sprintf( to, "%s\\DefaultIcon", typeKeyName ); 3575| WinX_delRegNest( HKEY_CLASSES_ROOT, to ); 3576| WinX_copyRegNest( HKEY_CLASSES_ROOT, to, HKEY_CLASSES_ROOT, from ); 3577| WinX_delRegNest( HKEY_CLASSES_ROOT, from ); 3578| } 3579| } 3580| 3581| /* HKEY_CLASSES_ROOT\(ext)file\CLSID_BK を CLSID に戻す */ 3582| { 3583| char from[512]; 3584| char to[512]; 3585| 3586| sprintf( from, "%s\\CLSID_BK", typeKeyName ); 3587| if ( WinX_isExistReg( HKEY_CLASSES_ROOT, from, true, false ) ) { 3588| sprintf( to, "%s\\CLSID", typeKeyName ); 3589| WinX_copyRegNest( HKEY_CLASSES_ROOT, to, HKEY_CLASSES_ROOT, from ); 3590| WinX_delRegNest( HKEY_CLASSES_ROOT, from ); 3591| } 3592| } 3593| 3594| /* HKEY_CLASSES_ROOT\(ext)file\shell\(cmd) を削除する */ 3595| for ( cmd = type->cmds; strcmp( cmd->name, "NULL" ) != 0; cmd++ ) { 3596| sprintf( s, "%s\\shell\\%s", typeKeyName, cmd->name ); 3597| WinX_delRegNest( HKEY_CLASSES_ROOT, s ); 3598| } 3599| 3600| /* HKEY_CLASSES_ROOT\(ext)file\(shell\) にサブキーが無ければ削除する */ 3601| sprintf( s, "%s\\shell", typeKeyName ); 3602| WinX_delRegIfNoSub( HKEY_CLASSES_ROOT, s ); 3603| sprintf( s, "%s", typeKeyName ); 3604| WinX_delRegIfNoSub( HKEY_CLASSES_ROOT, s ); 3605| 3606| /* HKEY_CLASSES_ROOT\.(ext)\backup を元に、 */ 3607| /* HKEY_CLASSES_ROOT\.(ext)\標準 を元に戻す */ 3608| /* backup が無ければ、HKEY_CLASSES_ROOT\.(ext) を削除する */ 3609| if ( strcmp( type->ext, "*" ) != 0 && stricmp( type->ext, "folder" ) != 0 ) { 3610| bool bResume = false; 3611| 3612| c_try { 3613| WinX_RegData data; 3614| 3615| WinX_RegData_init( &data, typeKeyName, sizeof(typeKeyName) ); 3616| sprintf( s, ".%s\\backup", type->ext ); 3617| WinX_getReg( HKEY_CLASSES_ROOT, s, false, &data ); 3618| WinX_delReg( HKEY_CLASSES_ROOT, s, false ); 3619| sprintf( s, ".%s", type->ext ); 3620| if ( data.size == 1 ) 3621| WinX_delRegNest( HKEY_CLASSES_ROOT, s ); 3622| else 3623| WinX_setReg( HKEY_CLASSES_ROOT, s, true, &data ); 3624| } Errors_ignore_catch( case WinX_Err_NoRegData: ); 3625| } 3626| } 3627| ERRORS_FUNC_END( WinX_Inst_uninstall ); 3628|} 3629|#endif 3630| 3631| 3632|/*------------------------------------------------------------------------*/ 3633|/* 12. <<<< ◆(WinX_Autorun) CD-ROM 自動実行の情報 >>>> */ 3634|/*------------------------------------------------------------------------*/ 3635| 3636| 3637| 3638|/*********************************************************************** 3639| 12-1. <<< [WinX_Autorun_read] Autorun.inf を読み込む >>> 3640|【引数】 3641| ・WinX_Autorun* m; Autorun.inf の情報の格納先 3642| ・char* path; Autorun.inf のパス 3643|************************************************************************/ 3644|#ifdef USES_INIFILE 3645|void WinX_Autorun_read( WinX_Autorun* m, const char* path ) 3646|{ 3647| IniFile_Read f; 3648| int i; 3649| char f_buf[256]; 3650| char name[256]; 3651| char* p; 3652| 3653| ERRORS_FUNC_START( WinX_Autorun_read ); 3654| 3655| strcpy( m->autorun_path, path ); 3656| IniFile_Read_init( &f, path, f_buf, sizeof(f_buf) ); 3657| IniFile_Read_setSection( &f, "Autorun" ); 3658| IniFile_Read_getPlusVar( &f, "open", "s", m->open, "" ); 3659| IniFile_Read_getPlusVar( &f, "icon", "s", m->iconPath, "" ); 3660| 3661| /* iconNum */ 3662| p = StrX_RSearchC2( m->iconPath, ',' ); 3663| if ( p != NULL ) { 3664| m->iconNum = atoi( p + 1 ); 3665| *p = '\0'; 3666| } 3667| else 3668| m->iconNum = 0; 3669| 3670| /* captions, commands */ 3671| i = 0; 3672| while ( IniFile_Read_getNextVar( &f, name, "s", m->captions[i] ) != -1L ) { 3673| if ( strnicmp( name, "shell", 5 ) != 0 ) break; 3674| p = StrX_RSearchC2( m->iconPath, '\\' ); 3675| if ( p != NULL && p > name + 5 && stricmp( p + 1, "command" ) == 0 ) { 3676| strcpy( m->commands[i], m->captions[i] ); 3677| IniFile_Read_getNextVar( &f, name, "s", m->captions[i] ); 3678| } 3679| else { 3680| IniFile_Read_getNextVar( &f, name, "s", m->commands[i] ); 3681| } 3682| if ( strnicmp( name, "shell", 5 ) != 0 ) break; 3683| i++; 3684| } 3685| m->nCommand = i; 3686| 3687| IniFile_Read_finish( &f ); 3688| 3689| ERRORS_FUNC_END( WinX_Autorun_read ); 3690|} 3691|#endif 3692| 3693|/*********************************************************************** 3694| 12-2. <<< [WinX_Autorun_exec] Autorun.inf の情報からコマンドを実行する >>> 3695|【引数】 3696| ・WinX_Autorun* m; Autorun.inf の情報 3697| ・char* iCommand; 実行するコマンドの番号(0〜=shell、-1=open) 3698|************************************************************************/ 3699|#ifdef USES_FILEX 3700|void WinX_Autorun_exec( WinX_Autorun* m, int iCommand ) 3701|{ 3702| char cmd2[_MAX_PATH]; 3703| char curDir[_MAX_PATH]; 3704| char* p; 3705| 3706| ERRORS_FUNC_START( WinX_Autorun_exec ); 3707| 3708| p = WinX_Autorun_getCmdPath( m, iCommand, cmd2, sizeof(cmd2) ); 3709| StrX_cpyFolder( curDir, cmd2 ); 3710| 3711| ShellExecute( NULL, NULL, cmd2, p, curDir, SW_SHOWNORMAL ); 3712| 3713| ERRORS_FUNC_END( WinX_Autorun_exec ); 3714|} 3715|#endif 3716| 3717|/*********************************************************************** 3718| 12-3. <<< [WinX_Autorun_getCmdPath] コマンドの実行ファイル部とパラメータ部を分ける >>> 3719|【引数】 3720| ・WinX_Autorun* m; Autorun.inf の情報 3721| ・char* iCommand; 実行するコマンドの番号(0〜=shell、-1=open) 3722| ・char* exe_path; 実行ファイルを格納する領域 3723| ・int exe_path_size; exe_path のメモリサイズ 3724| ・char* 返り値; パラメータ部の先頭(exe_path 内) 3725|【補足】 3726|・exe_path には、'\0' で区切られた、実行ファイルとパラメータの両方が格納されます。 3727|************************************************************************/ 3728|#ifdef USES_FILEX 3729|char* WinX_Autorun_getCmdPath( WinX_Autorun* m, int iCommand, 3730| char* exe_path, int exe_path_size ) 3731|{ 3732| char* cmd; 3733| char* exeParameters; 3734| char* p; 3735| 3736| ERRORS_FUNC_START( WinX_Autorun_getCmdPath ); 3737| 3738| if ( iCommand == -1 ) cmd = m->open; 3739| else cmd = m->commands[iCommand]; 3740| 3741| StrX_cpyAbsPath2( exe_path, cmd, exe_path_size, m->autorun_path ); 3742| 3743| p = strchr( exe_path, ' ' ); 3744| if ( p != NULL ) { 3745| *p = '\0'; exeParameters = p + 1; 3746| if ( ! FileX_isExist( exe_path ) ) { 3747| *p = ' '; exeParameters = NULL; 3748| } 3749| } 3750| else exeParameters = NULL; 3751| 3752| ERRORS_FUNC_END( WinX_Autorun_getCmdPath ); 3753| return exeParameters; 3754|} 3755|#endif 3756| 3757|/*------------------------------------------------------------------------*/ 3758|/* 13. <<<< ◆Windows 用高速ビットマップ描画(DDB = デバイス依存ビットマップ) >>>> */ 3759|/*------------------------------------------------------------------------*/ 3760| 3761| 3762|/*********************************************************************** 3763| 13-1. <<< [WinX_DDBmp_init] 初期化をする >>> 3764|【引数】 3765| ・char* path; DDB の保存先 3766|************************************************************************/ 3767|void WinX_DDBmp_init( WinX_DDBmp* m, const char* path ) 3768|{ 3769| strcpy( m->path, path ); 3770| m->width = -1; 3771| m->height = -1; 3772| m->size = 0; 3773| m->bmp = NULL; 3774|} 3775| 3776| 3777|/*********************************************************************** 3778| 13-2. <<< [WinX_DDBmp_finish] 後始末をする >>> 3779|************************************************************************/ 3780|void WinX_DDBmp_finish( WinX_DDBmp* m ) 3781|{ 3782| ASSERT( m->bmp == NULL ); 3783| 3784| if ( m->size != 0 ) 3785| remove( m->path ); 3786|} 3787| 3788| 3789| 3790|/*********************************************************************** 3791| 13-3. <<< [WinX_DDBmp_openForWrite] DDBの作成を開始する >>> 3792|【引数】 3793| ・HDC windowDC; ウィンドウから取得したデバイスコンテキスト 3794| ・int width; ビットマップの幅(0以上) 3795| ・int heifht; ビットマップの高さ(0以上) 3796| ・HDC 返り値; DDB に対して描画できるデバイスコンテキスト 3797|【補足】 3798|・プログラミング例 3799| CDC* bmpDC; 3800| bmpDC = CDC::FromHandle( WinX_DDBmp_openForWrite( &ddb, hDC, width, height ) ); 3801| bmpDC->Rectangle(0,0,100,100); 3802| bmpDC->Detach(); 3803| WinX_DDBmp_closeForWrite( &ddb ); 3804|************************************************************************/ 3805|HDC WinX_DDBmp_openForWrite( WinX_DDBmp* m, HDC windowDC, int width, int height ) 3806|{ 3807| ASSERT( m->bmp == NULL ); 3808| ASSERT( width >= 0 ); 3809| ASSERT( height >= 0 ); 3810| 3811| m->width = width; 3812| m->height = height; 3813| m->bmp = CreateCompatibleBitmap( windowDC, m->width, m->height ); 3814| m->bmpDC = CreateCompatibleDC( windowDC ); 3815| m->oldBmp = SelectObject( m->bmpDC, m->bmp ); 3816| 3817| return m->bmpDC; 3818|} 3819| 3820| 3821|/*********************************************************************** 3822| 13-4. <<< [WinX_DDBmp_closeForWrite] DDBの作成を終了して保存する >>> 3823|【補足】 3824|・WinX_DDBmp_openForWrite で取得した DC が CDC クラスなどにリンクしていたときは、 3825| この関数を呼び出す前にリンクを解除してください。 3826| CDC* bmpDC; 3827| bmpDC = CDC::FromHandle( WinX_DDBmp_openForWrite( &ddb, hDC ) ); 3828| bmpDC->Rectangle(0,0,100,100); 3829| bmpDC->Detach(); 3830| WinX_DDBmp_closeForWrite( &ddb ); 3831|************************************************************************/ 3832|void WinX_DDBmp_closeForWrite( WinX_DDBmp* m ) 3833|{ 3834| HANDLE f; 3835| void* bmpX; 3836| HANDLE fmap; 3837| BITMAP info; 3838| BITMAPINFO info2; 3839| 3840| ASSERT( m->bmp != NULL ); 3841| 3842| GetObject( m->bmp, sizeof(info), &info ); // info.bmBits = NULL 3843| info2.bmiHeader.biSize = sizeof(BITMAPINFO); 3844| info2.bmiHeader.biWidth = info.bmWidth; 3845| info2.bmiHeader.biHeight = info.bmHeight; 3846| info2.bmiHeader.biPlanes = info.bmPlanes; 3847| info2.bmiHeader.biBitCount = info.bmBitsPixel; 3848| info2.bmiHeader.biCompression = BI_RGB; 3849| info2.bmiHeader.biSizeImage = 0; 3850| info2.bmiHeader.biXPelsPerMeter = 1; 3851| info2.bmiHeader.biYPelsPerMeter = 1; 3852| info2.bmiHeader.biClrUsed = 0; 3853| info2.bmiHeader.biClrImportant = 0; 3854| 3855| m->size = info.bmWidthBytes * info.bmHeight; 3856| f = CreateFile( m->path, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); 3857| fmap = CreateFileMapping( f, NULL, PAGE_READWRITE, 0, m->size, NULL ); 3858| bmpX = MapViewOfFile( fmap, FILE_MAP_WRITE, 0, 0, 0 ); 3859| 3860| GetDIBits( m->bmpDC, m->bmp, 0, info2.bmiHeader.biHeight, bmpX, &info2, DIB_RGB_COLORS ); 3861| 3862| UnmapViewOfFile( bmpX ); 3863| CloseHandle( fmap ); 3864| CloseHandle( f ); 3865| 3866| SelectObject( m->bmpDC, m->oldBmp ); 3867| DeleteObject( m->bmp ); 3868| DeleteDC( m->bmpDC ); 3869| 3870| m->bmp = NULL; 3871|} 3872| 3873| 3874| 3875|/*********************************************************************** 3876| 13-5. <<< [WinX_DDBmp_openForRead] 作成したDDBを開く >>> 3877|【引数】 3878| ・HDC windowDC; ウィンドウから取得したデバイスコンテキスト 3879| ・HDC 返り値; DDB に対して描画できるデバイスコンテキスト 3880|【補足】 3881|・プログラミング例。 3882| bmpDC = WinX_DDBmp_openForRead( &ddb, hDC ); 3883| BitBlt( hDC, 0,0, ddb.width, ddb.height, bmpDC, 0, 0, SRCCOPY ); 3884| WinX_DDBmp_closeForRead( &ddb ); 3885|************************************************************************/ 3886|HDC WinX_DDBmp_openForRead( WinX_DDBmp* m, HDC windowDC ) 3887|{ 3888| HANDLE f; 3889| HANDLE fmap; 3890| void* bmpX; 3891| BITMAP info; 3892| BITMAPINFO info2; 3893| int r; 3894| 3895| ASSERT( m->size != 0 ); 3896| 3897| 3898| /* 背景ビットマップを動的に生成する。 */ 3899| m->bmp = CreateCompatibleBitmap( windowDC, m->width, m->height ); 3900| m->bmpDC = CreateCompatibleDC( windowDC ); 3901| m->oldBmp = SelectObject( m->bmpDC, m->bmp ); 3902| 3903| /* リードする */ 3904| f = CreateFile( m->path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); 3905| fmap = CreateFileMapping( f, NULL, PAGE_READONLY, 0, m->size, NULL ); 3906| bmpX = MapViewOfFile( fmap, FILE_MAP_READ, 0, 0, 0 ); 3907| 3908| GetObject( m->bmp, sizeof(info), &info ); // info.bmBits = NULL 3909| info2.bmiHeader.biSize = sizeof(BITMAPINFO); 3910| info2.bmiHeader.biWidth = info.bmWidth; 3911| info2.bmiHeader.biHeight = info.bmHeight; 3912| info2.bmiHeader.biPlanes = info.bmPlanes; 3913| info2.bmiHeader.biBitCount = info.bmBitsPixel; 3914| info2.bmiHeader.biCompression = BI_RGB; 3915| info2.bmiHeader.biSizeImage = 0; 3916| info2.bmiHeader.biXPelsPerMeter = 1; 3917| info2.bmiHeader.biYPelsPerMeter = 1; 3918| info2.bmiHeader.biClrUsed = 0; 3919| info2.bmiHeader.biClrImportant = 0; 3920| 3921| r = SetDIBits( m->bmpDC, m->bmp, 0, info2.bmiHeader.biHeight, bmpX, &info2, DIB_RGB_COLORS ); 3922| 3923| UnmapViewOfFile( bmpX ); 3924| CloseHandle( fmap ); 3925| CloseHandle( f ); 3926| 3927| return m->bmpDC; 3928|} 3929| 3930| 3931|/*********************************************************************** 3932| 13-6. <<< [WinX_DDBmp_closeForRead] 作成したDDBを閉じる >>> 3933|************************************************************************/ 3934|void WinX_DDBmp_closeForRead( WinX_DDBmp* m ) 3935|{ 3936| SelectObject( m->bmpDC, m->oldBmp ); 3937| DeleteObject( m->bmp ); 3938| DeleteDC( m->bmpDC ); 3939| 3940| m->bmp = NULL; 3941|} 3942| 3943| 3944| 3945|/*********************************************************************** 3946| 13-7. <<< [WinX_DDBmp_readDirect] 作成したDDBを描画する >>> 3947|【引数】 3948| ・HDC dc; ウィンドウやサーフェスなどから取得したデバイスコンテキスト 3949| ・int x, y; 描画位置 3950|************************************************************************/ 3951|bool WinX_DDBmp_readDirect( WinX_DDBmp* m, HDC dc, int x, int y ) 3952|{ 3953| HANDLE f; 3954| HANDLE fmap; 3955| void* bmpX; 3956| BITMAPINFO info2; 3957| int r; 3958| 3959| ASSERT( m->size != 0 ); 3960| 3961| /* リードする */ 3962| f = CreateFile( m->path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); 3963| fmap = CreateFileMapping( f, NULL, PAGE_READONLY, 0, m->size, NULL ); 3964| bmpX = MapViewOfFile( fmap, FILE_MAP_READ, 0, 0, 0 ); 3965| 3966| info2.bmiHeader.biSize = sizeof(BITMAPINFO); 3967| info2.bmiHeader.biWidth = m->width; 3968| info2.bmiHeader.biHeight = m->height; 3969| info2.bmiHeader.biPlanes = GetDeviceCaps( dc, PLANES ); 3970| info2.bmiHeader.biBitCount = GetDeviceCaps( dc, BITSPIXEL ); 3971| info2.bmiHeader.biCompression = BI_RGB; 3972| info2.bmiHeader.biSizeImage = 0; 3973| info2.bmiHeader.biXPelsPerMeter = 1; 3974| info2.bmiHeader.biYPelsPerMeter = 1; 3975| info2.bmiHeader.biClrUsed = 0; 3976| info2.bmiHeader.biClrImportant = 0; 3977| 3978| r = SetDIBitsToDevice( dc, x, y, info2.bmiHeader.biWidth, info2.bmiHeader.biHeight, 3979| 0, 0, 0, info2.bmiHeader.biHeight, bmpX, &info2, DIB_RGB_COLORS ); 3980| 3981| UnmapViewOfFile( bmpX ); 3982| CloseHandle( fmap ); 3983| CloseHandle( f ); 3984| 3985| return r != 0; 3986|} 3987| 3988|/*------------------------------------------------------------------------*/ 3989|/* 14. <<<< ◆DDE関係 >>>> */ 3990|/*------------------------------------------------------------------------*/ 3991| 3992|DWORD WinX_dde = 0; 3993|char WinX_dde_command[280]; 3994|char WinX_dde_service[80]; 3995|char WinX_dde_topic[80]; 3996| 3997| 3998|/************************************************************************** 3999| 14-1. <<< [WinX_callbackDDE] DDE コールバック >>> 4000|【補足】 4001|・内部用です 4002|***************************************************************************/ 4003|HDDEDATA CALLBACK WinX_callbackDDE( UINT uType, UINT uFmt, HCONV hconv, HSZ hsz1, 4004| HSZ hsz2, HDDEDATA hdata, DWORD dwData1, DWORD dwData2 ) 4005|{ 4006| ERRORS_FUNC_START( WinX_callbackDDE ); 4007| 4008|//MessageBox( NULL, "A", NULL, MB_OK ); 4009| switch ( uType ) { 4010| #if 0 4011| case XTYP_REGISTER: { 4012| char name[256]; 4013| char name2[256]; 4014| 4015| DdeQueryString( WinX_dde, hsz1, name, sizeof(name), CP_WINANSI ); 4016| DdeQueryString( WinX_dde, hsz2, name2, sizeof(name2), CP_WINANSI ); 4017| 4018| Errors_printf( "name = %s, name2 = %s", name, name2 ); 4019| ERRORS_FUNC_END( WinX_callbackDDE ); 4020| return (HDDEDATA)NULL; 4021| } 4022| #endif 4023| 4024| case XTYP_ADVDATA: 4025| ERRORS_FUNC_END( WinX_callbackDDE ); 4026| return (HDDEDATA)DDE_FACK; 4027| default: 4028| ERRORS_FUNC_END( WinX_callbackDDE ); 4029| return (HDDEDATA)NULL; 4030| } 4031|} 4032| 4033| 4034|/************************************************************************** 4035| 14-2. <<< [WinX_isOpenDDE] DDE サービスが活動中か調べる >>> 4036|【引数】 4037| ・char* service; サービス名(アプリケーション名) 4038| ・char* topic; トピック名(プロパティ名) 4039|***************************************************************************/ 4040|#if defined(USES_EXCEPT3) 4041|bool WinX_isOpenDDE( const char* service, char* topic ) 4042|{ 4043| bool ret; 4044| DWORD dde = 0; 4045| bool bDde = false; /* dde が有効かどうか */ 4046| HSZ hService = NULL, hTopic = NULL; 4047| HCONV con; 4048| 4049| ERRORS_FUNC_START( WinX_isOpenDDE ); 4050| 4051| c_try { 4052| 4053| /* DDE 通信の初期化 */ 4054| ret = DdeInitialize( &dde, WinX_callbackDDE, 4055| APPCMD_CLIENTONLY, 0L ); 4056| if ( ret != DMLERR_NO_ERROR ) WinX_throwDde( dde ); 4057| bDde = true; 4058| 4059| /* 通信を開始する */ 4060| hService = DdeCreateStringHandle( dde, service, CP_WINANSI ); 4061| hTopic = DdeCreateStringHandle( dde, topic, CP_WINANSI ); 4062| if ( hService == NULL || hTopic == NULL ) WinX_throwDde( dde ); 4063| con = DdeConnect( dde, hService, hTopic, NULL ); 4064| 4065| /* サービスがあるかどうか判定する */ 4066| if ( con == NULL ) { 4067| ret = false; 4068| } 4069| else { 4070| DdeDisconnect( con ); 4071| ret = true; 4072| } 4073| 4074| /* 通信を終了する */ 4075| DdeFreeStringHandle( dde, hService ); 4076| DdeFreeStringHandle( dde, hTopic ); 4077| 4078| /* DDE 通信の後始末 */ 4079| DdeUninitialize( dde ); 4080| } 4081| c_catch( Errors_Msg*, msg ) { 4082| if ( hService != NULL ) DdeFreeStringHandle( dde, hService ); 4083| if ( hTopic != NULL ) DdeFreeStringHandle( dde, hTopic ); 4084| if ( bDde ) DdeUninitialize( dde ); 4085| c_throw_again(); 4086| } c_end_catch; 4087| 4088| ERRORS_FUNC_END( WinX_isOpenDDE ); 4089| return ret; 4090|} 4091|#endif 4092| 4093| 4094| 4095|/************************************************************************** 4096| 14-3. <<< [WinX_sendDDE] DDE データを送る >>> 4097|【引数】 4098| ・char* command; 起動コマンド 4099| ・char* service; サービス名(アプリケーション名) 4100| ・char* topic; トピック名(プロパティ名) 4101| ・void* data; 送るデータが格納されている領域の先頭アドレス 4102| ・int data_size; 送るデータのサイズ(文字列の場合、末尾の'\0'を含まない) 4103| ・int sendType; WinX_Request or WinX_Execute 4104|【補足】 4105|・サービスを提供するアプリが無い場合、起動コマンドを実行してから 4106| DDE データを送ります。 4107|・command には、実行ファイルの絶対パスとオプションを指定します。 4108| ([スタート]-[プログラムを指定して実行]と同じ) 4109|・service と topic と「data のフォーマット」については、 4110| ソース(サーバ・アプリケーション)の DDE の仕様を調べてください。 4111|・大量のデータを効率よく送る場合は、直接 API を呼び出してください。 4112|***************************************************************************/ 4113|#if defined(USES_EXCEPT3) 4114|void WinX_sendDDE( const char* command, const char* service, 4115| const char* topic, const void* data, int data_size, int sendType ) 4116|{ 4117| int ret; 4118| DWORD dde = 0; 4119| bool bDde = false; /* dde が有効かどうか */ 4120| HSZ hService = NULL, hTopic = NULL; 4121| HCONV con; 4122| 4123| ERRORS_FUNC_START( WinX_sendDDE ); 4124| 4125| c_try { 4126| 4127| /* DDE 通信の初期化 */ 4128| ret = DdeInitialize( &dde, WinX_callbackDDE, 4129| APPCLASS_STANDARD | APPCMD_CLIENTONLY /*| MF_POSTMSGS*/, 0L ); 4130| if ( ret != DMLERR_NO_ERROR ) WinX_throwDde( dde ); 4131| WinX_dde = dde; 4132| bDde = true; 4133| 4134| /* 通信を開始する */ 4135| hService = DdeCreateStringHandle( dde, service, CP_WINANSI ); 4136| hTopic = DdeCreateStringHandle( dde, topic, CP_WINANSI ); 4137| StrX_cpy( WinX_dde_command, command, sizeof(WinX_dde_command) ); 4138| StrX_cpy( WinX_dde_service, service, sizeof(WinX_dde_service) ); 4139| StrX_cpy( WinX_dde_topic, topic, sizeof(WinX_dde_topic) ); 4140| if ( hService == NULL || hTopic == NULL ) WinX_throwDde( dde ); 4141| con = DdeConnect( dde, hService, hTopic, NULL ); /* status=(fAck fBusy) */ 4142| // con = DdeReconnect( dde ); /* status=(fAck fBusy) */ 4143| 4144| /* もし、サービスが無かったら、サービスを起動する */ 4145| if ( con == NULL ) { 4146| //WinExec( command, SW_SHOWNORMAL ); 4147| STARTUPINFO sinfo; 4148| PROCESS_INFORMATION proc; 4149| 4150| ZeroMemory( &sinfo, sizeof( sinfo ) ); 4151| ZeroMemory( &proc, sizeof( proc ) ); 4152| sinfo.cb = sizeof( sinfo ); 4153| sinfo.dwFlags = STARTF_USESHOWWINDOW; 4154| sinfo.wShowWindow = SW_SHOWNORMAL; 4155| if ( CreateProcess( NULL, (char*)command, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, 4156| NULL, NULL, &sinfo, &proc ) == 0 ) { 4157| WinX_error(); 4158| } 4159| 4160| WaitForInputIdle( proc.hProcess, INFINITE ); 4161| CloseHandle( proc.hProcess ); 4162| CloseHandle( proc.hThread ); 4163| 4164| con = DdeConnect( dde, hService, hTopic, NULL ); 4165| if ( con == NULL ) WinX_throwDde( dde ); 4166| } 4167| 4168| /* データを転送する */ 4169| if ( sendType == WinX_Request ) { /* Syncro Call */ 4170| HSZ hItem; 4171| 4172| if ( *( (char*)data + data_size ) == '\0' ) 4173| hItem = DdeCreateStringHandle( dde, data, CP_WINANSI ); 4174| else { 4175| char dataX[256]; 4176| 4177| ASSERT( data_size < sizeof(dataX) ); 4178| memcpy( dataX, data, data_size ); 4179| dataX[data_size] = '\0'; 4180| hItem = DdeCreateStringHandle( dde, data, CP_WINANSI ); 4181| } 4182| 4183| DdeClientTransaction( NULL, 0, con, hItem, CF_TEXT, 4184| XTYP_REQUEST, 1000, NULL ); 4185| 4186| DdeFreeStringHandle( dde, hItem ); 4187| } 4188| else if ( sendType == WinX_Execute ) { /* Unyncro Call : Server will be disconnected strongly */ 4189| DWORD res; 4190| 4191| #if 1 4192| HDDEDATA r; 4193| UINT err; 4194| 4195| for (;;) { 4196| r = DdeClientTransaction( (void*)data, data_size, con, 0, 0, 4197| XTYP_EXECUTE, 10000, &res ); 4198| if ( res == 0 || r != 0 ) break; 4199| err = DdeGetLastError( dde ); 4200| if ( err != DMLERR_NOTPROCESSED ) /* 0x4009 */ 4201| WinX_throwDde( dde ); 4202| } 4203| #else 4204| HDDEDATA hData; 4205| 4206| hData = DdeCreateDataHandle( dde, (void*)data, data_size, 0, 0L, CF_TEXT, HDATA_APPOWNED ); 4207| if ( DdeClientTransaction( (void*)hData, -1, con, 0, 0, 4208| XTYP_EXECUTE, 10000, &res ) == 0 ) 4209| WinX_throwDde( dde ); 4210| 4211| DdeFreeDataHandle( hData ); 4212| #endif 4213| } 4214| 4215| /* 通信を終了する */ 4216| DdeDisconnect( con ); 4217| DdeFreeStringHandle( dde, hService ); 4218| DdeFreeStringHandle( dde, hTopic ); 4219| 4220| /* DDE 通信の後始末 */ 4221| DdeUninitialize( dde ); 4222| WinX_dde = 0; 4223| } 4224| c_catch( Errors_Msg*, msg ) { 4225| if ( hService != NULL ) DdeFreeStringHandle( dde, hService ); 4226| if ( hTopic != NULL ) DdeFreeStringHandle( dde, hTopic ); 4227| if ( bDde ) DdeUninitialize( dde ); 4228| c_throw_again(); 4229| } c_end_catch; 4230| 4231| ERRORS_FUNC_END( WinX_sendDDE ); 4232|} 4233|#endif 4234| 4235|/************************************************************************** 4236| 14-4. <<< [WinX_receiveDDE] DDE データを受け取る >>> 4237|【引数】 4238| ・char* command; 起動コマンド 4239| ・char* service; サービス名(アプリケーション名) 4240| ・char* topic; トピック名(プロパティ名) 4241| ・void* data; 受け取るデータを格納する領域の先頭アドレス 4242| ・int data_size; data の領域のメモリサイズ 4243| ・int 返り値; 受信したデータのサイズ 4244|【補足】 4245|・サービスを提供するアプリが無い場合、起動コマンドを実行してから 4246| DDE データを受け取ります。 4247|・command には、実行ファイルの絶対パスとオプションを指定します。 4248| ([スタート]-[プログラムを指定して実行]と同じ) 4249|・service と topic と「data のフォーマット」については、 4250| ソース(サーバ・アプリケーション)の DDE の仕様を調べてください。 4251|・大量のデータを受け取る場合は、直接 API を呼び出してください。 4252|***************************************************************************/ 4253|#if defined(USES_EXCEPT3) 4254|int WinX_receiveDDE( const char* command, const char* service, 4255| const char* topic, void* data, int data_size ) 4256|{ 4257| int ret; 4258| DWORD size; 4259| DWORD dde = 0; 4260| bool bDde = false; /* dde が有効かどうか */ 4261| HSZ hService = NULL, hTopic = NULL, hItem = NULL; 4262| HCONV con; 4263| HDDEDATA hData; 4264| char* dataSrc; 4265| 4266| ERRORS_FUNC_START( WinX_receiveDDE ); 4267| 4268| c_try { 4269| 4270| /* DDE 通信の初期化 */ 4271| ret = DdeInitialize( &dde, WinX_callbackDDE, 4272| APPCLASS_STANDARD | APPCMD_CLIENTONLY, 0L ); 4273| if ( ret != DMLERR_NO_ERROR ) WinX_throwDde( dde ); 4274| bDde = true; 4275| 4276| /* 通信を開始する */ 4277| hService = DdeCreateStringHandle( dde, service, CP_WINANSI ); 4278| hTopic = DdeCreateStringHandle( dde, topic, CP_WINANSI ); 4279| hItem = DdeCreateStringHandle( dde, "-1", CP_WINANSI ); 4280| if ( hService == NULL || hTopic == NULL ) WinX_throwDde( dde ); 4281| con = DdeConnect( dde, hService, hTopic, NULL ); 4282| 4283| /* もし、サービスが無かったら、サービスを起動する */ 4284| if ( con == NULL ) { 4285| 4286| WinExec( command, SW_SHOWNORMAL ); 4287| #if 0 4288| PROCESS_INFORMATION proc; 4289| if ( CreateProcess( NULL, (char*)command, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, 4290| NULL, NULL, NULL, &proc ) != 0 ) 4291| WinX_error(); 4292| WaitForInputIdle( proc.hProcess, INFINITE ); 4293| #endif 4294| 4295| con = DdeConnect( dde, hService, hTopic, NULL ); 4296| if ( con == NULL ) { 4297|/* 4298| WS( command ); 4299| WD( dde ); 4300| WD( hService ); 4301| WS( service ); 4302| WD( hTopic ); 4303| WS( topic ); 4304| WinX_throwDde( dde ); 4305|*/ 4306| } 4307| } 4308| 4309| /* データを受信する */ 4310| hData = DdeClientTransaction( NULL, 0, con, hItem, CF_TEXT, 4311| XTYP_REQUEST, 1000, NULL ); 4312| if ( hData == NULL ) WinX_throwDde( dde ); 4313| dataSrc = DdeAccessData( hData, &size ); 4314| strcpy( data, dataSrc ); 4315| DdeUnaccessData( hData ); 4316| 4317| /* 通信を終了する */ 4318| DdeDisconnect( con ); 4319| DdeFreeStringHandle( dde, hService ); 4320| DdeFreeStringHandle( dde, hTopic ); 4321| 4322| /* DDE 通信の後始末 */ 4323| DdeUninitialize( dde ); 4324| } 4325| c_catch( Errors_Msg*, msg ) { 4326| if ( hService != NULL ) DdeFreeStringHandle( dde, hService ); 4327| if ( hTopic != NULL ) DdeFreeStringHandle( dde, hTopic ); 4328| if ( bDde ) DdeUninitialize( dde ); 4329| c_throw_again(); 4330| } c_end_catch; 4331| 4332| ERRORS_FUNC_END( WinX_receiveDDE ); 4333| return (int)size; 4334|} 4335|#endif 4336| 4337| 4338|/*------------------------------------------------------------------------*/ 4339|/* 15. <<<< ◆(WinX_DdeServ) DDEサーバ >>>> */ 4340|/*------------------------------------------------------------------------*/ 4341| 4342|HDDEDATA CALLBACK WinX_DdeServ_callback_imp( UINT uType, UINT uFmt, HCONV hconv, 4343| HSZ topicName, HSZ itemName, HDDEDATA hdata, DWORD dwData1, DWORD dwData2 ); 4344| 4345|WinX_DdeServ* WinX_ddeServ = NULL; 4346| 4347|/*********************************************************************** 4348| 15-1. <<< [WinX_DdeServ_init] DDEサーバーを起動する >>> 4349|************************************************************************/ 4350|void WinX_DdeServ_init( WinX_DdeServ* m, const char* serviceName, 4351| const char* topicName, const char* itemName, WinX_DdeServ_onMsgF onMsg ) 4352|{ 4353| UINT r; 4354| HDDEDATA r2; 4355| 4356| ASSERT( WinX_ddeServ == NULL ); 4357| 4358| r = DdeInitialize( &m->handle, WinX_DdeServ_callback_imp, 4359| CBF_SKIP_REGISTRATIONS, 0 ); 4360| if ( r != DMLERR_NO_ERROR ) error(); 4361| 4362| m->serviceName = DdeCreateStringHandle( m->handle, serviceName, CP_WINANSI ); 4363| m->topicName = DdeCreateStringHandle( m->handle, topicName, CP_WINANSI ); 4364| m->itemName = DdeCreateStringHandle( m->handle, itemName, CP_WINANSI ); 4365| strcpy( m->advdata, "0" ); 4366| m->onMsg = onMsg; 4367| 4368| r2 = DdeNameService( m->handle, m->serviceName, 0, DNS_REGISTER ); 4369| if ( r2 == 0 ) 4370| { WinX_DdeServ_finish( m ); error(); } 4371| 4372| WinX_ddeServ = m; 4373|} 4374| 4375| 4376| 4377|/*********************************************************************** 4378| 15-2. <<< [WinX_DdeServ_finish] DDEサーバーを終了する >>> 4379|************************************************************************/ 4380|void WinX_DdeServ_finish( WinX_DdeServ* m ) 4381|{ 4382| DdeFreeStringHandle( m->handle, m->serviceName ); 4383| DdeFreeStringHandle( m->handle, m->topicName ); 4384| DdeFreeStringHandle( m->handle, m->itemName ); 4385| 4386| DdeUninitialize( m->handle ); 4387| 4388| WinX_ddeServ = NULL; 4389|} 4390| 4391| 4392| 4393|/*********************************************************************** 4394| 15-3. <<< [WinX_DdeServ_callback_imp] DDEサーバーの内部コールバック関数 >>> 4395|【補足】 4396|・内部用です。 4397|************************************************************************/ 4398|HDDEDATA CALLBACK WinX_DdeServ_callback_imp( UINT uType, UINT uFmt, HCONV hconv, 4399| HSZ topicName, HSZ itemName, HDDEDATA hdata, DWORD dwData1, DWORD dwData2 ) 4400|{ 4401| WinX_DdeServ* m = WinX_ddeServ; 4402| char* data; 4403| 4404| switch ( uType ) { 4405| 4406| case XTYP_CONNECT: 4407| if ( topicName != m->topicName) return (HDDEDATA)FALSE; 4408| else return (HDDEDATA)TRUE; 4409| 4410| case XTYP_DISCONNECT: 4411| return (HDDEDATA)TRUE; 4412| 4413| case XTYP_REQUEST: 4414| if( topicName != m->topicName || itemName != m->itemName ) return NULL; 4415| return DdeCreateDataHandle( m->handle, m->advdata, 2, 0, m->itemName, CF_TEXT, 0 ); 4416| 4417| case XTYP_POKE: 4418| if( topicName != m->topicName || itemName != m->itemName ) { 4419| DdeFreeDataHandle( hdata ); 4420| return DDE_FNOTPROCESSED; 4421| } 4422| data = DdeAccessData( hdata, NULL ); 4423| m->onMsg( XTYP_POKE, data ); 4424| DdeUnaccessData( hdata ); 4425| DdeFreeDataHandle( hdata ); 4426| return (HDDEDATA)DDE_FACK; 4427| 4428| case XTYP_ADVSTART: 4429| if( topicName != m->topicName || itemName != m->itemName ) return (HDDEDATA)FALSE; 4430| 4431| m->advdata[0] = '0'; /* 初期化 */ 4432| return (HDDEDATA)TRUE; 4433| 4434| case XTYP_ADVSTOP: 4435| return (HDDEDATA)TRUE; 4436| 4437| case XTYP_ADVREQ: /* from DdePostAdvise */ 4438| if( topicName != m->topicName || itemName != m->itemName ) return NULL; 4439| return DdeCreateDataHandle( m->handle, m->advdata, 2, 0, m->itemName, CF_TEXT, 0 ); /* make advdata */ 4440| 4441| case XTYP_EXECUTE: 4442| if ( topicName != m->topicName ) { 4443| DdeFreeDataHandle(hdata); 4444| return DDE_FNOTPROCESSED; 4445| } 4446| data = DdeAccessData( hdata, NULL ); 4447| m->onMsg( XTYP_EXECUTE, data ); 4448| DdeUnaccessData( hdata ); 4449| DdeFreeDataHandle( hdata ); 4450| return (HDDEDATA)DDE_FACK; 4451| 4452| default: 4453| return (HDDEDATA)NULL; 4454| } 4455| return (HDDEDATA)NULL; 4456|} 4457| 4458| 4459|/*------------------------------------------------------------------------*/ 4460|/* 16. <<<< ◆(WinX_DdeAct) ファイルタイプの DDE アクション >>>> */ 4461|/*------------------------------------------------------------------------*/ 4462| 4463|/************************************************************************** 4464|* 16-1. <<< [WinX_DdeAct_init] レジストリから DDE アクションを取得する >>> 4465|*【引数】 4466|* ・WinX_DdeAct* m; ファイルタイプの DDE アクション 4467|* ・char* type; ファイルタイプ名(通常、拡張子) 4468|*【補足】 4469|*・ファイルタイプ名は、レジストリの HKEY_CLASSES_ROOT を参照してください。 4470|***************************************************************************/ 4471|void WinX_DdeAct_init( WinX_DdeAct* m, const char* type ) 4472|{ 4473| static char key[256]; 4474| 4475| sprintf( key, "%s\\shell\\open\\command", type ); 4476| WinX_getReg_s( HKEY_CLASSES_ROOT, key, NULL, m->command, _MAX_PATH ); 4477| sprintf( key, "%s\\shell\\open\\ddeexec", type ); 4478| WinX_getReg_s( HKEY_CLASSES_ROOT, key, NULL, m->data, WinX_DdeAct_size ); 4479| sprintf( key, "%s\\shell\\open\\ddeexec\\Application", type ); 4480| WinX_getReg_s( HKEY_CLASSES_ROOT, key, NULL, m->service, WinX_DdeAct_size ); 4481| sprintf( key, "%s\\shell\\open\\ddeexec\\Topic", type ); 4482| WinX_getReg_s( HKEY_CLASSES_ROOT, key, NULL, m->topic, WinX_DdeAct_size ); 4483|} 4484| 4485| 4486| 4487|/************************************************************************** 4488|* 16-2. <<< [WinX_DdeAct_isOpen] DDE サービスが活動中か調べる >>> 4489|*【引数】 4490|* ・WinX_DdeAct* m; ファイルタイプの DDE アクション 4491|***************************************************************************/ 4492|#if defined(USES_EXCEPT3) 4493|bool WinX_DdeAct_isOpen( WinX_DdeAct* m ) 4494|{ 4495| return WinX_isOpenDDE( m->service, m->topic ); 4496|} 4497|#endif 4498| 4499| 4500|/************************************************************************** 4501|* 16-3. <<< [WinX_DdeAct_send] DDE データを送る >>> 4502|*【引数】 4503|* ・WinX_DdeAct* m; ファイルタイプの DDE アクション 4504|* ・char* topic; トピック名(プロパティ名)(NULL or "" 可) 4505|* ・void* data; 送るデータが格納されている領域の先頭アドレス 4506|* ・int data_size; 送るデータのサイズ(文字列の場合、末尾の'\0'を含まない) 4507|*【補足】 4508|*・WinX_sendDDE の WinX_DdeAct 型版です。 4509|*・topic を NULL か "" にすると、m 中のトピック名を使用します。 4510|***************************************************************************/ 4511|#if defined(USES_EXCEPT3) 4512|void WinX_DdeAct_send( WinX_DdeAct* m, 4513| const char* topic, void* data, int data_size ) 4514|{ 4515| if ( topic == NULL || topic[0] == '\0' ) 4516| WinX_sendDDE( m->command, m->service, m->topic, data, data_size, WinX_Execute ); 4517| else 4518| WinX_sendDDE( m->command, m->service, topic, data, data_size, WinX_Execute ); 4519|} 4520|#endif 4521| 4522| 4523|/************************************************************************** 4524|* 16-4. <<< [WinX_DdeAct_receive] DDE データを受け取る >>> 4525|*【引数】 4526|* ・WinX_DdeAct* m; ファイルタイプの DDE アクション 4527|* ・char* topic; トピック名(プロパティ名)(NULL or "" 可) 4528|* ・void* data; 受け取るデータを格納する領域の先頭アドレス 4529|* ・int data_size; data の領域のメモリサイズ 4530|*【補足】 4531|*・WinX_receiveDDE の WinX_DdeAct 型版です。 4532|*・topic を NULL か "" にすると、m 中のトピック名を使用します。 4533|***************************************************************************/ 4534|#if defined(USES_EXCEPT3) 4535|void WinX_DdeAct_receive( WinX_DdeAct* m, 4536| const char* topic, void* data, int data_size ) 4537|{ 4538| if ( topic == NULL || topic[0] == '\0' ) 4539| WinX_receiveDDE( m->command, m->service, m->topic, data, data_size ); 4540| else 4541| WinX_receiveDDE( m->command, m->service, topic, data, data_size ); 4542|} 4543|#endif 4544| 4545| 4546| 4547|