GetHitKeyStateAll について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ganbarukun

GetHitKeyStateAll について

#1

投稿記事 by ganbarukun » 8年前

こんにちは。
今、c言語の勉強として簡単な電卓を作っているのですが、DXライブラリーのGetHitKeyStateAll関数について質問があります。
GetHitKeyStateAll関数は、一瞬しか入力を受け付けてくれないのでしょうか。
それとも、WaitKey関数のように何らかのキーが入力されるまで、入力を受け付けてくれるのでしょうか。
初心者なのでコードが汚く、必要ない処理をしているところがあるかもしれませんので、そんなところも教えてください。
コメントアウトした部分が問題だと思う部分です。
コメントアウトした部分は [第一引数の入力 --> 符号の入力 --> 第二引数の入力 --> 計算] という処理になるはずです。

コード:

#include "DxLib.h"
#include "main.h"

int calc_handle;
int clear_handle;
int button_handle[10];
int sign_handle[4];
//画像ハンドル
Point2D button[11];
//ボタンの座標
Sign sign;
//符号の座標
int input[2];
//入力値
Point2D clear;
//AC座標
int input_sign;
//符号チェック
int output;
//入力キーバッファ
char keybuf[ 256 ];


int LoadFiles(){
	calc_handle = LoadGraph( "media\\calc.bmp" );
	clear_handle = LoadGraph( "media\\clear.bmp" );
	if( LoadDivGraph( "media\\button.bmp" , 10, 10, 1, 90, 40, button_handle ) == -1 )	return -1;
	if( LoadDivGraph( "media\\sign.bmp" , 4, 4, 1, 60, 40, sign_handle ) == -1 ) return -1;
	button[0].x = 275;
	button[0].y = 360;
	button[1].x = 145;
	button[1].y = 310;
	button[4].x = 145;
	button[4].y = 260;
	button[7].x = 145;
	button[7].y = 210;
	sign.plus.x = 145;
	sign.plus.y = 155;
	sign.minus.x = 240;
	sign.minus.y = 155;
	sign.multiplication.x = 335;
	sign.multiplication.y = 155;
	sign.divide.x = 430;
	sign.divide.y = 155;
	clear.x = 145;
	clear.y = 105;

	for( int i=2; i<4; i++ ){
		button[i].x = button[1].x + (i - 1) * 40 + 90 * (i - 1);
		button[i].y = button[1].y;
	}
	for( int j=5; j<7; j++ ){
		button[j].x = button[4].x + (j - 4) * 40 + 90 * (j - 4);
		button[j].y = button[4].y;
	}
	for( int k=8; k<10; k++ ){
		button[k].x = button[7].x + (k - 7) * 40 + 90 * (k - 7);
		button[k].y = button[7].y;
	}
	for( int i=2; i<4; i++ ){
		button[i].x = button[1].x + (i - 1) * 40 + 90 * (i - 1);
		button[i].y = button[1].y;
	}
	return 0;
}

int WINAPI WinMain( HINSTANCE hI, HINSTANCE hP, LPSTR lpC, int nC ){
	SetMainWindowText( "電卓" );
	ChangeWindowMode( TRUE );
	if( DxLib_Init() == -1)		return -1;
	while ( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ){ 
	if( LoadFiles() == -1 )	return -1;
	DrawGraph( 125, 10, calc_handle , FALSE);
	DrawGraph( sign.plus.x, sign.plus.y, sign_handle[0], FALSE);
	DrawGraph( sign.minus.x, sign.minus.y, sign_handle[1], FALSE);
	DrawGraph( sign.multiplication.x, sign.multiplication.y, sign_handle[2], FALSE);
	DrawGraph( sign.divide.x, sign.divide.y, sign_handle[3], FALSE);
	for ( int i=0; i<10; i++ ){
	DrawGraph( button[i].x, button[i].y, button_handle[i], FALSE);
	}
	DrawGraph( clear.x, clear.y, clear_handle, TRUE );
	SetFontSize( 60 );
/*	input[0] = KeyInputNumber( 165, 40, 1000000000, 0, FALSE );
	while ( ProcessMessage() == 0 && keybuf[KEY_INPUT_ADD]  == 1 || keybuf[KEY_INPUT_SUBTRACT] == 1 || 
		keybuf[KEY_INPUT_MULTIPLY] == 1 || keybuf[KEY_INPUT_DIVIDE] == 1 ){
	GetHitKeyStateAll ( keybuf );
	}
	if( keybuf[KEY_INPUT_ADD]  == 1 || keybuf[KEY_INPUT_SUBTRACT] == 1 || 
		keybuf[KEY_INPUT_MULTIPLY] == 1 || keybuf[KEY_INPUT_DIVIDE] == 1 ){
	
	if( keybuf[KEY_INPUT_ADD]  == 1 )		input_sign = 1;
	if( keybuf[KEY_INPUT_SUBTRACT] == 1 )		input_sign = 2;
	if( keybuf[KEY_INPUT_MULTIPLY] == 1 )		input_sign = 3;
	if( keybuf[KEY_INPUT_DIVIDE] == 1 )		input_sign = 4;
	}
	input[1] = KeyInputNumber( 165, 40, 1000000000, 0, FALSE );
	switch( input_sign ){
	case 1:
		output = input[0] + input[1];
		break;
	case 2:
		output = input[0] - input[1];
		break;
	case 3:
		output = input[0] * input[1];
	break;
	case 4:
		output = input[0] / input[1];
	break;
	}
*/
	DrawString( 100, 100, (const char *) output, GetColor( 255, 255, 255 ) );
	WaitKey();
	}
	DxLib_End();
	return 0;
}




アバター
Ciel
記事: 252
登録日時: 9年前

Re: GetHitKeyStateAll について

#2

投稿記事 by Ciel » 8年前

一瞬しか見てませんが
GetHitKeyStateAll関数は実行したときのみ実行されます。

基本ゲームって、処理をループさせて動かしていると思いますので、
毎回その関数を呼ぶようにしていれば、実行されます。

WaitKey()は確かキーの入力を待つ関数だったと思います。
これはここでキーの入力を待つので処理が止まります。つまりループ自体も止まります。

whileでループしてるんだったら、

WaitKey()

はいらないんじゃないでしょうか?

とりあえず時間ないので、これだけ。
oui C'est la Vie♪

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 9年前
住所: 北海道札幌市
連絡を取る:

Re: GetHitKeyStateAll について

#3

投稿記事 by Dixq (管理人) » 8年前

WaitKeyを書いてしまうとそこで処理がとまってしまいます。
画面更新も、メッセージ処理も出来ません。

http://dixq.net/g/41.html

このような方法でキーの押された長さを監視する方法が良いでしょう。

ganbarukun

Re: GetHitKeyStateAll について

#4

投稿記事 by ganbarukun » 8年前

Cielさん、管理人さん返信ありがとうございます。
指摘されたWaitKey関数を外し、 管理人さんにアドバイスされたGetHitKeyStateAll_2関数を追加し、while文の中にまぜました。
しかし理想の結果になりません。KeyInputNumber関数が呼び出され何回数値を入力しても結果が返ってきません。
それにESCキーを押してもソフトが終了しません。
変更後のコードはこんな感じです。よろしくお願いします。

コード:

#include "DxLib.h"
#include "main.h"

int calc_handle;
int clear_handle;
int button_handle[10];
int sign_handle[4];
//画像ハンドル
Point2D button[11];
//ボタンの座標
Sign sign;
//符号の座標
int input[2];
//入力値
Point2D clear;
//AC座標
int input_sign;
//符号チェック
int output;
//入力キーバッファ
int keybuf[ 256 ];

int GetHitKeyStateAll_2(int KeyStateBuf[]){
        char GetHitKeyStateAll_Key[256];
        GetHitKeyStateAll( GetHitKeyStateAll_Key );
        for(int i=0;i<256;i++){
                if(GetHitKeyStateAll_Key[i]==1) KeyStateBuf[i]++;
                else                            KeyStateBuf[i]=0;
        }
        return 0;
}

int LoadFiles(){
	calc_handle = LoadGraph( "media\\calc.bmp" );
	clear_handle = LoadGraph( "media\\clear.bmp" );
	if( LoadDivGraph( "media\\button.bmp" , 10, 10, 1, 90, 40, button_handle ) == -1 )	return -1;
	if( LoadDivGraph( "media\\sign.bmp" , 4, 4, 1, 60, 40, sign_handle ) == -1 ) return -1;
	button[0].x = 275;
	button[0].y = 360;
	button[1].x = 145;
	button[1].y = 310;
	button[4].x = 145;
	button[4].y = 260;
	button[7].x = 145;
	button[7].y = 210;
	sign.plus.x = 145;
	sign.plus.y = 155;
	sign.minus.x = 240;
	sign.minus.y = 155;
	sign.multiplication.x = 335;
	sign.multiplication.y = 155;
	sign.divide.x = 430;
	sign.divide.y = 155;
	clear.x = 145;
	clear.y = 105;

	for( int i=2; i<4; i++ ){
		button[i].x = button[1].x + (i - 1) * 40 + 90 * (i - 1);
		button[i].y = button[1].y;
	}
	for( int j=5; j<7; j++ ){
		button[j].x = button[4].x + (j - 4) * 40 + 90 * (j - 4);
		button[j].y = button[4].y;
	}
	for( int k=8; k<10; k++ ){
		button[k].x = button[7].x + (k - 7) * 40 + 90 * (k - 7);
		button[k].y = button[7].y;
	}
	for( int i=2; i<4; i++ ){
		button[i].x = button[1].x + (i - 1) * 40 + 90 * (i - 1);
		button[i].y = button[1].y;
	}
	return 0;
}

int WINAPI WinMain( HINSTANCE hI, HINSTANCE hP, LPSTR lpC, int nC ){
	SetMainWindowText( "電卓" );
	ChangeWindowMode( TRUE );
	if( DxLib_Init() == -1)		return -1;
	while ( ProcessMessage() == 0 && keybuf[ KEY_INPUT_ESCAPE] == 0 && GetHitKeyStateAll_2( keybuf ) == 0 ){ 
	if( LoadFiles() == -1 )	return -1;
	DrawGraph( 125, 10, calc_handle , FALSE);
	DrawGraph( sign.plus.x, sign.plus.y, sign_handle[0], FALSE);
	DrawGraph( sign.minus.x, sign.minus.y, sign_handle[1], FALSE);
	DrawGraph( sign.multiplication.x, sign.multiplication.y, sign_handle[2], FALSE);
	DrawGraph( sign.divide.x, sign.divide.y, sign_handle[3], FALSE);
	for ( int i=0; i<10; i++ ){
	DrawGraph( button[i].x, button[i].y, button_handle[i], FALSE);
	}
	DrawGraph( clear.x, clear.y, clear_handle, TRUE );
	SetFontSize( 60 );
	input[0] = KeyInputNumber( 165, 40, 1000000000, 0, FALSE );
	if( keybuf[KEY_INPUT_ADD]  == 1 || keybuf[KEY_INPUT_SUBTRACT] == 1 || 
		keybuf[KEY_INPUT_MULTIPLY] == 1 || keybuf[KEY_INPUT_DIVIDE] == 1 ){
	
	if( keybuf[KEY_INPUT_ADD]  == 1 )		input_sign = 1;
	if( keybuf[KEY_INPUT_SUBTRACT] == 1 )		input_sign = 2;
	if( keybuf[KEY_INPUT_MULTIPLY] == 1 )		input_sign = 3;
	if( keybuf[KEY_INPUT_DIVIDE] == 1 )		input_sign = 4;
	}
	input[1] = KeyInputNumber( 165, 40, 1000000000, 0, FALSE );
	switch( input_sign ){
	case 1:
		output = input[0] + input[1];
		break;
	case 2:
		output = input[0] - input[1];
		break;
	case 3:
	output = input[0] * input[1];
	break;
	case 4:
	output = input[0] / input[1];
	break;
	}
	DrawString( 165, 40, (char *) output, GetColor( 255, 255, 255 ) );
	WaitKey();
	}
	DxLib_End();
	return 0;
}


アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 9年前
住所: 北海道札幌市
連絡を取る:

Re: GetHitKeyStateAll について

#5

投稿記事 by Dixq (管理人) » 8年前

KeyInputNumberを使ってしまうとそこで処理が止まってしまうので、DXライブラリを活かした処理ができなくなると思います。
DXライブラリを活かすには特定の場所で止まらず、常にループしている必要があります。
そもそもDXライブラリはゲームを作るための物なので、電卓アプリなどには向いていません。
もし電卓が作りたければWINAPIやMFCを使ってはどうでしょう?
もっと簡単に実装出来ますよ。

もしどうしてもDXライブラリを使ったアプリケーションに入力機能を付けたいならチャットを実装する時に使う関数を使ってはどうでしょうか。
http://homepage2.nifty.com/natupaji/DxL ... html#R5N13
int NumCharOnlyFlag : 数値文字のみの入力か否か(TRUE:数字文字のみ FALSE:フラグ無効)
のフラグを立てれば先ほどの関数同様数字のみの入力になります。

ganbarukun

Re: GetHitKeyStateAll について

#6

投稿記事 by ganbarukun » 8年前

WINAPIは前から少し興味があったのですが、今回はDXライブラリーを使ってプログラムを組もうと思います。
このプログラムが完成したら、WINAPIの勉強をしてみたいと思います。
管理人さんがおっしゃったようにKeyInputNumber関数の代わりにMakeKeyInput関数などを使ってコード組みなおしました。
しかし、まだ満足いく結果が返ってきません。今度は数値の入力はできますが、Enterキーなどを押しても次に進みません。
どこがうまくいっていないのか教えてください。

コード:

#include "DxLib.h"
#include "main.h"

int calc_handle;
int clear_handle;
int button_handle[10];
int sign_handle[4];
//画像ハンドル
Point2D button[11];
//ボタンの座標
Sign sign;
//符号の座標
int input[2];
//入力値
Point2D clear;
//AC座標
int input_sign;
//符号チェック
int output;
//入力キーバッファ
int keybuf[ 256 ];
//キー入力データ
int make_key[3] = {0,0,0};


int GetHitKeyStateAll_2(int KeyStateBuf[]){
        char GetHitKeyStateAll_Key[256];
        GetHitKeyStateAll( GetHitKeyStateAll_Key );
        for(int i=0;i<256;i++){
                if(GetHitKeyStateAll_Key[i]==1) KeyStateBuf[i]++;
                else                            KeyStateBuf[i]=0;
        }
        return 0;
}

int LoadFiles(){
	calc_handle = LoadGraph( "media\\calc.bmp" );
	clear_handle = LoadGraph( "media\\clear.bmp" );
	if( LoadDivGraph( "media\\button.bmp" , 10, 10, 1, 90, 40, button_handle ) == -1 )	return -1;
	if( LoadDivGraph( "media\\sign.bmp" , 4, 4, 1, 60, 40, sign_handle ) == -1 ) return -1;
	button[0].x = 275;
	button[0].y = 360;
	button[1].x = 145;
	button[1].y = 310;
	button[4].x = 145;
	button[4].y = 260;
	button[7].x = 145;
	button[7].y = 210;
	sign.plus.x = 145;
	sign.plus.y = 155;
	sign.minus.x = 240;
	sign.minus.y = 155;
	sign.multiplication.x = 335;
	sign.multiplication.y = 155;
	sign.divide.x = 430;
	sign.divide.y = 155;
	clear.x = 145;
	clear.y = 105;

	for( int i=2; i<4; i++ ){
		button[i].x = button[1].x + (i - 1) * 40 + 90 * (i - 1);
		button[i].y = button[1].y;
	}
	for( int j=5; j<7; j++ ){
		button[j].x = button[4].x + (j - 4) * 40 + 90 * (j - 4);
		button[j].y = button[4].y;
	}
	for( int k=8; k<10; k++ ){
		button[k].x = button[7].x + (k - 7) * 40 + 90 * (k - 7);
		button[k].y = button[7].y;
	}
	for( int i=2; i<4; i++ ){
		button[i].x = button[1].x + (i - 1) * 40 + 90 * (i - 1);
		button[i].y = button[1].y;
	}
	make_key[0] = MakeKeyInput( 10, FALSE, FALSE, TRUE );
	make_key[1] = MakeKeyInput( 10, FALSE, FALSE, TRUE );
	//キー入力データ作成
	return 0;
}

int WINAPI WinMain( HINSTANCE hI, HINSTANCE hP, LPSTR lpC, int nC ){
	SetMainWindowText( "電卓" );
	ChangeWindowMode( TRUE );
	if( DxLib_Init() == -1)		return -1;
	while ( ProcessMessage() == 0 && keybuf[ KEY_INPUT_ESCAPE] == 0 && GetHitKeyStateAll_2( keybuf ) == 0 ){ 
	if( LoadFiles() == -1 )	return -1;
	DrawGraph( 125, 10, calc_handle , FALSE);
	DrawGraph( sign.plus.x, sign.plus.y, sign_handle[0], FALSE);
	DrawGraph( sign.minus.x, sign.minus.y, sign_handle[1], FALSE);
	DrawGraph( sign.multiplication.x, sign.multiplication.y, sign_handle[2], FALSE);
	DrawGraph( sign.divide.x, sign.divide.y, sign_handle[3], FALSE);
	for ( int i=0; i<10; i++ ){
	DrawGraph( button[i].x, button[i].y, button_handle[i], FALSE);
	}
	DrawGraph( clear.x, clear.y, clear_handle, TRUE );
	SetFontSize( 60 );
	//数値入力1
	SetActiveKeyInput( make_key[0] );

	while( ProcessMessage() == 0 ){
	if (CheckKeyInput( make_key[0] ) != 0 )		break;
	DrawKeyInputString ( 160, 40, make_key[0] );
	}
	input[0] = ( make_key[0] );
	//符号の入力
	while( ProcessMessage() == 0 ){
	if( keybuf[KEY_INPUT_ADD]  == 1 || keybuf[KEY_INPUT_SUBTRACT] == 1 || 
		keybuf[KEY_INPUT_MULTIPLY] == 1 || keybuf[KEY_INPUT_DIVIDE] == 1 )		break;
	}
	if( keybuf[KEY_INPUT_ADD]  == 1 )		input_sign = 1;
	if( keybuf[KEY_INPUT_SUBTRACT] == 1 )		input_sign = 2;
	if( keybuf[KEY_INPUT_MULTIPLY] == 1 )		input_sign = 3;
	if( keybuf[KEY_INPUT_DIVIDE] == 1 )		input_sign = 4;
	
	//数値入力2
	SetActiveKeyInput( make_key[1] );

	while( ProcessMessage() == 0 ){
	if (CheckKeyInput( make_key[1] ) != 0 )		break;
	DrawKeyInputString ( 160, 40, make_key[1] );
	}
	input[1] = ( make_key[1] );

	switch( input_sign ){
	case 1:
		output = input[0] + input[1];
		break;
	case 2:
		output = input[0] - input[1];
		break;
	case 3:
	output = input[0] * input[1];
	break;
	case 4:
	output = input[0] / input[1];
	break;
	}
	DrawString( 165, 40, (char *) output, GetColor( 255, 255, 255 ) );
	WaitKey();
	}
	DxLib_End();
	return 0;
}

ganbarukun

Re: GetHitKeyStateAll について

#7

投稿記事 by ganbarukun » 8年前

こんにちは。あれから少しプログラムを自力で組みなおしました。
できるようになったのは、数値の入力です。
しかし、符号の入力と計算結果の表示ができません。
計算結果の表示のほうは、デバッグで符号を無理やり入れ、計算結果が表示されるか確認してみましたが、
エラーが出て表示することができませんでした。
エラーの内容は
testmain.exe の 0x00d98dd3 でハンドルされていない例外が発生しました: 0xC0000005: 場所 0x00000009 を読み込み中にアクセス違反が発生しました。
というものです。
よろしくお願いします。

コード:

#include "DxLib.h"
#include "main.h"

int calc_handle;
int clear_handle;
int button_handle[10];
int sign_handle[4];
//画像ハンドル
Point2D button[11];
//ボタンの座標
Sign sign;
//符号の座標
int input[2];
//入力値
Point2D clear;
//AC座標
int input_sign;
//符号チェック
int output;
//入力キーバッファ
int keybuf[ 256 ];
//キー入力データ
int make_key[2] = {0,0};


int GetHitKeyStateAll_2(int KeyStateBuf[]){
        char GetHitKeyStateAll_Key[256];
        GetHitKeyStateAll( GetHitKeyStateAll_Key );
        for(int i=0;i<256;i++){
                if(GetHitKeyStateAll_Key[i]==1) KeyStateBuf[i]++;
                else                            KeyStateBuf[i]=0;
        }
        return 0;
}

int LoadFiles(){
	calc_handle = LoadGraph( "media\\calc.bmp" );
	clear_handle = LoadGraph( "media\\clear.bmp" );
	if( LoadDivGraph( "media\\button.bmp" , 10, 10, 1, 90, 40, button_handle ) == -1 )	return -1;
	if( LoadDivGraph( "media\\sign.bmp" , 4, 4, 1, 60, 40, sign_handle ) == -1 ) return -1;
	button[0].x = 275;
	button[0].y = 360;
	button[1].x = 145;
	button[1].y = 310;
	button[4].x = 145;
	button[4].y = 260;
	button[7].x = 145;
	button[7].y = 210;
	sign.plus.x = 145;
	sign.plus.y = 155;
	sign.minus.x = 240;
	sign.minus.y = 155;
	sign.multiplication.x = 335;
	sign.multiplication.y = 155;
	sign.divide.x = 430;
	sign.divide.y = 155;
	clear.x = 145;
	clear.y = 105;

	for( int i=2; i<4; i++ ){
		button[i].x = button[1].x + (i - 1) * 40 + 90 * (i - 1);
		button[i].y = button[1].y;
	}
	for( int j=5; j<7; j++ ){
		button[j].x = button[4].x + (j - 4) * 40 + 90 * (j - 4);
		button[j].y = button[4].y;
	}
	for( int k=8; k<10; k++ ){
		button[k].x = button[7].x + (k - 7) * 40 + 90 * (k - 7);
		button[k].y = button[7].y;
	}
	for( int i=2; i<4; i++ ){
		button[i].x = button[1].x + (i - 1) * 40 + 90 * (i - 1);
		button[i].y = button[1].y;
	}
	make_key[0] = MakeKeyInput( 10, FALSE, FALSE, TRUE );
	make_key[1] = MakeKeyInput( 10, FALSE, FALSE, TRUE );
	//キー入力データ作成
	return 0;
}

void DrawScreen(){
	DrawGraph( 125, 10, calc_handle , FALSE);
	DrawGraph( sign.plus.x, sign.plus.y, sign_handle[0], FALSE);
	DrawGraph( sign.minus.x, sign.minus.y, sign_handle[1], FALSE);
	DrawGraph( sign.multiplication.x, sign.multiplication.y, sign_handle[2], FALSE);
	DrawGraph( sign.divide.x, sign.divide.y, sign_handle[3], FALSE);
	for ( int i=0; i<10; i++ ){
	DrawGraph( button[i].x, button[i].y, button_handle[i], FALSE);
	}
	DrawGraph( clear.x, clear.y, clear_handle, TRUE );
}

int WINAPI WinMain( HINSTANCE hI, HINSTANCE hP, LPSTR lpC, int nC ){
	SetMainWindowText( "電卓" );
	ChangeWindowMode( TRUE );
	if( DxLib_Init() == -1)		return -1;
	while ( ProcessMessage() == 0 && keybuf[ KEY_INPUT_ESCAPE] == 0 && GetHitKeyStateAll_2( keybuf ) == 0 ){ 
	if( LoadFiles() == -1 )	return -1;
	DrawScreen();
	
	//数値入力1
	SetActiveKeyInput( make_key[0] );

	while( ProcessMessage() == 0 ){
	if (CheckKeyInput( make_key[0] ) != 0 )		break;
	SetFontSize( 60 );
	DrawKeyInputString ( 160, 40, make_key[0] );
	}
	ClearDrawScreen();
	DrawScreen();
	input[0] = GetKeyInputNumber( make_key[0] );

	//符号入力
	while( ProcessMessage() == 0 ){
		if( keybuf[KEY_INPUT_ADD]  == 1 ){		
		input_sign = 1;
		break;
	}
	if( keybuf[KEY_INPUT_SUBTRACT] == 1 ){
		input_sign = 2;
		break;
	}
	if( keybuf[KEY_INPUT_MULTIPLY] == 1 ){
		input_sign = 3;
		break;
	}
	if( keybuf[KEY_INPUT_DIVIDE] == 1 ){
		input_sign = 4;
		break;
	}
	}
	
	//数値入力2
	SetActiveKeyInput( make_key[1] );

	while( ProcessMessage() == 0 ){
	if (CheckKeyInput( make_key[1] ) != 0 )		break;
	DrawKeyInputString ( 160, 40, make_key[1] );
	}
	ClearDrawScreen();
	DrawScreen();
	input[1] = GetKeyInputNumber( make_key[1] );

	switch( input_sign ){
	case 1:
		output = input[0] + input[1];
		break;
	case 2:
		output = input[0] - input[1];
		break;
	case 3:
	output = input[0] * input[1];
	break;
	case 4:
	output = input[0] / input[1];
	break;
	}
	DrawString( 165, 40, (char *)output, GetColor( 255, 255, 255 ) );    //ここがエラー
	}
	DxLib_End();
	return 0;
}

アバター
h2so5
副管理人
記事: 2212
登録日時: 9年前
住所: 東京
連絡を取る:

Re: GetHitKeyStateAll について

#8

投稿記事 by h2so5 » 8年前

数字を文字列に変換するにはsprintfを使います。
(char *)output はポインタへのキャストなので、不正なメモリアクセスを引き起こします。

[追記]
エラーの位置が分かっていて、しかもメモリのアクセス違反ならば、
質問する前にまずポインタ周りを疑うべきです。

ganbarukun

Re: GetHitKeyStateAll について

#9

投稿記事 by ganbarukun » 8年前

h2so5さん返信ありがとうございます。
sprintfはエラーが出るのでsprintf_Sを使いました。
しかし、使い方が分からずエラーが出ます。エラーの内容はコピーができません。
コードはこんな感じです。
よろしくお願いします。

コード:

#include "DxLib.h"
#include "main.h"

int calc_handle;
int clear_handle;
int button_handle[10];
int sign_handle[4];
//画像ハンドル
Point2D button[11];
//ボタンの座標
Sign sign;
//符号の座標
int input[2];
//入力値
Point2D clear;
//AC座標
int input_sign;
//符号チェック
char *output;
//入力キーバッファ
int keybuf[ 256 ];
//キー入力データ
int make_key[2] = {0,0};


int GetHitKeyStateAll_2(int KeyStateBuf[]){
        char GetHitKeyStateAll_Key[256];
        GetHitKeyStateAll( GetHitKeyStateAll_Key );
        for(int i=0;i<256;i++){
                if(GetHitKeyStateAll_Key[i]==1) KeyStateBuf[i]++;
                else                            KeyStateBuf[i]=0;
        }
        return 0;
}

int LoadFiles(){
	calc_handle = LoadGraph( "media\\calc.bmp" );
	clear_handle = LoadGraph( "media\\clear.bmp" );
	if( LoadDivGraph( "media\\button.bmp" , 10, 10, 1, 90, 40, button_handle ) == -1 )	return -1;
	if( LoadDivGraph( "media\\sign.bmp" , 4, 4, 1, 60, 40, sign_handle ) == -1 ) return -1;
	button[0].x = 275;
	button[0].y = 360;
	button[1].x = 145;
	button[1].y = 310;
	button[4].x = 145;
	button[4].y = 260;
	button[7].x = 145;
	button[7].y = 210;
	sign.plus.x = 145;
	sign.plus.y = 155;
	sign.minus.x = 240;
	sign.minus.y = 155;
	sign.multiplication.x = 335;
	sign.multiplication.y = 155;
	sign.divide.x = 430;
	sign.divide.y = 155;
	clear.x = 145;
	clear.y = 105;

	for( int i=2; i<4; i++ ){
		button[i].x = button[1].x + (i - 1) * 40 + 90 * (i - 1);
		button[i].y = button[1].y;
	}
	for( int j=5; j<7; j++ ){
		button[j].x = button[4].x + (j - 4) * 40 + 90 * (j - 4);
		button[j].y = button[4].y;
	}
	for( int k=8; k<10; k++ ){
		button[k].x = button[7].x + (k - 7) * 40 + 90 * (k - 7);
		button[k].y = button[7].y;
	}
	for( int i=2; i<4; i++ ){
		button[i].x = button[1].x + (i - 1) * 40 + 90 * (i - 1);
		button[i].y = button[1].y;
	}
	make_key[0] = MakeKeyInput( 10, FALSE, FALSE, TRUE );
	make_key[1] = MakeKeyInput( 10, FALSE, FALSE, TRUE );
	//キー入力データ作成
	return 0;
}

void DrawScreen(){
	DrawGraph( 125, 10, calc_handle , FALSE);
	DrawGraph( sign.plus.x, sign.plus.y, sign_handle[0], FALSE);
	DrawGraph( sign.minus.x, sign.minus.y, sign_handle[1], FALSE);
	DrawGraph( sign.multiplication.x, sign.multiplication.y, sign_handle[2], FALSE);
	DrawGraph( sign.divide.x, sign.divide.y, sign_handle[3], FALSE);
	for ( int i=0; i<10; i++ ){
	DrawGraph( button[i].x, button[i].y, button_handle[i], FALSE);
	}
	DrawGraph( clear.x, clear.y, clear_handle, TRUE );
}

int WINAPI WinMain( HINSTANCE hI, HINSTANCE hP, LPSTR lpC, int nC ){
	SetMainWindowText( "電卓" );
	ChangeWindowMode( TRUE );
	if( DxLib_Init() == -1)		return -1;
	while ( ProcessMessage() == 0 && keybuf[ KEY_INPUT_ESCAPE] == 0 && GetHitKeyStateAll_2( keybuf ) == 0 ){ 
	if( LoadFiles() == -1 )	return -1;
	DrawScreen();
	
	//数値入力1
	SetActiveKeyInput( make_key[0] );

	while( ProcessMessage() == 0 ){
	if (CheckKeyInput( make_key[0] ) != 0 )		break;
	SetFontSize( 60 );
	DrawKeyInputString ( 160, 40, make_key[0] );
	}
	ClearDrawScreen();
	DrawScreen();
	input[0] = GetKeyInputNumber( make_key[0] );

	//符号入力
	while( ProcessMessage() == 0 ){
		if( keybuf[KEY_INPUT_ADD]  == 1 ){		
		input_sign = 1;
		break;
	}
	if( keybuf[KEY_INPUT_SUBTRACT] == 1 ){
		input_sign = 2;
		break;
	}
	if( keybuf[KEY_INPUT_MULTIPLY] == 1 ){
		input_sign = 3;
		break;
	}
	if( keybuf[KEY_INPUT_DIVIDE] == 1 ){
		input_sign = 4;
		break;
	}
	}
	
	//数値入力2
	SetActiveKeyInput( make_key[1] );

	while( ProcessMessage() == 0 ){
	if (CheckKeyInput( make_key[1] ) != 0 )		break;
	DrawKeyInputString ( 160, 40, make_key[1] );
	}
	ClearDrawScreen();
	DrawScreen();
	input[1] = GetKeyInputNumber( make_key[1] );

	switch( input_sign ){
	case 1:
	sprintf_s( output, sizeof(output), "%d", input[0] + input[1] );
	break;
	case 2:
	sprintf_s( output, sizeof(output), "%d", input[0] - input[1] );
	break;
	case 3:
	sprintf_s( output, sizeof(output), "%d", input[0] * input[1] );
	break;
	case 4:
	sprintf_s( output, sizeof(output), "%d", input[0] / input[1] );
	break;
	}
	DrawString( 165, 40, output, GetColor( 255, 255, 255 ) );
	}
	DxLib_End();
	return 0;
}

しひ

Re: GetHitKeyStateAll について

#10

投稿記事 by しひ » 8年前

分からなかったらすぐ調べる癖を付けないとこれから辛いですよ。
http://msdn.microsoft.com/ja-jp/library ... s.80).aspx

コード:

#define SIZE 256
char output[SIZE];

sprintf( output, "%d", /*省略*/ ); // 非推奨
sprintf_s( output, sizeof( output ), "%d", /*省略*/ );

アバター
kimuchi
記事: 163
登録日時: 9年前
住所: 東京

Re: GetHitKeyStateAll について

#11

投稿記事 by kimuchi » 8年前

ちなみにsprintf_s関数はwindowsの独自拡張ですので、C言語の標準ライブラリではないです。
移植性を考えなければ使うのもありだと思いますが、
#define _CRT_SECURE_NO_WARNINGS
をコードの頭に書いておけば警告は出なくなります。

横レス失礼いたしました。

ganbarukun

Re: GetHitKeyStateAll について

#12

投稿記事 by ganbarukun » 8年前

しひさん・kimuchiさん返信ありがとうございます。
おかげで計算結果の表示ができるようになりました。
しひさん
>分からなかったらすぐ調べる癖を付けないとこれから辛いですよ。

一応、自分なりに調べいろいろなサイトを参考にしてプログラムを組みなおしたつもりでしたが、
できなかったので質問させていただきました。

kimuchiさん
>#define _CRT_SECURE_NO_WARNINGS
>をコードの頭に書いておけば警告は出なくなります。

#defineにそんな使い方があったとは知りませんでした。
今度機会があったら使ってみたいと思います。

これで 数値の入力と計算結果の表示はできるようになりましたが、符号の入力がまだできません。
数値1を入力した後反応しなくなります。
Escキーでの関数脱出もできません。
どのように書けばいいのでしょうか。
お願いします。

コード:

#include "DxLib.h"
#include "main.h"

#define SIZE 256

int calc_handle;
int clear_handle;
int button_handle[10];
int sign_handle[4];
//画像ハンドル
Point2D button[11];
//ボタンの座標
Sign sign;
//符号の座標
int input[2];
//入力値
Point2D clear;
//AC座標
int input_sign;
//符号チェック
char output[SIZE];
//入力キーバッファ
int keybuf[ 256 ];
//キー入力データ
int make_key[2] = {0,0};


int GetHitKeyStateAll_2(int KeyStateBuf[]){
        char GetHitKeyStateAll_Key[256];
        GetHitKeyStateAll( GetHitKeyStateAll_Key );
        for(int i=0;i<256;i++){
                if(GetHitKeyStateAll_Key[i]==1) KeyStateBuf[i]++;
                else                            KeyStateBuf[i]=0;
        }
        return 0;
}

int LoadFiles(){
	calc_handle = LoadGraph( "media\\calc.bmp" );
	clear_handle = LoadGraph( "media\\clear.bmp" );
	if( LoadDivGraph( "media\\button.bmp" , 10, 10, 1, 90, 40, button_handle ) == -1 )	return -1;
	if( LoadDivGraph( "media\\sign.bmp" , 4, 4, 1, 60, 40, sign_handle ) == -1 ) return -1;
	button[0].x = 275;
	button[0].y = 360;
	button[1].x = 145;
	button[1].y = 310;
	button[4].x = 145;
	button[4].y = 260;
	button[7].x = 145;
	button[7].y = 210;
	sign.plus.x = 145;
	sign.plus.y = 155;
	sign.minus.x = 240;
	sign.minus.y = 155;
	sign.multiplication.x = 335;
	sign.multiplication.y = 155;
	sign.divide.x = 430;
	sign.divide.y = 155;
	clear.x = 145;
	clear.y = 105;

	for( int i=2; i<4; i++ ){
		button[i].x = button[1].x + (i - 1) * 40 + 90 * (i - 1);
		button[i].y = button[1].y;
	}
	for( int j=5; j<7; j++ ){
		button[j].x = button[4].x + (j - 4) * 40 + 90 * (j - 4);
		button[j].y = button[4].y;
	}
	for( int k=8; k<10; k++ ){
		button[k].x = button[7].x + (k - 7) * 40 + 90 * (k - 7);
		button[k].y = button[7].y;
	}
	for( int i=2; i<4; i++ ){
		button[i].x = button[1].x + (i - 1) * 40 + 90 * (i - 1);
		button[i].y = button[1].y;
	}
	make_key[0] = MakeKeyInput( 10, FALSE, FALSE, TRUE );
	make_key[1] = MakeKeyInput( 10, FALSE, FALSE, TRUE );
	//キー入力データ作成
	return 0;
}

void DrawScreen(){
	DrawGraph( 125, 10, calc_handle , FALSE);
	DrawGraph( sign.plus.x, sign.plus.y, sign_handle[0], FALSE);
	DrawGraph( sign.minus.x, sign.minus.y, sign_handle[1], FALSE);
	DrawGraph( sign.multiplication.x, sign.multiplication.y, sign_handle[2], FALSE);
	DrawGraph( sign.divide.x, sign.divide.y, sign_handle[3], FALSE);
	for ( int i=0; i<10; i++ ){
	DrawGraph( button[i].x, button[i].y, button_handle[i], FALSE);
	}
	DrawGraph( clear.x, clear.y, clear_handle, TRUE );
}

int WINAPI WinMain( HINSTANCE hI, HINSTANCE hP, LPSTR lpC, int nC ){
	SetMainWindowText( "電卓" );
	ChangeWindowMode( TRUE );
	if( DxLib_Init() == -1)		return -1;
	while ( ProcessMessage() == 0 && keybuf[ KEY_INPUT_ESCAPE] == 0 && GetHitKeyStateAll_2( keybuf ) == 0 ){ 
	if( LoadFiles() == -1 )	return -1;
	DrawScreen();
	
	//数値入力1
	SetActiveKeyInput( make_key[0] );

	while( ProcessMessage() == 0 ){
	if (CheckKeyInput( make_key[0] ) != 0 )		break;
	SetFontSize( 60 );
	DrawKeyInputString ( 160, 40, make_key[0] );
	}
	ClearDrawScreen();
	DrawScreen();
	input[0] = GetKeyInputNumber( make_key[0] );

	//符号入力
	while( ProcessMessage() == 0 ){
		if( keybuf[KEY_INPUT_ADD]  == 1 ){		
		input_sign = 1;
		break;
	}
	if( keybuf[KEY_INPUT_SUBTRACT] == 1 ){
		input_sign = 2;
		break;
	}
	if( keybuf[KEY_INPUT_MULTIPLY] == 1 ){
		input_sign = 3;
		break;
	}
	if( keybuf[KEY_INPUT_DIVIDE] == 1 ){
		input_sign = 4;
		break;
	}
	}
	
	//数値入力2
	SetActiveKeyInput( make_key[1] );

	while( ProcessMessage() == 0 ){
	if (CheckKeyInput( make_key[1] ) != 0 )		break;
	DrawKeyInputString ( 160, 40, make_key[1] );
	}
	ClearDrawScreen();
	DrawScreen();
	input[1] = GetKeyInputNumber( make_key[1] );

	switch( input_sign ){
	case 1:
	sprintf_s( output, sizeof(output), "%d", input[0] + input[1] );
	break;
	case 2:
	sprintf_s( output, sizeof(output), "%d", input[0] - input[1] );
	break;
	case 3:
	sprintf_s( output, sizeof(output), "%d", input[0] * input[1] );
	break;
	case 4:
	sprintf_s( output, sizeof(output), "%d", input[0] / input[1] );
	break;
	}
	SetFontSize( 60 );
	DrawString( 165, 40, output, GetColor( 255, 255, 255 ) );
	WaitKey();
	DxLib_End();
	return 0;
	}
}

ganbarukun

Re: GetHitKeyStateAll について

#13

投稿記事 by ganbarukun » 8年前

しひさん・kimuchiさん返信ありがとうございます。
おかげで計算結果の表示ができるようになりました。
しひさん
>分からなかったらすぐ調べる癖を付けないとこれから辛いですよ。

一応、自分なりに調べいろいろなサイトを参考にしてプログラムを組みなおしたつもりでしたが、
できなかったので質問させていただきました。

kimuchiさん
>#define _CRT_SECURE_NO_WARNINGS
>をコードの頭に書いておけば警告は出なくなります。

#defineにそんな使い方があったとは知りませんでした。
今度機会があったら使ってみたいと思います。

これで 数値の入力と計算結果の表示はできるようになりましたが、符号の入力がまだできません。
数値1を入力した後反応しなくなります。
Escキーでの関数脱出もできません。
どのように書けばいいのでしょうか。
お願いします。

コード:

#include "DxLib.h"
#include "main.h"

#define SIZE 256

int calc_handle;
int clear_handle;
int button_handle[10];
int sign_handle[4];
//画像ハンドル
Point2D button[11];
//ボタンの座標
Sign sign;
//符号の座標
int input[2];
//入力値
Point2D clear;
//AC座標
int input_sign;
//符号チェック
char output[SIZE];
//入力キーバッファ
int keybuf[ 256 ];
//キー入力データ
int make_key[2] = {0,0};


int GetHitKeyStateAll_2(int KeyStateBuf[]){
        char GetHitKeyStateAll_Key[256];
        GetHitKeyStateAll( GetHitKeyStateAll_Key );
        for(int i=0;i<256;i++){
                if(GetHitKeyStateAll_Key[i]==1) KeyStateBuf[i]++;
                else                            KeyStateBuf[i]=0;
        }
        return 0;
}

int LoadFiles(){
	calc_handle = LoadGraph( "media\\calc.bmp" );
	clear_handle = LoadGraph( "media\\clear.bmp" );
	if( LoadDivGraph( "media\\button.bmp" , 10, 10, 1, 90, 40, button_handle ) == -1 )	return -1;
	if( LoadDivGraph( "media\\sign.bmp" , 4, 4, 1, 60, 40, sign_handle ) == -1 ) return -1;
	button[0].x = 275;
	button[0].y = 360;
	button[1].x = 145;
	button[1].y = 310;
	button[4].x = 145;
	button[4].y = 260;
	button[7].x = 145;
	button[7].y = 210;
	sign.plus.x = 145;
	sign.plus.y = 155;
	sign.minus.x = 240;
	sign.minus.y = 155;
	sign.multiplication.x = 335;
	sign.multiplication.y = 155;
	sign.divide.x = 430;
	sign.divide.y = 155;
	clear.x = 145;
	clear.y = 105;

	for( int i=2; i<4; i++ ){
		button[i].x = button[1].x + (i - 1) * 40 + 90 * (i - 1);
		button[i].y = button[1].y;
	}
	for( int j=5; j<7; j++ ){
		button[j].x = button[4].x + (j - 4) * 40 + 90 * (j - 4);
		button[j].y = button[4].y;
	}
	for( int k=8; k<10; k++ ){
		button[k].x = button[7].x + (k - 7) * 40 + 90 * (k - 7);
		button[k].y = button[7].y;
	}
	for( int i=2; i<4; i++ ){
		button[i].x = button[1].x + (i - 1) * 40 + 90 * (i - 1);
		button[i].y = button[1].y;
	}
	make_key[0] = MakeKeyInput( 10, FALSE, FALSE, TRUE );
	make_key[1] = MakeKeyInput( 10, FALSE, FALSE, TRUE );
	//キー入力データ作成
	return 0;
}

void DrawScreen(){
	DrawGraph( 125, 10, calc_handle , FALSE);
	DrawGraph( sign.plus.x, sign.plus.y, sign_handle[0], FALSE);
	DrawGraph( sign.minus.x, sign.minus.y, sign_handle[1], FALSE);
	DrawGraph( sign.multiplication.x, sign.multiplication.y, sign_handle[2], FALSE);
	DrawGraph( sign.divide.x, sign.divide.y, sign_handle[3], FALSE);
	for ( int i=0; i<10; i++ ){
	DrawGraph( button[i].x, button[i].y, button_handle[i], FALSE);
	}
	DrawGraph( clear.x, clear.y, clear_handle, TRUE );
}

int WINAPI WinMain( HINSTANCE hI, HINSTANCE hP, LPSTR lpC, int nC ){
	SetMainWindowText( "電卓" );
	ChangeWindowMode( TRUE );
	if( DxLib_Init() == -1)		return -1;
	while ( ProcessMessage() == 0 && keybuf[ KEY_INPUT_ESCAPE] == 0 && GetHitKeyStateAll_2( keybuf ) == 0 ){ 
	if( LoadFiles() == -1 )	return -1;
	DrawScreen();
	
	//数値入力1
	SetActiveKeyInput( make_key[0] );

	while( ProcessMessage() == 0 ){
	if (CheckKeyInput( make_key[0] ) != 0 )		break;
	SetFontSize( 60 );
	DrawKeyInputString ( 160, 40, make_key[0] );
	}
	ClearDrawScreen();
	DrawScreen();
	input[0] = GetKeyInputNumber( make_key[0] );

	//符号入力
	while( ProcessMessage() == 0 ){
		if( keybuf[KEY_INPUT_ADD]  == 1 ){		
		input_sign = 1;
		break;
	}
	if( keybuf[KEY_INPUT_SUBTRACT] == 1 ){
		input_sign = 2;
		break;
	}
	if( keybuf[KEY_INPUT_MULTIPLY] == 1 ){
		input_sign = 3;
		break;
	}
	if( keybuf[KEY_INPUT_DIVIDE] == 1 ){
		input_sign = 4;
		break;
	}
	}
	
	//数値入力2
	SetActiveKeyInput( make_key[1] );

	while( ProcessMessage() == 0 ){
	if (CheckKeyInput( make_key[1] ) != 0 )		break;
	DrawKeyInputString ( 160, 40, make_key[1] );
	}
	ClearDrawScreen();
	DrawScreen();
	input[1] = GetKeyInputNumber( make_key[1] );

	switch( input_sign ){
	case 1:
	sprintf_s( output, sizeof(output), "%d", input[0] + input[1] );
	break;
	case 2:
	sprintf_s( output, sizeof(output), "%d", input[0] - input[1] );
	break;
	case 3:
	sprintf_s( output, sizeof(output), "%d", input[0] * input[1] );
	break;
	case 4:
	sprintf_s( output, sizeof(output), "%d", input[0] / input[1] );
	break;
	}
	SetFontSize( 60 );
	DrawString( 165, 40, output, GetColor( 255, 255, 255 ) );
	WaitKey();
	DxLib_End();
	return 0;
	}
}

アバター
a5ua
記事: 199
登録日時: 9年前

Re: GetHitKeyStateAll について

#14

投稿記事 by a5ua » 8年前

107行目を

コード:

while( ProcessMessage() == 0 && GetHitKeyStateAll_2( keybuf ) == 0){
に修正すれば、一応動くかと思います。
(このままだと、一回の計算しかできないとか、一番外側のループの意味がないとか、いろいろと問題はありますが)

アバター
h2so5
副管理人
記事: 2212
登録日時: 9年前
住所: 東京
連絡を取る:

Re: GetHitKeyStateAll について

#15

投稿記事 by h2so5 » 8年前

ここまで来て言うのもなんですが、このプログラムは設計にかなり無理があり、
余計に問題を増やしてしまっている気がします。

(自力でできるならともかく)この状態で質問を続けて何とか動くようにしても、
あまり勉強にならない気もしますので、DXライブラリの使い方をもう一度確認して
まずはプログラムを整理することから始めたほうが良いと思います。

ganbarukun

Re: GetHitKeyStateAll について

#16

投稿記事 by ganbarukun » 8年前

a5uaさん、h2so5さん返信ありがとうございます。

期待どおりに動くようになりました。

>ここまで来て言うのもなんですが、このプログラムは設計にかなり無理があり、
>余計に問題を増やしてしまっている気がします。

>(自力でできるならともかく)この状態で質問を続けて何とか動くようにしても、
>あまり勉強にならない気もしますので、DXライブラリの使い方をもう一度確認して
>まずはプログラムを整理することから始めたほうが良いと思います。

はい。
このプログラムは大体動くようになったので、新しいプログラムを作って次は基礎を学んでいきたいと思います。


だいたい質問内容は解決したのでここで終わりにしたいと思います。
cielさん、管理人さん、h2so5さん、しひさん、kimuchiさん、a5uaさん 

閉鎖

“C言語何でも質問掲示板” へ戻る