WM_SIZINGメッセージが送られてきません

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

WM_SIZINGメッセージが送られてきません

#1

投稿記事 by ゴンマサ » 9年前

お世話になっております。
またよろしくお願い致します。

コールバック関数にWM_SIZINGを記述したのですがメッセージが送られません。
環境はVisualC++2010Express、ウインドウズ7です。

コード内容は、ウインドウのサイズを変更した場合、4:3のアスペクト比を保つ様にフロントバッファへの描画領域を変更するといったものです。
チェックのためにWM_SIZE,WM_SIZINGを通るたびにキャラクターの座標が初期位置に戻るようにしたのですが、WM_SIZINGを通っていないようです。
コード内の255,256行目がWM_SIZING、
327,328行目がWM_SIZEを通った場合、キャラクターの座標をリセットする記述です。
WM_SIZE内の記述を無効にすると、ウインドウをリサイズしてもキャラクターの位置がリセットされません。
作業環境がWM_SIZINGに対応していないのではないかと思ったのですが、カーソルを当てると
「#define WM_SIZING 0x0214」と表示されるので非対応というわけではなさそうです。
お手数ですが解決策をご教授いただけたらと思います。

コード:

#define NAME "DirectX勉強中"
#define INITGUID

#include <Windows.h>
#include <d3dx9.h>

// ライブラリのリンク
#pragma once
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
#pragma comment(lib,"dxguid.lib")
 
//開放のための関数
#define SAFE_RELEASE(x) if(x)  { x->Release(); x=NULL; }// #define & 構造体の定義
#define DIDEVICE_BUFFERSIZE	100						// デバイスに設定するバッファ・サイズ

//アプリケーション情報
//HINSTANCE hInstApp;							//アプリケーションのインスタンスハンドル
HWND                    g_hWnd = NULL;      // Window Handle
LPDIRECT3D9             g_pD3D = NULL;     //インターフェイスの取得のためのポインタの作成(構造体)
LPDIRECT3DDEVICE9       g_pDEV = NULL;      // 描写用デバイス(インターフェイス)
								//デバイス(装置、外部周辺機器)関連を管理するインターフェイス

LPDIRECT3DTEXTURE9 pTexture;//キャラクタのテクスチャハンドル
LPDIRECT3DTEXTURE9 phaikeiTexture;//背景のテクスチャハンドル

LPD3DXSPRITE pSprite;//スプライトハンドル
					
D3DXMATRIX m_Matrix;//キャラクタの行列
D3DXVECTOR2 m_vec2;//マトリックス自体の座標

D3DXVECTOR3 Position;//位置(x座標,y座標)キャラクタ

D3DXVECTOR3 haikeiPosition;//背景の座標

D3DDISPLAYMODE          d3ddm;//画面モード
D3DPRESENT_PARAMETERS   d3dpp;//インターフェイスの取得のためのポインタの作成 描画デバイスのパラメータ?

D3DVIEWPORT9 vp;	//ビューポートのハンドル


BYTE diKeyState[256];//キーボード・デバイス定数の状態を設定

RECT B_B_Area;//バックバッファのサイズ
RECT PaintArea;//フロントバッファの描画領域

RECT W_Size;//ウインドウサイズ
RECT C_Size;//クライアントサイズ

D3DRECT Windowsize;//クリアメソッド用のウインドウサイズ取得レクト



//テクスチャの作成
HRESULT textureCreate()
{
    HRESULT hr;//ハンドル
	hr =  D3DXCreateTextureFromFileEx(g_pDEV,"player.png",0,0,1,0,
							       D3DFMT_UNKNOWN,D3DPOOL_MANAGED,
							       D3DX_DEFAULT,D3DX_DEFAULT,
							       D3DCOLOR_XRGB(0,0,0),NULL,NULL,
							       &pTexture);
    if(FAILED(hr))
        return false;

	hr =  D3DXCreateTextureFromFileEx(g_pDEV,"背景2.png",
							       640,480,1,0,				//usage
							       D3DFMT_UNKNOWN,	//ピクセルフォーマット
						               D3DPOOL_MANAGED,	//メモリクラス
						               D3DX_DEFAULT,D3DX_DEFAULT,
						               D3DCOLOR_XRGB(0,0,0),NULL,NULL,	
							       &phaikeiTexture);
    if(FAILED(hr))
        return false;	
        return S_OK;
}

//スプライトの作成
HRESULT spriteCreate()
{
    HRESULT hr;//ハンドル
    hr = D3DXCreateSprite(g_pDEV,&pSprite);//1.使用するデバイス、2.受け取る変数
    if(FAILED(hr))
    return false;
    return S_OK;
}

//スプライトの描画(キャラクタ)
HRESULT drawsprite()
{
    HRESULT hr;//ハンドル
	D3DXMatrixTransformation2D(&m_Matrix,0,0,0,NULL,0,&m_vec2);
    //塗りつぶし
   g_pDEV->Clear(0,&Windowsize, 
				  (D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER),
				  D3DCOLOR_RGBA(100,100,255,0), 
				  1.0f,0);

    g_pDEV->BeginScene();//スプライトシーンの開始---------------------
		pSprite->Begin(D3DXSPRITE_ALPHABLEND|D3DXSPRITE_DONOTSAVESTATE);
			hr = pSprite->SetTransform(&m_Matrix);
			//背景
			hr = pSprite->Draw(phaikeiTexture,NULL,NULL,&haikeiPosition,0xffffffff);
			//キャラクタ
			hr = pSprite->Draw(pTexture,NULL,NULL,&Position,0xffffffff);

			if(FAILED(hr))
			return false;
		pSprite->End();//スプライトを描画して終了
    g_pDEV->EndScene();//シーンを終了----------------------------------
    return g_pDEV->Present(&B_B_Area, &PaintArea, g_hWnd, NULL);//ここでバック、フロントバッファの範囲、描画対象のウインドウなどを指定する
    return S_OK;
}
	
//初期化処理(デバイスの設定)
HRESULT Init3DDev()
{
    //インターフェイスの取得
    if (NULL==(g_pD3D=Direct3DCreate9(D3D_SDK_VERSION)))    return E_FAIL;
	//アダプタのデータを得る(数、幅、高さ、リフレッシュレート)
    if (FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddm)))   return E_FAIL;
 
    //D3DPRESENT_PARAMETERS構造体の設定
    ZeroMemory(&d3dpp,sizeof(d3dpp));
	d3dpp.BackBufferWidth = 640;//バックバッファサイズの指定
	d3dpp.BackBufferHeight =480;//バックバッファサイズはウインドウサイズに引き伸ばされる?
	

    d3dpp.Windowed                  = TRUE;        // ウィンドウモード
    d3dpp.SwapEffect =  D3DSWAPEFFECT_COPY;//D3DSWAPEFFECT_DISCARD;      // 映像信号に同期してフリップする
    d3dpp.BackBufferFormat          = d3ddm.Format;// カラーモードの指定
    d3dpp.EnableAutoDepthStencil    = TRUE;        // デプスバッファ(Zバッファ)とステンシルバッファを作成
    d3dpp.AutoDepthStencilFormat    = D3DFMT_D16;  // デプスバッファとして16bitを使う
 
    //デバイスの作成:CreateDeviceの実行//復元用
    if (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
									D3DDEVTYPE_HAL,
									g_hWnd,
                                    D3DCREATE_SOFTWARE_VERTEXPROCESSING,
									&d3dpp,
									&g_pDEV)))
    return E_FAIL;
    return S_OK;
}
 
//ビューポートの作成
HRESULT Viewport()//ビューポートはクライアント領域内の描画領域のこと。デバイスの描画領域とは無関係
{
    HRESULT hr;//ハンドル
    //ビューポートの作成
    vp.X = 0;
    vp.Y = 0;
	vp.Width = 640;//PaintArea.right;//d3dpp.BackBufferWidth;
    vp.Height =480;// PaintArea.bottom;//d3dpp.BackBufferHeight;
    vp.MinZ = 0.0f;
    vp.MaxZ = 1.0f;
    hr = g_pDEV -> SetViewport(&vp);
    if(FAILED(hr))
    return false;
    return S_OK;
}
 
// DirectX Graphics の終了処理:未開放有り
void Cleanup(void)
{
    SAFE_RELEASE(g_pDEV);
    SAFE_RELEASE(g_pD3D);
}
 
//画像の移動//これでプレイヤー画像を動かす
HRESULT idou()
{
		if(diKeyState[VK_RIGHT])
		{	
			Position.x += 5.0f;
		}
		else if(diKeyState[VK_LEFT])
		{	
			Position.x -= 5.0f;
		}
		else if(diKeyState[VK_DOWN])
		{	
			Position.y += 5.0f;
		}
		else if(diKeyState[VK_UP])
		{	
			Position.y -= 5.0f;
		}
	return S_OK;
}

void Action()
{
	idou();
	drawsprite();
}

//ウインドウのサイズ関連の調整
void AdjustmentWindow()
{
	//描画領域の指定
	B_B_Area.top = 0;
	B_B_Area.bottom = 480;
	B_B_Area.left = 0;
	B_B_Area.right = 640;

	//描画領域の指定
	PaintArea.top = 0;
	PaintArea.bottom = 480;
	PaintArea.left = 0;
	PaintArea.right = 640;


	//クライアント領域からウインドウサイズの調整
	GetWindowRect(g_hWnd,&W_Size);//ウインドウのサイズを取得
	GetClientRect(g_hWnd,&C_Size);//クライアント領域のサイズを取得


	//ウインドウバーの計算

	int WindowsX,WindowsY,W_BarX,W_BarY,W_X,W_Y;//正しいウインドウのサイズ、ウインドウのバーの太さ、およびウインドウ全体のサイズ

	//ウインドウのサイズを計算
	W_X = W_Size.right - W_Size.left;
	W_Y = W_Size.bottom - W_Size.top;

	//ウインドウバーのサイズを計算
	W_BarX = W_X - C_Size.right;
	W_BarY = W_Y - C_Size.bottom;

	//正しいウインドウのサイズを計算
	WindowsX = W_X + W_BarX;
	WindowsY = W_Y + W_BarY;

	//ウインドウのサイズを代入
	SetWindowPos(g_hWnd,HWND_TOP,600,300,WindowsX,WindowsY,
				 SWP_SHOWWINDOW);
}

// ウィンドウ処理(自分で処理したときは 0 を返す)
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, UINT wParam, LONG lParam)
{

    switch(msg)
    {   
	
	
	
	case WM_DESTROY:
            Cleanup();
            PostQuitMessage(0);
            break;
		
	case WM_SIZING:
		Position.x= 0.0f;
		Position.y= 0.0f;				
		break;
	
		case WM_SIZE:
	
				if(!g_pDEV || wParam == SIZE_MINIMIZED)
				{
					break;
				}
				if(wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED)
				{
					//フロントバッファの描画位置と領域を算出
					int WX,WY,FBArea;

					WX = LOWORD(lParam);
					WY = HIWORD(lParam);

					if(WX>WY)
					{
						//領域の高さ開始位置をリセット
						PaintArea.top = 0;
						//領域の高さを決定
						PaintArea.bottom = WY;
						//領域の幅を決定
						FBArea = (WY/3)*4;//③

						if(FBArea < WX)//算出されたX軸の描画範囲がウインドウよりも小さい場合
						{
							//領域の横開始位置を決定
							PaintArea.left = (WX - FBArea)/2;
							//領域の幅の開始から終点を決定
							PaintArea.right = PaintArea.left + FBArea;
						}
						else if(FBArea > WX)//算出されたX軸の描画範囲がウインドウよりも大きい場合
						{
							PaintArea.left = 0;
							PaintArea.right = WX;
							FBArea = (WX/4)*3;
							PaintArea.top = (WY - FBArea)/2;
							PaintArea.bottom = PaintArea.top + FBArea;
						}
					}
					else if(WX<WY)
					{
						//領域の高さ開始位置をリセット
						PaintArea.left = 0;
						//領域の幅を決定
						PaintArea.right = WX;
						//領域の高さを決定
						FBArea = (WX/4)*3;//③

						if(FBArea < WY)//算出されたY軸の描画範囲がウインドウよりも小さい場合
						{
							//領域の高さ開始位置を決定
							PaintArea.top = (WY - FBArea)/2;
							//領域の高さの開始から終点を決定
							PaintArea.bottom = PaintArea.top + FBArea;
						}
						else if(FBArea > WY)//算出されたY軸の描画範囲がウインドウよりも大きい場合
						{
							PaintArea.top = 0;
							PaintArea.bottom = WY;
							FBArea = (WY/3)*4;
							PaintArea.left = (WX - FBArea)/2;
							PaintArea.bottom = PaintArea.right + FBArea;
						}
					}

					//クリアメソッドの範囲設定
					Windowsize.x2 = LOWORD(lParam);
					Windowsize.y2 = HIWORD(lParam);
					Position.x= 0.0f;
					Position.y= 0.0f;

					pSprite->OnLostDevice();//スプライトのロスト
					g_pDEV->Reset(&d3dpp);
					InvalidateRect(hWnd, &PaintArea,TRUE);//第二引数にRECTを指定し、フロントバッファの描画範囲を指定
				}
				break;


        case WM_KEYDOWN:
            switch(wParam)
            {   case VK_ESCAPE:
                    DestroyWindow(hWnd);
                    break;
					default:
					diKeyState[wParam] = 1;
            }
            break;
		case WM_KEYUP:
			diKeyState[wParam] = 0;
			break;
			
       default:
            return DefWindowProc(hWnd, msg, wParam, lParam);
    }
    return 0;
}
 
//★ WinMain()
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR lpCmdLine, int nCmdShow)
{   
    MSG msg;

	//hInstApp=hInst;
	//ウインドウクラスの登録
    WNDCLASSEX wc = { sizeof(WNDCLASSEX),CS_CLASSDC,WndProc,
           0,0,hInst,NULL,NULL,NULL,NULL,NAME,NULL };
    if (!RegisterClassEx(&wc))  return FALSE;
	//メインウインドウ
    g_hWnd= CreateWindowEx(0,
						   NAME,NAME,
						   WS_OVERLAPPEDWINDOW,
						   600,300,640,480,//デスクトップ上のx、y、幅、高さ
						   NULL,NULL,hInst,NULL);
    if (!g_hWnd)  return FALSE;

    // DirectX Graphics の初期化
    if (FAILED(Init3DDev()))    return FALSE;

    // ウインドウ表示
    ShowWindow(g_hWnd, SW_SHOWNORMAL);
    UpdateWindow(g_hWnd);

	//ウインドウサイズ等の調整
	AdjustmentWindow();

    ZeroMemory(&msg,sizeof(msg));

	//描画関連
    textureCreate();//テクスチャの作成
    spriteCreate();//スプライトの作成
    Viewport();//ビューポートの作成

	//画像の初期位置のセット
	Position.x = 0.0f;
	Position.y = 0.0f;

	//背景の位置のセット
	haikeiPosition.x = 0.0f;
	haikeiPosition.y = 0.0f;

	//クリアメソッド用のサイズ
	Windowsize.x1 = 0;
	Windowsize.y1 = 0;
	Windowsize.x2 = 640;
	Windowsize.y2 = 480;

    //ループ
    while(msg.message!=WM_QUIT)
    {  
        //プロシージャ
        if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
        {   
			TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
	    {	 
			Action();
	    }
	}
    UnregisterClass(NAME, hInst);
    return  TRUE;
}

YuO
記事: 947
登録日時: 14年前
住所: 東京都世田谷区

Re: WM_SIZINGメッセージが送られてきません

#2

投稿記事 by YuO » 9年前

コードを見る限り,Position.xとPosition.yを0に設定しているだけで,描画等を行っていないように見えます。

case WM_SIZING:の次の文にブレークポイントを設定するとか,
OutputDebugStringを使ってデバッグ文字列を出力させるとかして,WM_SIZINGを通っているのかちゃんと検証してみてはどうでしょうか。

ゴンマサ

Re: WM_SIZINGメッセージが送られてきません

#3

投稿記事 by ゴンマサ » 9年前

>>YuO様

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

WM_SIZINGの内容を書き換えました。
RECT Wsizeをグローバル変数として記述し、
構造体の中身はWM_SIZE内のClearメソッドの範囲設定をした直後に、その内容をコピーしました。

この記述でブレークポイントを試してみたのですが、
switch関数のwParamの各caseに配置したところ、上下左右のバーをドラッグしたときは反応するのですが、
それ以外の斜め四方向になると、各二行目にブレークポイントを配置した場合、反応せず素通りしてしまいました。

またswitch関数を抜けた後の45から51行目にかけては
ウインドウの最大化の状態、または画面の端までウインドウを伸ばしきった状態から
上部のバーをドラッグして元のサイズに戻した場合のみ反応します。
バーをドラッグしてのswitch関数によるリサイズでは反応しませんでした。


コード:

case WM_SIZING:

		POINT *Crsor;		//カーソルの座標
		GetCursorPos(Crsor);		//カーソルの座標を取得

		switch(wParam)
		{

		case WMSZ_TOP:
			Wsize.top = Crsor->y;
			break;

		case WMSZ_BOTTOM:
			Wsize.bottom = Crsor->y;
			break;

		case WMSZ_LEFT:
			Wsize.left = Crsor->x;
			break;

		case WMSZ_RIGHT:
			Wsize.right = Crsor->x;
			break;

		case WMSZ_BOTTOMRIGHT:
			Wsize.right = Crsor->x;//ブレークポイント反応する
			Wsize.bottom = Crsor->y;//ブレークポイントがここだと反応しない
			break;

		case WMSZ_BOTTOMLEFT:
			Wsize.left = Crsor->x;
			Wsize.bottom = Crsor->y;//ブレークポイント反応しない
			break;

		case WMSZ_TOPLEFT:
			Wsize.left = Crsor->x;
			Wsize.top = Crsor->y;//ブレークポイント反応しない
			break;

		case WMSZ_TOPRIGHT:
			Wsize.right = Crsor->x;
			Wsize.top = Crsor->y;//ブレークポイント反応しない
			break;
		}
					Position.x= 0.0f;
					Position.y= 0.0f;		
					pSprite->OnLostDevice();//スプライトのロスト
					g_pDEV->Reset(&d3dpp);
					InvalidateRect(hWnd, &Wsize,TRUE);//第二引数にRECTを指定し、フロントバッファの描画範囲を指定

					return TRUE;

閉鎖

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