コールバック関数とWinApi関数内でのキーボード入力について
Posted: 2015年7月17日(金) 22:28
ご無沙汰しております。
前回は大変お世話になりました。
またよろしくお願いいたします。
現在DXライブラリを使用してゲームを作成しているのですが、
ウインドウのサイズを変更する際に、SetWindowSizeChangeEnableFlag関数を
使用したのですが、もっとスムーズな動きにしたいと思い、ウインドウハンドルとCreateWindowExを使ってウインドウを作成しました。
結果、マウスの左クリックを使用したウインドウのリサイズはスムーズに行えるのですが、クライアント領域は変更されず、最初に指定したウインドウサイズのままでした。
WINAPI関数内で、マウスの移動距離を計算し、SetWindowPos関数を使用すれば
クライアント領域を変更させることができると思ったのですが、Winmain関数内に記述した内容にキーボードの入力が反応しません。
コールバック関数へ記述しても反応はなく、左クリックに関して記述した場合は、ウインドウを閉じたりすることができなくなってしまいます。
DispatchMessageを無効にした場合はループができるのですが、それでもコールバック関数に記述しても、while内に記述してもキーボードの反応はなく、何が足りないのか検討もつかなくなってしまいました。
どうすればウインドウを自在にリサイズしつつ、キーボードからの入力をWINAPI関数で受け取ることができるのでしょうか。
以下のコードはクライアント領域のリサイズについては記述せず、
コールバック関数内にボックスの移動内容、
ループ内にはボックスの描画関数とDispatchMessageの有効無効を切り替えるスイッチを記述しています。
いずれもキーボードからの入力には反応しません。
何かヒントでもいただけたら幸いです。
よろしくお願い致します。
前回は大変お世話になりました。
またよろしくお願いいたします。
現在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;
}
何かヒントでもいただけたら幸いです。
よろしくお願い致します。