ページ 11

コールバック関数とWinApi関数内でのキーボード入力について

Posted: 2015年7月17日(金) 22:28
by ゴンマサ
ご無沙汰しております。
前回は大変お世話になりました。
またよろしくお願いいたします。

現在DXライブラリを使用してゲームを作成しているのですが、
ウインドウのサイズを変更する際に、SetWindowSizeChangeEnableFlag関数を
使用したのですが、もっとスムーズな動きにしたいと思い、ウインドウハンドルとCreateWindowExを使ってウインドウを作成しました。

結果、マウスの左クリックを使用したウインドウのリサイズはスムーズに行えるのですが、クライアント領域は変更されず、最初に指定したウインドウサイズのままでした。

WINAPI関数内で、マウスの移動距離を計算し、SetWindowPos関数を使用すれば
クライアント領域を変更させることができると思ったのですが、Winmain関数内に記述した内容にキーボードの入力が反応しません。

コールバック関数へ記述しても反応はなく、左クリックに関して記述した場合は、ウインドウを閉じたりすることができなくなってしまいます。



DispatchMessageを無効にした場合はループができるのですが、それでもコールバック関数に記述しても、while内に記述してもキーボードの反応はなく、何が足りないのか検討もつかなくなってしまいました。



どうすればウインドウを自在にリサイズしつつ、キーボードからの入力をWINAPI関数で受け取ることができるのでしょうか。



以下のコードはクライアント領域のリサイズについては記述せず、
コールバック関数内にボックスの移動内容、
ループ内にはボックスの描画関数とDispatchMessageの有効無効を切り替えるスイッチを記述しています。
いずれもキーボードからの入力には反応しません。

コード:

#include <windows.h>
#include "DxLib.h"


//グローバル変数
HINSTANCE g_hInstance;


int edd,dhfh,ssss;//カウント用変数
int hix,hiy,tuix,tuiy;//ウインドウの初期座標
int boxx,boxy,boxxx,boxyy;//ボックス座標

/////////////////////////////////////////////////////////////////////////////
//ウィンドウプロシージャ
//コールバック関数
LRESULT CALLBACK WndProc(HWND hwnd, UINT message,WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
		case WM_CLOSE:
		DestroyWindow(hwnd);
		return 0;

	case WM_DESTROY:
		PostQuitMessage(0);
		break;
		default:
		return (DefWindowProc(hwnd,message,wParam,lParam));

	//ボックスの操作
	case VK_UP:
		boxy-=5;
		boxyy-=5;
		return 0;

	case VK_DOWN:
		boxy+=5;
		boxyy+=5;
		return 0;

	case VK_LEFT:
		boxx-=5;
		boxxx-=5;
		return 0;
		
	case VK_RIGHT:
		
		boxx+=5;
		boxxx+=5;
		return 0;
	}
	return 0L;
}

//ウインドウのデスクトップ上での初期座標設定
void window_position()
{
	hix = 500;//ウインドウのデスクトップ上の左上x座標
	hiy = 500;			//ウインドウのデスクトップ上の左上y座標
	tuix = 350 + 16;	//ウインドウのデスクトップ上の右下x座標、バー補正有り
	tuiy = 350 + 38;	//ウインドウのデスクトップ上の右下y座標、バー補正有り
}


/////////////////////////////////////////////////////////////////////////////
//WinMain関数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmd, int nCmdShow)
{

	MSG msg;
	g_hInstance = hInstance;

	window_position();

	boxx = 25;
	boxy = 25;
	boxxx = 50;
	boxyy = 50;

	edd = 0;
	dhfh=1;
	ssss = 0;

//InitWindow関数の内容を記述
//***************************************************************************************
	HWND hWnd;//使用するウインドウのハンドルを作成

	LPCTSTR szclassName = "succ";
	WNDCLASSEX wcex;
	ZeroMemory((LPVOID)&wcex, sizeof(WNDCLASSEX));



	//ウィンドウクラスを登録
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = 0;


	wcex.lpfnWndProc = WndProc;//ここでコールバック関数を登録



	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hInstance = g_hInstance;
	wcex.hIcon = NULL;
	wcex.hCursor = LoadCursor(NULL,IDC_ARROW);
	wcex.hbrBackground = ( HBRUSH)( COLOR_WINDOW+3);
	wcex.lpszMenuName = NULL;
	wcex.lpszClassName = szclassName;
	wcex.hIconSm = NULL;
	RegisterClassEx(&wcex);


	//ウィンドウ作成
	hWnd=CreateWindowEx(0,szclassName,"test中",WS_OVERLAPPEDWINDOW,
	hix,hiy,//左上座標xy
	tuix,tuiy,//xyの幅
	NULL,NULL,g_hInstance,NULL);



	//ウィンドウ表示
	ShowWindow(hWnd, SW_SHOW);
	UpdateWindow(hWnd);

//***************************************************************************************


	int Cr ;
	Cr = GetColor( 255 , 255 , 255 ) ;

	SetUserWindow( hWnd ) ;//上記で設定された内容のウインドウを使用する

	if( DxLib_Init() == -1 )
	{
		return -1;
	}
	SetDrawScreen( DX_SCREEN_BACK );


	while (GetMessage (&msg, NULL, 0, 0))

	{
		ClearDrawScreen();


		DrawFormatString( 10, 20, Cr, "左上のx座標は %d です", Client.left ) ;
		DrawFormatString( 80, 40, Cr, "左上のy座標は %d です", Client.top ) ;
		DrawFormatString( 130, 60, Cr, "右下のx座標 %d です", Client.right ) ;
		DrawFormatString( 180, 80, Cr, "右下のy座標 %d です", Client.bottom ) ;

		DrawFormatString( 10, 120, Cr, "eddは %d です", edd ) ;
		DrawFormatString( 10, 140, Cr, "ssssは %d です", ssss ) ;
		//キーボードからのテスト命令

			

			edd++;
			ssss++;


			//ボックスの描画
			//操作についてはコールバック関数内に記述
			DrawBox(boxx,boxy,boxxx,boxyy,Cr,TRUE);
			

	

	//ウインドウへの命令
		TranslateMessage (&msg);
		if(CheckHitKey(KEY_INPUT_B)==1 && ssss < 50)
		{
			if(dhfh == 0)
			{
				dhfh = 1;
				ssss = 0;
			}
			else if(dhfh == 1)
			{
				dhfh = 0;
				ssss = 0;
			}
		}	
		//これが有効な場合はウインドウの操作ができるがループが自動で進まない
		//ない場合ループが進むがウインドウの操作ができなくなる
		if(dhfh == 0)
		{
			DispatchMessage (&msg);
		}
		ScreenFlip();
	}

	DxLib_End() ;
	return msg.wParam;
}


何かヒントでもいただけたら幸いです。
よろしくお願い致します。

Re: コールバック関数とWinApi関数内でのキーボード入力について

Posted: 2015年7月17日(金) 22:53
by みけCAT
PeekMessage関数を使ってみてはいかがでしょうか?
PeekMessageによる「メインループ」
PeekMessage 関数

Re: コールバック関数とWinApi関数内でのキーボード入力について

Posted: 2015年7月18日(土) 09:59
by ゴンマサ
みけCAT様

返信ありがとうございます。

PeekMessageについて調べてみます。
ありがとうございました。