/******************************************************************************
Ootake

 [KeyConfig.cpp]
	PCEゲームパッドやショートカットキーの割り当て設定を行うフォーム

Copyright(C)2006-2024 Kitao Nakamura.
	改造版・後継版を公開なさるときは必ずソースコードを添付してください。
	その際に事後でかまいませんので、ひとことお知らせいただけると幸いです。
	商的な利用は禁じます。
	あとは「GNU General Public License(一般公衆利用許諾契約書)」に準じます。

******************************************************************************/
#define _CRT_SECURE_NO_DEPRECATE

#define DIRECTINPUT_VERSION	0x0500	//Kitao追加。環境にもよるかもしれないが、DirectInput5が軽い。7だとやや遅延あり。スペースハリアーがわかりやすい。

#include <string.h>
#include "KeyConfig.h"
#include "App.h"
#include "PadConfig.h"
#include "resource.h"
#include "JoyPad.h"
#include "TurboConfig.h"
#include "Printf.h" //テスト用


#define LINE_LEN	73
#define N_LINES		21

enum OptionComponent
{
	COMBOBOX_PADNUM = 1,
	BUTTON_DPAD,
	EDIT_DPAD,
	BUTTON_2BPAD,
	EDIT_2BPAD,
	BUTTON_TURBO,
	BUTTON_3BPAD,
	EDIT_3BPAD,
	BUTTON_6BPAD,
	EDIT_6BPAD,
	BUTTON_FUNCTION,
	EDIT_FUNCTION,
	COMBOBOX_PADORD,
	BUTTON_HELP,
	BUTTON_DEFAULT,
	BUTTON_CLOSE,
};

static HWND			_hWndC[BUTTON_CLOSE]; //各コンポーネントのハンドル

static HBRUSH		_hMyBrush; //自作ブラシ色
static HFONT		_hFontB; //ボタン用フォント
static HBRUSH		_hEditBrush; //EDITの枠の色

static Uint32		_FontWidth;
static Uint32		_FontHeight;
static const char*	_pCaption = "\"Ootake\" PCE Pad Setting";
static HINSTANCE	_hInstance = NULL;
static HWND 		_hWnd = NULL;
static HWND 		_hParentWnd = NULL;

static Sint32		_PadID;
static Sint32		_PadOrd;
static Sint32		_SetOk = -1; //戻り値。設定完了なら1。キャンセルなら-1。未設定中は0。
static Sint32*		_pSetOk;


//フォントの高さを取得
static Uint32
get_font_height(
	HWND			hWnd)
{
	HDC 			hDC;
	HFONT			hFont;
	HFONT			hFontOld;
	TEXTMETRIC		tm;

	hDC 	 = GetDC(hWnd);
	hFont	 = (HFONT)GetStockObject(OEM_FIXED_FONT);	 /* 固定ピッチフォント */
	hFontOld = (HFONT)SelectObject(hDC, hFont);

	GetTextMetrics(hDC, &tm);

	SelectObject(hDC, hFontOld);
	DeleteObject(hFont);
	ReleaseDC(hWnd, hDC);

	return (Uint32)(tm.tmHeight);
}

//フォントの横幅を取得
static Uint32
get_font_width(
	HWND			hWnd)
{
	HDC 			hDC;
	HFONT			hFont;
	HFONT			hFontOld;
	TEXTMETRIC		tm;

	hDC 	 = GetDC(hWnd);
	hFont	 = (HFONT)GetStockObject(OEM_FIXED_FONT);	 /* 固定ピッチフォント */
	hFontOld = (HFONT)SelectObject(hDC, hFont);

	GetTextMetrics(hDC, &tm);

	SelectObject(hDC, hFontOld);
	DeleteObject(hFont);
	ReleaseDC(hWnd, hDC);

	return (Uint32)tm.tmAveCharWidth;
}

//Windowサイズを設定
static void
set_window_size(
	HWND			hWnd)
{
	RECT		rc;
	Uint32		wndW = _FontWidth  * LINE_LEN;
	Uint32		wndH = _FontHeight * N_LINES -2;

	SetRect(&rc, 0, 0, wndW, wndH);
	AdjustWindowRectEx(&rc, GetWindowLong(hWnd, GWL_STYLE),
						GetMenu(hWnd) != NULL, GetWindowLong(hWnd, GWL_EXSTYLE));
	wndW = rc.right - rc.left;
	wndH = rc.bottom - rc.top;
	GetWindowRect(_hParentWnd, &rc);
	MoveWindow(hWnd, rc.left, rc.top, wndW, wndH, TRUE);
}

//ジョイパッドの各ボタン設定コードを文字化する
void
KEYCONFIG_ToChrPcePad(
	char*	pBuf2,
	Sint16	data)
{
	char	buf[3+1]; //v2.96修正

	switch (data)
	{
		case -1:	sprintf(buf, "---"); break;//未設定

		case 0x00:	sprintf(buf, "SfR"); break;//DirectInputキーボード。DIKコード。日本語キーボードで右Shiftキーを押すと0x00で設定されるようなのでそれにも対応。
		case 0x01:	sprintf(buf, "Esc"); break;
		case 0x02:	sprintf(buf, " 1 "); break;
		case 0x03:	sprintf(buf, " 2 "); break;
		case 0x04:	sprintf(buf, " 3 "); break;
		case 0x05:	sprintf(buf, " 4 "); break;
		case 0x06:	sprintf(buf, " 5 "); break;
		case 0x07:	sprintf(buf, " 6 "); break;
		case 0x08:	sprintf(buf, " 7 "); break;
		case 0x09:	sprintf(buf, " 8 "); break;
		case 0x0A:	sprintf(buf, " 9 "); break;
		case 0x0B:	sprintf(buf, " 0 "); break;
		case 0x0C:	sprintf(buf, " - "); break;
		case 0x0D:	sprintf(buf, " = "); break;
		case 0x0E:	sprintf(buf, " Bs"); break;
		case 0x0F:	sprintf(buf, "Tab"); break;
		case 0x10:	sprintf(buf, " Q "); break;
		case 0x11:	sprintf(buf, " W "); break;
		case 0x12:	sprintf(buf, " E "); break;
		case 0x13:	sprintf(buf, " R "); break;
		case 0x14:	sprintf(buf, " T "); break;
		case 0x15:	sprintf(buf, " Y "); break;
		case 0x16:	sprintf(buf, " U "); break;
		case 0x17:	sprintf(buf, " I "); break;
		case 0x18:	sprintf(buf, " O "); break;
		case 0x19:	sprintf(buf, " P "); break;
		case 0x1A:	sprintf(buf, " [ "); break;
		case 0x1B:	sprintf(buf, " ] "); break;
		case 0x1C:	sprintf(buf, "Ent"); break;
		case 0x1D:	sprintf(buf, "CtL"); break;
		case 0x1E:	sprintf(buf, " A "); break;
		case 0x1F:	sprintf(buf, " S "); break;
		case 0x20:	sprintf(buf, " D "); break;
		case 0x21:	sprintf(buf, " F "); break;
		case 0x22:	sprintf(buf, " G "); break;
		case 0x23:	sprintf(buf, " H "); break;
		case 0x24:	sprintf(buf, " J "); break;
		case 0x25:	sprintf(buf, " K "); break;
		case 0x26:	sprintf(buf, " L "); break;
		case 0x27:	sprintf(buf, " ; "); break;
		case 0x28:	sprintf(buf, " ' "); break;
		case 0x29:	sprintf(buf, " ` "); break;
		case 0x2A:	sprintf(buf, "SfL"); break;
		case 0x2B:	sprintf(buf, " \\ "); break;
		case 0x2C:	sprintf(buf, " Z "); break;
		case 0x2D:	sprintf(buf, " X "); break;
		case 0x2E:	sprintf(buf, " C "); break;
		case 0x2F:	sprintf(buf, " V "); break;
		case 0x30:	sprintf(buf, " B "); break;
		case 0x31:	sprintf(buf, " N "); break;
		case 0x32:	sprintf(buf, " M "); break;
		case 0x33:	sprintf(buf, " , "); break;
		case 0x34:	sprintf(buf, " . "); break;
		case 0x35:	sprintf(buf, " / "); break;
		case 0x36:	sprintf(buf, "SfR"); break;
		case 0x37:	sprintf(buf, "n* "); break;
		case 0x38:	sprintf(buf, "AlL"); break;
		case 0x39:	sprintf(buf, "Spc"); break;
		case 0x3A:	sprintf(buf, "Cap"); break;
		case 0x3B:	sprintf(buf, " F1"); break;
		case 0x3C:	sprintf(buf, " F2"); break;
		case 0x3D:	sprintf(buf, " F3"); break;
		case 0x3E:	sprintf(buf, " F4"); break;
		case 0x3F:	sprintf(buf, " F5"); break;
		case 0x40:	sprintf(buf, " F6"); break;
		case 0x41:	sprintf(buf, " F7"); break;
		case 0x42:	sprintf(buf, " F8"); break;
		case 0x43:	sprintf(buf, " F9"); break;
		case 0x44:	sprintf(buf, "F10"); break;
		case 0x45:	sprintf(buf, "Num"); break;
		case 0x46:	sprintf(buf, "Scr"); break;
		case 0x47:	sprintf(buf, "n7 "); break;
		case 0x48:	sprintf(buf, "n8 "); break;
		case 0x49:	sprintf(buf, "n9 "); break;
		case 0x4A:	sprintf(buf, "n- "); break;
		case 0x4B:	sprintf(buf, "n4 "); break;
		case 0x4C:	sprintf(buf, "n5 "); break;
		case 0x4D:	sprintf(buf, "n6 "); break;
		case 0x4E:	sprintf(buf, "n+ "); break;
		case 0x4F:	sprintf(buf, "n1 "); break;
		case 0x50:	sprintf(buf, "n2 "); break;
		case 0x51:	sprintf(buf, "n3 "); break;
		case 0x52:	sprintf(buf, "n0 "); break;
		case 0x53:	sprintf(buf, "n. "); break;
		case 0x57:	sprintf(buf, "F11"); break;
		case 0x58:	sprintf(buf, "F12"); break;
		case 0x64:	sprintf(buf, "F13"); break;
		case 0x65:	sprintf(buf, "F14"); break;
		case 0x66:	sprintf(buf, "F15"); break;
		case 0x70:	sprintf(buf, "Kan"); break;
		case 0x79:	sprintf(buf, "Hen"); break;
		case 0x7B:	sprintf(buf, "MuH"); break;
		case 0x7D:	sprintf(buf, " \\ "); break;
		case 0x8D:	sprintf(buf, "n= "); break;
		case 0x90:	sprintf(buf, " ^ "); break;
		case 0x91:	sprintf(buf, " @ "); break;
		case 0x92:	sprintf(buf, " : "); break;
		case 0x93:	sprintf(buf, " _ "); break;
		case 0x94:	sprintf(buf, "Knj"); break;
		case 0x95:	sprintf(buf, "Stp"); break;
		case 0x96:	sprintf(buf, " AX"); break;
		case 0x97:	sprintf(buf, "J31"); break;
		case 0x9C:	sprintf(buf, "nEn"); break;
		case 0x9D:	sprintf(buf, "CtR"); break;
		case 0xB3:	sprintf(buf, "n, "); break;
		case 0xB5:	sprintf(buf, "n/ "); break;
		case 0xB7:	sprintf(buf, "Prn"); break;
		case 0xB8:	sprintf(buf, "AlR"); break;
		case 0xC5:	sprintf(buf, "Pau"); break;
		case 0xC7:	sprintf(buf, "Hom"); break;
		case 0xC8:	sprintf(buf, "arU"); break;
		case 0xC9:	sprintf(buf, "PUp"); break;
		case 0xCB:	sprintf(buf, "arL"); break;
		case 0xCD:	sprintf(buf, "arR"); break;
		case 0xCF:	sprintf(buf, "End"); break;
		case 0xD0:	sprintf(buf, "arD"); break;
		case 0xD1:	sprintf(buf, "PDn"); break;
		case 0xD2:	sprintf(buf, "Ins"); break;
		case 0xD3:	sprintf(buf, "Del"); break;
		case 0xDB:	sprintf(buf, "Win"); break;
		case 0xDC:	sprintf(buf, "Win"); break;
		case 0xDD:	sprintf(buf, "Men"); break;
		case 0xDE:	sprintf(buf, "Pow"); break;
		case 0xDF:	sprintf(buf, "Slp"); break;

		case 300:	sprintf(buf, "d1U"); break;//DirectInputパッド１本目
		case 301:	sprintf(buf, "d1R"); break;
		case 302:	sprintf(buf, "d1D"); break;
		case 303:	sprintf(buf, "d1L"); break;
		case 304:	sprintf(buf, "d1u"); break;//(小文字はハットスイッチ)
		case 305:	sprintf(buf, "d1r"); break;
		case 306:	sprintf(buf, "d1d"); break;
		case 307:	sprintf(buf, "d1l"); break;
		case 400:	sprintf(buf, "d2U"); break;//DirectInputパッド２本目
		case 401:	sprintf(buf, "d2R"); break;
		case 402:	sprintf(buf, "d2D"); break;
		case 403:	sprintf(buf, "d2L"); break;
		case 404:	sprintf(buf, "d2u"); break;
		case 405:	sprintf(buf, "d2r"); break;
		case 406:	sprintf(buf, "d2d"); break;
		case 407:	sprintf(buf, "d2l"); break;
		case 500:	sprintf(buf, "d3U"); break;//DirectInputパッド３本目
		case 501:	sprintf(buf, "d3R"); break;
		case 502:	sprintf(buf, "d3D"); break;
		case 503:	sprintf(buf, "d3L"); break;
		case 504:	sprintf(buf, "d3u"); break;
		case 505:	sprintf(buf, "d3r"); break;
		case 506:	sprintf(buf, "d3d"); break;
		case 507:	sprintf(buf, "d3l"); break;
		case 600:	sprintf(buf, "d4U"); break;//DirectInputパッド４本目
		case 601:	sprintf(buf, "d4R"); break;
		case 602:	sprintf(buf, "d4D"); break;
		case 603:	sprintf(buf, "d4L"); break;
		case 604:	sprintf(buf, "d4u"); break;
		case 605:	sprintf(buf, "d4r"); break;
		case 606:	sprintf(buf, "d4d"); break;
		case 607:	sprintf(buf, "d4l"); break;
		case 700:	sprintf(buf, "d5U"); break;//DirectInputパッド５本目
		case 701:	sprintf(buf, "d5R"); break;
		case 702:	sprintf(buf, "d5D"); break;
		case 703:	sprintf(buf, "d5L"); break;
		case 704:	sprintf(buf, "d5u"); break;
		case 705:	sprintf(buf, "d5r"); break;
		case 706:	sprintf(buf, "d5d"); break;
		case 707:	sprintf(buf, "d5l"); break;

		case 308:	sprintf(buf, "d1y"); break;//Z軸トリガL
		case 309:	sprintf(buf, "d1z"); break;//Z軸トリガR
		case 408:	sprintf(buf, "d2y"); break;
		case 409:	sprintf(buf, "d2z"); break;
		case 508:	sprintf(buf, "d3y"); break;
		case 509:	sprintf(buf, "d3z"); break;
		case 608:	sprintf(buf, "d4y"); break;
		case 609:	sprintf(buf, "d4z"); break;
		case 708:	sprintf(buf, "d5y"); break;
		case 709:	sprintf(buf, "d5z"); break;

		case 350:	sprintf(buf, "d11"); break;//ボタン１
		case 351:	sprintf(buf, "d12"); break;
		case 352:	sprintf(buf, "d13"); break;
		case 353:	sprintf(buf, "d14"); break;
		case 354:	sprintf(buf, "d15"); break;
		case 355:	sprintf(buf, "d16"); break;
		case 356:	sprintf(buf, "d17"); break;
		case 357:	sprintf(buf, "d18"); break;
		case 358:	sprintf(buf, "d19"); break;
		case 359:	sprintf(buf, "d1a"); break;
		case 360:	sprintf(buf, "d1b"); break;
		case 361:	sprintf(buf, "d1c"); break;
		case 362:	sprintf(buf, "d1d"); break;
		case 363:	sprintf(buf, "d1e"); break;
		case 364:	sprintf(buf, "d1f"); break;
		case 365:	sprintf(buf, "d1g"); break;//ボタン16
		case 450:	sprintf(buf, "d21"); break;
		case 451:	sprintf(buf, "d22"); break;
		case 452:	sprintf(buf, "d23"); break;
		case 453:	sprintf(buf, "d24"); break;
		case 454:	sprintf(buf, "d25"); break;
		case 455:	sprintf(buf, "d26"); break;
		case 456:	sprintf(buf, "d27"); break;
		case 457:	sprintf(buf, "d28"); break;
		case 458:	sprintf(buf, "d29"); break;
		case 459:	sprintf(buf, "d2a"); break;
		case 460:	sprintf(buf, "d2b"); break;
		case 461:	sprintf(buf, "d2c"); break;
		case 462:	sprintf(buf, "d2d"); break;
		case 463:	sprintf(buf, "d2e"); break;
		case 464:	sprintf(buf, "d2f"); break;
		case 465:	sprintf(buf, "d2g"); break;
		case 550:	sprintf(buf, "d31"); break;
		case 551:	sprintf(buf, "d32"); break;
		case 552:	sprintf(buf, "d33"); break;
		case 553:	sprintf(buf, "d34"); break;
		case 554:	sprintf(buf, "d35"); break;
		case 555:	sprintf(buf, "d36"); break;
		case 556:	sprintf(buf, "d37"); break;
		case 557:	sprintf(buf, "d38"); break;
		case 558:	sprintf(buf, "d39"); break;
		case 559:	sprintf(buf, "d3a"); break;
		case 560:	sprintf(buf, "d3b"); break;
		case 561:	sprintf(buf, "d3c"); break;
		case 562:	sprintf(buf, "d3d"); break;
		case 563:	sprintf(buf, "d3e"); break;
		case 564:	sprintf(buf, "d3f"); break;
		case 565:	sprintf(buf, "d3g"); break;
		case 650:	sprintf(buf, "d41"); break;
		case 651:	sprintf(buf, "d42"); break;
		case 652:	sprintf(buf, "d43"); break;
		case 653:	sprintf(buf, "d44"); break;
		case 654:	sprintf(buf, "d45"); break;
		case 655:	sprintf(buf, "d46"); break;
		case 656:	sprintf(buf, "d47"); break;
		case 657:	sprintf(buf, "d48"); break;
		case 658:	sprintf(buf, "d49"); break;
		case 659:	sprintf(buf, "d4a"); break;
		case 660:	sprintf(buf, "d4b"); break;
		case 661:	sprintf(buf, "d4c"); break;
		case 662:	sprintf(buf, "d4d"); break;
		case 663:	sprintf(buf, "d4e"); break;
		case 664:	sprintf(buf, "d4f"); break;
		case 665:	sprintf(buf, "d4g"); break;
		case 750:	sprintf(buf, "d51"); break;
		case 751:	sprintf(buf, "d52"); break;
		case 752:	sprintf(buf, "d53"); break;
		case 753:	sprintf(buf, "d54"); break;
		case 754:	sprintf(buf, "d55"); break;
		case 755:	sprintf(buf, "d56"); break;
		case 756:	sprintf(buf, "d57"); break;
		case 757:	sprintf(buf, "d58"); break;
		case 758:	sprintf(buf, "d59"); break;
		case 759:	sprintf(buf, "d5a"); break;
		case 760:	sprintf(buf, "d5b"); break;
		case 761:	sprintf(buf, "d5c"); break;
		case 762:	sprintf(buf, "d5d"); break;
		case 763:	sprintf(buf, "d5e"); break;
		case 764:	sprintf(buf, "d5f"); break;
		case 765:	sprintf(buf, "d5g"); break;

		case 800:	sprintf(buf, "x1U"); break;//XInputパッド１本目
		case 801:	sprintf(buf, "x1R"); break;
		case 802:	sprintf(buf, "x1D"); break;
		case 803:	sprintf(buf, "x1L"); break;
		case 900:	sprintf(buf, "x2U"); break;//XInputパッド２本目
		case 901:	sprintf(buf, "x2R"); break;
		case 902:	sprintf(buf, "x2D"); break;
		case 903:	sprintf(buf, "x2L"); break;
		case 1000:	sprintf(buf, "x3U"); break;//XInputパッド３本目
		case 1001:	sprintf(buf, "x3R"); break;
		case 1002:	sprintf(buf, "x3D"); break;
		case 1003:	sprintf(buf, "x3L"); break;
		case 1100:	sprintf(buf, "x4U"); break;//XInputパッド４本目
		case 1101:	sprintf(buf, "x4R"); break;
		case 1102:	sprintf(buf, "x4D"); break;
		case 1103:	sprintf(buf, "x4L"); break;

		case 850:	sprintf(buf, "x11"); break;//ボタン１
		case 851:	sprintf(buf, "x12"); break;
		case 852:	sprintf(buf, "x13"); break;
		case 853:	sprintf(buf, "x14"); break;
		case 854:	sprintf(buf, "x15"); break;
		case 855:	sprintf(buf, "x16"); break;
		case 856:	sprintf(buf, "x17"); break;
		case 857:	sprintf(buf, "x18"); break;
		case 858:	sprintf(buf, "x19"); break;
		case 859:	sprintf(buf, "x1a"); break;//ボタン10
		case 950:	sprintf(buf, "x21"); break;
		case 951:	sprintf(buf, "x22"); break;
		case 952:	sprintf(buf, "x23"); break;
		case 953:	sprintf(buf, "x24"); break;
		case 954:	sprintf(buf, "x25"); break;
		case 955:	sprintf(buf, "x26"); break;
		case 956:	sprintf(buf, "x27"); break;
		case 957:	sprintf(buf, "x28"); break;
		case 958:	sprintf(buf, "x29"); break;
		case 959:	sprintf(buf, "x2a"); break;
		case 1050:	sprintf(buf, "x31"); break;
		case 1051:	sprintf(buf, "x32"); break;
		case 1052:	sprintf(buf, "x33"); break;
		case 1053:	sprintf(buf, "x34"); break;
		case 1054:	sprintf(buf, "x35"); break;
		case 1055:	sprintf(buf, "x36"); break;
		case 1056:	sprintf(buf, "x37"); break;
		case 1057:	sprintf(buf, "x38"); break;
		case 1058:	sprintf(buf, "x39"); break;
		case 1059:	sprintf(buf, "x3a"); break;
		case 1150:	sprintf(buf, "x41"); break;
		case 1151:	sprintf(buf, "x42"); break;
		case 1152:	sprintf(buf, "x43"); break;
		case 1153:	sprintf(buf, "x44"); break;
		case 1154:	sprintf(buf, "x45"); break;
		case 1155:	sprintf(buf, "x46"); break;
		case 1156:	sprintf(buf, "x47"); break;
		case 1157:	sprintf(buf, "x48"); break;
		case 1158:	sprintf(buf, "x49"); break;
		case 1159:	sprintf(buf, "x4a"); break;

		default:	sprintf(buf, "%3X", data); break;
	}
	strcpy(pBuf2, buf);//値を返す
}

//ボタン設定の状態を表示
static void
update_status()
{
	PCEPAD	pcePad;
	char	buf[128];
	char	buf2[3+1]; //v2.96修正
	
	//十字キーの設定状態
	APP_GetPcePad2(_PadID, &pcePad);
	strcpy(buf, " up..[");
	KEYCONFIG_ToChrPcePad(buf2, pcePad.buttonU);
	strcat(buf, buf2);
	strcat(buf, "]  right..[");
	KEYCONFIG_ToChrPcePad(buf2, pcePad.buttonR);
	strcat(buf, buf2);
	strcat(buf, "]  down..[");
	KEYCONFIG_ToChrPcePad(buf2, pcePad.buttonD);
	strcat(buf, buf2);
	strcat(buf, "]  left..[");
	KEYCONFIG_ToChrPcePad(buf2, pcePad.buttonL);
	strcat(buf, buf2);
	strcat(buf, "]");
	SendDlgItemMessage(_hWnd, EDIT_DPAD, EM_SETSEL, 0, -1);	
	SendDlgItemMessage(_hWnd, EDIT_DPAD, EM_REPLACESEL, FALSE, (LPARAM)buf);	

	//２ボタンパッドのボタン設定状態
	strcpy(buf, " I..[");
	KEYCONFIG_ToChrPcePad(buf2, pcePad.button1);
	strcat(buf, buf2);
	strcat(buf, "]  II..[");
	KEYCONFIG_ToChrPcePad(buf2, pcePad.button2);
	strcat(buf, buf2);
	strcat(buf, "]  select..[");
	KEYCONFIG_ToChrPcePad(buf2, pcePad.buttonSel);
	strcat(buf, buf2);
	strcat(buf, "]  run..[");
	KEYCONFIG_ToChrPcePad(buf2, pcePad.buttonRun);
	strcat(buf, buf2);
	strcat(buf, "]");
	SendDlgItemMessage(_hWnd, EDIT_2BPAD, EM_SETSEL, 0, -1);	
	SendDlgItemMessage(_hWnd, EDIT_2BPAD, EM_REPLACESEL, FALSE, (LPARAM)buf);	

	//３ボタンパッドのボタン設定状態
	APP_GetPcePad3(_PadID, &pcePad);
	strcpy(buf, " I..[");
	KEYCONFIG_ToChrPcePad(buf2, pcePad.button1);
	strcat(buf, buf2);
	strcat(buf, "]  II..[");
	KEYCONFIG_ToChrPcePad(buf2, pcePad.button2);
	strcat(buf, buf2);
	strcat(buf, "]  IIIr..[");
	KEYCONFIG_ToChrPcePad(buf2, pcePad.button3);
	strcat(buf, buf2);
	strcat(buf, "]  IIIs..[");
	KEYCONFIG_ToChrPcePad(buf2, pcePad.button4);
	strcat(buf, buf2);
	strcat(buf, "]  sel..[");
	KEYCONFIG_ToChrPcePad(buf2, pcePad.buttonSel);
	strcat(buf, buf2);
	strcat(buf, "]  run..[");
	KEYCONFIG_ToChrPcePad(buf2, pcePad.buttonRun);
	strcat(buf, buf2);
	strcat(buf, "]");
	SendDlgItemMessage(_hWnd, EDIT_3BPAD, EM_SETSEL, 0, -1);	
	SendDlgItemMessage(_hWnd, EDIT_3BPAD, EM_REPLACESEL, FALSE, (LPARAM)buf);	

	//６ボタンパッドのボタン設定状態
	APP_GetPcePad6(_PadID, &pcePad);
	strcpy(buf, " I-VI..[");
	KEYCONFIG_ToChrPcePad(buf2, pcePad.button1);
	strcat(buf, buf2);
	strcat(buf, "][");
	KEYCONFIG_ToChrPcePad(buf2, pcePad.button2);
	strcat(buf, buf2);
	strcat(buf, "][");
	KEYCONFIG_ToChrPcePad(buf2, pcePad.button3);
	strcat(buf, buf2);
	strcat(buf, "][");
	KEYCONFIG_ToChrPcePad(buf2, pcePad.button4);
	strcat(buf, buf2);
	strcat(buf, "][");
	KEYCONFIG_ToChrPcePad(buf2, pcePad.button5);
	strcat(buf, buf2);
	strcat(buf, "][");
	KEYCONFIG_ToChrPcePad(buf2, pcePad.button6);
	strcat(buf, buf2);
	strcat(buf, "]  sel..[");
	KEYCONFIG_ToChrPcePad(buf2, pcePad.buttonSel);
	strcat(buf, buf2);
	strcat(buf, "]  run..[");
	KEYCONFIG_ToChrPcePad(buf2, pcePad.buttonRun);
	strcat(buf, buf2);
	strcat(buf, "]");
	SendDlgItemMessage(_hWnd, EDIT_6BPAD, EM_SETSEL, 0, -1);	
	SendDlgItemMessage(_hWnd, EDIT_6BPAD, EM_REPLACESEL, FALSE, (LPARAM)buf);	

	//ファンクションボタンの設定状態
	strcpy(buf, " function..[");
	KEYCONFIG_ToChrPcePad(buf2, (Sint16)APP_GetFunctionButton());
	strcat(buf, buf2);
	strcat(buf, "]");
	SendDlgItemMessage(_hWnd, EDIT_FUNCTION, EM_SETSEL, 0, -1);	
	SendDlgItemMessage(_hWnd, EDIT_FUNCTION, EM_REPLACESEL, FALSE, (LPARAM)buf);	
}

//Window表示を更新
static void
update_window(
	HWND			hWnd)
{
	HDC 			hDC;
	HFONT			hFont;
	HFONT			hFontOld;
	PAINTSTRUCT 	ps;
	Uint32			x;
	Uint32			y;

	/* 描画準備 */
	hDC = BeginPaint(hWnd, &ps);
	SetBkMode(hDC, OPAQUE);	//文字の背景を塗りつぶす
	SetBkColor(hDC, RGB(64,128,64));
	SetTextColor(hDC, RGB(240,240,240));
	hFont = (HFONT)GetStockObject(OEM_FIXED_FONT);
	hFontOld = (HFONT)SelectObject(hDC, hFont);

	x = _FontWidth*26;
	y = _FontHeight +3;
	if (JOYPAD_GetConnectSixButton())
		TextOut(hDC, x, y, "[ playing 6-Button Pad Game now! ]", 34);
	else if (JOYPAD_GetConnectThreeButton())
		TextOut(hDC, x, y, "[ playing 3-Button Pad Game now! ]", 34);
	else if (APP_GetInit()) //ゲームをすでに起動している場合(つまり起動時のSettingボタンからの呼び出しじゃない場合)
		TextOut(hDC, x, y, "[ playing 2-Button Pad Game now! ]", 34);
	else	
		TextOut(hDC, x, y, "[ Most games use 2-Button Pad. ]", 32);
	x = _FontWidth*3 +2;
	y += _FontHeight+_FontHeight/2 +6;
	TextOut(hDC, x, y, "PCE Directional Pad Setting  十字キー設定", 41);
	x += _FontWidth+_FontWidth/2 -1;
	y += _FontHeight*3;
	TextOut(hDC, x, y, "for 2-Button Pad Games", 22);
	y += _FontHeight*3;
	TextOut(hDC, x, y, "for 3-Button Pad Games", 22);
	y += _FontHeight*3;
	TextOut(hDC, x, y, "for 6-Button Pad Games", 22);
	x = _FontWidth*2 -1;
	y += _FontHeight*3;
	TextOut(hDC, x, y, "Function Button", 15);
	x += _FontWidth*36;
	TextOut(hDC, x, y, "Windows Pad Order パッド接続順序", 32);
	x = _FontWidth*2 -1;
	y += _FontHeight*4 +2;
	TextOut(hDC, x, y, "[d1?]=DirectInput [x1?]=XInput", 30);

	/* 終了処理 */
	EndPaint(hWnd, &ps);
	SelectObject(hDC, hFontOld);
	DeleteObject(hFont);
	ReleaseDC(hWnd, hDC);
}


static LRESULT CALLBACK
keyconfig_wnd_proc(
	HWND		hWnd,
	UINT		uMsg,
	WPARAM		wParam,
	LPARAM		lParam)
{
	MSG			msg;
	PCEPAD		pcePad; //ボタン設定用バッファ
	PCEPAD		pcePad0; //ボタン設定用バッファ。十字キー書き換え時用
	Sint32		setOk;

	switch (uMsg)
	{
	case WM_CREATE:
		EnableWindow(_hParentWnd, FALSE);//親ウィンドウを無効化してモーダルに。
		_hFontB = CreateFont(  0,						// 高さ。0 = デフォルト
		                       0,						// 幅。0なら高さに合った幅
    		                   0,						// 角度
        		               0,						// ベースラインとの角度
            		           FW_NORMAL,				// 太さ
                		       FALSE,					// イタリック
	                    	   FALSE,					// アンダーライン
		                       FALSE,					// 打ち消し線
    		                   0,						// 日本語を取り扱うときはSHIFTJIS_CHARSETにする。
        		               0,						// 出力精度
            		           0,						// クリッピング精度
                		       0,						// 出力品質
                    		   0,						// ピッチとファミリー
		                       ""						// 書体名
							); //英語のデフォルトフォントに設定
		_FontWidth	= get_font_width(hWnd);
		_FontHeight = get_font_height(hWnd);
		set_window_size(hWnd);
		_hEditBrush = CreateSolidBrush(RGB(0,0,0)); //EDITの枠の色
		break;

	case WM_PAINT:
		update_window(hWnd);
		break;

	case WM_CTLCOLORSTATIC:
		{	//読み取り専用のEDITはWM_CTLCOLORSTATICで扱われるのでここで色指定する。
			SetBkMode((HDC)wParam, OPAQUE);	//文字の背景を塗りつぶす
			SetTextColor(((HDC)wParam), RGB(255,255,255)); //EDITの文字色
			SetBkColor(((HDC)wParam), RGB(0,0,0)); //EDITの背景色
		}
		return (LRESULT)_hEditBrush; //枠表示に使う色を返す

	case WM_KEYDOWN:
		if (wParam == VK_ESCAPE)
		{
			KEYCONFIG_Deinit();
			return 0;
		}
		break;

	case WM_COMMAND:
		switch (LOWORD(wParam))
		{
			case COMBOBOX_PADNUM:
				//パッドナンバー選択
				if (HIWORD(wParam) == CBN_SELCHANGE)
				{
					_PadID = SendMessage(GetDlgItem(hWnd, COMBOBOX_PADNUM), CB_GETCURSEL, 0, 0) + 1;
					if (_PadID == 6)
						_PadID = 0; //v3.05追加
					update_status(); //ボタン設定の状況表示を更新
				}
				if (HIWORD(wParam) == CBN_CLOSEUP)
					SetFocus(GetDlgItem(hWnd, BUTTON_CLOSE)); //Closeボタンにフォーカス
				break;

			case BUTTON_DPAD:
				//十字キー設定
				setOk = 0;
				PADCONFIG_Init(_hWnd, _hInstance, 12, _PadID, 0, &pcePad, &setOk); //PadConfigダイアログを表示
				while (setOk == 0) //ダイアログが結果を返すまでループ
				{ 
					GetMessage(&msg ,NULL, 0, 0);
					TranslateMessage(&msg);
					DispatchMessage(&msg);
				}
				if (setOk == 1) //設定が成功した場合
				{
					//App.cppの_PcePadの十字キー部分だけを書き換える。2ボタン，3ボタン，6ボタンそれぞれを書き換える。
					ZeroMemory(&pcePad0, sizeof(pcePad0));
					APP_GetPcePad2(_PadID, &pcePad0);
					pcePad0.buttonU = pcePad.buttonU;
					pcePad0.buttonR = pcePad.buttonR;
					pcePad0.buttonD = pcePad.buttonD;
					pcePad0.buttonL = pcePad.buttonL;
					APP_SetPcePad2(_PadID, pcePad0);
					APP_GetPcePad3(_PadID, &pcePad0);
					pcePad0.buttonU = pcePad.buttonU;
					pcePad0.buttonR = pcePad.buttonR;
					pcePad0.buttonD = pcePad.buttonD;
					pcePad0.buttonL = pcePad.buttonL;
					APP_SetPcePad3(_PadID, pcePad0);
					APP_GetPcePad6(_PadID, &pcePad0);
					pcePad0.buttonU = pcePad.buttonU;
					pcePad0.buttonR = pcePad.buttonR;
					pcePad0.buttonD = pcePad.buttonD;
					pcePad0.buttonL = pcePad.buttonL;
					APP_SetPcePad6(_PadID, pcePad0);
					update_status(); //ボタン設定の状況表示を更新
					_SetOk = 1; //全体のフラグ(１つでも設定更新したらフラグを立てる)も立てる
				}
				break;

			case BUTTON_2BPAD:
				//２ボタンパッドのボタン設定
				setOk = 0;
				ZeroMemory(&pcePad, sizeof(pcePad));
				APP_GetPcePad2(_PadID, &pcePad);
				PADCONFIG_Init(_hWnd, _hInstance, 0, _PadID, 2, &pcePad, &setOk); //PadConfigダイアログを表示
				while (setOk == 0) //ダイアログが結果を返すまでループ
				{ 
					GetMessage(&msg ,NULL, 0, 0);
					TranslateMessage(&msg);
					DispatchMessage(&msg);
				}
				if (setOk == 1) //設定が成功した場合
				{
					APP_SetPcePad2(_PadID, pcePad);
					update_status(); //ボタン設定の状況表示を更新
					_SetOk = 1; //全体のフラグ(１つでも設定更新したらフラグを立てる)も立てる
				}
				break;
		
			case BUTTON_3BPAD:
				//３ボタンパッドのボタン設定
				setOk = 0;
				ZeroMemory(&pcePad, sizeof(pcePad));
				APP_GetPcePad3(_PadID, &pcePad);
				PADCONFIG_Init(_hWnd, _hInstance, 0, _PadID, 3, &pcePad, &setOk); //PadConfigダイアログを表示
				while (setOk == 0) //ダイアログが結果を返すまでループ
				{ 
					GetMessage(&msg ,NULL, 0, 0);
					TranslateMessage(&msg);
					DispatchMessage(&msg);
				}
				if (setOk == 1) //設定が成功した場合
				{
					APP_SetPcePad3(_PadID, pcePad);
					update_status(); //ボタン設定の状況表示を更新
					_SetOk = 1; //全体のフラグ(１つでも設定更新したらフラグを立てる)も立てる
				}
				break;
		
			case BUTTON_6BPAD:
				//６ボタンパッドのボタン設定
				setOk = 0;
				ZeroMemory(&pcePad, sizeof(pcePad));
				APP_GetPcePad6(_PadID, &pcePad);
				PADCONFIG_Init(_hWnd, _hInstance, 0, _PadID, 6, &pcePad, &setOk); //PadConfigダイアログを表示
				while (setOk == 0) //ダイアログが結果を返すまでループ
				{ 
					GetMessage(&msg ,NULL, 0, 0);
					TranslateMessage(&msg);
					DispatchMessage(&msg);
				}
				if (setOk == 1) //設定が成功した場合
				{
					APP_SetPcePad6(_PadID, pcePad);
					update_status(); //ボタン設定の状況表示を更新
					_SetOk = 1; //全体のフラグ(１つでも設定更新したらフラグを立てる)も立てる
				}
				break;

			case BUTTON_TURBO:
				//連射(Turbo)ボタン設定画面を呼び出す
				setOk = 0;
				TURBOCONFIG_Init(_hWnd, _hInstance, _PadID, &setOk);
				//メッセージループ
				while (setOk == 0) //ダイアログが結果を返すまでループ
				{ 
					GetMessage(&msg ,NULL, 0, 0);
					TranslateMessage(&msg);
					DispatchMessage(&msg);
				}
				if (setOk == 1) //設定が１つでも更新された場合
					_SetOk = 1; //全体のフラグ(１つでも設定更新したらフラグを立てる)も立てる
				break;
		
			case BUTTON_FUNCTION:
				//ファンクションボタンの設定
				APP_SetShortcutButton(_hWnd, _hInstance, 6);
				update_status(); //ボタン設定の状況表示を更新
				_SetOk = 1; //全体のフラグ(１つでも設定更新したらフラグを立てる)も立てる
				break;
		
			case COMBOBOX_PADORD:
				//Windowsパッド接続順序の設定
				if (HIWORD(wParam) == CBN_SELCHANGE)
				{
					_PadOrd = SendMessage(GetDlgItem(hWnd, COMBOBOX_PADORD), CB_GETCURSEL, 0, 0);
					APP_SetPadOrder(_PadOrd);
				}
				if (HIWORD(wParam) == CBN_CLOSEUP)
					SetFocus(GetDlgItem(hWnd, BUTTON_CLOSE)); //Closeボタンにフォーカス
				break;

			case BUTTON_HELP:
				//ボタン設定時に注意する点などを表示
				MessageBox(hWnd,
					"In real machine \"PC Engine(TG16)\", three types of game pad (    \n"
					"[2 button pad],[3 button pad],and [6 button pad]) exists.    \n"
					"In Ootake, setting of the button is set by three separate    \n"
					"settings. And, settings of three types are saved.    \n"
					"Press \"Yes\" button, and Setup-Screen appears. Please set it.    \n"
					"Most games are played with [2 button pad] setting.    \n"
					"+In real machine, [RUN] or [SELECT] either is selected at    \n"
					" [III]button of [3 button pad]. In Ootake, set [IIIr]button and    \n"
					" [IIIs]button, and they can be used at the same time.    \n\n"
					"In Japanese language\n"
					"PCエンジン（実機）には、「２ボタン」「３ボタン」「６ボタン」の   \n"
					"３種類のゲームパッドが存在します。   \n"
					"Ootakeでは、ボタン設定を３種類別々に設定し、別々に保存します。   \n"
					"ほとんどのゲームは「２ボタン」設定で遊びます。   \n"
					"※「３ボタンパッド」は、実機では３ボタン目が「RUN,SELECTどちら   \n"
					"　かを切り替えて使用」でしたが、Ootakeでは、RUNとSELECTを別々   \n"
					"　にそれぞれを「IIIrボタン,IIIsボタンとして設定」します。   ",
					"About \"PCE Pad Controller\" Setting", MB_OK);
				MessageBox(hWnd,
					"In the game for 2-5 players, connect multiple game pads to your    \n"
					"PC. Or, use the keyboard.    \n"
					"\n"
					"Witn Ootake, you can set the \"Function Button\" on your joypad.    \n"
					"[ Set the button you press with your left hand index finger(e.g.     \n"
					"  L2 button at the PS-Pad) to the \"Function Button\". It is    \n"
					"  very useful because it can be various settings at hand. ]    \n"
					"Function Button + [I]  button -> Switching of Auto-fire(Turbo)    \n"
					"Function Button + [II] button -> Switching of Auto-fire(Turbo)    \n"
					"Function Button + [RUN] button -> Switching the Game Soft.    \n"
					"Function Button + [SELECT] button -> Shooting of Screenshots    \n"
					"Function Button + Up,Down,Left,Right -> Audio Volume control    \n"
					"+ Operate while Pressing the Function Button    \n\n"
					"In Japanese language\n"
					"なお、２人〜５人プレイ対応のゲームでは、パソコンにゲームパッドを   \n"
					"複数つなげるか、キーボードの利用で、実機同様のプレイができます。   \n"
					"\n"
					"Ootakeは、ジョイパッド上に\"ファンクションボタン\"を設定できます。   \n"
					"[ 左手人差し指で押すボタン（例えばPS型ならL2ボタン）をファンク   \n"
					"  ションボタンに設定すると、手元で色々設定できるので便利です。]   \n"
					"ファンクションボタン＋ Iボタン or IIボタン…「連射設定の切替」   \n"
					"ファンクションボタン＋ RUNボタン…「ゲームの切替」   \n"
					"ファンクションボタン＋ SELECTボタン…「スクリーンショット保存」   \n"
					"ファンクションボタン＋ 十字キー…「音量の調節」   \n"
					"※上記の操作は、ファンクションボタンを押しながら操作します。   ",
					"About \"PCE Pad Controller\" Setting", MB_OK);
				break;
		
			case BUTTON_DEFAULT:
				//キー状態を全てデフォルトへ戻す。※ショートカットキーの設定もデフォルトへ。v2.94
				if (MessageBox(_hWnd,
					"Do you return \"Input Configuration all of Ootake\" to the default setting?    \n"
					"* All Ootake shortcut keys are also initialized.    \n\n"
					"※全てのOotakeショートカットキー設定も初期化されます。    ",
					"Ootake Input Initialize", MB_YESNO) == IDYES)
				{
					//パッド設定を初期化
					APP_InitPadConfiguration(TRUE);
					//各種ショートカットキー設定を初期化
					APP_InitShortcutConfiguration();
					_SetOk = 1; //全体のフラグ(１つでも設定更新したらフラグを立てる)も立てる
					//設定中の選択をパッド１へ戻す
					_PadID = 1;
					SendMessage(_hWndC[COMBOBOX_PADNUM], CB_SETCURSEL, 0, 0);
					update_status(); //ボタン設定の状況表示を更新
				}
				break;

			case BUTTON_CLOSE:
				KEYCONFIG_Deinit();
				return 0;
		}
		break;

	case WM_CLOSE:
		KEYCONFIG_Deinit();
		return 0;
	}

	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}


static BOOL
keyconfig_main()
{
	WNDCLASS	wc;
	HWND		hWnd;
	RECT		rc;
	Uint32		x;
	Uint32		y;
	HWND		hWndTmp;
	
	ZeroMemory(&wc, sizeof(wc));
	wc.style		 = 0;
	wc.lpfnWndProc	 = keyconfig_wnd_proc;
	wc.cbClsExtra	 = 0;
	wc.cbWndExtra	 = 0;
	wc.hInstance	 = _hInstance;
	wc.hIcon		 = LoadIcon(_hInstance, MAKEINTRESOURCE(IDI_ICON)); //アイコンを読み込み
	wc.hCursor		 = LoadCursor(NULL, IDC_ARROW);
	_hMyBrush = CreateSolidBrush(RGB(64,128,64)); //ブラシを作る
	wc.hbrBackground = _hMyBrush;
	wc.lpszMenuName  = "";
	wc.lpszClassName = _pCaption;

	if (RegisterClass(&wc) == 0)
		return FALSE;

	hWnd = CreateWindow(
		_pCaption,
		_pCaption,
		WS_SYSMENU | WS_CAPTION,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		0,
		0,
		_hParentWnd,
		NULL,
		_hInstance,
		NULL
	);

	if (hWnd == NULL)
		return FALSE;

	_hWnd = hWnd;

	//設定を行うパッドナンバー切替用コンボボックスを作成
	x = _FontWidth*2 -1;
	y = _FontHeight/2 +5;
	_hWndC[COMBOBOX_PADNUM] = CreateWindow(
		"COMBOBOX", "",
		WS_CHILD | WS_VISIBLE | WS_VSCROLL | CBS_DROPDOWNLIST,
		x, y, _FontWidth*23+2, _FontHeight*10,
		_hWnd, (HMENU)COMBOBOX_PADNUM, _hInstance, NULL
	);
	SendMessage(_hWndC[COMBOBOX_PADNUM], WM_SETFONT, (WPARAM)_hFontB, MAKELPARAM(TRUE, 0));//フォントを設定
	SendMessage(_hWndC[COMBOBOX_PADNUM], CB_ADDSTRING, 0, (LPARAM)"PCE Pad #1 Setting");
	SendMessage(_hWndC[COMBOBOX_PADNUM], CB_ADDSTRING, 0, (LPARAM)"PCE Pad #2 Setting");
	SendMessage(_hWndC[COMBOBOX_PADNUM], CB_ADDSTRING, 0, (LPARAM)"PCE Pad #3 Setting");
	SendMessage(_hWndC[COMBOBOX_PADNUM], CB_ADDSTRING, 0, (LPARAM)"PCE Pad #4 Setting");
	SendMessage(_hWndC[COMBOBOX_PADNUM], CB_ADDSTRING, 0, (LPARAM)"PCE Pad #5 Setting");
	SendMessage(_hWndC[COMBOBOX_PADNUM], CB_ADDSTRING, 0, (LPARAM)"PCE Pad #0 Setting"); //#1の代わりに1Player用として使える設定。Inputメニューで切り替える。使う設定にすると#1と#0どちらとも同時に使えるようにした。v3.05追加
	if (_PadID == 0)
		SendMessage(_hWndC[COMBOBOX_PADNUM], CB_SETCURSEL, 5, 0);//#0を選択
	else
		SendMessage(_hWndC[COMBOBOX_PADNUM], CB_SETCURSEL, _PadID-1, 0);//選択

	//十字キー設定ボタンを作成
	x = _FontWidth*3 +1;
	y = _FontHeight*4 +2;
	hWndTmp = CreateWindow(
		"BUTTON", "Set ",
		WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
		x, y, _FontWidth*6-1, _FontHeight+6,
		_hWnd, (HMENU)BUTTON_DPAD, _hInstance, NULL
	);
	SendMessage(hWndTmp, WM_SETFONT, (WPARAM)_hFontB, MAKELPARAM(TRUE, 0));

	//十字キー設定状況の表示エディット(Read Only)作成
	x += _FontWidth*6;
	hWndTmp = CreateWindow(
		"EDIT", " up..[J1U]  right..[ D ]  down..[ X ]  left..[ A ]",
		WS_CHILD | WS_VISIBLE | ES_LEFT | ES_READONLY,
		x, y, _FontWidth*62-1, _FontHeight+5,
		_hWnd, (HMENU)EDIT_DPAD, _hInstance, NULL
	);
	SendMessage(hWndTmp, WM_SETFONT, (WPARAM)_hFontB, MAKELPARAM(TRUE, 0));

	//２ボタンパッド設定のボタンを作成
	x = _FontWidth*4+_FontWidth/2;
	y += _FontHeight*3;
	hWndTmp = CreateWindow(
		"BUTTON", "Set ",
		WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
		x, y, _FontWidth*6-1, _FontHeight+6,
		_hWnd, (HMENU)BUTTON_2BPAD, _hInstance, NULL
	);
	SendMessage(hWndTmp, WM_SETFONT, (WPARAM)_hFontB, MAKELPARAM(TRUE, 0));

	//２ボタンパッド設定状況の表示エディット(Read Only)作成
	x += _FontWidth*6;
	hWndTmp = CreateWindow(
		"EDIT", " I..[ N ]  II..[Spc]  select..[Tab]  run..[Ent]",
		WS_CHILD | WS_VISIBLE | ES_LEFT | ES_READONLY,
		x, y, _FontWidth*43+_FontWidth/2+6, _FontHeight+5,
		_hWnd, (HMENU)EDIT_2BPAD, _hInstance, NULL
	);
	SendMessage(hWndTmp, WM_SETFONT, (WPARAM)_hFontB, MAKELPARAM(TRUE, 0));

	//連射(Turbo)ボタン設定のボタンを作成
	x += _FontWidth*45 +4;
	hWndTmp = CreateWindow(
		"BUTTON", "Turbo Button ",
		WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
		x, y, _FontWidth*15, _FontHeight+6,
		_hWnd, (HMENU)BUTTON_TURBO, _hInstance, NULL
	);
	SendMessage(hWndTmp, WM_SETFONT, (WPARAM)_hFontB, MAKELPARAM(TRUE, 0));

	//３ボタンパッド設定のボタンを作成
	x = _FontWidth*4+_FontWidth/2;
	y += _FontHeight*3;
	hWndTmp = CreateWindow(
		"BUTTON", "Set ",
		WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
		x, y, _FontWidth*6-1, _FontHeight+6,
		_hWnd, (HMENU)BUTTON_3BPAD, _hInstance, NULL
	);
	SendMessage(hWndTmp, WM_SETFONT, (WPARAM)_hFontB, MAKELPARAM(TRUE, 0));

	//３ボタンパッド設定状況の表示エディット(Read Only)作成
	x += _FontWidth*6;
	hWndTmp = CreateWindow(
		"EDIT", " I..[ N ]  II..[Spc]  IIIr..[ B ]  IIIs..[ V ]  sel..[Tab]  run..[Ent]",
		WS_CHILD | WS_VISIBLE | ES_LEFT | ES_READONLY,
		x, y, _FontWidth*60+_FontWidth/2-1, _FontHeight+5,
		_hWnd, (HMENU)EDIT_3BPAD, _hInstance, NULL
	);
	SendMessage(hWndTmp, WM_SETFONT, (WPARAM)_hFontB, MAKELPARAM(TRUE, 0));

	//６ボタンパッド設定のボタンを作成
	x = _FontWidth*4+_FontWidth/2;
	y += _FontHeight*3;
	hWndTmp = CreateWindow(
		"BUTTON", "Set ",
		WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
		x, y, _FontWidth*6-1, _FontHeight+6,
		_hWnd, (HMENU)BUTTON_6BPAD, _hInstance, NULL
	);
	SendMessage(hWndTmp, WM_SETFONT, (WPARAM)_hFontB, MAKELPARAM(TRUE, 0));

	//６ボタンパッド設定状況の表示エディット(Read Only)作成
	x += _FontWidth*6;
	hWndTmp = CreateWindow(
		"EDIT", " I-VI..[ N ][Spc][ V ][ F ][ G ][ H ]  sel..[Tab]  run..[Ent]",
		WS_CHILD | WS_VISIBLE | ES_LEFT | ES_READONLY,
		x, y, _FontWidth*60+_FontWidth/2-1, _FontHeight+5,
		_hWnd, (HMENU)EDIT_6BPAD, _hInstance, NULL
	);
	SendMessage(hWndTmp, WM_SETFONT, (WPARAM)_hFontB, MAKELPARAM(TRUE, 0));

	//ファンクションボタン設定のボタンを作成
	x = _FontWidth*2 -2;
	y += _FontHeight*3;
	hWndTmp = CreateWindow(
		"BUTTON", "Set ",
		WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
		x, y, _FontWidth*6-1, _FontHeight+6,
		_hWnd, (HMENU)BUTTON_FUNCTION, _hInstance, NULL
	);
	SendMessage(hWndTmp, WM_SETFONT, (WPARAM)_hFontB, MAKELPARAM(TRUE, 0));

	//ファンクションボタン設定状況の表示エディット(Read Only)作成
	x += _FontWidth*6;
	hWndTmp = CreateWindow(
		"EDIT", " function..[---]",
		WS_CHILD | WS_VISIBLE | ES_LEFT | ES_READONLY,
		x, y, _FontWidth*29, _FontHeight+5,
		_hWnd, (HMENU)EDIT_FUNCTION, _hInstance, NULL
	);
	SendMessage(hWndTmp, WM_SETFONT, (WPARAM)_hFontB, MAKELPARAM(TRUE, 0));

	//Windowsパッド接続順序設定用コンボボックスを作成
	x += _FontWidth*30;
	y -= 2;
	_hWndC[COMBOBOX_PADORD] = CreateWindow(
		"COMBOBOX", "",
		WS_CHILD | WS_VISIBLE | WS_VSCROLL | CBS_DROPDOWNLIST,
		x, y, _FontWidth*33+2, _FontHeight*52,
		_hWnd, (HMENU)COMBOBOX_PADORD, _hInstance, NULL
	);
	SendMessage(_hWndC[COMBOBOX_PADORD], WM_SETFONT, (WPARAM)_hFontB, MAKELPARAM(TRUE, 0));//フォントを設定
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"1 - 2 - 3 - 4 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"1 - 2 - 4 - 3 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"1 - 3 - 2 - 4 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"1 - 3 - 4 - 2 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"1 - 4 - 2 - 3 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"1 - 4 - 3 - 2 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"2 - 1 - 3 - 4 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"2 - 1 - 4 - 3 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"2 - 3 - 1 - 4 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"2 - 3 - 4 - 1 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"2 - 4 - 1 - 3 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"2 - 4 - 3 - 1 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"3 - 1 - 2 - 4 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"3 - 1 - 4 - 2 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"3 - 2 - 1 - 4 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"3 - 2 - 4 - 1 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"3 - 4 - 1 - 2 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"3 - 4 - 2 - 1 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"4 - 1 - 2 - 3 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"4 - 1 - 3 - 2 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"4 - 2 - 1 - 3 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"4 - 2 - 3 - 1 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"4 - 3 - 1 - 2 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"4 - 3 - 2 - 1 - 5  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"5 - 1 - 2 - 3 - 4  (Max 5 Pads)");
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"5 - 4 - 3 - 2 - 1  (Max 5 Pads)");
	//SendMessage(_hWndC[COMBOBOX_PADORD], CB_ADDSTRING, 0, (LPARAM)"5 - 1 - 2 - 4 - 3  (Max 5 Pads)");	5番目のパッドが先頭の時の組合せは多すぎるので保留。将来もっと設定し易く実装。
	SendMessage(_hWndC[COMBOBOX_PADORD], CB_SETCURSEL, _PadOrd, 0);//選択

	//Helpボタンを作成
	x = _FontWidth*33 +_FontWidth/2 +5;
	y += _FontHeight*2 +7;
	hWndTmp = CreateWindow(
		"BUTTON", "Help",
		WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
		x, y, _FontWidth*10, _FontHeight*2-3,
		_hWnd, (HMENU)BUTTON_HELP, _hInstance, NULL
	);
	SendMessage(hWndTmp, WM_SETFONT, (WPARAM)_hFontB, MAKELPARAM(TRUE, 0));

	//Defaultボタンを作成
	x += _FontWidth*11 -3;
	hWndTmp = CreateWindow(
		"BUTTON", "Initialize",
		WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
		x, y, _FontWidth*16, _FontHeight*2-3,
		_hWnd, (HMENU)BUTTON_DEFAULT, _hInstance, NULL
	);
	SendMessage(hWndTmp, WM_SETFONT, (WPARAM)_hFontB, MAKELPARAM(TRUE, 0));

	//Closeボタンを作成
	x += _FontWidth*17 -3;
	hWndTmp = CreateWindow(
		"BUTTON", "Close",
		WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
		x, y, _FontWidth*10, _FontHeight*2-3,
		_hWnd, (HMENU)BUTTON_CLOSE, _hInstance, NULL
	);
	SendMessage(hWndTmp, WM_SETFONT, (WPARAM)_hFontB, MAKELPARAM(TRUE, 0));

	//ボタン設定の状況を表示
	update_status();

	ShowWindow(_hWnd, SW_SHOWNORMAL);
	UpdateWindow(_hWnd);
	GetWindowRect(_hWnd, &rc);
	SetWindowPos(_hWnd, HWND_TOP, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_FRAMECHANGED);
	ImmAssociateContext(_hWnd, 0); //IMEを無効にする

	return TRUE;
}


BOOL
KEYCONFIG_Init(
	HWND		hWnd,
	HINSTANCE	hInstance,
	Sint32	 	padID,
	Sint32*		setOk)
{
	if (_hInstance != NULL)
		KEYCONFIG_Deinit();

	_hParentWnd = hWnd; //親ウィンドウのハンドル
	_hInstance = hInstance;

	_PadID	= padID;
	_PadOrd	= APP_GetPadOrder();//v2.95追加
	_pSetOk	= setOk;
	_SetOk	= -1; //キャンセル

	return keyconfig_main();
}


void
KEYCONFIG_Deinit()
{
	if (_hInstance != NULL)
	{
		DestroyWindow(_hWnd);
		_hWnd = NULL;
		UnregisterClass(_pCaption, _hInstance);
		_hInstance = NULL;
		
		DeleteObject(_hFontB); //ボタン用フォントを開放
		DeleteObject(_hMyBrush); //ブラシを開放
		DeleteObject(_hEditBrush); //ブラシを開放
		
		//メインウィンドウにフォーカスを戻し前面に。
		EnableWindow(_hParentWnd, TRUE);
		SetForegroundWindow(_hParentWnd);
		
		*_pSetOk = _SetOk; //戻り値を設定。この瞬間にメインウィンドウは動き出す。
	}
}

