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