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|