/* 関数の管理と引数の確認、関数の呼び出し */

#include "stdafx.h"
#include "function.h"
#include "addctrl.h"
#include "refresh.h"
#include "token.h"
#include "dlllib.h"
#include "helpdlg.h"
#include "symbol.h"
#include "opendlg.h"
#include "splash.h"
#include "inputdlg.h"
#include "filetypes.h"
#include "cpp_func.h"
#include "LvEdit.h"
#include "commfunc.h"
#include <winerror.h>

// fread/fwrite/fappendの動作設定：fmodebinary() でテキストモードかバイナリモードかを決定する
unsigned char fmode_bin = 0;
// fread/fwrite/fappendの動作設定：fmodewide() でワイド文字かマルチバイト文字かを決定する
unsigned char fmode_wide = 0;

// インターバルタイマのとび先ラベル
char *pszEditDialogTimerLabel;

// 関数名の最大長
#define FUNCLENGTH	28

#pragma warning( disable : 4100 )

// 引数の型と数をチェック
static int args_typecheck(const struct ARGS *args, const char *types)
{
	const struct ARGS *p = args;

	if (p == NULL) {
		if (types == NULL || types[0] == 0) {
			return 1; // OK
		}
		else {
			return 0; // NG
		}
	}

	do {
		switch ( p->type ) {
			case UFCT_ARG_INT:
				if (*types != 'i') {
					return 0; // NG
				}
				break;

			case UFCT_ARG_STRING:
				if (*types != 's') {
					return 0; // NG
				}
				break;

			case UFCT_ARG_INTS:
				if (*types != 'a') {
					return 0; // NG
				}
				break;

			case UFCT_ARG_STRINGS:
				if (*types != 'r') {
					return 0; // NG
				}
				break;
		}
		
		types++;
	} while( (p = p->next) != NULL );

	if ( *types == 0 ) { // argsが終端に達したとき、typeも終端に達したか?
		return 1; // OK
	}
	else {
		return 0; // NG
	}
}

// 関数リスト（数値返却型）
typedef struct {
	const char func[FUNCLENGTH];
	unsigned int const (*pfunc) (HWND, const struct ARGS *, BYTE *);
} RFUNCS;

// 関数リスト（文字列返却型）
typedef struct {
	const char func[FUNCLENGTH];
	char * const (*pfuncd) (HWND, const struct ARGS *, BYTE *);
} RFUNCSD;


// メッセージダイアログ
// textout( メッセージ$ [, キャプション$] )
unsigned int rfunc_textout(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		destroy_splash_window();
		return MessageBox( hWnd, ARG1.text, ARG2.text, MB_OK );
	}
	else if ( args_typecheck(args, "s") ) {
		destroy_splash_window();
		return MessageBox( hWnd, ARG1.text, "メッセージ", MB_OK );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい // 引数がおかしい
		return ERRORVALUE;
	}
}

// 警告メッセージダイアログ
// warning( メッセージ$ [, キャプション$] )
unsigned int rfunc_warning(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		destroy_splash_window();
		return MessageBox( hWnd, ARG1.text, ARG2.text, MB_OK | MB_ICONEXCLAMATION );
	}
	else if ( args_typecheck(args, "s") ) {
		destroy_splash_window();
		return MessageBox( hWnd, ARG1.text, "警告", MB_OK | MB_ICONEXCLAMATION );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい // 引数がおかしい
		return ERRORVALUE;
	}
}

// 情報メッセージ
// information( メッセージ$ [, キャプション$] )
unsigned int rfunc_information(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		destroy_splash_window();
		return MessageBox( hWnd, ARG1.text, ARG2.text, MB_OK | MB_ICONINFORMATION );
	}
	else if ( args_typecheck(args, "s") ) {
		destroy_splash_window();
		return MessageBox( hWnd, ARG1.text, "情報", MB_OK | MB_ICONINFORMATION );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい // 引数がおかしい
		return ERRORVALUE;
	}
}

// エラーメッセージ
// error( メッセージ$ [, キャプション$] )
unsigned int rfunc_error(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		destroy_splash_window();
		return MessageBox( hWnd, ARG1.text, ARG2.text, MB_OK | MB_ICONSTOP );
	}
	else if ( args_typecheck(args, "s") ) {
		destroy_splash_window();
		return MessageBox( hWnd, ARG1.text, "エラー", MB_OK | MB_ICONSTOP );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい // 引数がおかしい
		return ERRORVALUE;
	}
}

// ユーザーへの問い合わせダイアログ
// question( メッセージ$ [, キャプション$] )
unsigned int rfunc_question(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		destroy_splash_window();
		return (IDYES == MessageBox( hWnd, ARG1.text, ARG2.text, MB_YESNO | MB_ICONQUESTION ));
	}
	else if ( args_typecheck(args, "s") ) {
		destroy_splash_window();
		return (IDYES == MessageBox( hWnd, ARG1.text, "問い合わせ", MB_YESNO | MB_ICONQUESTION ));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい // 引数がおかしい
		return ERRORVALUE;
	}
}

// ユーザーへの問い合わせダイアログ(OK, Cancel)
// question_okcancel( メッセージ$ [, キャプション$] )
unsigned int rfunc_question_okcancel(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		destroy_splash_window();
		return (IDOK == MessageBox( hWnd, ARG1.text, ARG2.text, MB_OKCANCEL | MB_ICONQUESTION ));
	}
	else if ( args_typecheck(args, "s") ) {
		destroy_splash_window();
		return (IDOK == MessageBox( hWnd, ARG1.text, "問い合わせ", MB_OKCANCEL | MB_ICONQUESTION ));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// ユーザーへの問い合わせダイアログ(yes, no, cancel)
// question_yesnocancel( メッセージ$ [, キャプション$] )
unsigned int rfunc_question_yesnocancel(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	int rv = ERRORVALUE;

	if ( args_typecheck(args, "ss") ) {
		destroy_splash_window();
		rv = MessageBox( hWnd, ARG1.text, ARG2.text, MB_YESNOCANCEL | MB_ICONQUESTION );
	}
	else if ( args_typecheck(args, "s") ) {
		destroy_splash_window();
		rv = MessageBox( hWnd, ARG1.text, "問い合わせ", MB_YESNOCANCEL | MB_ICONQUESTION );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}

	switch( rv ) {
		case IDYES:
			return 1;
		case IDNO:
			return 0;
		default: // IDCANCEL:
			return ERRORVALUE;
	}
}

// 音声ファイルの再生
// playsound( 音声ファイル名$, オプション )
unsigned int rfunc_playsound(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "si") ) {
		BOOL bRet = FALSE;

		if (ARG1.text[0] == 0) {
			// ファイル名が空なら再生停止
			bRet = PlaySound(NULL, NULL, 0);
		}
		else if (ARG2.integer == 0) {
			// 非同期再生
			bRet = PlaySound(ARG1.text, NULL, SND_SYNC | SND_FILENAME | SND_NODEFAULT);
		}
		else if (ARG2.integer == 1) {
			// 同期再生
			bRet = PlaySound(ARG1.text, NULL, SND_ASYNC | SND_FILENAME | SND_NODEFAULT);
		}
		else if (ARG2.integer == 2) {
			// ループ再生
			bRet = PlaySound(ARG1.text, NULL, SND_ASYNC | SND_LOOP | SND_FILENAME | SND_NODEFAULT);
		}
		
		return (int)bRet;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい // 引数がおかしい
		return ERRORVALUE;
	}
}

// スタティックテキストの配置
// text( 文字列$ )
// text( 文字列$, x:次の編集ボックスなどを配置する最低限のx座標 )
unsigned int rfunc_text(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return (NULL != addctrl(hWnd, TEXT_CTRL, 1, 0, 0, 0, 0, 0, ARG1.text, 0, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "si") ) {
		return (NULL != addctrl(hWnd, TEXT_CTRL, 1, ARG2.integer, 0, 0, 0, 0, ARG1.text, 0, 0, 0, 0, 0, 0, 0, 0));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 太字スタティックテキストの配置
// boldtext( 文字列$ )
unsigned int rfunc_boldtext(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return (NULL != addctrl(hWnd, TEXT_CTRL, 1, 0, 0, 0, 0, 0, ARG1.text, 0, 0, 0, 2, 0, 0, 0, 0));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 水平線の配置
// border()
unsigned int rfunc_border(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		return (NULL != addctrl(hWnd, TEXT_CTRL, 1 , 0, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "i") ) {
		return (NULL != addctrl(hWnd, TEXT_CTRL, ARG1.integer , 0, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 0));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 囲み枠線の開始
unsigned int rfunc_startgroupbox(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return (NULL != addctrl(hWnd, TEXT_CTRL, 1 , 0, 0, 0, 0, 0, ARG1.text, 0, 0, 0, 1, 0, 0, 0, 0));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 囲み枠線の終了
unsigned int rfunc_endgroupbox(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		return (NULL != addctrl(hWnd, TEXT_CTRL, 1 , 0, 0, 0, 0, 0, NULL, 0, 0, 0, 1, 0, 0, 0, 0));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// チェックボックスの配置
// checkbox( ID$, デフォルト<0 or 1>, 表示される文字列$ [, key$, entry$, [(ValueOfCheck, ValueOfUnCheck) or (ValueOfCheck$, ValueOfUnCheck$)] [, flag] )
unsigned int rfunc_checkbox(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sisi") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 0, ARG4.integer, 0, 0, 0, ARG2.integer, ARG3.text, ARG1.text, 1, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sis") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 0, 0, 0, 0, 0, ARG2.integer, ARG3.text, ARG1.text, 1, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisssi") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 0, ARG6.integer, ARG4.text, ARG5.text, 0, ARG2.integer, ARG3.text, ARG1.text, 1, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisss") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 0, 0, ARG4.text, ARG5.text, 0, ARG2.integer, ARG3.text, ARG1.text, 1, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisssiii") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 0, ARG8.integer, ARG4.text, ARG5.text, 0, ARG2.integer, ARG3.text, ARG1.text, ARG6.integer, ARG7.integer, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisssii") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 0, 0, ARG4.text, ARG5.text, 0, ARG2.integer, ARG3.text, ARG1.text, ARG6.integer, ARG7.integer, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisssssi") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 0, ARG8.integer, ARG4.text, ARG5.text, 0, ARG2.integer, ARG3.text, ARG1.text, 1, 0, 0, 0, ARG6.text, ARG7.text, 0));
	}
	else if ( args_typecheck(args, "sisssss") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 0, 0, ARG4.text, ARG5.text, 0, ARG2.integer, ARG3.text, ARG1.text, 1, 0, 0, 0, ARG6.text, ARG7.text, 0));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// チェックボックスの配置(3state) [値が削除されている＝半チェック]
// checkbox3( ID$, 表示される文字列$, key$, entry$, [(ValueOfCheck, ValueOfUnCheck) or (ValueOfCheck$, ValueOfUnCheck$)] [, flag] )
// checkbox3( ID$, デフォルト(<0:なし | 1:あり | 2:半チェック>), 表示される文字列$ [, flag] )
unsigned int rfunc_checkbox3(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ssssi") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 1, ARG5.integer, ARG3.text, ARG4.text, 0, 0, ARG2.text, ARG1.text, 1, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "ssssiii") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 1, ARG7.integer, ARG3.text, ARG4.text, 0, 0, ARG2.text, ARG1.text, ARG5.integer, ARG6.integer, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "ssssssi") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 1, ARG7.integer, ARG3.text, ARG4.text, 0, 0, ARG2.text, ARG1.text, 1, 0, 0, 0, ARG5.text, ARG6.text, 0));
	}
	else if ( args_typecheck(args, "ssss") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 1, 0, ARG3.text, ARG4.text, 0, 0, ARG2.text, ARG1.text, 1, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "ssssii") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 1, 0, ARG3.text, ARG4.text, 0, 0, ARG2.text, ARG1.text, ARG5.integer, ARG6.integer, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "ssssss") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 1, 0, ARG3.text, ARG4.text, 0, 0, ARG2.text, ARG1.text, 1, 0, 0, 0, ARG5.text, ARG6.text, 0));
	}
	else if ( args_typecheck(args, "sisi") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 1, ARG4.integer, 0, 0, 0, ARG2.integer, ARG3.text, ARG1.text, 1, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sis") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 1, 0, 0, 0, 0, ARG2.integer, ARG3.text, ARG1.text, 1, 0, 0, 0, 0, 0, 0));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// チェックボックスの配置 - レジストリからバイナリデータの特定のビットを(0|1)を読む/へ書き込む
// checkbox_bin( ID$, デフォルト<0|1>, 表示される文字列$, Key$, Entry$, 何バイト目?<0->, 何ビット目?<0-7> [, ValueOfCheck, ValueOfUnCheck][, flag] )
unsigned int rfunc_checkbox_bin(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sisssiii") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 2, ARG8.integer, ARG4.text, ARG5.text, 0, ARG2.integer, ARG3.text, ARG1.text, ARG6.integer, ARG7.integer, 1, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisssiiiii") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 2, ARG8.integer, ARG4.text, ARG5.text, 0, ARG2.integer, ARG3.text, ARG1.text, ARG6.integer, ARG7.integer, ARG9.integer, ARG10.integer, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisssii") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 2, 0, ARG4.text, ARG5.text, 0, ARG2.integer, ARG3.text, ARG1.text, ARG6.integer, ARG7.integer, 1, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisssiiii") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 2, 0, ARG4.text, ARG5.text, 0, ARG2.integer, ARG3.text, ARG1.text, ARG6.integer, ARG7.integer, ARG8.integer, ARG9.integer, 0, 0, 0));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// チェックボックスの配置 - レジストリからDWORDデータの特定のビットを(0|1)を読む/へ書き込む
// checkbox_bindw( ID$, デフォルト<0|1>, 表示される文字列$, Key$, Entry$, 何ビット目?<0-31> [, ValueOfCheck, ValueOfUnCheck][, flag] )
unsigned int rfunc_checkbox_bindw(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sisssii") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 3, ARG7.integer, ARG4.text, ARG5.text, 0, ARG2.integer, ARG3.text, ARG1.text, 0, ARG6.integer, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisssiiii") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 3, ARG7.integer, ARG4.text, ARG5.text, 0, ARG2.integer, ARG3.text, ARG1.text, 0, ARG6.integer, ARG8.integer, ARG9.integer, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisssi") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 3, 0, ARG4.text, ARG5.text, 0, ARG2.integer, ARG3.text, ARG1.text, 0, ARG6.integer, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisssiii") ) {
		return (NULL != addctrl(hWnd, CHECK_CTRL, 3, 0, ARG4.text, ARG5.text, 0, ARG2.integer, ARG3.text, ARG1.text, 0, ARG6.integer, ARG7.integer, ARG8.integer, 0, 0, 0));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 編集ボックスの配置 - 数値
// editbox_num( ID$, デフォルト [, key$, entry$] [, 単位指定$] [, 最小値, 最大値 [, 増分1, 増分2] ] [, flag] )
unsigned int rfunc_editbox_num(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sii") ) { // フラグ
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, ARG3.integer, 0, 0, 0, ARG2.integer, 0, ARG1.text, 0, 0xffffffff, 1, 5, 0, 0, 0));
	}
	else if ( args_typecheck(args, "si") ) {
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, 0, 0, 0, 0, ARG2.integer, 0, ARG1.text, 0, 0xffffffff, 1, 1, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sissi") ) { // キー、エントリ、フラグ
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, ARG5.integer, ARG3.text, ARG4.text, 0, ARG2.integer, 0, ARG1.text, 0, 0xffffffff, 1, 5, 0, 0, 0));
	}
	else if ( args_typecheck(args, "siss") ) { // キー、エントリ
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, 0, ARG3.text, ARG4.text, 0, ARG2.integer, 0, ARG1.text, 0, 0xffffffff, 1, 5, 0, 0, 0));
	}
	else if ( args_typecheck(args, "siiii") ) { // 最大、最小、フラグ
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, ARG5.integer, 0, 0, 0, ARG2.integer, 0, ARG1.text, ARG3.integer, ARG4.integer, 1, 5, 0, 0, 0));
	}
	else if ( args_typecheck(args, "siiiiii") ) { // 最大、最小、増分１，増分２，フラグ
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, ARG7.integer, 0, 0, 0, ARG2.integer, 0, ARG1.text, ARG3.integer, ARG4.integer, ARG5.integer, ARG6.integer, 0, 0, 0));
	}
	else if ( args_typecheck(args, "siii") ) { // 最大、最小、フラグ
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, 0, 0, 0, 0, ARG2.integer, 0, ARG1.text, ARG3.integer, ARG4.integer, 1, 5, 0, 0, 0));
	}
	else if ( args_typecheck(args, "siiiii") ) { // 最大、最小、増分１，増分２
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, 0, 0, 0, 0, ARG2.integer, 0, ARG1.text, ARG3.integer, ARG4.integer, ARG5.integer, ARG6.integer, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sissiii") ) { // キー、エントリ、最大、最小、フラグ
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, ARG7.integer, ARG3.text, ARG4.text, 0, ARG2.integer, 0, ARG1.text, ARG5.integer, ARG6.integer, 1, 5, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sissiiiii") ) { // キー、エントリ、最大、最小、増分１，増分２，フラグ
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, ARG9.integer, ARG3.text, ARG4.text, 0, ARG2.integer, 0, ARG1.text, ARG5.integer, ARG6.integer, ARG7.integer, ARG8.integer, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sissii") ) { // キー、エントリ、最大、最小
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, 0, ARG3.text, ARG4.text, 0, ARG2.integer, 0, ARG1.text, ARG5.integer, ARG6.integer, 1, 5, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sissiiii") ) { // キー、エントリ、最大、最小、増分１、増分２
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, 0, ARG3.text, ARG4.text, 0, ARG2.integer, 0, ARG1.text, ARG5.integer, ARG6.integer, ARG7.integer, ARG8.integer, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisi") ) { // 単位、フラグ
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, ARG4.integer, 0, 0, 0, ARG2.integer, ARG3.text, ARG1.text, 0, 0xffffffff, 1, 5, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sis") ) { // 単位
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, 0, 0, 0, 0, ARG2.integer, ARG3.text, ARG1.text, 0, 0xffffffff, 1, 5, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisssi") ) { // キー、エントリ、単位、フラグ
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, ARG6.integer, ARG3.text, ARG4.text, 0, ARG2.integer, ARG5.text, ARG1.text, 0, 0xffffffff, 1, 5, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisss") ) { // キー、エントリ、単位
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, 0, ARG3.text, ARG4.text, 0, ARG2.integer, ARG5.text, ARG1.text, 0, 0xffffffff, 1, 5, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisiii") ) { // 単位、最大、最小、フラグ
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, ARG6.integer, 0, 0, 0, ARG2.integer, ARG3.text, ARG1.text, ARG4.integer, ARG5.integer, 1, 5, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisiiiii") ) { // 単位、最大、最小、増分１，増分２、フラグ
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, ARG8.integer, 0, 0, 0, ARG2.integer, ARG3.text, ARG1.text, ARG4.integer, ARG5.integer, ARG6.integer, ARG7.integer, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisii") ) { // 単位、最大、最小
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, 0, 0, 0, 0, ARG2.integer, ARG3.text, ARG1.text, ARG4.integer, ARG5.integer, 1, 5, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisiiii") ) { // 単位、最大、最小、増分１、増分２
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, 0, 0, 0, 0, ARG2.integer, ARG3.text, ARG1.text, ARG4.integer, ARG5.integer, ARG6.integer, ARG7.integer, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisssiii") ) { // キー、エントリ、単位、最大、最小、フラグ
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, ARG8.integer, ARG3.text, ARG4.text, 0, ARG2.integer, ARG5.text, ARG1.text, ARG6.integer, ARG7.integer, 1, 5, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisssiiiii") ) { // キー、エントリ、単位、最大、最小、増分１，増分２、フラグ
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, ARG10.integer, ARG3.text, ARG4.text, 0, ARG2.integer, ARG5.text, ARG1.text, ARG6.integer, ARG7.integer, ARG8.integer, ARG9.integer, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisssii") ) { // キー、エントリ、単位、最大、最小
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, 0, ARG3.text, ARG4.text, 0, ARG2.integer, ARG5.text, ARG1.text, ARG6.integer, ARG7.integer, 1, 5, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisssiiii") ) { // キー、エントリ、単位、最大、最小、増分１，増分２
		return (NULL != addctrl(hWnd, EDIT_CTRL, 1, 0, ARG3.text, ARG4.text, 0, ARG2.integer, ARG5.text, ARG1.text, ARG6.integer, ARG7.integer, ARG8.integer, ARG9.integer, 0, 0, 0));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 編集ボックスの配置 - 文字列 - レジストリから読み込む/へ書き込む
// editbox( ID$, デフォルト$ [, Key$, Entry$] [, 参照ボタンの名前$] [, flag] )
unsigned int rfunc_editbox(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ssi") ) {
		return (NULL != addctrl(hWnd, EDIT_CTRL, 0, ARG3.integer, 0, 0, ARG2.text, 0, "参照...", ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "ss") ) {
		return (NULL != addctrl(hWnd, EDIT_CTRL, 0, 0, 0, 0, ARG2.text, 0, "参照...", ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sssi") ) {
		return (NULL != addctrl(hWnd, EDIT_CTRL, 0, ARG4.integer, 0, 0, ARG2.text, 0, ARG3.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sss") ) {
		return (NULL != addctrl(hWnd, EDIT_CTRL, 0, 0, 0, 0, ARG2.text, 0, ARG3.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "ssssi") ) {
		return (NULL != addctrl(hWnd, EDIT_CTRL, 0, ARG5.integer, ARG3.text, ARG4.text, ARG2.text, 0, "参照...", ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "ssss") ) {
		return (NULL != addctrl(hWnd, EDIT_CTRL, 0, 0, ARG3.text, ARG4.text, ARG2.text, 0, "参照...", ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sssssi") ) {
		return (NULL != addctrl(hWnd, EDIT_CTRL, 0, ARG6.integer, ARG3.text, ARG4.text, ARG2.text, 0, ARG5.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sssss") ) {
		return (NULL != addctrl(hWnd, EDIT_CTRL, 0, 0, ARG3.text, ARG4.text, ARG2.text, 0, ARG5.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// アイコン編集ボタンの配置 - レジストリから読み込む/へ書き込む
// icon( ID$, デフォルト$ [, Key$, Entry$] [, flag] )
unsigned int rfunc_icon(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ssi") ) {
		return (NULL != addctrl(hWnd, ICON_BUTTON, 0, ARG3.integer, 0, 0, ARG2.text, 0, 0, ARG1.text, 0, 0, 0, 0, 0, 0, 0) );
	}
	else if ( args_typecheck(args, "ss") ) {
		return (NULL != addctrl(hWnd, ICON_BUTTON, 0, 0, 0, 0, ARG2.text, 0, 0, ARG1.text, 0, 0, 0, 0, 0, 0, 0) );
	}
	else if ( args_typecheck(args, "ssssi") ) {
		return (NULL != addctrl(hWnd, ICON_BUTTON, 0, ARG5.integer, ARG3.text, ARG4.text, ARG2.text, 0, 0, ARG1.text, 0, 0, 0, 0, 0, 0, 0) );
	}
	else if ( args_typecheck(args, "ssss") ) {
		return (NULL != addctrl(hWnd, ICON_BUTTON, 0, 0, ARG3.text, ARG4.text, ARG2.text, 0, 0, ARG1.text, 0, 0, 0, 0, 0, 0, 0) );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 値リスト - レジストリから読み込む/へ書き込む
// ValueList( ID$, Key$, 値の意味$, データの意味$ [, 新規ボタンの名前$, 編集ボタンの名前$, 削除ボタンの名前$] [, flag] )
unsigned int rfunc_ValueList(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	MULTISTRING mulstr;

	if ( args_typecheck(args, "ssssi") ) {
		mulstr.str1 = "新規...";
		mulstr.str2 = "編集...";
		mulstr.str3 = "削除";
		return (NULL != addctrl(hWnd, LIST_CTRL, 0, ARG5.integer, ARG2.text, (char *)&mulstr, ARG3.text, 0, ARG4.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "ssss") ) {
		mulstr.str1 = "新規...";
		mulstr.str2 = "編集...";
		mulstr.str3 = "削除";
		return (NULL != addctrl(hWnd, LIST_CTRL, 0, 0, ARG2.text, (char *)&mulstr, ARG3.text, 0, ARG4.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sssssssi") ) {
		mulstr.str1 = ARG5.text;
		mulstr.str2 = ARG6.text;
		mulstr.str3 = ARG7.text;
		return (NULL != addctrl(hWnd, LIST_CTRL, 0, ARG8.integer, ARG2.text, (char *)&mulstr, ARG3.text, 0, ARG4.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sssssss") ) {
		mulstr.str1 = ARG5.text;
		mulstr.str2 = ARG6.text;
		mulstr.str3 = ARG7.text;
		return (NULL != addctrl(hWnd, LIST_CTRL, 0, 0, ARG2.text, (char *)&mulstr, ARG3.text, 0, ARG4.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// キーリスト - レジストリから読み込む/へ書き込む
// keyList( ID$, Key$, 値の配列$[], 意味の配列$[], データの意味$, [新規ボタンの名前$, 編集ボタンの名前$, 削除ボタンの名前$] [, flag] )
unsigned int rfunc_KeyList(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	MULTISTRING mulstr;

	if ( args_typecheck(args, "ssrri") ) {
		mulstr.str1 = "新規...";
		mulstr.str2 = "編集...";
		mulstr.str3 = "削除";
		return (NULL != addctrl(hWnd, LIST_CTRL, 1, ARG5.integer, ARG2.text, (char *)&mulstr, ARG3.text, 0, ARG4.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "ssrr") ) {
		mulstr.str1 = "新規...";
		mulstr.str2 = "編集...";
		mulstr.str3 = "削除";
		return (NULL != addctrl(hWnd, LIST_CTRL, 1, 0, ARG2.text, (char *)&mulstr, ARG3.text, 0, ARG4.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "ssrrsssi") ) {
		mulstr.str1 = ARG5.text;
		mulstr.str2 = ARG6.text;
		mulstr.str3 = ARG7.text;
		return (NULL != addctrl(hWnd, LIST_CTRL, 1, ARG8.integer, ARG2.text, (char *)&mulstr, ARG3.text, 0, ARG4.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "ssrrsss") ) {
		mulstr.str1 = ARG5.text;
		mulstr.str2 = ARG6.text;
		mulstr.str3 = ARG7.text;
		return (NULL != addctrl(hWnd, LIST_CTRL, 1, 0, ARG2.text, (char *)&mulstr, ARG3.text, 0, ARG4.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// ただのリストビュー
// CreateListView( ID$, 値の配列$[], [新規ボタンの名前$, 編集ボタンの名前$, 削除ボタンの名前$] [, flag] )
unsigned int rfunc_CreateListView(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	MULTISTRING mulstr;

	if ( args_typecheck(args, "sri") ) {
		mulstr.str1 = "新規...";
		mulstr.str2 = "編集...";
		mulstr.str3 = "削除";
		return (NULL != addctrl(hWnd, LIST_CTRL, 1, ARG3.integer, 0, (char *)&mulstr, 0, 0, ARG2.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sr") ) {
		mulstr.str1 = "新規...";
		mulstr.str2 = "編集...";
		mulstr.str3 = "削除";
		return (NULL != addctrl(hWnd, LIST_CTRL, 1, 0, 0, (char *)&mulstr, 0, 0, ARG2.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "srsssi") ) {
		mulstr.str1 = ARG3.text;
		mulstr.str2 = ARG4.text;
		mulstr.str3 = ARG5.text;
		return (NULL != addctrl(hWnd, LIST_CTRL, 1, ARG6.integer, 0, (char *)&mulstr, 0, 0, ARG2.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "srsss") ) {
		mulstr.str1 = ARG3.text;
		mulstr.str2 = ARG4.text;
		mulstr.str3 = ARG5.text;
		return (NULL != addctrl(hWnd, LIST_CTRL, 1, 0, 0, (char *)&mulstr, 0, 0, ARG2.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// リストビュー・チェックボックスリストのアイテムの数を得る
// ListViewGetNum( ID$ )
unsigned int rfunc_ListViewGetNum(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return ListView_GetNum( ARG1.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// リストビュー・チェックボックスリストのカーソル位置を設定する
// ListViewSetCursor( ID$, n )
unsigned int rfunc_ListViewSetCursor(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "si") ) {
		return ListView_SetCursor( ARG1.text, ARG2.integer );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// リストビュー・チェックボックスリストの、現在カーソルの置かれている行の番号を返す（カーソルが置かれていないとERRORVALUE）
// ListViewGetCursor( ID$ )
unsigned int rfunc_ListViewGetCursor(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return ListView_GetCursor( ARG1.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// リストビュー・チェックボックスリストのn行i桁に文字列をセットする
// ListViewSetText( ID$, n, i , 文字列$ )
unsigned int rfunc_ListViewSetText(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "siis") ) {
		return ListView_SetText( ARG1.text, ARG2.integer, ARG3.integer, ARG4.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// リストビューに項目を追加する（追加を指示するだけで、設定はListViewSetTextで）
// ListViewAdd( ID$, 第一項目名$ )
unsigned int rfunc_ListViewAdd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		return ListView_Add( ARG1.text, ARG2.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// リストビューのi行目の項目を削除する
// ListViewDelete( ID$, i )
unsigned int rfunc_ListViewDelete(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "si") ) {
		return ListView_Del( ARG1.text, ARG2.integer );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 値リストビュー内の項目の特殊な複数行編集を行う（delim$で指定された1文字を区切りとして、改行に置き換えて編集）
// ListViewMultiLineEdit( item$[], data$[], delim$ )
unsigned int rfunc_ListViewMultiLineEdit(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "rrs") ) {
		char *buf1 = getVariable_d_a(ARG2.text, 0);
		char *buf2 = getVariable_d_a(ARG2.text, 1);
		BOOL bRet;

		if (buf1) buf1 = _strdup(buf1);
		else      buf1 = _strdup("");
		if (buf2) buf2 = _strdup(buf2);
		else      buf2 = _strdup("");

		bRet = lv_edititem_m(hWnd, &buf1, &buf2, getVariable_d_a(ARG1.text, 0), getVariable_d_a(ARG1.text, 1), ARG3.text);

		if (bRet) {
			resize_variables_d(ARG2.text, 2);
			setVariable_d_a(ARG2.text, 0, buf1);
			free(buf1);
			setVariable_d_a(ARG2.text, 1, buf2);
			free(buf2);
			return 1;
		}
		else {
			free(buf1);
			free(buf2);
			return 0;
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// リストビュー・チェックボックスリストの特定のカラム(c)から、文字列を検索する
// ListViewSearch( ID$, c, 文字列$ )
// 文字列が見つかれば項目番号が返り、見つからなければ ERROR が返る
unsigned int rfunc_ListViewSearch(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sis") ) {
		return ListView_Search( ARG1.text, ARG2.integer, ARG3.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// リストビュー・チェックボックスリストのn行目が反転状態になっているかどうかを調べる
// ListView_isSelected( ID$, n )
unsigned int rfunc_ListView_isSelected(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "si") ) {
		return ListView_isSelected( ARG1.text, ARG2.integer );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}


// ボタンを作成（ボタンが押されると、ラベルにジャンプ）
// CreateButton( ボタンが押されたときに飛ばされるラベル名$, キャプション$ [, flag] )
unsigned int rfunc_CreateButton(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ssi") ) {
		return (NULL != addctrl(hWnd, GOTO_BUTTON, 0, ARG3.integer, 0, 0, 0, 0, ARG2.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "ss") ) {
		return (NULL != addctrl(hWnd, GOTO_BUTTON, 0, 0, 0, 0, 0, 0, ARG2.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 色選択ボタンを作成
// ColorButton( ID$, デフォルト [, Key$, Entry$][, flag] )
unsigned int rfunc_ColorButton(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sissi") ) {
		return (NULL != addctrl(hWnd, COLOR_BUTTON, 0, ARG5.integer, ARG3.text, ARG4.text, 0, ARG2.integer, 0, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "siss") ) {
		return (NULL != addctrl(hWnd, COLOR_BUTTON, 0, 0, ARG3.text, ARG4.text, 0, ARG2.integer, 0, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sii") ) {
		return (NULL != addctrl(hWnd, COLOR_BUTTON, 0, ARG3.integer, 0, 0, 0, ARG2.integer, 0, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "si") ) {
		return (NULL != addctrl(hWnd, COLOR_BUTTON, 0, 0, 0, 0, 0, ARG2.integer, 0, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 色選択ボタンから値を取得
// GetColorButton( ID$ )
unsigned int rfunc_GetColorButton(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return GetColorButton( ARG1.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 色選択ボタンへ値を設定
// SetColorButton( ID$, color )
unsigned int rfunc_SetColorButton(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "si") ) {
		return SetColorButton( ARG1.text, ARG2.integer );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 複数行のスタティックテキストの配置
// multitext( 行数, 文字列$ )
unsigned int rfunc_multitext(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "is") ) {
		return (NULL != addctrl(hWnd, TEXT_CTRL, ARG1.integer, 0, 0, 0, 0, 0, ARG2.text, 0, 0, 0, 0, 0, 0, 0, 0));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 複数行編集ボックスの配置 - レジストリから読み込む/へ書き込み（REG_MULTI_SZで書き込む）
// multiedit( ID$, 行数, デフォルト$ [, Key$, Entry$], flag )
unsigned int rfunc_multiedit(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sisi") ) {
		return (NULL != addctrl(hWnd, MULTI_EDIT, ARG2.integer, ARG4.integer, 0, 0, ARG3.text, 0, 0, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sis") ) {
		return (NULL != addctrl(hWnd, MULTI_EDIT, ARG2.integer, 0, 0, 0, ARG3.text, 0, 0, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisssi") ) {
		return (NULL != addctrl(hWnd, MULTI_EDIT, ARG2.integer, ARG6.integer, ARG4.text, ARG5.text, ARG3.text, 0, 0, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "sisss") ) {
		return (NULL != addctrl(hWnd, MULTI_EDIT, ARG2.integer, 0, ARG4.text, ARG5.text, ARG3.text, 0, 0, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// コンボボックスの作成
// ComboBox( ID$, 文字列リスト$[], 初期カーソル位置 [, flag] )
unsigned int rfunc_ComboBox(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "srii") )
		return (NULL != addctrl(hWnd, COMBO_CTRL, 0, ARG4.integer, 0, 0, 0, ARG3.integer, ARG2.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	else if ( args_typecheck(args, "sri") )
		return (NULL != addctrl(hWnd, COMBO_CTRL, 0, 0, 0, 0, 0, ARG3.integer, ARG2.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// コンボボックスの作成(REG_SZ用)
// ComboBox_sz( ID$, KEY$, Entry$, 文字列リスト$[], 文字列リストに各要素に対応するREG_SZの値リスト$[], カーソル位置 [, flag] )
unsigned int rfunc_ComboBox_sz(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sssrrii") )
		return (NULL != addctrl( hWnd, COMBO_CTRL, 0, ARG7.integer, ARG2.text, ARG3.text, ARG5.text, ARG6.integer, ARG4.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0) );
	else if ( args_typecheck(args, "sssrri") )
		return (NULL != addctrl( hWnd, COMBO_CTRL, 0, 0, ARG2.text, ARG3.text, ARG5.text, ARG6.integer, ARG4.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0) );
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// コンボボックスの作成(REG_DWORD用)
// ComboBox_dw( ID$, KEY$, Entry$, 文字列リスト$[], 文字列リストに各要素に対応するREG_DWORDの値リスト[], カーソル位置 [, flag] )
unsigned int rfunc_ComboBox_dw(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sssraii") )
		return (NULL != addctrl( hWnd, COMBO_CTRL, 1, ARG7.integer, ARG2.text, ARG3.text, ARG5.text, ARG6.integer, ARG4.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	else if ( args_typecheck(args, "sssrai") )
		return (NULL != addctrl( hWnd, COMBO_CTRL, 1, 0, ARG2.text, ARG3.text, ARG5.text, ARG6.integer, ARG4.text, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// コンボボックスのカーソル位置を得る
// GetComboBoxCursor( ID$ )
unsigned int rfunc_GetComboBoxCursor(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return GetComboBoxCursor( ARG1.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// コンボボックスのカーソル位置を設定
// SetComboBoxCursor( ID$, n )
unsigned int rfunc_SetComboBoxCursor(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "si") ) {
		return SetComboBoxCursor( ARG1.text, ARG2.integer );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// チェックボックスリストの作成開始（この先作成されるCheckBoxとTextは、リストビューの中に治められる）
// StartCheckBoxList( ID$[, flag] )
unsigned int rfunc_StartCheckBoxList(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return (NULL != addctrl(hWnd, CHKLIST_CTRL, 0, 0, 0, 0, 0, 0, 0, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else if ( args_typecheck(args, "si") ) {
		return (NULL != addctrl(hWnd, CHKLIST_CTRL, 0, ARG2.integer, 0, 0, 0, 0, 0, ARG1.text, 0, 0, 0, 0, 0, 0, 0));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// チェックボックスリストの作成終了
// EndCheckBoxList()
unsigned int rfunc_EndCheckBoxList(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		return (NULL != addctrl(hWnd, CHKLIST_CTRL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// コントロール間に(上下の)隙間を空ける
// space()
// space( 間隔 )
unsigned int rfunc_space(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		addctrl(hWnd, AC_DOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
		return 1;
	}
	else if ( args_typecheck(args, "i") ) {
		UINT i;

		for(i=0 ; i<ARG1.integer ; i++) {
			addctrl(hWnd, AC_DOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
		}

		return 1;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 全タスクへの通知を行う（この場では予約するだけ）
// notify()
unsigned int rfunc_notify(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		system_refresh(GetParent(hWnd), hWnd, 1); // 単純な通知を予約
		return 1;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// シェルに刺激をして、全タスクへの通知を行う（この場では予約するだけ）
// refresh()
unsigned int rfunc_refresh(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		system_refresh(GetParent(hWnd), hWnd, 2); // アイコンサイズを一瞬だけ変更する方法の通知を予約
		return 1;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// OSを再起動（この場では予約するだけ）
// reboot()
unsigned int rfunc_reboot(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		system_refresh(GetParent(hWnd), hWnd, 3); // OSの再起動を予約
		return 1;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 環境変数を設定
// SetEnv( 環境変数名$, 中身$ )
unsigned int rfunc_setenv(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		return (SetEnvironmentVariable(ARG1.text, ARG2.text) != 0)?1:0;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// この環境で HKLM 配下のキーに書き込みアクセスできるか？
// isStandardAccount()
unsigned int rfunc_isStandardAccount(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		return bCannotWriteHKLM == TRUE ? 1 : 0;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// Windows NT系か?
// isNT()
unsigned int rfunc_isnt(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		return isNT;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// Windowsのバージョン番号を major*100 + minor で返す
// GetWindowsVersion()
unsigned int rfunc_GetWindowsVersion(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		return winver;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// Internet Explorerのmajor version
// GetIEVersion()
unsigned int rfunc_GetIEVersion(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		return  iever;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// OSの各種バージョン情報を取得する
// GetOSInfo(info)
unsigned int rfunc_GetOSInfo(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		if ( _stricmp(ARG1.text, "isNT") == 0 ) {
			return isNT;	// Windows NT系なら1、そうでないなら 0
		}
		else if ( _stricmp(ARG1.text, "IEver") == 0 ) {
			return iever;	// 取得可能ならばIEのメジャーバージョン
		}
		else if ( _stricmp(ARG1.text, "winver") == 0 ) {
			return winver;	// Windows のバージョン(major*100+minor)
		}
		else if ( _stricmp(ARG1.text, "is64bit") == 0 ) {
			// Rnsf7.exeがx64用かx86用かを返す（実行中のWindowsのbitではないことに注意!!）
#ifdef _WIN64
			return 1;
#else
			return 0;
#endif
		}
		else if ( _stricmp(ARG1.text, "wow64") == 0 ) {
			// Rnsf7.exeがWOW64配下で動いているかどうかを返す（x86版のRnsf.exeがx64 OS上で動いている場合のみ1）
#ifdef _WIN64
			return 0;
#else
			return tf_IsWow64Process();
#endif
		}
		else {
			OSVERSIONINFOEX oviex;

			ZeroMemory( &oviex, sizeof(OSVERSIONINFOEX) );
			oviex.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
			GetVersionEx((OSVERSIONINFO *)&oviex);

			if ( _stricmp(ARG1.text, "Major") == 0 ) {
				return oviex.dwMajorVersion;	// Windowsのメジャーバージョン
			}
			else if ( _stricmp(ARG1.text, "Minor") == 0 ) {
				return oviex.dwMinorVersion;	// Windowsのマイナーバージョン
			}
			else if ( _stricmp(ARG1.text, "Build") == 0 ) {
				return oviex.dwBuildNumber;		// Windowsのビルドナンバ
			}
			else if ( _stricmp(ARG1.text, "Platform") == 0 ) {
				return oviex.dwPlatformId;		// WindowsのプラットフォームID(0:Win32s 1:Win9x 2:WinNT)
			}
			else if ( _stricmp(ARG1.text, "SPMajor") == 0 ) {
				return oviex.wServicePackMajor;	// サービスパックのメジャーバージョン
			}
			else if ( _stricmp(ARG1.text, "SPMinor") == 0 ) {
				return oviex.wServicePackMinor;	// サービスパックのマイナーバージョン
			}
			else if ( _stricmp(ARG1.text, "SuiteMask") == 0 ) {
				return oviex.wSuiteMask;	// 各ビットの組み合わせで、OSの情報を表す
											// VER_SUITE_SMALLBUSINESS             0x00000001
											// VER_SUITE_ENTERPRISE                0x00000002
											// VER_SUITE_BACKOFFICE                0x00000004
											// VER_SUITE_COMMUNICATIONS            0x00000008
											// VER_SUITE_TERMINAL                  0x00000010
											// VER_SUITE_SMALLBUSINESS_RESTRICTED  0x00000020
											// VER_SUITE_EMBEDDEDNT                0x00000040
											// VER_SUITE_DATACENTER                0x00000080
											// VER_SUITE_SINGLEUSERTS              0x00000100
											// VER_SUITE_PERSONAL                  0x00000200
											// VER_SUITE_BLADE                     0x00000400
											// VER_SUITE_EMBEDDED_RESTRICTED       0x00000800
			}
			else if ( _stricmp(ARG1.text, "ProductType") == 0 ) {
				return oviex.wProductType;	// 追加情報(0:未対応 1:Workstation(Professional, Home)
											//			2:ドメインコントローラ 3:NTサーバ)
			}
			else if ( _stricmp(ARG1.text, "ProductInfo") == 0 ) { // Vista以降
				typedef BOOL (WINAPI *PFUNC_GetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD);
				PFUNC_GetProductInfo pGetProductInfo = NULL;
				// GetProcAddressにより、Kernel32.dll内のGetProductInfoのアドレスを直接取得
				pGetProductInfo = (PFUNC_GetProductInfo)GetProcAddress(GetModuleHandle("kernel32.dll"), "GetProductInfo");

				if (pGetProductInfo) {
					DWORD dwReturnedProductType = 0;

				   // GetProductInfoの呼出し
					if ( pGetProductInfo(oviex.dwMajorVersion, oviex.dwMinorVersion, oviex.wServicePackMajor, oviex.wServicePackMinor, &dwReturnedProductType) ) {
						// 成功
						return dwReturnedProductType;
					}
				}
			}
		}

		return ERRORVALUE;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// OSの様々な情報を取得する
// GetSystemMetrics(nIndex)
unsigned int rfunc_GetSystemMetrics(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "i") ) {
		return GetSystemMetrics(ARG1.integer);
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 特定のビットだけを1にしたときの値を得る
// bit( n )
unsigned int rfunc_bit(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "i") ) {
		return ( 1 << ARG1.integer );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// (Shift-JIS)漢字の1バイト目かどうかを調べる
// isKanji1( str$, n )
unsigned int rfunc_isKanji1(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "si") ) {
		return ( isKanji1(ARG1.text, ARG2.integer) );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// チェックボックスの内容を得る
// GetCheckBox( ID$ )
unsigned int rfunc_getcheckbox(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return GetCheckBox( ARG1.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 編集ボックスの内容を数値で得る
// GetEditBoxNum( ID$ )
unsigned int rfunc_geteditboxnum(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return atoi( GetEditBox( ARG1.text ) );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// チェックボックスの状態を設定
// SetCheckBox( ID$, <0|1|2> )
unsigned int rfunc_setcheckbox(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "si") ) {
		return SetCheckBox( ARG1.text, ARG2.integer );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 編集ボックスの内容を数値で設定する
// SetEditBoxNum( ID$, 数値 )
unsigned int rfunc_seteditboxnum(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "si") ) {
		char itbuf[16];
		BOOL rv = ERRORVALUE;

		if ( 0 == _ultoa_s(ARG2.integer, itbuf, _countof(itbuf), 10) ) {
			rv = SetEditBox( ARG1.text, itbuf );
		}
		return rv;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 編集ボックスの内容を文字列で設定する
// SetEditBox( ID$, 文字列$ )
unsigned int rfunc_seteditbox(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		return SetEditBox( ARG1.text, ARG2.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// アイコンを設定する
// SetIconBox( ID$, アイコン$ )
unsigned int rfunc_seticonbox(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		return SetIconBox( ARG1.text, ARG2.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// テキスト・チェックボックス・ボタン内の文字列を設定する
// SetTextCtrl( ID$, 文字列$ )
unsigned int rfunc_settextctrl(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		return SetTextCtrl( ARG1.text, ARG2.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 文字列の文字数を得る
// strlen( 文字列$ )
unsigned int rfunc_strlen(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return lstrlen( ARG1.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 配列の大きさを得る/文字列の文字数を得る
// sizeof( <数値 | 文字列$ | 文字列型配列$[] | 数値型配列[]> )
unsigned int rfunc_sizeof(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "r") ) {
		return sizeof_variables_d( ARG1.text );
	}
	else if ( args_typecheck(args, "a") ) {
		return sizeof_variables( ARG1.text );
	}
	else if ( args_typecheck(args, "s") ) {
		return lstrlen( ARG1.text )+1;
	}
	else if ( args_typecheck(args, "i") ) {
		return sizeof(UINT);
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 文字列中のn(0〜)文字目の文字コードを得る
// GetAsciiCode( 文字列$, n )
unsigned int rfunc_GetAsciiCode(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "si") ) {
		if ( (UINT)lstrlen(ARG1.text) > ARG2.integer ) {
			return (unsigned)( ARG1.text[ARG2.integer] );
		}
		return 0;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 文字列中の特定のビットを得る
// GetStrBit( 文字列$, 何バイト目?<0->, 何ビット目?<0-7> )
unsigned int rfunc_getstrbit(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sii") ) {
		if ( strlen(ARG1.text) > (size_t)ARG2.integer )
			return (int)( ((unsigned char)ARG1.text[ARG2.integer] >> ARG3.integer) & 1 );
		else
			return 0;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 複数行編集ボックスの行数を得る
// GetMultiEditLineCount( ID$ )
unsigned int rfunc_GetMultiEditLineCount(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return GetMultiEditLineCount( ARG1.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 複数行編集ボックスの内容をチェックする。チェック結果は checkMultiEdit() の戻り値参照。
// CheckMultiEdit( ID$ )
unsigned int rfunc_checkmultiedit(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return checkMultiEdit( ARG1.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 複数行編集ボックスから、文字列を検索する
// MultiEditSearch( ID$, text$ )
// 文字列が見つかれば項目番号が返り、見つからなければ ERROR が返る
unsigned int rfunc_MultiEditSearch(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		return MultiEdit_Search( ARG1.text, ARG2.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// レジストリへ数の書き込み
// RegWriteInt( Key$, Entry$, 数 )
// RegWriteInteger( Key$, Entry$, 数 )
unsigned int rfunc_regwriteint(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ssi") ) {
		HKEY hKey;

		if (NULL != (hKey = tRegOpenKey( NULL, ARG1.text, 1 )) ) {
			UINT rv;

			rv = (UINT)tRegWriteInteger( hKey, ARG2.text, ARG3.integer );
			if (!rv) {
				LONG lasterr = tRegGetLastError();
				if (lasterr != ERROR_SUCCESS && rnsf7RegRead("regErrorMessage", 0)) {
					dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegWriteInt)", "レジストリキー'", ARG1.text,
									 "'のエントリ'",ARG2.text,"'への書き込みを行おうとしてエラーになりました。\nAPIが報告した原因：",
									 getLastErrorString(lasterr));
				}
			}
			RegCloseKey( hKey );
			return rv;
		}
		else {
			LONG lasterr = tRegGetLastError();
			if (lasterr != ERROR_SUCCESS && rnsf7RegRead("regErrorMessage", 0)) {
				dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegWriteInt)", "レジストリキー'", ARG1.text,
								 "'を書き込みアクセスで開こうとしてエラーになりました。\nAPIが報告した原因：",
								 getLastErrorString(lasterr), NULL, NULL);
			}
			return 0;
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// レジストリへ文字列の書き込み
// RegWriteSz( Key$, Entry$, 文字列$ )
// RegWriteString( Key$, Entry$, 文字列$ )
unsigned int rfunc_regwritesz(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sss") ) {
		HKEY hKey;
		UINT rv;

		if (NULL != (hKey = tRegOpenKey( NULL, ARG1.text, TREG_OPEN_CREATE )) ) {
			rv = (UINT)tRegWriteString( hKey, ARG2.text, ARG3.text, TREG_SZ );
			if (!rv) {
				LONG lasterr = tRegGetLastError();
				if (lasterr != ERROR_SUCCESS && rnsf7RegRead("regErrorMessage", 0)) {
					dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegWriteSz)", "レジストリキー'", ARG1.text,
									 "'のエントリ'",ARG2.text,"'への書き込みを行おうとしてエラーになりました。\nAPIが報告した原因：",
									 getLastErrorString(lasterr));
				}
			}
			RegCloseKey( hKey );
			return rv;
		}
		else {
			LONG lasterr = tRegGetLastError();
			if (lasterr != ERROR_SUCCESS && rnsf7RegRead("regErrorMessage", 0)) {
				dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegWriteSz)", "レジストリキー'", ARG1.text,
								 "'を書き込みアクセスで開こうとしてエラーになりました。\nAPIが報告した原因：",
								 getLastErrorString(lasterr), NULL, NULL);
			}
			return 0;
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// レジストリへ展開文字列の書き込み
// RegWriteExpandSz( Key$, Entry$, 文字列$ )
// RegWriteExpandString( Key$, Entry$, 文字列$ )
unsigned int rfunc_regwriteexpandsz(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sss") ) {
		HKEY hKey;
		UINT rv;

		if (NULL != (hKey = tRegOpenKey( NULL, ARG1.text, TREG_OPEN_CREATE )) ) {
			rv = (UINT)tRegWriteString( hKey, ARG2.text, ARG3.text, TREG_EXPAND_SZ );
			if (!rv) {
				LONG lasterr = tRegGetLastError();
				if (lasterr != ERROR_SUCCESS && rnsf7RegRead("regErrorMessage", 0)) {
					dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegWriteExpandSz)", "レジストリキー'", ARG1.text,
									 "'のエントリ'",ARG2.text,"'への書き込みを行おうとしてエラーになりました。\nAPIが報告した原因：",
									 getLastErrorString(lasterr));
				}
			}
			RegCloseKey( hKey );
			return rv;
		}
		else {
			LONG lasterr = tRegGetLastError();
			if (lasterr != ERROR_SUCCESS && rnsf7RegRead("regErrorMessage", 0)) {
				dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegWriteExpandSz)", "レジストリキー'", ARG1.text,
								 "'を書き込みアクセスで開こうとしてエラーになりました。\nAPIが報告した原因：",
								 getLastErrorString(lasterr), NULL, NULL);
			}
			return 0;
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// レジストリへバイナリデータの書き込み (特定のbyteを指定する形式)
// RegWriteByte( Key$, Entry$, 何バイト目<0->,<0-255> )
unsigned int rfunc_regwritebyte(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ssii") ) {
		HKEY hKey;
		int  l;
		UINT rv;
		char *buf;

		if (NULL != (hKey = tRegOpenKey( NULL, ARG1.text, TREG_OPEN_CREATE )) ) {
			l = tRegValueExist( hKey, ARG2.text );
			if (l <= 0) {
				l = ARG3.integer+1;
				buf = (char *)calloc( 1, l );
			}
			else if ( l <= (signed)ARG3.integer ) {
				l = ARG3.integer+1;
				buf = (char *)calloc( 1, l );
				tRegReadString( hKey, ARG2.text, buf, l );
			}
			else {
				buf = (char *)calloc( 1, l );
				tRegReadString( hKey, ARG2.text, buf, l );
			}
				
			buf[ ARG3.integer ] = (char)ARG4.integer;

			rv = (UINT)tRegWriteBinary( hKey, ARG2.text, buf, l );
			if (!rv) {
				LONG lasterr = tRegGetLastError();
				if (lasterr != ERROR_SUCCESS && rnsf7RegRead("regErrorMessage", 0)) {
					dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegWriteByte)", "レジストリキー'", ARG1.text,
									 "'のエントリ'",ARG2.text,"'への書き込みを行おうとしてエラーになりました。\nAPIが報告した原因：",
									 getLastErrorString(lasterr));
				}
			}
			RegCloseKey( hKey );
			safefree( buf );

			return rv;
		}
		else {
			LONG lasterr = tRegGetLastError();
			if (lasterr != ERROR_SUCCESS && rnsf7RegRead("regErrorMessage", 0)) {
				dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegWriteByte)", "レジストリキー'", ARG1.text,
								 "'を書き込みアクセスで開こうとしてエラーになりました。\nAPIが報告した原因：",
								 getLastErrorString(lasterr), NULL, NULL);
			}
			return 0;
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// レジストリへバイナリデータの書き込み (特定のbitを指定する形式)
// RegWriteBit( Key$, Entry$, 何バイト目<0->, 何ビット目<0-7>, <0|1> )
unsigned int rfunc_regwritebit(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ssiii") ) {
		HKEY hKey;
		int  l;
		UINT rv;
		char *buf;

		if (NULL != (hKey = tRegOpenKey( NULL, ARG1.text, TREG_OPEN_CREATE )) ) {
			l = tRegValueExist( hKey, ARG2.text );
			if (l <= 0) {
				l = ARG3.integer+1;
				buf = (char *)calloc( 1, l );
			}
			else if ( l <= (signed)ARG3.integer ) {
				l = ARG3.integer+1;
				buf = (char *)calloc( 1, l );
				tRegReadString( hKey, ARG2.text, buf, l );
			}
			else {
				buf = (char *)calloc( 1, l );
				tRegReadString( hKey, ARG2.text, buf, l );
			}

			if ( ARG5.integer != 0 ) {
				buf[ARG3.integer] |= (1 << ARG4.integer);
			}
			else {
				buf[ARG3.integer] &= (~(1 << ARG4.integer));
			}

			rv = tRegWriteBinary( hKey, ARG2.text, buf, l );
			if (!rv) {
				LONG lasterr = tRegGetLastError();
				if (lasterr != ERROR_SUCCESS && rnsf7RegRead("regErrorMessage", 0)) {
					dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegWriteBit)", "レジストリキー'", ARG1.text,
									 "'のエントリ'",ARG2.text,"'への書き込みを行おうとしてエラーになりました。\nAPIが報告した原因：",
									 getLastErrorString(lasterr));
				}
			}
			RegCloseKey( hKey );
			safefree( buf );

			return rv;
		}
		else {
			LONG lasterr = tRegGetLastError();
			if (lasterr != ERROR_SUCCESS && rnsf7RegRead("regErrorMessage", 0)) {
				dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegWriteBit)", "レジストリキー'", ARG1.text,
								 "'を書き込みアクセスで開こうとしてエラーになりました。\nAPIが報告した原因：",
								 getLastErrorString(lasterr), NULL, NULL);
			}
			return 0;
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// レジストリから数値の読み出し
// RegReadInt( Key$, Entry$, デフォルト )
// RegReadInteger( Key$, Entry$, デフォルト )
unsigned int rfunc_regreadint(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ssi") ) {
		HKEY hKey;
		UINT rv;

		if (NULL != (hKey = tRegOpenKey(NULL, ARG1.text, TREG_OPEN_READONLY)) ) {
			rv = tRegReadInteger(hKey, ARG2.text, ARG3.integer);
			RegCloseKey( hKey );
		}
		else
			rv = ARG3.integer;

		return rv;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// レジストリのバイナリ値から特定のバイトの読み出し
// RegReadByte( Key$, Entry$, デフォルト<0-255>, 何バイト目?<0-> )
unsigned int rfunc_regreadbyte(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ssii") ) {
		HKEY hKey;
		unsigned char *value = NULL;
		int  l = 0, rv = ERRORVALUE;

		if (NULL != (hKey = tRegOpenKey(NULL, ARG1.text, TREG_OPEN_READONLY)) ) {
			if ( 0 < (l = tRegValueExist(hKey, ARG2.text)) && l > (signed)ARG4.integer) {
				value = (unsigned char *)zalloc( l );
				if ( value ) {
					tRegReadString(hKey, ARG2.text, (char *)value, l);
					rv = value[ ARG4.integer ];
					safefree( value );
				}
			}
			else {
				rv = ARG3.integer;
			}
			RegCloseKey( hKey );
		}
		else
			rv = ARG3.integer;

		return rv;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// レジストリのバイナリ値から特定のビットの読み出し
// RegReadBit( Key$, Entry$, デフォルト<0|1>, 何バイト目?<0->, 何ビット目?<0-7> )
unsigned int rfunc_regreadbit(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ssiii") ) {
		HKEY hKey;
		unsigned char *value = NULL;
		int  l = 0, rv = ERRORVALUE;

		if (NULL != (hKey = tRegOpenKey(NULL, ARG1.text, TREG_OPEN_READONLY)) ) {
			if ( 0 < (l = tRegValueExist(hKey, ARG2.text)) && l > (signed)ARG4.integer) {
				value = (unsigned char *)zalloc( l );
				if ( value ) {
					tRegReadString(hKey, ARG2.text, (char *)value, l);
					rv = ((value[ ARG4.integer ] >> ARG5.integer) & 1);
					safefree( value );
				}
			}
			else {
				rv = ARG3.integer;
			}
			RegCloseKey( hKey );
		}
		else {
			rv = ARG3.integer;
		}

		return rv;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// レジストリ値を削除
// RegDeleteValue( Key$, Entry$ )
unsigned int rfunc_regdeletevalue(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		HKEY hKey;
		UINT rv;

		if (NULL != (hKey = tRegOpenKey(NULL, ARG1.text, 0)) ) {
			LONG lasterr = RegDeleteValue(hKey, ARG2.text);
			if (lasterr != ERROR_SUCCESS) {
				if (lasterr != ERROR_FILE_NOT_FOUND && rnsf7RegRead("regErrorMessage", 0)) {
					dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegDeleteValue)", "レジストリキー'", ARG1.text,
									 "'のエントリ'",ARG2.text,"'を削除しようとしてエラーになりました。\nAPIが報告した原因：",
									 getLastErrorString(lasterr));
				}
				rv = 0;
			}
			else {
				rv = 1;
			}

			RegCloseKey( hKey );
		}
		else {
			LONG lasterr = tRegGetLastError();
			if (lasterr != ERROR_SUCCESS && lasterr != ERROR_FILE_NOT_FOUND && rnsf7RegRead("regErrorMessage", 0)) {
				dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegDeleteValue)", "レジストリキー'", ARG1.text,
								 "'を書き込みアクセスで開こうとしてエラーになりました。\nAPIが報告した原因：",
								 getLastErrorString(lasterr), NULL, NULL);
			}
			rv = 0;
		}

		return rv;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// レジストリキー内のすべての値を削除（サブキーの中までは削除しない）
// RegDeleteAllValue( Key$, Entry$ )
unsigned int rfunc_regdeleteallvalue(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		HKEY hKey;
		UINT rv = FALSE;
		LONG lasterr;

		if (NULL != (hKey = tRegOpenKey(NULL, ARG1.text, 0)) ) {
			int i;
			DWORD numValues;       // サブキーの数
			DWORD lenMaxValueName; // サブキー名の最大長

			if (ERROR_SUCCESS == (lasterr = RegQueryInfoKey(hKey, NULL, 0, NULL, NULL, NULL, NULL, &numValues, &lenMaxValueName, NULL, NULL, NULL))) {
				if (numValues > 0) {
					char **valuenames = (char **)calloc(numValues, sizeof(char *));   // 値名を入れるためのリストのメモリ確保
					char *valuename1 = (char *)calloc(lenMaxValueName+1, sizeof(WCHAR)); // １つの値名を入れるためのメモリ確保（とりあえず最大長で確保）。WinNTでRegQueryInfoKeyは文字数単位で返すので、バイト単位を指定するときはサイズはsizeof(WCHARA)倍する必要がある

					// 値を列挙しながら、値名をリストへ格納していく。同時にメモリ確保
					for(i=0 ; i<(int)numValues ; ++i) {
						lenMaxValueName = (lenMaxValueName + 1) * sizeof(WCHAR);
						RegEnumValue(hKey, i, valuename1, &lenMaxValueName, NULL, NULL, NULL, NULL);
						valuenames[i] = _strdup(valuename1);
					}

					// １つの値名を入れるためのメモリは、もはや不要なので削除
					safefree(valuename1);

					rv = TRUE;
					// リストに格納された値名を順に削除していく
					for(i=0 ; i<(int)numValues ; ++i) {
						if (ERROR_SUCCESS != (lasterr = RegDeleteValue(hKey, valuenames[i]))) {
							rv = FALSE; // 1つでも削除失敗があったら、全体的に失敗扱い
							if (rnsf7RegRead("regErrorMessage", 0)) {
								dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegDeleteAllValue)", "レジストリキー'", ARG1.text,
												 "'のエントリ'",valuenames[i],"'を削除しようとしてエラーになりました。\nAPIが報告した原因：",
												 getLastErrorString(lasterr));
							}
						}
					}

					// リストに格納された値名のエリアを開放
					for(i=(int)numValues-1 ; i>=0 ; --i) {
						safefree(valuenames[i]);
					}
					safefree(valuenames);
				}
			}
			else {
				if (lasterr != ERROR_SUCCESS && rnsf7RegRead("regErrorMessage", 0)) {
					dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegDeleteAllValue)", "レジストリキー'", ARG1.text,
									 "'を調べようとしてエラーになりました。\nAPIが報告した原因：",
									 getLastErrorString(lasterr), NULL, NULL);
				}
			}

			RegCloseKey( hKey );
		}
		else {
			LONG lasterr = tRegGetLastError();
			if (lasterr != ERROR_SUCCESS && lasterr != ERROR_FILE_NOT_FOUND && rnsf7RegRead("regErrorMessage", 0)) {
				dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegDeleteAllValue)", "レジストリキー'", ARG1.text,
								 "'を書き込みアクセスで開こうとしてエラーになりました。\nAPIが報告した原因：",
								 getLastErrorString(lasterr), NULL, NULL);
			}
			rv = 0;
		}

		return rv;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// レジストリキーを作成
// RegCreateKey( Key$ )
// RegCreateKey( Key$, SubKey$ )
unsigned int rfunc_regcreatekey(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	HKEY hKey;

	if ( args_typecheck(args, "s") ) {
		if ( NULL != (hKey = tRegOpenKey(NULL, ARG1.text, TREG_OPEN_CREATE)) ) {
            RegCloseKey( hKey );
			return 1;
		}
		else {
			LONG lasterr = tRegGetLastError();
			if (lasterr != ERROR_SUCCESS && rnsf7RegRead("regErrorMessage", 0)) {
				dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegCreateKey/1)", "レジストリキー'", ARG1.text,
								 "'を作ろうとしてエラーになりました。\nAPIが報告した原因：",
								 getLastErrorString(lasterr), NULL, NULL);
			}
			return 0;
		}
	}
	else if ( args_typecheck(args, "ss") ) {
		if ( NULL != (hKey = tRegOpenSubKey(NULL, ARG1.text, ARG2.text, TREG_OPEN_CREATE)) ) {
			RegCloseKey( hKey );
			return 1;
		}
		else {
			LONG lasterr = tRegGetLastError();
			if (lasterr != ERROR_SUCCESS && rnsf7RegRead("regErrorMessage", 0)) {
				dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegCreateKey/2)", "レジストリキー'", ARG1.text, "\\", ARG2.text,
								 "'を作ろうとしてエラーになりました。\nAPIが報告した原因：",
								 getLastErrorString(lasterr));
			}
			return 0;
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// レジストリキーを削除
// RegDeleteKey( Key$ )
// RegDeleteKey( Key$, SubKey$ )
unsigned int rfunc_regdeletekey(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	char *key, *subkey = NULL;
	BYTE one_param_flag = 0;

	if ( args_typecheck(args, "s") ) {
		UINT i;

		if ( strchr(ARG1.text, '\\') == 0 )
			return 0;

		one_param_flag = 1;
		key = _strdup(ARG1.text); // 引数をいじるわけにはいかないので、メモリ確保
		for( i=lstrlen(key)-1 ; i>0 ; i-- ) {
			if ( key[i] == '\\' && !isKanji1(key,i-1) ) {
				key[i] = 0;
				subkey = &key[i+1];
				break;
			}
		}
		if ( subkey == NULL ) {
			safefree(key);
			return 0;
		}
	}
	else if ( args_typecheck(args, "ss") ) {
		key = ARG1.text;
		subkey = ARG2.text;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}

	{
		HKEY hKey = 0;
		UINT rv = 0;
		LONG lasterr = ERROR_SUCCESS;

		if ( strchr(key,'\\') == 0 ) {
			hKey = tRegHiveKey( key );
			if ( hKey ) {
                rv = (ERROR_SUCCESS == (lasterr = RegDeleteKey(hKey, subkey)));
			}
		}
		if (NULL != (hKey = tRegOpenKey(NULL, key, 0)) ) {
			rv = (ERROR_SUCCESS == (lasterr = RegDeleteKey(hKey, subkey)));
			RegCloseKey( hKey );
		}
		else {
			lasterr = tRegGetLastError();
		}

		if (lasterr != ERROR_SUCCESS && lasterr != ERROR_FILE_NOT_FOUND && rnsf7RegRead("regErrorMessage", 0)) {
			dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegDeleteKey)", "レジストリキー'", key,
							 "'のサブキー'",subkey,"'を削除しようとしてエラーになりました。\nAPIが報告した原因：",
							 getLastErrorString(lasterr));
		}

		if (one_param_flag) { // パラメータが１つだけの場合、keyにstrdupするので、ここで解放
			safefree(key);
		}

		return rv;
	}
}

// レジストリ値の存在を確認 (値が存在すれば1、存在しなければ0を返す)
// RegValueExist( Key$, Entry$ )
unsigned int rfunc_RegValueExist(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		HKEY hKey;
		int  rv;

		if (NULL != (hKey = tRegOpenKey(NULL, ARG1.text, TREG_OPEN_READONLY)) ) {
			rv = tRegValueExist(hKey, ARG2.text);
			RegCloseKey( hKey );
			return (rv != -1);
		}
		else {
			return 0;
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// レジストリキーを下位のサブキーごと削除
// RegDeleteSubKeys( Key$ )
// RegDeleteSubKeys( Key$, SubKey$ )
unsigned int rfunc_regdeletesubkeys(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	char *key, *subkey = NULL;
	BYTE one_param_flag = 0;

	if ( args_typecheck(args, "s") ) {
		UINT i;

		if ( strchr(ARG1.text, '\\') == 0 )
			return 0;

		one_param_flag = 1;
		key = _strdup(ARG1.text); // 引数をいじるわけにはいかないので、メモリ確保
		for( i=lstrlen(key)-1 ; i>0 ; i-- ) {
			if ( key[i] == '\\' && !isKanji1(key,i-1) ) {
				key[i] = 0;
				subkey = &key[i+1];
				break;
			}
		}
		if ( subkey == NULL ) {
			safefree(key);
			return 0;
		}
	}
	else if ( args_typecheck(args, "ss") ) {
		key = ARG1.text;
		subkey = ARG2.text;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}

	{
		HKEY hKey = 0;
		UINT rv = 0;

		if ( strchr(key,'\\') == 0 ) {
			hKey = tRegHiveKey( key );
			if ( hKey ) {
                rv = (TRUE == tRegDeleteSubKey(hKey, subkey));
			}
		}
		if (NULL != (hKey = tRegOpenKey(NULL, key, 0)) ) {
			rv = (TRUE == tRegDeleteSubKey(hKey, subkey));
			RegCloseKey( hKey );
		}

		if (rv != TRUE) {
			LONG lasterr = tRegGetLastError();
			if (lasterr != ERROR_SUCCESS && lasterr != ERROR_FILE_NOT_FOUND && rnsf7RegRead("regErrorMessage", 0)) {
				dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegDeleteSubKeys)", "レジストリキー'", key,
								 "'のサブキー'",subkey,"'を削除しようとしてエラーになりました。\nAPIが報告した原因：",
								 getLastErrorString(lasterr));
			}
		}

		if (one_param_flag) { // パラメータが１つだけの場合、keyにstrdupするので、ここで解放
			safefree(key);
		}

		return rv;
	}
}

// レジストリ値のサイズを返す (値が存在しないと-1を返す)
// RegValueSize( Key$, Entry$ )
unsigned int rfunc_RegValueSize(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		HKEY hKey;
		int  rv; // tRegValueExistの返却値はint型

		if (NULL != (hKey = tRegOpenKey(NULL, ARG1.text, TREG_OPEN_READONLY)) ) {
			rv = tRegValueExist(hKey, ARG2.text);
			RegCloseKey( hKey );
			return rv; // -1はERRORVALUEに変換されることが期待されている
		}
		else {
			return ERRORVALUE;
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// レジストリ値の型を返す (値が存在しないと0を返す)
// RegValueType( Key$, Entry$ )
unsigned int rfunc_RegValueType(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		HKEY hKey;
		UINT rv;

		if (NULL != (hKey = tRegOpenKey(NULL, ARG1.text, TREG_OPEN_READONLY)) ) {
			rv = tRegValueType(hKey, ARG2.text);
			RegCloseKey( hKey );
			return rv;
		}
		else {
			return 0;
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// レジストリキーの存在を確認 (存在すれば1、存在しなければ0を返す)
// RegKeyExist( Key$ )
unsigned int rfunc_RegKeyExist(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		HKEY hKey;

		if (NULL != (hKey = tRegOpenKey(NULL, ARG1.text, TREG_OPEN_READONLY)) ) {
			RegCloseKey( hKey );
			return 1;
		}
		else {
			return 0;
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// レジストリエントリ名を変更する（成功すれば1、失敗したら0を返す）
// RegRenameValue( Key$, OldName$, NewName$ )
unsigned int rfunc_RegRenameValue(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sss") ) {
		HKEY hKey;
		int  rv = FALSE;

		if (NULL != (hKey = tRegOpenKey(NULL, ARG1.text, 0)) ) {
			rv = tRegRenValue(hKey, ARG2.text, ARG3.text);
			if (rv != TRUE) {
				LONG lasterr = tRegGetLastError();
				if (rnsf7RegRead("regErrorMessage", 0)) {
					dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegRenameValue)", "レジストリキー'", ARG1.text,
								 "'のエントリ'",ARG2.text,"'の名前を変更しようとしてエラーになりました。\nAPIが報告した原因：",
								 getLastErrorString(lasterr));
				}
			}
			RegCloseKey( hKey );
		}
		else {
			LONG lasterr = tRegGetLastError();
			if (lasterr != ERROR_SUCCESS && lasterr != ERROR_FILE_NOT_FOUND && rnsf7RegRead("regErrorMessage", 0)) {
				dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegRenameValue)", "レジストリキー'", ARG1.text,
								 "'を書き込みアクセスで開こうとしてエラーになりました。\nAPIが報告した原因：",
								 getLastErrorString(lasterr), NULL, NULL);
			}
		}

		return rv;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// (OSによっては使えないかも)
// レジストリキーのリネーム
unsigned int rfunc_regrenamekey(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sss") ) {
		HKEY hKey;
		int  rv = FALSE;

		if (NULL != (hKey = tRegOpenKey(NULL, ARG1.text, 0)) ) {
			rv = tRegRenameKey(hKey, ARG2.text, ARG3.text);
			if (rv != ERROR_SUCCESS) {
				if (rnsf7RegRead("regErrorMessage", 0)) {
					dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegRenameKey)", "レジストリキー'", ARG1.text,
								 "'のサブキー'",ARG2.text,"'の名前を変更しようとしてエラーになりました。\nAPIが報告した原因：",
								 getLastErrorString(rv));
				}
			}
			RegCloseKey( hKey );
		}
		else {
			LONG lasterr = tRegGetLastError();
			if (lasterr != ERROR_SUCCESS && lasterr != ERROR_FILE_NOT_FOUND && rnsf7RegRead("regErrorMessage", 0)) {
				dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegRenameKey)", "レジストリキー'", ARG1.text,
								 "'を書き込みアクセスで開こうとしてエラーになりました。\nAPIが報告した原因：",
								 getLastErrorString(lasterr), NULL, NULL);
			}
		}

		return rv == 0 ? TRUE : FALSE;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// iniファイルから数値を読み込む
// iniReadInt( file$, section$, key$, default )
// iniReadInteger( file$, section$, key$, default )
unsigned int rfunc_iniReadInt(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sssi") ) {
		return GetPrivateProfileInt( ARG2.text, ARG3.text, ARG4.integer, ARG1.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// iniファイルに数値を書き込む
// iniWriteInt( file$, section$, key$, value )
// iniWriteInteger( file$, section$, key$, value )
unsigned int rfunc_iniWriteInt(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sssi") ) {
		char itbuf[16];

		if ( 0 != _ultoa_s(ARG4.integer, itbuf, _countof(itbuf), 10) ) {
			// エラーの場合は"err"を埋め込み
			lstrcpy(itbuf, "err");
		}
		return WritePrivateProfileString( ARG2.text, ARG3.text, itbuf, ARG1.text )?1:0;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// iniファイルに文字列を書き込む
// iniWriteString( file$, section$, key$, value$ )
unsigned int rfunc_iniWriteString(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ssss") ) {
		return WritePrivateProfileString( ARG2.text, ARG3.text, ARG4.text, ARG1.text )?1:0;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// iniファイルからキーを消す
// iniDeleteKey( file$, section$, key$ )
unsigned int rfunc_iniDeleteKey(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sss") ) {
		return WritePrivateProfileString( ARG2.text, ARG3.text, NULL, ARG1.text )?1:0;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// iniファイルからセクションの数を得る
// iniNumSection( file$ )
unsigned int rfunc_iniNumSection(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return tiniNumSection( ARG1.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// iniファイルのセクションからキーの数を得る
// iniNumKey( file$, section$ )
unsigned int rfunc_iniNumKey(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		return tiniNumKey( ARG1.text, ARG2.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// iniファイルからバイナリデータを読み込む
// iniReadBinary( inifile$, section$, key$, ints[] )
unsigned int rfunc_iniReadBinary(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sssa") ) {
		unsigned len, i, rv;
		unsigned char *value;

		len = sizeof_variables( ARG4.text );
		if ( len != NO_VALUE ) {
			value = (unsigned char *)calloc( len, 1 );
			if ( value ) {
				if ( GetPrivateProfileStruct( ARG2.text, ARG3.text, value, len, ARG1.text ) ) {
					for(i=0 ; i<len ; i++) {
						setVariable_a(ARG4.text, i, (UINT)value[i]);
					}
					rv = 1;
				}
				else {
					rv = 0; // 読み込み失敗
				}

				safefree( value );
				return rv;
			}
			else {
				return 0; // メモリ不足
			}
		}
		else {
			char *mes;

			mes = zalloc( strlen(ARG4.text) + 200 );
			if ( mes ) {
				wsprintf( mes, "iniReadBinary()で利用されている配列%s[]は、宣言されないまま使われています。レジストリへの書き込みは行いません。", ARG4.text);
				destroy_splash_window();
				MessageBox(NULL, mes, "R-Script警告", MB_OK | MB_ICONEXCLAMATION);
				safefree( mes );
			}

			return 0;
		}	
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// iniファイルにバイナリデータを書き込む
// iniWriteBinary( inifile$, section$, key$, ints[] )
unsigned int rfunc_iniWriteBinary(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sssa") ) {
		unsigned len, u, i, rv;
		unsigned char *value;

		len = sizeof_variables( ARG4.text );
		if ( len != NO_VALUE ) {
			value = (unsigned char *)calloc( len, 1 );
			if ( value ) {
				for(i=0 ; i<len ; i++) {
					getVariable_a(ARG4.text, i, &u);
					value[i] = (unsigned char)u;
				}
				rv = WritePrivateProfileStruct( ARG2.text, ARG3.text, value, len, ARG1.text )?1:0;
				safefree( value );
				return rv;
			}
			else {
				return 0; // メモリ不足
			}
		}
		else {
			char *mes;

			mes = zalloc( strlen(ARG4.text) + 200 );
			if ( mes ) {
				wsprintf( mes, "iniWriteBinary()で利用されている配列%s[]は、宣言されないまま使われています。レジストリへの書き込みは行いません。", ARG4.text);
				destroy_splash_window();
				MessageBox(NULL, mes, "R-Script警告", MB_OK | MB_ICONEXCLAMATION);
				safefree( mes );
			}

			return 0;
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 文字列を数値に変換（0+文字列$ でも変換できる）
// toInt( 文字列$ )
unsigned int rfunc_toInt(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return atou( ARG1.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// コントロールを有効化する
// Enable( ID$ )
unsigned int rfunc_enable(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return (UINT)DisableControl( ARG1.text, TRUE );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// コントロールを無効化（グレイアウト）する
// Disable( ID$ )
unsigned int rfunc_disable(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return (UINT)DisableControl( ARG1.text, FALSE );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 指定されたIDが自動的にレジストリに書き込もうとする動作を停止する(指定後1回のみ有効)
// Stop( ID$ )
unsigned int rfunc_stop(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return (UINT)StopControl( ARG1.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 指定されたIDが自動的にレジストリに書き込もうとする動作を行うようにする(指定後1回のみ有効)
// Active( ID$ )
unsigned int rfunc_active(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return (UINT)ActiveControl( ARG1.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 指定されたIDのコントロールにフォーカスをあわせる
// SetFocus( ID$ )
unsigned int rfunc_setfocus(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return (UINT)SetFocusControl( ARG1.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// DLLの関数を呼び出す(戻り値は数値)
// CallDll( DLLファイル名$, 関数名$, 引数... )
unsigned int rfunc_CallDll(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args != NULL && args->type == UFCT_ARG_STRING && args->next != NULL && args->next->type == UFCT_ARG_STRING ) {
		HINSTANCE lib;
		RSC_CALLDLL_INT func;
		UINT rv;
		struct ARGS *p_args;

		lib = LoadDllLibrary( ARG1.text );
		if ( lib == NULL ) {
			*result = UFS_NOTFOUNDDLL;
			return ERRORVALUE;
		}
		func = (RSC_CALLDLL_INT)GetProcAddress( lib, ARG2.text );
		if ( func == NULL ) {
			*result = UFS_NOTFOUNDDLLFUNC;
			return ERRORVALUE;
		}

		// 配列変数の名前が書かれている部分は、その配列変数を表す構造体のポインタに差し替える
		{
			p_args = args->next->next;

			while ( p_args ) {
				if ( p_args->type == UFCT_ARG_INTS ) {
					p_args->v.pva = search_pointer_a( p_args->v.text );
				}
				else if ( p_args->type == UFCT_ARG_STRINGS ) {
					p_args->v.pvda = search_pointer_d_a( p_args->v.text );
				}
				p_args = p_args->next;
			} 
		}
		rv = func( hWnd, args->next->next );
		return rv;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 実行ファイルを呼び出す
// CallExe( コマンドライン$ )		- 同期実行（終了まで待つ。戻り値はErrorLevel）
unsigned int rfunc_CallExe(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		STARTUPINFO sinfo;
		PROCESS_INFORMATION pinfo;
		UINT		rv;
		HANDLE		hph;

		ZeroMemory( &sinfo, sizeof( STARTUPINFO ) );
		ZeroMemory( &pinfo, sizeof( PROCESS_INFORMATION ) );
		sinfo.cb = sizeof( STARTUPINFO );
		sinfo.dwFlags = STARTF_USESHOWWINDOW;
		sinfo.wShowWindow = SW_SHOWNORMAL;
		
		if ( CreateProcess( NULL, ARG1.text, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &sinfo, &pinfo ) ) {
			WaitForInputIdle( pinfo.hProcess, INFINITE );
			WaitForSingleObject( pinfo.hProcess, INFINITE );
			if ( isNT ) hph = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, pinfo.dwProcessId );
			GetExitCodeProcess(pinfo.hProcess, (LPDWORD)&rv);
			if ( isNT ) CloseHandle(hph);

			CloseHandle(pinfo.hProcess);
			return rv;
		}
		else {
			*result = UFC_CANTRUNEXE;
            return ERRORVALUE;
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 実行ファイルを呼び出す
// CallExeAsync( コマンドライン$ )	- 非同期実行（終了まで待たない。戻り値は0）
unsigned int rfunc_CallExeAsync(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		STARTUPINFO sinfo;
		PROCESS_INFORMATION pinfo;

		ZeroMemory( &sinfo, sizeof( STARTUPINFO ) );
		ZeroMemory( &pinfo, sizeof( PROCESS_INFORMATION ) );
		sinfo.cb = sizeof( STARTUPINFO );
		sinfo.dwFlags = STARTF_USESHOWWINDOW;
		sinfo.wShowWindow = SW_SHOWNORMAL;
		
		if ( CreateProcess( NULL, ARG1.text, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &sinfo, &pinfo ) ) {
			CloseHandle(pinfo.hProcess);
			return 0;
		}
		else {
			*result = UFC_CANTRUNEXE;
            return ERRORVALUE;
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// コマンドラインを呼び出す(戻り値は0)
// CallCmd( コマンドライン$ )		- 同期実行（終了まで待つ）
unsigned int rfunc_CallCmd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		STARTUPINFO sinfo;
		PROCESS_INFORMATION pinfo;

		ZeroMemory( &sinfo, sizeof( STARTUPINFO ) );
		ZeroMemory( &pinfo, sizeof( PROCESS_INFORMATION ) );
		sinfo.cb = sizeof( STARTUPINFO );
		sinfo.dwFlags = STARTF_USESHOWWINDOW;
		sinfo.wShowWindow = SW_SHOWNORMAL;
		
		if ( !CreateProcess( NULL, ARG1.text, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &sinfo, &pinfo ) ) {
			char *cl = (char *)zalloc(lstrlen(ARG1.text) + 30);

			if ( cl ) {
				lstrcpy(cl, isNT?"CMD.EXE /C ":"COMMAND.COM /C ");
				lstrcat(cl, ARG1.text);
				if ( !CreateProcess( NULL, cl, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &sinfo, &pinfo ) ) {
					lstrcpy(cl, isNT?"CMD.EXE /C START ":"COMMAND.COM /C START ");
					lstrcat(cl, ARG1.text);
					if ( !CreateProcess( NULL, cl, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &sinfo, &pinfo ) ) {
						safefree( cl );
						return ERRORVALUE;
					}
				}

				safefree( cl );
			}
			else {
                return ERRORVALUE;
			}
		}

		// コマンドから帰ってくるまでウェイト
		WaitForInputIdle( pinfo.hProcess, INFINITE );
		WaitForSingleObject( pinfo.hProcess, INFINITE );
		CloseHandle(pinfo.hProcess);

		return 0;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// コマンドラインを呼び出す(戻り値は0)
// CallCmdAsync( コマンドライン$ )	- 非同期実行（終了まで待たない）
unsigned int rfunc_CallCmdAsync(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		STARTUPINFO sinfo;
		PROCESS_INFORMATION pinfo;

		ZeroMemory( &sinfo, sizeof( STARTUPINFO ) );
		ZeroMemory( &pinfo, sizeof( PROCESS_INFORMATION ) );
		sinfo.cb = sizeof( STARTUPINFO );
		sinfo.dwFlags = STARTF_USESHOWWINDOW;
		sinfo.wShowWindow = SW_SHOWNORMAL;
		
		if ( !CreateProcess( NULL, ARG1.text, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &sinfo, &pinfo ) ) {
			char *cl = (char *)zalloc(lstrlen(ARG1.text) + 30);

			if ( cl ) {
				lstrcpy(cl, isNT?"CMD.EXE /C ":"COMMAND.COM /C ");
				lstrcat(cl, ARG1.text);
				if ( !CreateProcess( NULL, cl, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &sinfo, &pinfo ) ) {
					lstrcpy(cl, isNT?"CMD.EXE /C START ":"COMMAND.COM /C START ");
					lstrcat(cl, ARG1.text);
					if ( !CreateProcess( NULL, cl, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &sinfo, &pinfo ) ) {
						safefree( cl );
						return ERRORVALUE;
					}
				}

				safefree( cl );
			}
			else {
                return ERRORVALUE;
			}
		}

		CloseHandle(pinfo.hProcess);

		return 0;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// キーの中のサブキー数を取得
// RegNumKey( Key$ )
unsigned int rfunc_RegNumKey(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		if ( strchr(ARG1.text,'\\') == 0 ) {
			HKEY hKey;
			DWORD subkeys = 0;

			hKey = tRegHiveKey( ARG1.text );
			RegQueryInfoKey( hKey, NULL, NULL, NULL, &subkeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
			return subkeys;
		}
		else {
			HKEY hKey;
			DWORD subkeys = 0;

			if ( NULL != (hKey = tRegOpenKey( NULL, ARG1.text, TREG_OPEN_READONLY )) ) {
                RegQueryInfoKey( hKey, NULL, NULL, NULL, &subkeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
				RegCloseKey( hKey );
			}
			return subkeys;
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// キーの中の値の数を取得
// RegNumValue( Key$ )
unsigned int rfunc_RegNumValue(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		if ( strchr(ARG1.text,'\\') == 0 ) {
			HKEY hKey;
			DWORD values = 0;

			hKey = tRegHiveKey( ARG1.text );
			RegQueryInfoKey( hKey, NULL, NULL, NULL, NULL, NULL, NULL, &values, NULL, NULL, NULL, NULL);
			return values;
		}
		else {
			HKEY hKey;
			DWORD values = 0;

			if ( NULL != (hKey = tRegOpenKey( NULL, ARG1.text, TREG_OPEN_READONLY )) ) {
                RegQueryInfoKey( hKey, NULL, NULL, NULL, NULL, NULL, NULL, &values, NULL, NULL, NULL, NULL);
				RegCloseKey( hKey );
			}
			return values;
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// レジストリエントリをバイナリで読み出す
// RegReadBinary( Key$, Entry$, int[] )
unsigned int rfunc_RegReadBinary(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ssa") ) {
		HKEY hKey;
		unsigned i, len, retval = 0;

		if (NULL != (hKey = tRegOpenKey(NULL, ARG1.text, TREG_OPEN_READONLY)) ) {
			if (0 < (len = tRegValueExist( hKey, ARG2.text ))) {
				if ( 0 == resize_variables( ARG3.text, len ) ) {
					char *value = mtRegReadString(hKey, ARG2.text, NULL);
					if ( value ) {
						retval = 1;
						for(i=0 ; i<len ; i++) {
							setVariable_a(ARG3.text, i, (unsigned int)value[i]);
						}
						safefree( value );
					}
				}
			}

			RegCloseKey( hKey );
			return retval;
		}
		else
			return 0;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// レジストリエントリをバイナリで書き出す
// RegWriteBinary( Key$, Entry$, int[], type )
unsigned int rfunc_RegWriteBinary(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ssai") ) {
		HKEY hKey;
		unsigned retval = 0;
		unsigned i, len, u;
		LONG lasterr;

		if (NULL != (hKey = tRegOpenKey(NULL, ARG1.text, TREG_OPEN_CREATE)) ) {
			len = sizeof_variables( ARG3.text );
			if ( len != NO_VALUE ) {
				unsigned char *value = (unsigned char *)calloc( len, 1 );
				if ( value ) {
					for(i=0 ; i<len ; i++) {
						getVariable_a(ARG3.text, i, &u);
						value[i] = (unsigned char)u;
					}

					if (ERROR_SUCCESS == (lasterr = RegSetValueEx( hKey, ARG2.text, 0, ARG4.integer, value, len ))) {
						retval = 1;
					}
					else if (rnsf7RegRead("regErrorMessage", 0)) {
						dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegWriteBinary)", "レジストリキー'", ARG1.text, "'のエントリ'", ARG2.text,
								 "'へ書き込もうとしてエラーになりました。\nAPIが報告した原因：",
								 getLastErrorString(lasterr));
					}

					safefree( value );
				}
			}
			else {
				char *mes;

				mes = zalloc( strlen(ARG3.text) + 200 );
				if ( mes ) {
					wsprintf( mes, "RegWriteBinary()で利用されている配列%s[]は、宣言されないまま使われています。レジストリへの書き込みは行いません。", ARG3.text);
					destroy_splash_window();
					MessageBox(NULL, mes, "R-Script警告", MB_OK | MB_ICONEXCLAMATION);
					safefree( mes );
				}
			}

			RegCloseKey( hKey );
			return retval;
		}
		else {
			LONG lasterr = tRegGetLastError();
			if (lasterr != ERROR_SUCCESS && rnsf7RegRead("regErrorMessage", 0)) {
				dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegWriteBinary)", "レジストリキー'", ARG1.text,
								 "'を書き込みアクセスで開こうとしてエラーになりました。\nAPIが報告した原因：",
								 getLastErrorString(lasterr), NULL, NULL);
			}
			return 0; // レジストリキーを開けない
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 指定されたIDが存在するかどうか
// isID( ID$ )
unsigned int rfunc_isID(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		UINT i;

		for(i=0 ; i<nctrls ; i++) {
			if ( rctrls[i].id && _stricmp(rctrls[i].id, ARG1.text) == 0 ) {
				return 1;
			}
		}
		return 0;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 指定されたIDのコントロールが有効か
// isIDEnabled( ID$ )
unsigned int rfunc_isIDEnabled(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		UINT i;

		for(i=0 ; i<nctrls ; i++) {
			if ( rctrls[i].id && _stricmp(rctrls[i].id, ARG1.text) == 0 ) {
				return (IsWindowEnabled( rctrls[i].hCtrl )!=0)?1:0;
			}
		}
		return ERRORVALUE;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// ダイアログ上に存在するコントロールの数を返す
// numID()
unsigned int rfunc_numID(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		return nctrls;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// ダイアログを開いてから、または、[適用]を押してから、変更されたか
// isChanged( id$ )
unsigned int rfunc_isChanged(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return isChanged( ARG1.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 編集ダイアログのタイトルを設定する
// SetDialogTitle( 文字列$ )
unsigned int rfunc_SetDialogTitle(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return ( 0 != SetWindowText(hWnd, ARG1.text) );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// いじくるつくーるのタイトルを設定する
// SetWindowTitle( 文字列$ )
unsigned int rfunc_SetWindowTitle(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return ( 0 != SetWindowText(GetParent(hWnd), ARG1.text) );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 文字列1の中から文字列2を探し、何文字目(0-)で見つかったかを返す(見つからなければエラー(0xffffffff)を返す
// strstr( 文字列1$, 文字列2 )
unsigned int rfunc_strstr(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		char *p;

		p = sjisstr( ARG1.text, ARG2.text );
		if ( p )
			return (int)(p - ARG1.text);
		else
			return ERRORVALUE;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 文字列1の中から文字列2を探し、何文字目(0-)で見つかったかを返す(見つからなければエラー(0xffffffff)を返す, 英大小文字を区別しない
// strstri( 文字列1$, 文字列2 )
unsigned int rfunc_strstri(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		char *p;
		UINT r = ERRORVALUE;

		p = sjisstri(ARG1.text, ARG2.text);
		if ( p ) {
			r = (UINT)(p - ARG1.text);
		}
		return r;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// ファイルをコピーする
// CopyFile( src$, dst$, FailIfExists )
unsigned int rfunc_CopyFile(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ssi") ) {
		return (CopyFile( ARG1.text, ARG2.text, ARG3.integer ) != 0)?1:0;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// ファイル群をコピーする
// CopyFiles( src$, dst$ )
unsigned int rfunc_CopyFiles(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		SHFILEOPSTRUCT fos;
		char *s, *d;
		int  rv = 0;

		s = calloc( lstrlen(ARG1.text)+2, 1 );
		if ( s ) {
			lstrcpy(s, ARG1.text);
			d = calloc( lstrlen(ARG2.text)+2, 1 );
			if ( d ) {
				lstrcpy(d, ARG2.text);
				fos.hwnd = hWnd;
				fos.wFunc = FO_COPY;
				fos.pFrom = s;
				fos.pTo = d;
				fos.fFlags = FOF_NOCONFIRMMKDIR;
				fos.fAnyOperationsAborted = FALSE;
				fos.hNameMappings = 0;
				fos.lpszProgressTitle = "ファイルのコピー";
				rv = (SHFileOperation( &fos ) == 0)?1:0;
				safefree( d );
			}
			safefree( s );
		}
		return rv;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// ファイルを移動する
// MoveFile( src$, dst$ )
unsigned int rfunc_MoveFile(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		return (MoveFile( ARG1.text, ARG2.text ) != 0)?1:0;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// ファイル群を移動する
// MoveFiles( src$, dst$ )
unsigned int rfunc_MoveFiles(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		SHFILEOPSTRUCT fos;
		char *s, *d;
		int  rv = 0;

		s = calloc( lstrlen(ARG1.text)+2, 1 );
		if ( s ) {
			lstrcpy(s, ARG1.text);
			d = calloc( lstrlen(ARG2.text)+2, 1 );
			if ( d ) {
				lstrcpy(d, ARG2.text);
				fos.hwnd = hWnd;
				fos.wFunc = FO_MOVE;
				fos.pFrom = s;
				fos.pTo = d;
				fos.fFlags = FOF_NOCONFIRMMKDIR;
				fos.fAnyOperationsAborted = FALSE;
				fos.hNameMappings = 0;
				fos.lpszProgressTitle = "ファイルの移動";
				rv = (SHFileOperation( &fos ) == 0)?1:0;
				safefree( d );
			}
			safefree( s );
		}
		return rv;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// ファイルを削除する
// DeleteFile( file$ )
unsigned int rfunc_DeleteFile(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return (DeleteFile( ARG1.text ) != 0)?1:0;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// ファイル群を削除する
// DeleteFiles( files$ )
unsigned int rfunc_DeleteFiles(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		SHFILEOPSTRUCT fos;
		char *p;
		int  rv = 0;

		// \0\0で終わっているバッファを作るため、文字列の長さ+2で初期化する
		p = calloc( lstrlen(ARG1.text)+2, 1 );
		if ( p ) {
			lstrcpy( p, ARG1.text );
			fos.hwnd = hWnd;
			fos.wFunc = FO_DELETE;
			fos.pFrom = p;
			fos.pTo = NULL;
			fos.fFlags = FOF_NOCONFIRMMKDIR | FOF_NOCONFIRMATION;
			fos.fAnyOperationsAborted = FALSE;
			fos.hNameMappings = 0;
			fos.lpszProgressTitle = "ファイルの削除";
			rv = (SHFileOperation( &fos ) == 0)?1:0;
            safefree( p );
		}
		return rv;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// フォルダを削除する
// deletedirectory( folder$ )
unsigned int rfunc_DeleteDirectory(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return (RemoveDirectory( ARG1.text ) != 0)?1:0;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// フォルダの中のファイル・フォルダを再帰的に削除する。書込禁止属性は解除する。使用中等で削除できない場合は無視して処理続行
// 指定フォルダそのものを削除するのではなく、指定フォルダの中身を空にする事に注意。
// EmptyDirectory( folder$ )
// EmptyDirectory( folder$, beforeDays ) … 指定した日数よりも前に作成されたものだったら削除(beforeDays=0で指定なしと同じ。1で1日前, 2で2日前, …)
unsigned int rfunc_EmptyDirectory(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return (emptyDir( ARG1.text, NULL ) != 0)?1:0;
	}
	else if ( args_typecheck(args, "si") ) {
		if (ARG2.integer == 0) {
			return (emptyDir( ARG1.text, NULL ) != 0)?1:0;
		}
		else {
			SYSTEMTIME st;
			FILETIME ft;
			UINT64 ui64;

			// 現在の日付時刻を得てFILETIME型に変換し、それをUINT64型で100ns単位時間へ再解釈。
			GetSystemTime(&st);
			SystemTimeToFileTime(&st, &ft);
			ui64 = (UINT64)ft.dwHighDateTime<<32 | (UINT64)ft.dwLowDateTime;

			// 100ns単位時間で、ARG2.integer 日前の時間を計算
			ui64 -= (UINT64)ARG2.integer * (UINT64)10000000 * (UINT64)60 * (UINT64)60 * (UINT64)24;

			// 再びFILETIME型へ戻す
			ft.dwHighDateTime = (DWORD)(ui64>>32);
			ft.dwLowDateTime = (DWORD)(ui64&0xffffffff);

			return (emptyDir( ARG1.text, &ft ) != 0)?1:0;
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// フォルダを作成する
// createdirectory( folder$ )
unsigned int rfunc_createdirectory(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return (CreateDirectory( ARG1.text, NULL ) != 0)?1:0;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// ショートカットを作成する
// createshortcut( file$, arg$, link$ [, iconfile$, iconno ] )
unsigned int rfunc_createshortcut(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sss") ) {
		return (UINT)MakeLink(ARG1.text, ARG2.text, ARG3.text);
	}
	else if ( args_typecheck(args, "ssssi") ) {
		return (UINT)MakeLinkIcon(ARG1.text, ARG2.text, ARG3.text, ARG4.text, ARG5.integer);
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// ファイルの存在を確認する
// fileexist( file$ )
unsigned int rfunc_fileexist(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return (UINT)tFileExist(ARG1.text);
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// ワイルドカードを用いて指定した名前に合致するファイル名を取得する
// SearchFiles( wildcard$, files$[] )
unsigned int rfunc_SearchFiles(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sr") ) {
		HANDLE hFind;
		WIN32_FIND_DATA520 wfd;
		UINT nfound;

		nfound = 0;
		if ( INVALID_HANDLE_VALUE != (hFind = FindFirstFile520(ARG1.text, &wfd)) ) {
			do {
				if ( !(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) {
					if ( 0 == resize_variables_d( ARG2.text, nfound+1 ) ) {
						setVariable_d_a( ARG2.text, nfound++, wfd.cFileName );
					}
					else { // エラー
						break;
					}
				}
			} while( FindNextFile520(hFind, &wfd) );
			FindClose( hFind );
		}
		return nfound;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// ワイルドカードを用いて指定した名前に合致するディレクトリ名を取得する
// SearchDirectorys( wildcard$, dirs$[] )
unsigned int rfunc_SearchDirectorys(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sr") ) {
		HANDLE hFind;
		WIN32_FIND_DATA520 wfd;
		UINT nfound;

		nfound = 0;
		if ( INVALID_HANDLE_VALUE != (hFind = FindFirstFile520(ARG1.text, &wfd)) ) {
			do {
				if ( wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
					if ( 0 == resize_variables_d( ARG2.text, nfound+1 ) ) {
						setVariable_d_a( ARG2.text, nfound++, wfd.cFileName );
					}
					else { // エラー
						break;
					}
				}
			} while( FindNextFile520(hFind, &wfd) );
			FindClose( hFind );
		}
		return nfound;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 現在の年(西暦)を取得
// GetCurrentYear()
unsigned int rfunc_GetCurrentYear(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		SYSTEMTIME st;

		GetLocalTime( &st );
		return (UINT)st.wYear;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 現在の月を取得
// GetCurrentMonth() [1月=1, ...]
unsigned int rfunc_GetCurrentMonth(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		SYSTEMTIME st;

		GetLocalTime( &st );
		return (UINT)st.wMonth;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 現在の日を取得
// GetCurrentDay()
unsigned int rfunc_GetCurrentDay(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		SYSTEMTIME st;

		GetLocalTime( &st );
		return (UINT)st.wDay;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 現在の年(西暦)を取得
// GetCurrentDayOfWeek() [日曜=0, ...]
unsigned int rfunc_GetCurrentDayOfWeek(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		SYSTEMTIME st;

		GetLocalTime( &st );
		return (UINT)st.wDayOfWeek;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 現在の時間を取得
// GetCurrentHour()
unsigned int rfunc_GetCurrentHour(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		SYSTEMTIME st;

		GetLocalTime( &st );
		return (UINT)st.wHour;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 現在の分を取得
// GetCurrentMinute()
unsigned int rfunc_GetCurrentMinute(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		SYSTEMTIME st;

		GetLocalTime( &st );
		return (UINT)st.wMinute;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 現在の秒を取得
// GetCurrentSecond()
unsigned int rfunc_GetCurrentSecond(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		SYSTEMTIME st;

		GetLocalTime( &st );
		return (UINT)st.wSecond;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 現在のミリ秒を取得
// GetCurrentMilliseconds()
unsigned int rfunc_GetCurrentMilliseconds(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		SYSTEMTIME st;

		GetLocalTime( &st );
		return (UINT)st.wMilliseconds;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 現在の時刻を設定
// SetCurrentTime()
unsigned int rfunc_SetCurrentTime(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "iiiiiii") ) {
		SYSTEMTIME st;

		st.wYear         = (WORD)ARG1.integer;
		st.wMonth        = (WORD)ARG2.integer;
		st.wDay          = (WORD)ARG3.integer;
		st.wHour         = (WORD)ARG4.integer;
		st.wMinute       = (WORD)ARG5.integer;
		st.wSecond       = (WORD)ARG6.integer;
		st.wMilliseconds = (WORD)ARG7.integer;
		return (SetLocalTime( &st ) != 0)?1:0;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}


// fwrite/fappend/fread() 利用時のテキスト／バイナリモード決定（デフォルト：テキスト(0)）
// FModeBinary( mode )
unsigned int rfunc_FModeBinary(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "i") ) {
		if ( ARG1.integer != 0 ) {
            fmode_bin = 1;
		}
		else {
			fmode_bin = 0;
		}
		return (unsigned)fmode_bin;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// fwrite/fappend/fread() 利用時のワイド文字／マルチバイト文字モード決定（デフォルト：マルチバイト文字(0)）
// なお、マルチバイト文字指定の場合は、暗黙のうちにバイナリモードとなる
// FModeWide( mode )
unsigned int rfunc_FModeWide(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "i") ) {
		if ( ARG1.integer != 0 ) {
            fmode_wide = 1; // 内部的にUTF-16(LE)←→Shift-JIS変換を行う（外部的にはUTF-16を使い、内部的にはShift-JISを使う）
		}
		else {
			fmode_wide = 0;
		}
		return (unsigned)fmode_wide;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// ファイルへの書き込み(上書き)
// fwrite( fname$, data$ )
// fwrite( fname$, lines$[] )
unsigned int rfunc_fwrite(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		FILE *fp;
		UINT rv = 0;

		if ( 0 == fopen_s(&fp, ARG1.text, (fmode_wide || fmode_bin) ? "wb" : "wt") ) {
			if ( fmode_wide == 1 ) {
				LPWSTR wstr = NULL;
                int    iWstrSize = 0;

				iWstrSize = MultiByteToWideChar(GetACP(), MB_PRECOMPOSED, ARG2.text, -1, wstr, 0);
				if ( iWstrSize > 0 ) {
					iWstrSize+=2;

					wstr = (LPWSTR)calloc(iWstrSize, sizeof(WCHAR));
					if ( wstr ) {
						iWstrSize = MultiByteToWideChar(GetACP(), MB_PRECOMPOSED, ARG2.text, -1, wstr, iWstrSize);
						if ( iWstrSize > 0 ) {
							// BOMの書き込み
							fputwc( 0xfeff, fp );
							// 本体の書き込み
							rv = (EOF != fputws( wstr, fp ));
						}
						safefree( wstr );
					}
				}
			}
			else {
				rv = (EOF != fputs( ARG2.text, fp ));
			}
			fclose( fp );
		}
		return rv;
	}
	else if ( args_typecheck(args, "sr") ) {
		FILE *fp;
		UINT rv = 0, len, i;

		len = sizeof_variables_d( ARG2.text );
		if ( len == NO_VALUE ) {
			char *mes;

			mes = zalloc( strlen(ARG4.text) + 200 );
			if ( mes ) {
				wsprintf( mes, "FWrite()で利用されている配列%s[]は、宣言されないまま使われています。ファイルへの書き込みは行いません。", ARG4.text);
				destroy_splash_window();
				MessageBox(NULL, mes, "R-Script警告", MB_OK | MB_ICONEXCLAMATION);
				safefree( mes );
			}
			return 0;
		}
		if ( 0 == fopen_s(&fp, ARG1.text, (fmode_wide || fmode_bin) ? "wb" : "wt") ) {
			if ( fmode_wide == 1 ) {
				// BOMの書き込み
				fputwc( 0xfeff, fp );
			}

			for(i=0 ; i<len ; i++) {
				char *v = getVariable_d_a(ARG2.text, i);

				if ( v[0] ) {
					if ( fmode_wide == 1 ) {
						LPWSTR wstr = NULL;
						int    iWstrSize = 0;

						iWstrSize = MultiByteToWideChar(GetACP(), MB_PRECOMPOSED, v, -1, wstr, 0);
						if ( iWstrSize > 0 ) {
							iWstrSize+=2;

							wstr = (LPWSTR)calloc(iWstrSize, sizeof(WCHAR));
							if ( wstr ) {
								iWstrSize = MultiByteToWideChar(GetACP(), MB_PRECOMPOSED, v, -1, wstr, iWstrSize);
								if ( iWstrSize > 0 ) {
									rv = (EOF != fputws( wstr, fp ));
								}
								safefree( wstr );
							}
						}
					}
					else {
						rv = (EOF != fputs( v, fp ));
					}

					if ( rv == 0 ) {
						break;
					}
				}

				if ( fmode_wide == 1 ) {
					rv = (EOF != fputws( fmode_bin ? L"\r\n" : L"\n", fp ));
				}
				else {
					rv = (EOF != fputs( fmode_bin ? "\r\n" : "\n", fp ));
				}

				if ( rv == 0 ) {
					break;
				}
			}
			fclose( fp );
		}
		return rv;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// ファイルへの書き込み(追記)
// fappend( fname$, data$ )
// fappend( fname$, lines$[] )
unsigned int rfunc_fappend(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		FILE *fp;
		UINT rv = 0;
		DWORD fesize = 0;

		fesize = getFileSize( ARG1.text );
		if ( 0 == fopen_s(&fp, ARG1.text, (fmode_wide || fmode_bin) ? "ab" : "at") ) {
			if ( fmode_wide == 1 ) {
				LPWSTR wstr = NULL;
                int    iWstrSize = 0;

				iWstrSize = MultiByteToWideChar(GetACP(), MB_PRECOMPOSED, ARG2.text, -1, wstr, 0);
				if ( iWstrSize > 0 ) {
					iWstrSize+=2;

					wstr = (LPWSTR)calloc(iWstrSize, sizeof(WCHAR));
					if ( wstr ) {
						iWstrSize = MultiByteToWideChar(GetACP(), MB_PRECOMPOSED, ARG2.text, -1, wstr, iWstrSize);
						if ( iWstrSize > 0 ) {
							// ファイルの先頭ならば、BOMの書き込み
							if ( fesize == 0 || fesize == -1 ) {
								fputwc( 0xfeff, fp );
							}
							// 本体の書き込み
							rv = (EOF != fputws( wstr, fp ));
						}
						safefree( wstr );
					}
				}
			}
			else {
				rv = (EOF != fputs( ARG2.text, fp ));
			}
			fclose( fp );
		}
		return rv;
	}
	else if ( args_typecheck(args, "sr") ) {
		FILE *fp;
		UINT rv = 0, len, i;
		DWORD fesize = 0;

		len = sizeof_variables_d( ARG2.text );
		if ( len == NO_VALUE ) {
			char *mes;

			mes = zalloc( strlen(ARG4.text) + 200 );
			if ( mes ) {
				wsprintf( mes, "FAppend()で利用されている配列%s[]は、宣言されないまま使われています。ファイルへの書き込みは行いません。", ARG4.text);
				destroy_splash_window();
				MessageBox(NULL, mes, "R-Script警告", MB_OK | MB_ICONEXCLAMATION);
				safefree( mes );
			}
			return 0;
		}

		fesize = getFileSize( ARG1.text );
		if ( 0 == fopen_s(&fp, ARG1.text, (fmode_wide || fmode_bin) ? "ab" : "at") ) {
			if ( fmode_wide == 1 && (fesize == 0 || fesize == -1) ) {
				// BOMの書き込み
				fputwc( 0xfeff, fp );
			}

			for(i=0 ; i<len ; i++) {
				char *v = getVariable_d_a(ARG2.text, i);

				if ( v[0] ) {
					if ( fmode_wide == 1 ) {
						LPWSTR wstr = NULL;
						int    iWstrSize = 0;

						iWstrSize = MultiByteToWideChar(GetACP(), MB_PRECOMPOSED, v, -1, wstr, 0);
						if ( iWstrSize > 0 ) {
							iWstrSize+=2;

							wstr = (LPWSTR)calloc(iWstrSize, sizeof(WCHAR));
							if ( wstr ) {
								iWstrSize = MultiByteToWideChar(GetACP(), MB_PRECOMPOSED, v, -1, wstr, iWstrSize);
								if ( iWstrSize > 0 ) {
									rv = (EOF != fputws( wstr, fp ));
								}
								safefree( wstr );
							}
						}
					}
					else {
						rv = (EOF != fputs( v, fp ));
					}
				}

				if ( fmode_wide == 1 ) {
					rv = (EOF != fputws( fmode_bin ? L"\r\n" : L"\n", fp ));
				}
				else {
					rv = (EOF != fputs( fmode_bin ? "\r\n" : "\n", fp ));
				}

				if ( rv == 0 ) {
					break;
				}
			}
			fclose( fp );
		}
		return rv;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// ファイルをテキストモードで開き、各行を文字列型配列に入れる
// fread( fname$, lines$[] )
unsigned int rfunc_fread(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sr") ) {
		FILE *fp;
		UINT64 qwSize = 0;
		UINT fsize = 0, i, rv = 0;
		char *buf, *p;

		qwSize = getFileSizeQ(ARG1.text);
		if ( qwSize >= 2u*1024u*1024u*1024u-16u ) {
			// エラー(-1==0xffffffffffffffff)またはファイルサイズが2GB以上の場合は取り扱わない
            return 0;
		}
		fsize = (UINT)qwSize;

		if ( 0 == fopen_s(&fp, ARG1.text, (fmode_wide || fmode_bin) ? "rb" : "rt") ) {
			buf = zalloc(fsize+2);
			if ( buf ) {
				i = 0;
				while( !feof(fp) ) {
					buf[0] = 0;
					if ( fmode_wide == 1 ) {
						LPWSTR wbuf = (LPWSTR)zalloc(fsize+2);
						fgetws( wbuf, fsize, fp );
						WideCharToMultiByte(GetACP(), 0, (wbuf[0] == 0xfeff)?wbuf+1:wbuf, -1, buf, fsize+2, NULL, NULL);
					}
					else {
						fgets( buf, fsize, fp );
					}

					if ( 0 == resize_variables_d( ARG2.text, i+1 ) ) {
						p = strchr(buf, '\n'); // 改行記号は取り除く
						if ( p ) {
							*p = 0;
						}
						p = strchr(buf, '\r'); // 改行記号は取り除く
						if ( p ) {
							*p = 0;
						}
						setVariable_d_a( ARG2.text, i, buf );
						rv = 1;
						i++;
					}
					else { // エラー
						rv = 0;
					}
				}
				safefree( buf );
			}
			else {
                rv = 0;
			}
			fclose( fp );
		}
		return rv;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// ファイルサイズを返す
// getfsize( fname$ )
unsigned int rfunc_getfsize(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		UINT64 qwSize = 0;

		qwSize = getFileSizeQ(ARG1.text);
		if ( qwSize >= 2u*1024u*1024u*1024u-16u ) {
			// エラー(-1==0xffffffffffffffff)またはファイルサイズが2GB以上の場合は取り扱わない
            return ERRORVALUE;
		}

		return (UINT)qwSize;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// バイナリモードでファイルを読み込む
// freadbinary( fname$, ints[] )
unsigned int rfunc_freadbinary(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sa") ) {
		FILE *fp;
		UINT fsize = 0, rv = 0, i;
		unsigned char *buf;
		UINT64 qwSize = 0;

		qwSize = getFileSizeQ(ARG1.text);
		if ( qwSize >= 2u*1024u*1024u*1024u/4u-16u ) {
			// エラー(-1==0xffffffffffffffff)またはファイルサイズが2GB以上の場合は取り扱わない
            return 0;
		}
		fsize = (UINT)qwSize;

		if ( 0 == fopen_s(&fp, ARG1.text, "rb") ) {
			buf = (unsigned char *)zalloc( fsize+1 );
			if ( buf ) {
				rv = (UINT)fread( buf, fsize, 1, fp );
				if ( 0 == resize_variables( ARG2.text, fsize ) ) {
					for(i=0 ; i<fsize ; i++) {
						setVariable_a(ARG2.text, i, (unsigned int)buf[i]);
					}
                    rv = 1;							
				}
				safefree( buf );
			}
			fclose( fp );
		}
		return rv;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// バイナリモードでファイルへ書き込む
// fwritebinary( fname$, ints[] )
unsigned int rfunc_fwritebinary(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sa") ) {
		FILE *fp;
		UINT fsize = 0, rv = 0, i, v;
		unsigned char *buf;

		if ( 0 == fopen_s(&fp, ARG1.text, "wb") ) {
			fsize = sizeof_variables(ARG2.text); // ファイルサイズ
			if ( fsize != ERRORVALUE ) {
				buf = calloc( fsize, 1 );
				if ( buf ) {
					for(i=0 ; i<fsize ; i++) {
						getVariable_a(ARG2.text, i, &v);
						buf[i] = (unsigned char)v;
					}

					rv = (UINT)fwrite( buf, fsize, 1, fp );
					safefree( buf );
				}
			}
			else {
				char *mes;

				mes = zalloc( strlen(ARG4.text) + 200 );
				if ( mes ) {
					wsprintf( mes, "FWriteBinary()で利用されている配列%s[]は、宣言されないまま使われています。ファイルへの書き込みは行いません。", ARG4.text);
					destroy_splash_window();
					MessageBox(NULL, mes, "R-Script警告", MB_OK | MB_ICONEXCLAMATION);
					safefree( mes );
				}
			}
			fclose( fp );
		}
		return rv;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// バイナリモードでファイルへ書き込む
// fappendbinary( fname$, ints[] )
unsigned int rfunc_fappendbinary(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sa") ) {
		FILE *fp;
		UINT fsize = 0, rv = 0, i, v;
		unsigned char *buf;

		if ( 0 == fopen_s(&fp, ARG1.text, "ab") ) {
			fsize = sizeof_variables(ARG2.text); // ファイルサイズ
			if ( fsize != ERRORVALUE ) {
				buf = calloc( fsize, 1 );
				if ( buf ) {
					for(i=0 ; i<fsize ; i++) {
						getVariable_a(ARG2.text, i, &v);
						buf[i] = (unsigned char)v;
					}

					rv = (UINT)fwrite( buf, fsize, 1, fp );
					safefree( buf );
				}
			}
			else {
				char *mes;

				mes = zalloc( strlen(ARG4.text) + 200 );
				if ( mes ) {
					wsprintf( mes, "FWriteBinary()で利用されている配列%s[]は、宣言されないまま使われています。ファイルへの書き込みは行いません。", ARG4.text);
					destroy_splash_window();
					MessageBox(NULL, mes, "R-Script警告", MB_OK | MB_ICONEXCLAMATION);
					safefree( mes );
				}
			}
			fclose( fp );
		}
		return rv;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 複数行エントリから文字列型配列へ読み込む
// RegReadMultiString( Key$, entry$, var$[] )
unsigned int rfunc_RegReadMultiString(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ssr") ) {
		HKEY hKey;
		char *buf;
		DWORD n, i, j;
		DWORD bufsize;

		if ( NULL != (hKey = tRegOpenKey(NULL, ARG1.text, TREG_OPEN_READONLY)) ) {
            buf = mtRegReadMultiStringDirect(hKey, ARG2.text, &bufsize);
			RegCloseKey( hKey );
			if ( buf ) {
				n = numMultiString( buf, bufsize );
				resize_variables_d(ARG3.text, n);
				for(i=j=0 ; i<n ; i++) { 
					setVariable_d_a(ARG3.text, i, &buf[j]);
					while ( buf[j] ) { // 次の\0までスキップ
						j++;
					}
					j++;
				}
				safefree( buf );
				return 1;
			}
		}
		return 0;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 文字列型配列から複数行エントリへ書き込む
// RegWriteMultiString( Key$, entry$, var$[] )
unsigned int rfunc_RegWriteMultiString(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ssr") ) {
		HKEY hKey;
		char *buf, *p;
		DWORD n, i, byte, j;
		int rv = 0;

		if ( NULL != (hKey = tRegOpenKey(NULL, ARG1.text, TREG_OPEN_CREATE)) ) {
			// 文字列型配列変数の各配列を調べ、複数行文字列に何バイト必要かを調べる
			n = sizeof_variables_d( ARG3.text );
			for(i=byte=0 ; i<n ; i++) {
				p = getVariable_d_a(ARG3.text, i);
				if ( p == NULL ) {
					char *mes = zalloc( strlen(ARG3.text) + 200 );
					if ( mes ) {
						RegCloseKey( hKey );
						wsprintf( mes, "RegReadMultiString()で利用されている配列%s[]は、宣言されないまま使われています。ファイルへの書き込みは行いません。", ARG3.text);
						destroy_splash_window();
						MessageBox(NULL, mes, "R-Script警告", MB_OK | MB_ICONEXCLAMATION);
						safefree( mes );
						return 0;
					}
				}

				byte += (lstrlen( p ) + 1);
			}
			byte++;

			buf = calloc( byte, 1 );
			if ( buf ) {
				for(i=j=0 ; i<n ; i++) {
					p = getVariable_d_a(ARG3.text, i);
					lstrcpy(&buf[j], p);
					j += (lstrlen( p ) + 1);
				}

				rv = tRegWriteMultiStringDirect(hKey, ARG2.text, buf, byte);
				if (!rv) {
					LONG lasterr = tRegGetLastError();
					if (lasterr != ERROR_SUCCESS && rnsf7RegRead("regErrorMessage", 0)) {
						dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegWriteMultiString)", "レジストリキー'", ARG1.text, "'のエントリ'", ARG2.text,
										 "'へ書き込みを行おうとしてエラーになりました。\nAPIが報告した原因：",
										 getLastErrorString(lasterr));
					}
				}
				RegCloseKey( hKey );

				safefree( buf );
				return rv;
			}
			RegCloseKey( hKey );
		}
		else {
			LONG lasterr = tRegGetLastError();
			if (lasterr != ERROR_SUCCESS && rnsf7RegRead("regErrorMessage", 0)) {
				dispErrorMessage(hWnd, MB_OK | MB_ICONSTOP, "レジストリへの書き込み中エラー(RegWriteMultiString)", "レジストリキー'", ARG1.text,
								 "'を書き込みアクセスで開こうとしてエラーになりました。\nAPIが報告した原因：",
								 getLastErrorString(lasterr), NULL, NULL);
			}
		}
		return rv;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// iniファイルからセクションを丸ごと読み込む
// iniReadSection( inifile$, section$, var$[] )
unsigned int rfunc_iniReadSection(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ssr") ) {
		char *buf;
		DWORD n, i, j;

		buf = mtiniReadSection(ARG1.text, ARG2.text);
		if ( buf ) {
			n = numMultiString( buf, 0 );
			resize_variables_d(ARG3.text, n);
			for(i=j=0 ; i<n ; i++) { 
				setVariable_d_a(ARG3.text, i, &buf[j]);
				while ( buf[j] ) { // 次の\0までスキップ
					j++;
				}
				j++;
			}
			safefree( buf );
			return 1;
		}
		return 0;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// iniファイルへセクションを丸ごと書き込む
// iniWriteSection( inifile$, section$, var$[] )
unsigned int rfunc_iniWriteSection(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ssr") ) {
		char *buf, *p;
		DWORD n, i, byte, j;
		BOOL  rv = 0;

		// 文字列型配列変数の各配列を調べ、複数行文字列に何バイト必要かを調べる
		n = sizeof_variables_d( ARG3.text );
		for(i=byte=0 ; i<n ; i++) {
			p = getVariable_d_a(ARG3.text, i);
			if ( p == NULL ) {
				char *mes = zalloc( strlen(ARG3.text) + 200 );
				if ( mes ) {
					wsprintf( mes, "iniWriteSection()で利用されている配列%s[]は、宣言されないまま使われています。ファイルへの書き込みは行いません。", ARG3.text);
					destroy_splash_window();
					MessageBox(NULL, mes, "R-Script警告", MB_OK | MB_ICONEXCLAMATION);
					safefree( mes );
					return 0;
				}
			}

			byte += (lstrlen( p ) + 1);
		}
		byte++;

		buf = calloc( byte, 1 );
		if ( buf ) {
			for(i=j=0 ; i<n ; i++) {
				p = getVariable_d_a(ARG3.text, i);
				lstrcpy(&buf[j], p);
				j += (lstrlen( p ) + 1);
			}

			rv = tiniWriteSection(ARG1.text, ARG2.text, buf);
			safefree( buf );
		}
		return rv;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// コマンドラインから指定されたパラメータの数を返却
// GetIParamNum()
unsigned int rfunc_GetIParamNum(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		// 純粋に、指定されたパラメタの数(インタプリタ名やRSCファイルも、それぞれ1つと数える)を返す
		return __argc;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 配列へ要素を追加する
// ArrayAdd(name[], expr, ...)
unsigned int rfunc_ArrayAdd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	const struct ARGS *p = args;	// 引数ポインタ
	unsigned int numint = 0;		// 追加要素数
	unsigned int orgsize = 0;		// オリジナルの配列要素数（未宣言の配列は0）
	unsigned int rv = 0, i = 0;		// 戻り値保存用とカウンタ用

	if ( p->type == UFCT_ARG_INTS && p->next ) {
		numint = 0;
		// 引数の型を確認しながら、追加要素数をカウント
		for( p = args->next ; p ; p = p->next ) {
			if ( p->type == UFCT_ARG_INT ) {
				numint++;
			}
			else if ( p->type == UFCT_ARG_INTS ) {
				unsigned tmpn = sizeof_variables( p->v.text );
				if ( tmpn == NO_VALUE ) {
					return 0;	// エラー：未宣言の配列
				}
                numint += tmpn;
			}
			else {
				*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
				return ERRORVALUE;
			}
		}

		// 配列をリサイズ（ただし、元から配列が存在しない場合は新規作成）
		orgsize = sizeof_variables( ARG1.text );
		if ( orgsize == NO_VALUE ) {
			orgsize = 0;
		}
		rv = resize_variables( ARG1.text, orgsize + numint );

		if ( rv == 1 ) {
			return 0;	// エラー：メモリ不足
		}

		// 値の代入
		i = orgsize;
		for( p = args->next ; p ; p = p->next ) {
			if ( p->type == UFCT_ARG_INT ) {
				setVariable_a(ARG1.text, i, p->v.integer);
				++i;
			}
			else if ( p->type == UFCT_ARG_INTS ) {
				unsigned n = sizeof_variables( p->v.text );
				unsigned j, t;
				for( j=0 ; j<n ; ++j ) {
					getVariable_a(p->v.text,  j, &t);
					setVariable_a(ARG1.text, i+j, t);
				}
				i += n;
			}
		}
		return 1;
	}
	else if ( p->type == UFCT_ARG_STRINGS && p->next && p->next->type == UFCT_ARG_STRING ) {
		numint = 0;
		// 引数の型を確認しながら、追加要素数をカウント
		for( p = args->next ; p ; p = p->next ) {
			if ( p->type == UFCT_ARG_STRING ) {
				numint++;
			}
			else if ( p->type == UFCT_ARG_STRINGS ) {
				unsigned tmpn = sizeof_variables_d( p->v.text );
				if ( tmpn == NO_VALUE ) {
					return 0;	// エラー：未宣言の配列
				}
                numint += tmpn;
			}
			else {
				*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
				return ERRORVALUE;
			}
		}

		// 配列をリサイズ（ただし、元から配列が存在しない場合は新規作成）
		orgsize = sizeof_variables_d( ARG1.text );
		if ( orgsize == NO_VALUE ) {
			orgsize = 0;
		}
		rv = resize_variables_d( ARG1.text, orgsize + numint );

		if ( rv == 1 ) {
			return 0;	// エラー：メモリ不足
		}

		// 値の代入
		i = orgsize;
		for( p = args->next ; p ; p = p->next ) {
			if ( p->type == UFCT_ARG_STRING ) {
				setVariable_d_a(ARG1.text, i, p->v.text);
				++i;
			}
			else /*if ( p->type == UFCT_ARG_STRINGS )*/ {
				unsigned n = sizeof_variables_d( p->v.text );
				unsigned j;
				char *t;
				for( j=0 ; j<n ; ++j ) {
					t = getVariable_d_a(p->v.text, j);
					setVariable_d_a(ARG1.text, i+j, t);
				}
				i += n;
			}
		}
		return 1;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}


// 配列の準備とリサイズ
// ArrayInit(name[], expr, ... )
unsigned int rfunc_ArrayInit(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	const struct ARGS *p = args;	// 引数ポインタ
	unsigned int numint = 0;		// （新配列の）要素数
	unsigned int rv = 0, i = 0;		// 戻り値保存用とカウンタ用

	if ( p->type == UFCT_ARG_INTS && p->next ) {
		numint = 0;
		// 引数の型を確認しながら、（新配列の）要素数をカウント
		for( p = args->next ; p ; p = p->next ) {
			if ( p->type == UFCT_ARG_INT ) {
				numint++;
			}
			else if ( p->type == UFCT_ARG_INTS ) {
				unsigned tmpn = sizeof_variables( p->v.text );
				if ( tmpn == NO_VALUE ) {
					return 0;	// エラー：未宣言の配列
				}
                numint += tmpn;
			}
			else {
				*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
				return ERRORVALUE;
			}
		}

		// 配列を確保
		rv = array_variables( ARG1.text, numint );

		if ( rv == 1 ) {
			return 0;	// エラー：メモリ不足またはarrayinitで変数名の再利用をした
		}

		// 値の代入
		i = 0;
		for( p = args->next ; p ; p = p->next ) {
			if ( p->type == UFCT_ARG_INT ) {
				setVariable_a(ARG1.text, i, p->v.integer);
				++i;
			}
			else if ( p->type == UFCT_ARG_INTS ) {
				unsigned n = sizeof_variables( p->v.text );
				unsigned j, t;
				for( j=0 ; j<n ; ++j ) {
					getVariable_a(p->v.text,  j, &t);
					setVariable_a(ARG1.text, i+j, t);
				}
				i += n;
			}
		}

		return 1;
	}
	else if ( p->type == UFCT_ARG_STRINGS && p->next ) {
		numint = 0;
		// 引数の型を確認しながら、（新配列の）要素数をカウント
		for( p = args->next ; p ; p = p->next ) {
			if ( p->type == UFCT_ARG_STRING ) {
				numint++;
			}
			else if ( p->type == UFCT_ARG_STRINGS ) {
				unsigned tmpn = sizeof_variables_d( p->v.text );
				if ( tmpn == NO_VALUE ) {
					return 0;	// エラー：未宣言の配列
				}
                numint += tmpn;
			}
			else {
				*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
				return ERRORVALUE;
			}
		}

		// 配列を確保
		rv = array_variables_d( ARG1.text, numint );

		if ( rv == 1 ) {
			return 0;	// エラー：メモリ不足またはarrayinitで変数名の再利用をした
		}

		// 値の代入
		i = 0;
		for( p = args->next ; p ; p = p->next ) {
			if ( p->type == UFCT_ARG_STRING ) {
				setVariable_d_a(ARG1.text, i, p->v.text);
				++i;
			}
			else /*if ( p->type == UFCT_ARG_STRINGS )*/ {
				unsigned n = sizeof_variables_d( p->v.text );
				unsigned j;
				char *t;
				for( j=0 ; j<n ; ++j ) {
					t = getVariable_d_a(p->v.text, j);
					setVariable_d_a(ARG1.text, i+j, t);
				}
				i += n;
			}
		}

		return 1;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 配列の準備とリサイズ
// ResizeInit(name[], expr, ... )
unsigned int rfunc_ResizeInit(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	const struct ARGS *p = args;	// 引数ポインタ
	unsigned int numint = 0;		// （新配列の）要素数
	unsigned int rv = 0, i = 0;		// 戻り値保存用とカウンタ用

	if ( p->type == UFCT_ARG_INTS && p->next ) {
		numint = 0;
		// 引数の型を確認しながら、（新配列の）要素数をカウント
		for( p = args->next ; p ; p = p->next ) {
			if ( p->type == UFCT_ARG_INT ) {
				numint++;
			}
			else if ( p->type == UFCT_ARG_INTS ) {
				unsigned tmpn = sizeof_variables( p->v.text );
				if ( tmpn == NO_VALUE ) {
					return 0;	// エラー：未宣言の配列
				}
                numint += tmpn;
			}
			else {
				*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
				return ERRORVALUE;
			}
		}

		// 配列を確保（またはリサイズ）
		rv = resize_variables( ARG1.text, numint );

		if ( rv == 1 ) {
			return 0;	// エラー：メモリ不足またはarrayinitで変数名の再利用をした
		}

		// 値の代入
		i = 0;
		for( p = args->next ; p ; p = p->next ) {
			if ( p->type == UFCT_ARG_INT ) {
				setVariable_a(ARG1.text, i, p->v.integer);
				++i;
			}
			else if ( p->type == UFCT_ARG_INTS ) {
				unsigned n = sizeof_variables( p->v.text );
				unsigned j, t;
				for( j=0 ; j<n ; ++j ) {
					getVariable_a(p->v.text,  j, &t);
					setVariable_a(ARG1.text, i+j, t);
				}
				i += n;
			}
		}

		return 1;
	}
	else if ( p->type == UFCT_ARG_STRINGS && p->next ) {
		numint = 0;
		// 引数の型を確認しながら、（新配列の）要素数をカウント
		for( p = args->next ; p ; p = p->next ) {
			if ( p->type == UFCT_ARG_STRING ) {
				numint++;
			}
			else if ( p->type == UFCT_ARG_STRINGS ) {
				unsigned tmpn = sizeof_variables_d( p->v.text );
				if ( tmpn == NO_VALUE ) {
					return 0;	// エラー：未宣言の配列
				}
                numint += tmpn;
			}
			else {
				*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
				return ERRORVALUE;
			}
		}

		// 配列を確保（またはリサイズ）
		rv = resize_variables_d( ARG1.text, numint );

		if ( rv == 1 ) {
			return 0;	// エラー：メモリ不足またはarrayinitで変数名の再利用をした
		}

		// 値の代入
		i = 0;
		for( p = args->next ; p ; p = p->next ) {
			if ( p->type == UFCT_ARG_STRING ) {
				setVariable_d_a(ARG1.text, i, p->v.text);
				++i;
			}
			else /*if ( p->type == UFCT_ARG_STRINGS )*/ {
				unsigned n = sizeof_variables_d( p->v.text );
				unsigned j;
				char *t;
				for( j=0 ; j<n ; ++j ) {
					t = getVariable_d_a(p->v.text, j);
					setVariable_d_a(ARG1.text, i+j, t);
				}
				i += n;
			}
		}

		return 1;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}


// 正規表現を用いて、文字列のマッチを検査(Boostライブラリによる)
// regex_match( str, re [, option] )
// str : 検査対象文字列
// re  : 正規表現
// option : オプション(i,g,s)
// 戻り値 : 0 - マッチせず, 1 - マッチした, ERRORVALUE - エラー
unsigned int rfunc_RegEx_Match(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		return cpp_regex_match(ARG1.text, ARG2.text, "");
	}
	else if ( args_typecheck(args, "sss") ) {
		return cpp_regex_match(ARG1.text, ARG2.text, ARG3.text);
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 正規表現を用いて、文字列のマッチをサーチ(Boostライブラリによる)
// regex_match( str, re [, option] )
// str : 検索対象文字列
// re  : 正規表現
// option : オプション(i,g,s)
// 戻り値 : マッチした文字位置 (ERRORVALUE - 見つからないかエラー)
unsigned int rfunc_RegEx_Search(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ss") ) {
		return cpp_regex_search(ARG1.text, ARG2.text, "", NULL, NULL);
	}
	else if ( args_typecheck(args, "sss") ) {
		return cpp_regex_search(ARG1.text, ARG2.text, ARG3.text, NULL, NULL);
	}
	else if ( args_typecheck(args, "ssaa") ) {
		return cpp_regex_search(ARG1.text, ARG2.text, "", ARG3.text, ARG4.text);
	}
	else if ( args_typecheck(args, "sssaa") ) {
		return cpp_regex_search(ARG1.text, ARG2.text, ARG3.text, ARG4.text, ARG5.text);
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// 指定時間のウェイト（および画面の再描画）
// sleep( n )
// n : ここで指定した時間だけ停止します（ミリ秒単位）
// 戻り値 : 1
unsigned int rfunc_sleep(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "i") ) {
		MSG msg;

		// ダイアログの再描画
		if ( hWnd ) {
			while( PeekMessage(&msg, hWnd, WM_PAINT, WM_PAINT, PM_REMOVE) ) {
				DispatchMessage(&msg);
			}
		}

		// ウェイト
		if ( ARG1.integer == 0xFFFFFFFF ) { // 0xFFFFFFFF(INFINITE)は特殊な意味を持つため
			Sleep(ARG1.integer-1);
			Sleep(1);
		}
		else {
			Sleep(ARG1.integer);
		}

		// ダイアログの再描画
		if ( hWnd ) {
			while( PeekMessage(&msg, hWnd, WM_PAINT, WM_PAINT, PM_REMOVE) ) {
				DispatchMessage(&msg);
			}
		}

		return 1;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return ERRORVALUE;
	}
}

// カレントディレクトリを取得する（最後に \ が付きます）
// GetCurrentDirectory$()
char *rfunc_getcurrentdirectory_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		char   cdir[MAX_PATH*2];
		size_t i;
			
		GetCurrentDirectory(_countof(cdir), cdir);
		i = strlen( cdir );
		if ( cdir[i-1] != '\\' || isKanji1(cdir,(int)i-2) ) {
			cdir[i] = '\\';
			cdir[i+1] = 0;
		}
		return _strdup(cdir);
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// Windowsディレクトリを取得する（最後に \ が付きます）
// GetWindowsDirectory$()
char *rfunc_getwindowsdirectory_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		char    wdir[MAX_PATH*2];
		size_t  i;

		GetWindowsDirectory(wdir, _countof(wdir));
		i = strlen( wdir );
		if ( wdir[i-1] != '\\' || isKanji1(wdir,(int)i-2) ) {
			wdir[i] = '\\';
			wdir[i+1] = 0;
		}
		return _strdup(wdir);
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// Systemディレクトリを取得する（最後に \ が付きます）
// GetSystemDirectory$()
char *rfunc_getsystemdirectory_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		char   sdir[MAX_PATH*2];
		size_t i;

		GetSystemDirectory(sdir, _countof(sdir));
		i = strlen( sdir );
		if ( sdir[i-1] != '\\' || isKanji1(sdir,(int)i-2) ) {
			sdir[i] = '\\';
			sdir[i+1] = 0;
		}
		return _strdup(sdir);
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 実行中のスクリプトが存在するディレクトリを返す（最後に \ が付きます）
// GetRscDirectory$()
char *rfunc_GetRscDirectory_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		int  i;

		// 実行中のスクリプトがフルパス指定なら、最後の\\を探して、その次に\0を入れることによりパスのみをゲッツ
		// そうでなければ、インタプリタのフルパスを返す
		for( i=lstrlen(rscname)-1 ; i>0 ; i-- ) {
			if ( rscname[i] == '\\' && !isKanji1(rscname,i-1) ) {
				char *p;

				p = zalloc( i+3 );
				if ( p ) {
					lstrcpyn(p, rscname, i+2);
					p[i+2] = 0;
				}
				return p;
			}
		}

		return funccall_d( hWnd, "GetInterpreterDirectory$", args, result );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// インタプリタが存在するディレクトリを返す（最後に \ が付きます）
// GetInterpreterDirectory$()
char *rfunc_GetInterpreterDirectory_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		char exename[MAX_PATH*2];
		int  i;

		// インタプリタのフルパスを取得し、最後の\\を探して、その次に\0を入れることによりパスのみをゲッツ
		if ( GetModuleFileName(NULL, exename, _countof(exename)) ) {
			for( i = lstrlen(exename)-1 ; i>0 ; i-- ) {
				if ( exename[i] == '\\' && !isKanji1(exename,i-1) ) {
					exename[i+1] = 0;
					break;
				}
			}

			return _strdup( exename );
		}

		return 0;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 実行中のスクリプトのファイル名を返す（メインメニューからの通常の呼び出しだと、パスは付加されません）
// GetRscName$()
char *rfunc_GetRscName_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		return _strdup(rscname);
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 環境変数を取得する
// GetEnv$( 環境変数名$ )
char *rfunc_getenv_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		char *value, *tmp;
		DWORD i;
			
		value = zalloc( 2 );
		if ( value ) {
			i = GetEnvironmentVariable(ARG1.text, value, 2);
			if ( i > 1 ) {
				tmp = (char *)realloc( value, i );
				if ( tmp ) {
					value = tmp;
					GetEnvironmentVariable(ARG1.text, value, i);
				}
				else {
					value[0] = 0;
				}
			}
			else if ( i == 0 ) {
				value[0] = 0;
			}
		}
		return value;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 環境変数展開後の文字列を取得する
// ExpandEnvironmentStrings$( 文字列$ )
char *rfunc_ExpandEnvironmentStrings_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		char *value;
		DWORD i;
			
		value = zalloc( 5 );
		if ( value ) {
			i = ExpandEnvironmentStrings(ARG1.text, value, 2);
			if ( i > 2 ) {
				i = i*2 + 1;
				safefree( value );
				value = zalloc( i );
				if ( value ) {
					if ( 0 != ExpandEnvironmentStrings(ARG1.text, value, i) ) {
						// 確保したメモリを、文字列の大きさに切りつめる
						char *tmp = realloc(value, lstrlen(value)+1);
						if ( tmp ) {
							value = tmp;
						}
					}
				}
				else {
					value[0] = 0;
				}
			}
			else if ( i == 0 ) {
				value[0] = 0;
			}
		}
		return value;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// レジストリから文字列を取得する
// RegReadSz$( Key$, Entry$, デフォルト$ )
// RegReadString$( Key$, Entry$, デフォルト$ )
char *rfunc_regreadsz_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sss") ) {
		HKEY hKey;
		char *value;
		int  l;

		if (NULL != (hKey = tRegOpenKey(NULL, ARG1.text, TREG_OPEN_READONLY)) ) {
			if (0 < (l = tRegValueExist( hKey, ARG2.text ))) {
				value = zalloc( l+1 );
				if ( value ) {
					tRegReadString( hKey, ARG2.text, value, l+1 );
				}
			}
			else {
				value = _strdup( ARG3.text );
			}

			RegCloseKey( hKey );
			return value;
		}
		else
			return _strdup( ARG3.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 編集ボックスから文字列を取得する, またはアイコンボタンからアイコン名を取得する
// チェックボックス・ボタン内の文字列を取得する
// GetEditBox$( ID$ )
// GetIconName$( ID$ )・GetIconBox$( ID$ )
// GetTextCtrl$( ID$ )
char *rfunc_geteditbox_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return GetEditBox( ARG1.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 文字列を大文字に変換する
// _strupr$( 文字列$ )
char *rfunc_strupr_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return sjisupr(_strdup(ARG1.text));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 文字列を小文字に変換する
// strlwr$( 文字列$ )
char *rfunc_strlwr_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return sjislwr(_strdup(ARG1.text));
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 文字列の特定のバイトを得る (文字列として)
// GetStrByte$( 文字列$, 何バイト目?<0-> )
char *rfunc_getstrbyte_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "si") ) {
		char s[2];

		if (strlen( ARG1.text ) > (size_t)ARG2.integer ) {
			s[0] = ARG1.text[ARG2.integer];
			s[1] = 0;
			return _strdup( s );
		}
		else {
			return _strdup( "" );
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 文字列の左から○文字までを抜き出す
// left$( 文字列$, 抜き出す文字数 )
char *rfunc_left_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "si") ) {
		char *s, *p;

		if (strlen( ARG1.text ) > (size_t)ARG2.integer ) {
			s = _strdup( ARG1.text );
			s[ ARG2.integer ] = 0;
			p = _strdup( s );
			safefree( s );
			return p;
		}
		else {
			return _strdup( ARG1.text );
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 文字列の右から○文字までを抜き出す
// right$( 文字列$, 抜き出す文字数 )
char *rfunc_right_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "si") ) {
		size_t i;

		i = strlen( ARG1.text );
		if ( i > (size_t)ARG2.integer ) {
			return _strdup( &(ARG1.text[i-(size_t)ARG2.integer]) );
		}
		else {
			return _strdup( ARG1.text );
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 文字列の真ん中の○バイト目から○文字を抜き出す
// mid$( 文字列$, バイト数, 抜き出す文字数 )
// substr$( 文字列$, バイト数, 抜き出す文字数 )
// substring$( 文字列$, バイト数, 抜き出す文字数 )
char *rfunc_mid_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sii") ) {
		char *s, *p;

		if ( strlen( ARG1.text ) > (size_t)ARG2.integer ) {
			s = _strdup( &(ARG1.text[ARG2.integer]) );
			if ( strlen( &(ARG1.text[ARG2.integer]) ) > (size_t)ARG3.integer ) {
				s[ ARG3.integer ] = 0;
				p = _strdup( s );
				safefree( s );
				return p;
			}
			else {
				return s;
			}
		}
		else
			return _strdup( "" );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// iniファイルから文字列を読む
// iniReadString$( file$, section$, key$, default$ )
char *rfunc_iniReadString_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ssss") ) {
		return mtiniReadString( ARG1.text, ARG2.text, ARG3.text, ARG4.text );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 数値を文字列に変換（""+数値 でも変換できる）
// toStr$( 数値[, 桁数] )
char *rfunc_toStr_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "i") ) {
		char itbuf[16], *rv = NULL;

		if ( 0 == _ultoa_s(ARG1.integer, itbuf, _countof(itbuf), 10) ) {
			rv = _strdup(itbuf);
		}
		return rv;
	}
	else if ( args_typecheck(args, "ii") ) { // 桁数つき
		char itbuf[16];
		UINT len, i;

		if ( 0 == _ultoa_s(ARG1.integer, itbuf, _countof(itbuf), 10) ) {
			len = lstrlen(itbuf);
			if ( len >= ARG2.integer ) { // 指定された桁数よりも、すでに多い桁数だったら
				return _strdup( itbuf ); // そのまま返す
			}
			else { // そうでなかった場合は、頭に0を補う
				char *r;

				r = zalloc( ARG2.integer + 1 );
				if ( r ) {
					for(i=0 ; i<ARG2.integer-len ; i++) {
						r[i] = '0';
					}
					lstrcpy(&r[i], itbuf);
				}
				return r;
			}
		}
		else {
			return NULL;
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 数値を符号付きであると見なし、文字列に変換
// SignedtoStr$( 数値 )
char *rfunc_SignedToStr_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "i") ) {
		return _strdup( s_itoa10( ARG1.integer ) );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 数値を2進数と見なして文字列に変換
// toStr2$( 数値 )
char *rfunc_toStr2_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "i") ) {
		char s[33];
		UINT i, j;

		// ARG1.integer を 2進数に変換
		for( i=j=0 ; i<32 ; i++ ) {
            s[j] = (char)((((unsigned)ARG1.integer >> (31-i)) & 1) + '0');
			if ( j ) {
				j++;
			}
			else {
				if ( s[0] == '1' ) {
					j = 1;
				}
			}
		}
		if ( j ) {
            s[j] = 0;
		}
		else {
			s[0] = '0';
			s[1] = 0;
		}
		return _strdup( s );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 数値を8進数と見なして文字列に変換
// toStr8$( 数値 )
char *rfunc_toStr8_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "i") ) {
		char s[15];

		wsprintf(s, "%o", ARG1.integer); // ARG1.integer を 8進数に変換
		return _strdup( s );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 数値を16進数と見なして文字列に変換
// toStr16$( 数値 )
char *rfunc_toStr16_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "i") ) {
		char s[10];

		wsprintf(s, "%x", ARG1.integer); // ARG1.integer を 16進数に変換
		return _strdup( s );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 文字コードnに対応する文字だけの文字列を生成
// AsciiCode$( n )
char *rfunc_AsciiCode_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "i") ) {
		unsigned char s[2];

		s[0] = (unsigned char)ARG1.integer;
		s[1] = 0;
		return _strdup( (char *)s );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// DLLの関数を呼び出す(戻り値は文字列)
// CallDll$( DLLファイル名$, 関数名$, 引数... )
char *rfunc_CallDll_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args != NULL && args->type == UFCT_ARG_STRING && args->next != NULL && args->next->type == UFCT_ARG_STRING ) {
		HINSTANCE lib;
		RSC_CALLDLL_STRING func;
		HGLOBAL hMem;
		char    *p ,*q;

		lib = LoadLibrary( ARG1.text );
		if ( lib == NULL ) {
			*result = UFS_NOTFOUNDDLL;
			return 0;
		}
		func = (RSC_CALLDLL_STRING)GetProcAddress( lib, ARG2.text );
		if ( func == NULL ) {
			*result = UFS_NOTFOUNDDLLFUNC;
			return 0;
		}

		// 配列変数の名前が書かれている部分は、その配列変数を表す構造体のポインタに差し替える
		{
			struct ARGS *p_args = args->next->next;

			while ( p_args ) {
				if ( p_args->type == UFCT_ARG_INTS ) {
					p_args->v.pva = search_pointer_a( p_args->v.text );
				}
				else if ( p_args->type == UFCT_ARG_STRINGS ) {
					p_args->v.pvda = search_pointer_d_a( p_args->v.text );
				}
				p_args = p_args->next;
			} 
		}

		hMem = func( hWnd, args->next->next );
		if ( hMem && (NULL != (p = (char *)GlobalLock( hMem ))) ) {
			q = _strdup( p );
			GlobalUnlock( hMem );
			safegfree( hMem );
		}
		else {
			q = _strdup( "" );
		}
		FreeLibrary( lib );
		return q;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// キーの中のi番目のサブキーの名前を取得
// EnumKey$( Key$, i )
char *rfunc_EnumKey_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "si") ) {
		if ( strchr(ARG1.text,'\\') == 0 ) {
			HKEY hKey;
			DWORD len = 0;
			char *name = NULL;

			hKey = tRegHiveKey( ARG1.text );
			RegQueryInfoKey( hKey, NULL, NULL, NULL, NULL, &len, NULL, NULL, NULL, NULL, NULL, NULL);
			len = (len+1)*sizeof(WCHAR); // WinNT系での対策
			name = zalloc( len );
			if ( name ) {
				if ( ERROR_SUCCESS == RegEnumKeyEx( hKey, ARG2.integer, name, &len, NULL, NULL, NULL, NULL ) ) {
					// 確保されたメモリを文字列の大きさまで切りつめる
					char *tmp = realloc( name, lstrlen(name)+1 );
					if ( tmp ) {
						name = tmp;
					}
				}
				else {
					safefree( name );
					name = _strdup( "" );
				}
			}
			return name;
		}
		else {
			HKEY hKey;
			DWORD len = 0;
			char *name;

			if ( NULL != (hKey = tRegOpenKey( NULL, ARG1.text, TREG_OPEN_READONLY )) ) {
				RegQueryInfoKey( hKey, NULL, NULL, NULL, NULL, &len, NULL, NULL, NULL, NULL, NULL, NULL);
				len = (len+1)*sizeof(WCHAR); // WinNT系での対策
				name = zalloc( len );
				if ( name ) {
					if ( ERROR_SUCCESS == RegEnumKeyEx( hKey, ARG2.integer, name, &len, NULL, NULL, NULL, NULL ) ) {
						// 確保されたメモリを文字列の大きさまで切りつめる
						char *tmp = realloc( name, lstrlen(name)+1 );
						if ( tmp ) {
							name = tmp;
						}
					}
					else {
						safefree( name );
						name = _strdup( "" );
					}
				}
				RegCloseKey( hKey );
			}
			else {
				name = _strdup( "" );
			}
			return name;
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// キーの中のi番目の値の名前を取得
// EnumValue$( Key$, i )
char *rfunc_EnumValue_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "si") ) {
		if ( strchr(ARG1.text,'\\') == 0 ) {
			HKEY hKey;
			DWORD len = 0;
			char *name;

			hKey = tRegHiveKey( ARG1.text );
			RegQueryInfoKey( hKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &len, NULL, NULL, NULL);
			len = (len+1)*sizeof(WCHAR); // WinNT系での対策
			name = zalloc( len );
			if ( name ) {
				if ( ERROR_SUCCESS == RegEnumValue( hKey, ARG2.integer, name, &len, NULL, NULL, NULL, NULL ) ) {
					// 確保されたメモリを文字列の大きさまで切りつめる
					char *tmp = realloc( name, lstrlen(name)+1 );
					if ( tmp ) {
						name = tmp;
					}
				}
				else {
                    safefree( name );
					name = _strdup( "" );
				}
			}
			return name;
		}
		else {
			HKEY hKey;
			DWORD len = 0;
			char *name;

			if ( NULL != (hKey = tRegOpenKey( NULL, ARG1.text, TREG_OPEN_READONLY )) ) {
				RegQueryInfoKey( hKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &len, NULL, NULL, NULL);
				len = (len+1)*sizeof(WCHAR); // WinNT系での対策
				name = zalloc( len );
				if ( name ) {
					if ( ERROR_SUCCESS == RegEnumValue( hKey, ARG2.integer, name, &len, NULL, NULL, NULL, NULL ) ) {
						// 確保されたメモリを文字列の大きさまで切りつめる
						char *tmp = realloc( name, lstrlen(name)+1 );
						if ( tmp ) {
							name = tmp;
						}
					}
					else {
						safefree( name );
						name = _strdup( "" );
					}
				}
				RegCloseKey( hKey );
			}
			else {
				name = _strdup( "" );
			}
			return name;
		}
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// iniファイルからセクションを列挙
// iniEnumSection$( file$, i )
// file$が空文字列の場合は、Win.iniから検索
char *rfunc_iniEnumSection_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "si") ) {
		char *retp = mtiniEnumSection( ARG1.text[0]?ARG1.text:NULL, ARG2.integer );

		if ( retp == NULL ) {
			retp = _strdup( "" );
		}

		return retp;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// iniファイルのセクションからキーを列挙
// iniEnumKey$( file$, section$, i )
char *rfunc_iniEnumKey_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "ssi") ) {
		char *retp = mtiniEnumKey( ARG1.text, ARG2.text, ARG3.integer );
		
		if ( retp == NULL ) {
			retp = _strdup( "" );
		}

		return retp;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// リストビュー・チェックボックスリストのn行i桁から文字列を得る
// ListViewGetText$( ID$, n, i )
char *rfunc_ListViewGetText_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sii") ) {
		return ListView_GetText( ARG1.text, ARG2.integer, ARG3.integer );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 複数行編集ボックスの行を得る
// GetMultiEditLine$( ID$, n )
char *rfunc_GetMultiEditLine_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "si") ) {
		return GetMultiEditLine( ARG1.text, ARG2.integer );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 指定された拡張子の関連づけられた名前を返す(特に名前がなければ拡張子そのものが名前)
// つまり、.bmpに対する Paint.Picture や、.exeに対するexefileなど
// .lzhや.zipは、標準のものがないので、特に何もさしていなければ.lzhや.zip自身を返す
// GetExtName( ext$ )
char *rfunc_GetExtName_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		HKEY hkey;
		char *extc;

		if ( NULL != (hkey = tRegOpenKey( HKEY_CLASSES_ROOT, ARG1.text, TREG_OPEN_READONLY )) ) {
			extc = mtRegReadString( hkey, "", NULL );
			RegCloseKey( hkey );
			if ( extc == NULL ) {
				extc = _strdup( ARG1.text );
			}
			else {
				if ( extc[0] != 0 && NULL != (hkey = tRegOpenKey( HKEY_CLASSES_ROOT, extc, TREG_OPEN_READONLY )) ) {
					RegCloseKey( hkey );
				}
				else {
                    safefree( extc );
					extc = _strdup( ARG1.text );
				}
			}
			
		}
		else {
			extc = _strdup( ARG1.text );
		}

		return extc;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// ダイアログ上に存在するi番目のコントロールのIDを返す
// enumID$( i )
char *rfunc_enumID_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "i") ) {
		return _strdup( (nctrls>ARG1.integer && rctrls[ARG1.integer].id) ? rctrls[ARG1.integer].id : "" );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// ダイアログ上の指定されたIDのコントロールの種類を調べる
// GetControlType$( s )
char *rfunc_GetControlType_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		return _strdup( getControlType( ARG1.text ) );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 編集ダイアログのタイトルを返す
// GetDialogTitle$()
char *rfunc_GetDialogTitle_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		int len;
		char *buf;

		len = GetWindowTextLength( hWnd ) + 2;
		buf = zalloc( len );
		if ( buf ) {
			GetWindowText( hWnd, buf, len+1 );
		}
		return buf;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// いじくるつくーるのタイトルを返す
// GetWindowTitle$()
char *rfunc_GetWindowTitle_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		int len;
		char *buf;

		len = GetWindowTextLength( GetParent(hWnd) ) + 1;
		buf = zalloc( len );
		if ( buf ) {
			GetWindowText( GetParent(hWnd), buf, len );
		}
		return buf;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 現在のユーザーのデスクトップの物理フォルダを返す
// GetDesktopDirectory$()
char *rfunc_GetDesktopDirectory_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		char *tmp = NULL, *buf2 = NULL;
		int  len = 0;

		tmp = GetDesktopFolder();
		len = lstrlen(tmp);

		if ( tmp[len-1] == '\\' && !isKanji1(tmp,len-2) ) {
			return _strdup( tmp );
		}
		else {
            buf2 = zalloc( len + 2 );
			if ( buf2 ) {
				lstrcpy( buf2, tmp );
				lstrcat( buf2, "\\" );
			}
		}

		return buf2;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 全ユーザーのデスクトップの物理フォルダを返す
// GetCommonDesktopDirectory$()
char *rfunc_GetCommonDesktopDirectory_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		char *tmp = NULL, *buf2 = NULL;
		int  len = 0;

		tmp = GetCommonDesktopFolder();
		len = lstrlen(tmp);

		if ( tmp[len-1] == '\\' && !isKanji1(tmp,len-2) ) {
			return _strdup( tmp );
		}
		else {
            buf2 = zalloc( len + 2 );
			if ( buf2 ) {
				lstrcpy( buf2, tmp );
				lstrcat( buf2, "\\" );
			}
		}

		return buf2;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 現在のユーザーのデスクトップの物理フォルダを返す
// GetProgramDirectory$()
char *rfunc_GetProgramDirectory_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		char *tmp = NULL, *buf2 = NULL;
		int  len = 0;

		tmp = GetProgramFolder();
		if ( !tmp ) {
            return NULL;
		}

		len = lstrlen(tmp);

		if ( tmp[len-1] == '\\' && !isKanji1(tmp,len-2) ) {
			return _strdup( tmp );
		}
		else {
            buf2 = zalloc( len + 2 );
			if ( buf2 ) {
				lstrcpy( buf2, tmp );
				lstrcat( buf2, "\\" );
			}
		}

		return buf2;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 全ユーザーのデスクトップの物理フォルダを返す
// GetCommonProgramDirectory$()
char *rfunc_GetCommonProgramDirectory_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		char *tmp = NULL, *buf2 = NULL;
		int  len = 0;

		tmp = GetCommonProgramFolder();
		if ( !tmp ) {
            return NULL;
		}

		len = lstrlen(tmp);

		if ( tmp[len-1] == '\\' && !isKanji1(tmp,len-2) ) {
			return _strdup( tmp );
		}
		else {
            buf2 = zalloc( len + 2 );
			if ( buf2 ) {
				lstrcpy( buf2, tmp );
				lstrcat( buf2, "\\" );
			}
		}

		return buf2;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 開くファイルを選択する
// SelectOpenFile$( ダイアログのタイトル$ )
char *rfunc_SelectOpenFile_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		char fname[MAX_PATH*2] = "";

		openDialog( hWnd, FILETYPES, fname, _countof(fname), ARG1.text, NULL );
		return _strdup( fname );
	}
	else if ( args_typecheck(args, "ss") ) {
		char fname[MAX_PATH*2] = "";

		if (lstrlen(ARG2.text) < _countof(fname)) {
			lstrcpy( fname, ARG2.text );
		}
		openDialog( hWnd, FILETYPES, fname, _countof(fname), ARG1.text, NULL );
		return _strdup( fname );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 保存ファイルを選択または入力する
// SelectSaveFile$( ダイアログのタイトル$ )
char *rfunc_SelectSaveFile_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		char fname[MAX_PATH*2] = "";

		saveDialog( hWnd, FILETYPES, fname, _countof(fname), ARG1.text, NULL );
		return _strdup( fname );
	}
	else if ( args_typecheck(args, "ss") ) {
		char fname[MAX_PATH*2] = "";

		if (lstrlen(ARG2.text) < _countof(fname)) {
			lstrcpy(fname, ARG2.text);
		}
		saveDialog( hWnd, FILETYPES, fname, _countof(fname), ARG1.text, NULL );
		return _strdup( fname );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// フォルダを選択する
// SelectFolder$( ダイアログのタイトル$ )
char *rfunc_SelectFolder_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
        char chPutFolder[MAX_PATH*2] = "";

		browseFolder( hWnd, chPutFolder, ARG1.text );
		return _strdup( chPutFolder );
	}
	if ( args_typecheck(args, "ss") ) {
        char chPutFolder[MAX_PATH*2] = "";

		if (lstrlen(ARG2.text) < _countof(chPutFolder)) {
			lstrcpy(chPutFolder, ARG2.text);
		}
		browseFolder( hWnd, chPutFolder, ARG1.text );
		return _strdup( chPutFolder );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// ヘルプドキュメントの動的生成
// 文字列を追加して、そのままその文字列を返却する

// ヘルプに太字でテキストを追加(&排除、\n→\\par, \t→\\tab)
// dhelps$( section$ )
char *rfunc_dhelps_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		helpdoc_section( ARG1.text, 0 );
		return _strdup( ARG1.text );            
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// ヘルプにテキストを追加(\n→\\par, \t→\\tab)
// dhelp$( paragraph$ )
char *rfunc_dhelp_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		helpdoc_text( ARG1.text, 0 );
		return _strdup( ARG1.text );            
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// ヘルプにOKボタン等に関するヘルプテキストを追加(\n→\\par, \t→\\tab)
// dhelpbuttons$()
char *rfunc_dhelpbuttons_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		char *text = " {\\b\\cf13 [OK]}を押すと、設定の有効化が行われ、必要に応じてシステムの再起動を要求されます。システムの再起動を要求された場合は、なるべく速やかにシステムを再起動して下さい。\n {\\b\\cf13 [キャンセル]}を押すと、その場で行った設定は全てキャンセルされます。事前に[適用({\\ul A})]を押していた場合は、適用を押した後からの変更がキャンセルされます。\n {\\b\\cf13 [適用({\\ul A})]}を押すと、設定の有効化だけが行われ、編集を続行できます。\n {\\b\\cf13 [戻す({\\ul R})]}を押すと、設定ダイアログが開かれたときの状態に戻ります。\n {\\b\\cf13 [保存({\\ul S})]}を押すと、現在の設定ダイアログの状態をファイルへ保存します。\n {\\b\\cf13 [読込({\\ul L})]}を押すと、設定ダイアログの状態をファイルから読み出します。\n {\\b\\cf13 [ヘルプ({\\ul H})]}を押すと、現在表示中のダイアログに関するヘルプが表示されます。\n";

		helpdoc_text( text, 0 );
		return _strdup( text );            
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// ファイルからの読み込み
// fread$( fname$ )
// fread$( fname$, line )
char *rfunc_fread_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		FILE *fp;
		UINT fsize = 0;
		char *buf;
		UINT64 qwSize = 0;

		qwSize = getFileSizeQ(ARG1.text);
		if ( qwSize >= 2u*1024u*1024u*1024u-16u ) {
			// エラー(-1==0xffffffffffffffff)またはファイルサイズが2GB以上の場合は取り扱わない
            return _strdup( "" );
		}
		fsize = (UINT)qwSize+1;

		if ( 0 == fopen_s(&fp, ARG1.text, (fmode_wide || fmode_bin) ? "rb" : "rt") ) {
			buf = zalloc( fsize+2 );
			if ( buf ) {
				if ( fmode_wide == 1 ) {
					LPWSTR wbuf = (LPWSTR)zalloc(fsize+2);

					if ( wbuf ) {
						fread(wbuf, fsize, 1, fp);
						// BOMから始まっていたら、それを無視する
						WideCharToMultiByte(GetACP(), 0, (wbuf[0] == 0xfeff)?wbuf+1:wbuf, -1, buf, fsize+2, NULL, NULL);
						safefree(wbuf);
					}
				}
				else {
                    fread(buf, fsize, 1, fp);
				}
			}
			else {
				buf = _strdup( "" );
			}

			fclose( fp );
		}
		else {
			buf = _strdup( "" );
		}
		return buf;
	}
	else if ( args_typecheck(args, "si") ) {
		FILE *fp;
		UINT fsize = 0, i;
		char *buf, *rv;
		UINT64 qwSize = 0;

		qwSize = getFileSizeQ(ARG1.text);
		if ( qwSize >= 2u*1024u*1024u*1024u-16u ) {
			// エラー(-1==0xffffffffffffffff)またはファイルサイズが2GB以上の場合は取り扱わない
            return _strdup( "" );
		}
		fsize = (UINT)qwSize+1;

		if ( 0 == fopen_s(&fp, ARG1.text, (fmode_wide || fmode_bin) ? "rb" : "rt") ) {
			buf = zalloc( fsize+2 );
			if ( buf ) {
				for(i=0 ; i<=ARG2.integer ; i++) {
					buf[0] = 0;
					if ( fmode_wide == 1 ) {
						LPWSTR wbuf = (LPWSTR)zalloc(fsize+2);

						if ( wbuf ) {
							fgetws( wbuf, fsize, fp );
							// １行目の読み込みの場合、BOMから始まっていたら、それを無視する
							WideCharToMultiByte(GetACP(), 0, (i == 0 && wbuf[0] == 0xfeff)?wbuf+1:wbuf, -1, buf, fsize+2, NULL, NULL);
							safefree(wbuf);
						}
					}
					else {
						fgets(buf, fsize, fp);
					}
				}
				i = (UINT)strlen( buf );
				if ( buf[i] == '\n' || buf[i] =='\r' ) { // 行末の改行記号は取り除く
					buf[i] = 0;
				}
				rv = _strdup( buf );
				safefree( buf );
            }
			else {
				rv = _strdup( "" );
			}

			fclose( fp );
		}
		else {
			rv = _strdup( "" );
		}
		return rv;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// ユーザーから文字列の入力を受け付ける
// input$( default$, text$, caption$ )
char *rfunc_input_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sss") ) {
		return inputdlg(hWnd, ARG1.text, ARG2.text, ARG3.text);
		// inputdlg は malloc で確保したメモリを返す
	}
	else if ( args_typecheck(args, "ss") ) {
		return inputdlg(hWnd, ARG1.text, ARG2.text, "入力");
		// inputdlg は malloc で確保したメモリを返す
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// ユーザーからパスワード文字列の入力を受け付ける
// inputpassword$( default$, text$, caption$ )
char *rfunc_inputpassword_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sss") ) {
		return inputdlg_password(hWnd, ARG1.text, ARG2.text, ARG3.text);
		// inputdlg は malloc で確保したメモリを返す
	}
	else if ( args_typecheck(args, "ss") ) {
		return inputdlg_password(hWnd, ARG1.text, ARG2.text, "パスワード");
		// inputdlg は malloc で確保したメモリを返す
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// str$中のrepb$をrepa$に置き換えた文字列を返す
// replace$( str$, repb$[, repa$] )
char *rfunc_replace_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sss") ) {
		return replacestr(ARG1.text, ARG2.text, ARG3.text);
	}
	else if ( args_typecheck(args, "ss") ) {
		return replacestr(ARG1.text, ARG2.text, "");
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 文字列中の=よりも前の部分を取り出す
// BeforeEq$( str$ )
char *rfunc_BeforeEq_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		char *str1;
		char *p_eq, *p_st;

		str1 = _strdup( ARG1.text );
		if ( str1 ) {
			p_eq = strchr( str1, '=' );
			if ( p_eq ) {
				char *tmp;

				// =の左側の文字列の右側のスペース・TABを排除
				// スペース・TABがあれば下がっていく
				while( str1 < p_eq ) {
					if ( *(p_eq-1) == ' ' || *(p_eq-1) == '\t' ) {
						p_eq--;
					}
					else {
						break;
					}
				}

				*p_eq = 0;

				// =の左側の文字列の左側のスペース・TABを排除
				// スペース・TABがあれば上がっていく
				p_st = str1;
				while( p_st < p_eq ) {
					if ( *p_st == ' ' || *p_st == '\t' ) {
						p_st++;
					}
					else {
						break;
					}
				}

				tmp = _strdup(p_st);
				if ( tmp ) {
					safefree( str1 );
					str1 = tmp;
				}

				return str1;
			}
			safefree( str1 );
		}

		return _strdup( "" );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 文字列中の=よりも後の部分を取り出す
// AfterEq$( str$ )
char *rfunc_AfterEq_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		char *str1;
		char *p_eq, *p_ed;

		str1 = _strdup( ARG1.text );
		if ( str1 ) {
			p_eq = strchr( str1, '=' );
			if ( p_eq ) {
				char *rv;

				p_eq++;

				// =の右側の文字列の左側のスペース・TABを排除
				// スペース・TABがあればあがっていく
				while( *p_eq ) {
					if ( *p_eq == ' ' || *p_eq == '\t' ) {
						p_eq++;
					}
					else {
						break;
					}
				}

				// =の右側の文字列の右側のスペース・TABを排除
				p_ed = p_eq + lstrlen(p_eq);
				while( p_eq < p_ed ) {
					if ( *(p_ed-1) == ' ' || *(p_ed-1) == '\t' ) {
						p_ed--;
					}
					else {
						break;
					}
				}
				*p_ed = 0;

				rv = _strdup( p_eq );
				if ( rv ) {
					safefree( str1 );
					str1 = rv;
				}

				return str1;
			}
			safefree( str1 );
		}

		return _strdup( "" );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// コマンドラインで指定されたn番目のパラメータを返す
// GetIParam$( n ) … ↑(__argv)
// GetIParam$() … 指定されたコマンドラインをそのまま返す(GetCommandLine API)
char *rfunc_GetIParam_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "i") ) {
		return _strdup( ( (unsigned)__argc > ARG1.integer ) ? __argv[ARG1.integer] : "" );
	}
	else if ( args_typecheck(args, "") ) {
		return _strdup( GetCommandLine() );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// OSの各種バージョン情報を取得する(文字列返却バージョン)
// GetOSInfo$(info)
char *rfunc_GetOSInfo_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "s") ) {
		OSVERSIONINFOEX oviex;

		ZeroMemory( &oviex, sizeof(OSVERSIONINFOEX) );
		oviex.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
		GetVersionEx((OSVERSIONINFO *)&oviex);

		if ( _stricmp(ARG1.text, "CSDVersion") == 0 ) {
			return _strdup( oviex.szCSDVersion );	// 追加情報（主にサービスパック）
		}

		return _strdup( "" );
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 書式化した文字列を返す
// FormatString$( format$, arg1, ... )
char *rfunc_FormatString_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args->type == UFCT_ARG_STRING ) {
		struct ARGS *p;
		char *f = args->v.text, *f2;	// 書式文字列
		char *o = _strdup("");			// 返却文字列
		char c1[2]="x", c2[3]="xx";	// １文字の文字列コピー用作業域

		while( *f ) {
			if ( ISKANJI1M( *f ) ) { // 漢字の１バイト目
				if ( f[1] ) {
					c2[0] = f[0];
					c2[1] = f[1];
                    o = realloc_strcat(o, c2);
					f++;
				}
				else {
                    break;
				}
			}
			else if ( *f == '{' ) { // 引数取り込み左端( {index[,[-]W][:C*]} …… {0,-10:X3} : 0番目引数を左詰10桁[足りない分はスペース]で、3桁16進先頭0から始まる )
				int  width = 0, keta = 0, msize;
                char index, type = 's', i;
				char *pf;

				f++;
				if ( *f == '{' ) {	// {{ → { と表示
					c1[0] = *f;
                    o = realloc_strcat(o, c1);
					f++;
				}
				else {
					f2 = strchr(f, '}');	// '}' を発見
					if ( f2 ) {
						index = (char)atoi(f);
					}
					else {
						break;
					}

					if ( f[0] == '}' ) { // 書式文字が一切なかったら解析終了
						f = f2;
						continue;
					}

					// インデックスを取得
					index = (char)atoi(f);

					// 幅を取得（負の数なら左詰、正の数なら右詰、実際の桁数より足りない場合は実際の桁数が幅となる）
					//                                           実際の桁数より多い場合は、足りない部分はスペースで埋められる
					pf = strchr(f, ',');
					if ( pf && pf < f2 ) {
						pf++;
                        width = atoi(pf);
					}

					// 書式文字と桁数を取得（１文字目が書式文字、２文字目以降が桁数。桁数は省略可）
					// 書式文字：u - 10進数値、o - 8進数値、x - 16進数値[ただし10〜15はa〜fで]
					//           s - 文字列                 X - 16進数値[ただし10〜15はA〜Fで]
					// 桁数：実際の桁数より足りない場合は、実際の桁数が幅となる
					//       実際の桁数より多い場合は、足りない部分は0で補われる。
					pf = strchr(f, ':');
					if ( pf && pf < f2 ) {
						pf++;
						switch ( *pf ) {
							case 'u':
							case 'U':
								type = 'u';
								break;

							case 'o':
							case 'O':
								type = 'o';
								break;

							case 'x':
							case 'X':
								type = *pf;
								break;

							default : // 's'を想定
								type = 's';
								break;
						}
                        keta = atoi(pf+1);
					}

					// これまでの情報を元に表示を行う
					p = args->next;
					for(i=0 ; i<index ; i++) {
						if ( p ) {
							p = p->next;
						}
					}

					if ( p ) {
						char *pbuf, *pbuf2, fmt[15];
						// 12, width, keta, 実引数長の中で、最も大きいもの+1を、確保するメモリサイズとする
						msize = 12;
						if ( msize < width ) {
							msize = width;
						}
						if ( msize < keta ) {
							msize = keta;
						}
						if ( p->type == UFCT_ARG_STRING && msize < lstrlen(p->v.text) ) {
                            msize = lstrlen(p->v.text);
						}
						msize++;

						pbuf = zalloc(msize);
						pbuf2 = zalloc(msize);
						if ( pbuf && pbuf2 ) {
							if ( type == 'u' ) {
								unsigned int u;

								if ( p->type == UFCT_ARG_STRING ) {
									u = atou(p->v.text);
								}
								else if ( p->type == UFCT_ARG_INT ) {
									u = p->v.integer;
								}
								else {
									u = 0;
								}
								wsprintf(fmt, "%%0%uu", keta);
								wsprintf(pbuf, fmt, u);

								wsprintf(fmt, "%%%ds", width);
								wsprintf(pbuf2, fmt, pbuf);

								o = realloc_strcat(o, pbuf2);
							}
							else if ( type == 'o' ) {
								unsigned int u;

								if ( p->type == UFCT_ARG_STRING ) {
									u = atou(p->v.text);
								}
								else if ( p->type == UFCT_ARG_INT ) {
									u = p->v.integer;
								}
								else {
									u = 0;
								}
								wsprintf(fmt, "%%0%uo", keta);
								wsprintf(pbuf, fmt, u);

								wsprintf(fmt, "%%%ds", width);
								wsprintf(pbuf2, fmt, pbuf);

								o = realloc_strcat(o, pbuf2);
							}
							else if ( type == 'x' ) {
								unsigned int u;

								if ( p->type == UFCT_ARG_STRING ) {
									u = atou(p->v.text);
								}
								else if ( p->type == UFCT_ARG_INT ) {
									u = p->v.integer;
								}
								else {
									u = 0;
								}
								wsprintf(fmt, "%%0%ux", keta);
								wsprintf(pbuf, fmt, u);

								wsprintf(fmt, "%%%ds", width);
								wsprintf(pbuf2, fmt, pbuf);

								o = realloc_strcat(o, pbuf2);
							}
							else if ( type == 'X' ) {
								unsigned int u;

								if ( p->type == UFCT_ARG_STRING ) {
									u = atou(p->v.text);
								}
								else if ( p->type == UFCT_ARG_INT ) {
									u = p->v.integer;
								}
								else {
									u = 0;
								}
								wsprintf(fmt, "%%0%uX", keta);
								wsprintf(pbuf, fmt, u);

								wsprintf(fmt, "%%%ds", width);
								wsprintf(pbuf2, fmt, pbuf);

								o = realloc_strcat(o, pbuf2);
							}
							else if ( type == 's' ) {
								char itbuf[16];
								char *s = "err";

								if ( p->type == UFCT_ARG_STRING ) {
									s = p->v.text;
								}
								else if ( p->type == UFCT_ARG_INT ) {
									if ( 0 == _ultoa_s(p->v.integer, itbuf, _countof(itbuf), 10) ) {
										s = itbuf;
									}
								}
								else {
									s = "";
								}

								wsprintf(fmt, "%%%ds", width);
								wsprintf(pbuf2, fmt, s);

								o = realloc_strcat(o, pbuf2);
							}
						}
						safefree(pbuf2);
						safefree(pbuf);
					}


					f = f2;
				}
			}
			else {
				c1[0] = f[0];
				o = realloc_strcat(o, c1);
			}
			f++;
		}

		return o;
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 正規表現を用いて、文字列の置換を行う(Boostライブラリによる)
// regex_replace( str, re, rep [, option] )
// str : 検査対象文字列
// re  : 正規表現
// rep : 置換後文字列（フォーマット）
// option : オプション(i,g,s)
// 戻り値 : 置換後文字列
char *rfunc_Regex_Replace_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sss") ) {
		return cpp_regex_replace(ARG1.text, ARG2.text, ARG3.text, "");
	}
	else if ( args_typecheck(args, "ssss") ) {
		return cpp_regex_replace(ARG1.text, ARG2.text, ARG3.text, ARG4.text);
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// インターバルタイマの設定
// SetTimer(label$, msec)
// label$ : タイムアウトの時に呼び出されるラベル
// msec : タイムアウトまでの時間（ミリ秒単位）
// 戻り値：1 - 成功、0 - 失敗
unsigned int rfunc_SetTimer(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "si") ) {
		if (ARG1.text[0] == 0 || ARG2.integer == 0) {
			// とび先ラベルが0の場合、または、時間が０の場合は、タイマ解除
			if (KillTimer(hWnd, EDITDIALOG_TIMERID) != 0) {
				safefree(pszEditDialogTimerLabel);
				return 1; // 成功
			}
		}
		else {
			if (EDITDIALOG_TIMERID == SetTimer(hWnd, EDITDIALOG_TIMERID, ARG2.integer, NULL)) {
				safefree(pszEditDialogTimerLabel);
				pszEditDialogTimerLabel = _strdup(ARG1.text);
				if (pszEditDialogTimerLabel) {
					return 1; // 成功
				}
				else {
					// メモリ不足による失敗の場合は、タイマを無効化する
					KillTimer(hWnd, EDITDIALOG_TIMERID);
				}
			}
		}
		return 0; // 失敗
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// インターバルタイマの解除
// KillTimer()
// 戻り値：1 - 成功、0 - 失敗
unsigned int rfunc_KillTimer(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "") ) {
		if (KillTimer(hWnd, EDITDIALOG_TIMERID) != 0) {
			safefree(pszEditDialogTimerLabel);
			return 1; // 成功
		}
		return 0; // 失敗
	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 複数行編集を行う（delim$で指定された1文字を区切りとして、改行に置き換えて編集）
// MultiLineEdit$( item$, data$, delim$ )
char *rfunc_MultiLineEdit_dd(HWND hWnd, const struct ARGS *args, BYTE *result)
{
	if ( args_typecheck(args, "sss") ) {
		char *buf1 = _strdup("");
		char *buf2 = _strdup(ARG2.text);

		if (lv_edititem_m(hWnd, &buf1, &buf2, NULL, ARG1.text, ARG3.text)) {
			free(buf1);
			return buf2;
		}
		else {
			free(buf2);
			free(buf1);
			return _strdup(ARG2.text);
		}

	}
	else {
		*result = UFC_MISSMATCH_ARGS; // 引数がおかしい
		return 0;
	}
}

// 数値返却型関数一覧（すべて小文字で記述し、アルファベット順にソートすること）
// 注意。SORTコマンドだと、"_" < "3" だが、strcmp では "_" > "3" であるので注意すること。
const RFUNCS rfuncs[] = {
	{"active",rfunc_active},
	{"arrayadd",rfunc_ArrayAdd},
	{"arrayinit",rfunc_ArrayInit},
	{"bit",rfunc_bit},
	{"boldtext",rfunc_boldtext},
	{"border",rfunc_border},
	{"callcmd",rfunc_CallCmd},
	{"callcmdasync",rfunc_CallCmdAsync},
	{"calldll",rfunc_CallDll},
	{"callexe",rfunc_CallExe},
	{"callexeasync",rfunc_CallExeAsync},
	{"checkbox",rfunc_checkbox},
	{"checkbox3",rfunc_checkbox3},
	{"checkbox_bin",rfunc_checkbox_bin},
	{"checkbox_bindw",rfunc_checkbox_bindw},
	{"checkmultiedit",rfunc_checkmultiedit},
	{"colorbutton",rfunc_ColorButton},
	{"combobox",rfunc_ComboBox},
	{"combobox_dw",rfunc_ComboBox_dw},
	{"combobox_sz",rfunc_ComboBox_sz},
	{"copyfile",rfunc_CopyFile},
	{"copyfiles",rfunc_CopyFiles},
	{"createbutton",rfunc_CreateButton},
	{"createdirectory",rfunc_createdirectory},
	{"createlistview",rfunc_CreateListView},
	{"createshortcut",rfunc_createshortcut},
	{"deletedirectory",rfunc_DeleteDirectory},
	{"deletefile",rfunc_DeleteFile},
	{"deletefiles",rfunc_DeleteFiles},
	{"disable",rfunc_disable},
	{"editbox",rfunc_editbox},
	{"editbox_num",rfunc_editbox_num},
	{"emptydirectory",rfunc_EmptyDirectory},
	{"enable",rfunc_enable},
	{"endcheckboxlist",rfunc_EndCheckBoxList},
	{"endgroupbox",rfunc_endgroupbox},
	{"error",rfunc_error},
	{"fappend",rfunc_fappend},
	{"fappendbinary",rfunc_fappendbinary},
	{"fileexist",rfunc_fileexist},
	{"fmodebinary",rfunc_FModeBinary},
	{"fmodewide",rfunc_FModeWide},
	{"fread",rfunc_fread},
	{"freadbinary",rfunc_freadbinary},
	{"fwrite",rfunc_fwrite},
	{"fwritebinary",rfunc_fwritebinary},
	{"getasciicode",rfunc_GetAsciiCode},
	{"getcheckbox",rfunc_getcheckbox},
	{"getcolorbutton",rfunc_GetColorButton},
	{"getcomboboxcursor",rfunc_GetComboBoxCursor},
	{"getcurrentday",rfunc_GetCurrentDay},
	{"getcurrentdayofweek",rfunc_GetCurrentDayOfWeek},
	{"getcurrenthour",rfunc_GetCurrentHour},
	{"getcurrentmilliseconds",rfunc_GetCurrentMilliseconds},
	{"getcurrentminute",rfunc_GetCurrentMinute},
	{"getcurrentmonth",rfunc_GetCurrentMonth},
	{"getcurrentsecond",rfunc_GetCurrentSecond},
	{"getcurrentyear",rfunc_GetCurrentYear},
	{"geteditboxnum",rfunc_geteditboxnum},
	{"getfsize",rfunc_getfsize},
	{"getieversion",rfunc_GetIEVersion},
	{"getiparamnum",rfunc_GetIParamNum},
	{"getmultieditlinecount",rfunc_GetMultiEditLineCount},
	{"getosinfo",rfunc_GetOSInfo},
	{"getstrbit",rfunc_getstrbit},
	{"getsystemmetrics",rfunc_GetSystemMetrics},
	{"getwindowsversion",rfunc_GetWindowsVersion},
	{"icon",rfunc_icon},
	{"information",rfunc_information},
	{"inideletekey",rfunc_iniDeleteKey},
	{"ininumkey",rfunc_iniNumKey},
	{"ininumsection",rfunc_iniNumSection},
	{"inireadbinary",rfunc_iniReadBinary},
	{"inireadint",rfunc_iniReadInt},
	{"inireadinteger",rfunc_iniReadInt},
	{"inireadsection",rfunc_iniReadSection},
	{"iniwritebinary",rfunc_iniWriteBinary},
	{"iniwriteint",rfunc_iniWriteInt},
	{"iniwriteinteger",rfunc_iniWriteInt},
	{"iniwritesection",rfunc_iniWriteSection},
	{"iniwritestring",rfunc_iniWriteString},
	{"ischanged",rfunc_isChanged},
	{"isid",rfunc_isID},
	{"isidenabled",rfunc_isIDEnabled},
	{"iskanji1",rfunc_isKanji1},
	{"isnt",rfunc_isnt},
	{"isstandardaccount",rfunc_isStandardAccount},
	{"keylist",rfunc_KeyList},
	{"killtimer",rfunc_KillTimer},
	{"listview_isselected",rfunc_ListView_isSelected},
	{"listviewadd",rfunc_ListViewAdd},
	{"listviewdelete",rfunc_ListViewDelete},
	{"listviewgetcursor",rfunc_ListViewGetCursor},
	{"listviewgetnum",rfunc_ListViewGetNum},
	{"listviewmultilineedit",rfunc_ListViewMultiLineEdit},
	{"listviewsearch",rfunc_ListViewSearch},
	{"listviewsetcursor",rfunc_ListViewSetCursor},
	{"listviewsettext",rfunc_ListViewSetText},
	{"messagebox",rfunc_textout},
	{"movefile",rfunc_MoveFile},
	{"movefiles",rfunc_MoveFiles},
	{"multiedit",rfunc_multiedit},
	{"multieditsearch",rfunc_MultiEditSearch},
	{"multitext",rfunc_multitext},
	{"notify",rfunc_notify},
	{"numid",rfunc_numID},
	{"playsound",rfunc_playsound},
	{"question",rfunc_question},
	{"question_okcancel",rfunc_question_okcancel},
	{"question_yesnocancel",rfunc_question_yesnocancel},
	{"reboot",rfunc_reboot},
	{"refresh",rfunc_refresh},
	{"regcreatekey",rfunc_regcreatekey},
	{"regdeleteallvalue",rfunc_regdeleteallvalue},
	{"regdeletekey",rfunc_regdeletekey},
	{"regdeletesubkeys",rfunc_regdeletesubkeys},
	{"regdeletevalue",rfunc_regdeletevalue},
	{"regex_match",rfunc_RegEx_Match},
	{"regex_search",rfunc_RegEx_Search},
	{"regkeyexist",rfunc_RegKeyExist},
	{"regnumkey",rfunc_RegNumKey},
	{"regnumvalue",rfunc_RegNumValue},
	{"regreadbinary",rfunc_RegReadBinary},
	{"regreadbit",rfunc_regreadbit},
	{"regreadbyte",rfunc_regreadbyte},
	{"regreadint",rfunc_regreadint},
	{"regreadinteger",rfunc_regreadint},
	{"regreadmultistring",rfunc_RegReadMultiString},
	{"regrenamekey",rfunc_regrenamekey},
	{"regrenamevalue",rfunc_RegRenameValue},
	{"regvalueexist",rfunc_RegValueExist},
	{"regvaluesize",rfunc_RegValueSize},
	{"regvaluetype",rfunc_RegValueType},
	{"regwritebinary",rfunc_RegWriteBinary},
	{"regwritebit",rfunc_regwritebit},
	{"regwritebyte",rfunc_regwritebyte},
	{"regwriteexpandstring",rfunc_regwriteexpandsz},
	{"regwriteexpandsz",rfunc_regwriteexpandsz},
	{"regwriteint",rfunc_regwriteint},
	{"regwriteinteger",rfunc_regwriteint},
	{"regwritemultistring",rfunc_RegWriteMultiString},
	{"regwritestring",rfunc_regwritesz},
	{"regwritesz",rfunc_regwritesz},
	{"resizeinit",rfunc_ResizeInit},
	{"searchdirectorys",rfunc_SearchDirectorys},
	{"searchfiles",rfunc_SearchFiles},
	{"setcheckbox",rfunc_setcheckbox},
	{"setcolorbutton",rfunc_SetColorButton},
	{"setcomboboxcursor",rfunc_SetComboBoxCursor},
	{"setcurrenttime",rfunc_SetCurrentTime},
	{"setdialogtitle",rfunc_SetDialogTitle},
	{"seteditbox",rfunc_seteditbox},
	{"seteditboxnum",rfunc_seteditboxnum},
	{"setenv",rfunc_setenv},
	{"setfocus",rfunc_setfocus},
	{"seticonbox",rfunc_seticonbox},
	{"settextctrl",rfunc_settextctrl},
	{"settimer",rfunc_SetTimer},
	{"setwindowtitle",rfunc_SetWindowTitle},
	{"sizeof",rfunc_sizeof},
	{"sleep",rfunc_sleep},
	{"space",rfunc_space},
	{"startcheckboxlist",rfunc_StartCheckBoxList},
	{"startgroupbox",rfunc_startgroupbox},
	{"stop",rfunc_stop},
	{"strlen",rfunc_strlen},
	{"strstr",rfunc_strstr},
	{"strstri",rfunc_strstri},
	{"text",rfunc_text},
	{"textout",rfunc_textout},
	{"toint",rfunc_toInt},
	{"valuelist",rfunc_ValueList},
	{"warning",rfunc_warning},
};

// 文字列返却型関数一覧（すべて小文字で記述し、アルファベット順にソートすること）
const RFUNCSD rfuncsd[] = {
	{"aftereq$",rfunc_AfterEq_dd},
	{"asciicode$",rfunc_AsciiCode_dd},
	{"beforeeq$",rfunc_BeforeEq_dd},
	{"calldll$",rfunc_CallDll_dd},
	{"dhelp$",rfunc_dhelp_dd},
	{"dhelpbuttons$",rfunc_dhelpbuttons_dd},
	{"dhelps$",rfunc_dhelps_dd},
	{"enumid$",rfunc_enumID_dd},
	{"enumkey$",rfunc_EnumKey_dd},
	{"enumvalue$",rfunc_EnumValue_dd},
	{"expandenvironmentstrings$",rfunc_ExpandEnvironmentStrings_dd},
	{"formatstring$",rfunc_FormatString_dd},
	{"fread$",rfunc_fread_dd},
	{"getcommondesktopdirectory$",rfunc_GetCommonDesktopDirectory_dd},
	{"getcommonprogramdirectory$",rfunc_GetCommonProgramDirectory_dd},
	{"getcontroltype$",rfunc_GetControlType_dd},
	{"getcurrentdirectory$",rfunc_getcurrentdirectory_dd},
	{"getdesktopdirectory$",rfunc_GetDesktopDirectory_dd},
	{"getdialogtitle$",rfunc_GetDialogTitle_dd},
	{"geteditbox$",rfunc_geteditbox_dd},
	{"getenv$",rfunc_getenv_dd},
	{"getextname$",rfunc_GetExtName_dd},
	{"geticonbox$",rfunc_geteditbox_dd},
	{"geticonname$",rfunc_geteditbox_dd},
	{"getinterpreterdirectory$",rfunc_GetInterpreterDirectory_dd},
	{"getiparam$",rfunc_GetIParam_dd},
	{"getmultieditline$",rfunc_GetMultiEditLine_dd},
	{"getosinfo$",rfunc_GetOSInfo_dd},
	{"getprogramdirectory$",rfunc_GetProgramDirectory_dd},
	{"getrscdirectory$",rfunc_GetRscDirectory_dd},
	{"getrscname$",rfunc_GetRscName_dd},
	{"getstrbyte$",rfunc_getstrbyte_dd},
	{"getsystemdirectory$",rfunc_getsystemdirectory_dd},
	{"gettextctrl$",rfunc_geteditbox_dd},
	{"getwindowsdirectory$",rfunc_getwindowsdirectory_dd},
	{"getwindowtitle$",rfunc_GetWindowTitle_dd},
	{"inienumkey$",rfunc_iniEnumKey_dd},
	{"inienumsection$",rfunc_iniEnumSection_dd},
	{"inireadstring$",rfunc_iniReadString_dd},
	{"input$",rfunc_input_dd},
	{"inputpassword$",rfunc_inputpassword_dd},
	{"left$",rfunc_left_dd},
	{"listviewgettext$",rfunc_ListViewGetText_dd},
	{"mid$",rfunc_mid_dd},
	{"multilineedit$", rfunc_MultiLineEdit_dd},
	{"regex_replace$",rfunc_Regex_Replace_dd},
	{"regreadstring$",rfunc_regreadsz_dd},
	{"regreadsz$",rfunc_regreadsz_dd},
	{"replace$",rfunc_replace_dd},
	{"right$",rfunc_right_dd},
	{"selectfolder$",rfunc_SelectFolder_dd},
	{"selectopenfile$",rfunc_SelectOpenFile_dd},
	{"selectsavefile$",rfunc_SelectSaveFile_dd},
	{"signedtostr$",rfunc_SignedToStr_dd},
	{"strlwr$",rfunc_strlwr_dd},
	{"strupr$",rfunc_strupr_dd},
	{"substr$",rfunc_mid_dd},
	{"substring$",rfunc_mid_dd},
	{"tostr$",rfunc_toStr_dd},
	{"tostr16$",rfunc_toStr16_dd},
	{"tostr2$",rfunc_toStr2_dd},
	{"tostr8$",rfunc_toStr8_dd},
};

// 数値返却型関数の呼出
unsigned int funccall(HWND hWnd, const char *funcname, const struct ARGS *args, BYTE *result)
{
	char funclwr[FUNCLENGTH+1] = "";	// エラー時に$を付けて再試行するための "+1"
	RFUNCS *prfunc;

	if ( strlen(funcname) < FUNCLENGTH ) { // 関数名の長さが全関数の長さより短かったら正常処理
		                                   // (本来、ここではFUNCLENGTHではなく_countofを使いたい
		                                   //  ところだが、あとで$を付けるかもしれない都合で
		                                   //  使わないでいる。以下同様)
		// 関数名を小文字にしておく（あとでサーチに手間をかけないようにするため）
		strcpy_s(funclwr, FUNCLENGTH, funcname);
		_strlwr_s(funclwr, FUNCLENGTH);

		// R-Script関数をバイナリサーチ
		prfunc = (RFUNCS *)bsearch(funclwr, rfuncs, _countof(rfuncs), sizeof(RFUNCS), strcmp);

		if (prfunc) { // 関数が見つかった
			*result = UFC_SUCCESS;
			return prfunc->pfunc(hWnd, args, result);
		}
		else {	// 関数名が見つからない
			// $を付けるべきだった？かもしれないのでそれをサーチ
			RFUNCSD *prfuncd;

			strcat_s(funclwr, _countof(funclwr), "$");
			prfuncd = (RFUNCSD *)bsearch(funclwr, rfuncsd, _countof(rfuncsd), sizeof(RFUNCSD), strcmp);

			if (prfuncd) {
				// $を付けたら関数名がヒット→$を付けるようにエラーメッセージを出力する
				*result = UFS_NEED_DOLLAR;
			}
			else {
				// それでも関数名が見つけられない
				*result = UFC_UNKNOWN_FUNCNAME;
			}
		}
	}
	else {
		// 関数名が異常に長い場合は、関数名が見つけられなかったことにして終了
		*result = UFC_UNKNOWN_FUNCNAME;
	}

	// エラー
	return 0xfffffffe;

}

// 文字列返却型関数の呼出し
// (戻り値はstrdupで確保したメモリであるので、freeで解放すること)
char *funccall_d(HWND hWnd, const char *funcname, const struct ARGS *args, BYTE *result)
{
	char funclwr[FUNCLENGTH] = "";
	RFUNCSD *prfuncd;

	if ( strlen(funcname) < _countof(funclwr) ) { // 関数名の長さが全関数の長さより短かったら正常処理
		// 関数名を小文字にしておく（あとでサーチに手間をかけないようにするため）
		strcpy_s(funclwr, _countof(funclwr), funcname);
		_strlwr_s(funclwr, _countof(funclwr));

		// R-Script関数をバイナリサーチ
		prfuncd = (RFUNCSD *)bsearch(funclwr, rfuncsd, _countof(rfuncsd), sizeof(RFUNCSD), strcmp);

		if (prfuncd) { // 関数が見つかった
			*result = UFC_SUCCESS;
			return prfuncd->pfuncd(hWnd, args, result);
		}
		else {	// 関数名が見つからない
			*result = UFC_UNKNOWN_FUNCNAME;
		}
	}
	else {
		// 関数名が異常に長い場合は、関数名が見つけられなかったことにして終了
		*result = UFC_UNKNOWN_FUNCNAME;
	}

	// エラー
	return 0;
}
