DXライブラリでのウインドウ最大化について

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

DXライブラリでのウインドウ最大化について

#1

投稿記事 by dragon-spirit » 14年前

ウインドウに最大化ボタンを付け、
そこを押すとウインドウのサイズが最大化する。
のようにしたいのですが、
ここを見ながら、この様なプログラムを作り
コンパイル実行すると、
フルスクリーンになってしまいます。

コード:

 
#include "DxLib.h"
 
void ChangeCallback( void *Data ){
	
	ShowWindow(GetMainWindowHandle(),3);

}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){ 

    SetUseASyncChangeWindowModeFunction( TRUE, ChangeCallback, NULL );	
	ChangeWindowMode( TRUE ) ; // ウインドウモードに変更        
	if( DxLib_Init() == -1 ) return -1; // DXライブラリ初期化処理 エラーが起きたら終了 
    
 
 
    WaitKey() ;             // キーの入力待ち(『WaitKey』を使用) 
    DxLib_End() ;           // DXライブラリ使用の終了処理
    return 0 ;              // ソフトの終了
}
何が、おかしいのでしょうか?

OSは、windows 7 で、
コンパイラは、Microsoft Visual C++ 2010 Express です。

アバター
bitter_fox
記事: 607
登録日時: 14年前
住所: 大阪府

Re: DXライブラリでのウインドウ最大化について

#2

投稿記事 by bitter_fox » 14年前

dragon-spirit さんが書きました:ウインドウに最大化ボタンを付け、
そこを押すとウインドウのサイズが最大化する。
のようにしたいのですが、
フルスクリーンになってしまいます。
DXライブラリで、最大化をフルスクリーンとして描画してるからではないでしょうか?

アバター
bitter_fox
記事: 607
登録日時: 14年前
住所: 大阪府

Re: DXライブラリでのウインドウ最大化について

#3

投稿記事 by bitter_fox » 14年前

DXライブラリがWM_SIZEメッセージのSIZE_MAXIMIZEDを検知してフルスクリーン化しているので、サブクラス化してDXライブラリのウィンドウプロシージャを飛ばしてあげることによってdragon-spiritさんが望んでおられるであろう結果を得られました。

コード:

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

WNDPROC dxWndProc;
 
void ChangeCallback( void *Data ){
    
    ShowWindow(GetMainWindowHandle(),3);
 
}

//
// ウィンドウプロシージャ
////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
	switch (msg)
	{
	case WM_SIZE:
		switch (wp)
		{
		case SIZE_MAXIMIZED: // 最大化された際にDXライブラリが実装しているウィンドウプロシージャを飛ばす(そのままデフォルトのウィンドウプロシージャを呼んでるので想定外の問題が発生する可能性も・・・)
			return (DefWindowProc(hWnd, msg, wp, lp));
		}
		break;
	default:
		break;
	}

	return (CallWindowProc((WNDPROC)dxWndProc, hWnd, msg, wp, lp)); // DXライブラリが実装しているウィンドウプロシージャを呼び出す。
}
 
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){ 
 
    SetUseASyncChangeWindowModeFunction( TRUE, ChangeCallback, NULL );  

	ChangeWindowMode( TRUE ) ; // ウインドウモードに変更        
    if( DxLib_Init() == -1 ) return -1; // DXライブラリ初期化処理 エラーが起きたら終了 
 
	HWND hWnd = GetMainWindowHandle();
	dxWndProc = (WNDPROC)GetWindowLong(hWnd, GWL_WNDPROC); // DXライブラリが実装しているウィンドウプロシージャを取得
	SetWindowLong(hWnd, GWL_WNDPROC, (LONG)WndProc); // サブクラス化してあげる
 
    WaitKey() ;             // キーの入力待ち(『WaitKey』を使用) 
    DxLib_End() ;           // DXライブラリ使用の終了処理
    return 0 ;              // ソフトの終了
}
コード内でも書きましたがこれによって想定外の現象が発生するかもしれません。

[hr][追記]色々やってみるとどうやら描画可能領域のサイズが変わってないですね・・・

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

Re: DXライブラリでのウインドウ最大化について

#4

投稿記事 by a5ua » 14年前

dragon-spirit さんが書きました: ウインドウに最大化ボタンを付け、
そこを押すとウインドウのサイズが最大化する。
これだけなら、SetUseASyncChangeWindowModeFunctionのコールバック関数は特に必要ないと思います。

コード:

#include "DxLib.h"
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
{ 
	// 「Alt+Enter」や、最大化ボタンによるフルスクリーン化を有効にする
    SetUseASyncChangeWindowModeFunction(TRUE, NULL, NULL);
	
	// ウインドウモードで起動
    ChangeWindowMode( TRUE );     
    
	if (DxLib_Init() != 0) {
		return -1;
	}
 
	while (ProcessMessage() == 0 && !CheckHitKey(KEY_INPUT_ESCAPE)) {
		WaitTimer(30);
	}

    DxLib_End();

    return 0;
}
追記:質問の内容を勘違いしていました。この回答は無視してください。
最後に編集したユーザー a5ua on 2011年4月22日(金) 02:21 [ 編集 1 回目 ]

アバター
bitter_fox
記事: 607
登録日時: 14年前
住所: 大阪府

Re: DXライブラリでのウインドウ最大化について

#5

投稿記事 by bitter_fox » 14年前

コード:

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

WNDPROC dxWndProc;
 
void ChangeCallback( void *Data ){
    
    ShowWindow(GetMainWindowHandle(),3);
 
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
	RECT rc;

	switch (msg)
	{
	case WM_SIZE:
		switch (wp)
		{
		case SIZE_MAXIMIZED:
		case SIZE_RESTORED:
			GetWindowRect(hWnd, &rc);
			SendMessage(hWnd, WM_SIZING, WMSZ_LEFT, (LPARAM)&rc); // WM_SIZINGを送ることで比率を変更させる
			break;
		}
		break;
	default:
		return CallWindowProc((WNDPROC)dxWndProc, hWnd, msg, wp, lp);
	}

	return DefWindowProc(hWnd, msg, wp, lp);
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){ 
 
    SetUseASyncChangeWindowModeFunction( TRUE, ChangeCallback, NULL );  
    ChangeWindowMode( TRUE ) ; // ウインドウモードに変更        
    if( DxLib_Init() == -1 ) return -1; // DXライブラリ初期化処理 エラーが起きたら終了 
    
 	HWND hWnd = GetMainWindowHandle();
	dxWndProc = (WNDPROC)GetWindowLong(hWnd, GWL_WNDPROC);
	SetWindowLong(hWnd, GWL_WNDPROC, (LONG)WndProc);
 
    WaitKey() ;             // キーの入力待ち(『WaitKey』を使用) 
    DxLib_End() ;           // DXライブラリ使用の終了処理
    return 0 ;              // ソフトの終了
}

これでしっかりとした出力になります。
ですが、クライアント領域のアスペクト比とDXライブラリの描画領域のアスペクト比が一致していない場合には画面に表示されないところが出てきしまいます。
(DXライブラリの本家で質問した方が詳しい返答もしくは解決策を頂けるのではないでしょうか?)
[hr][追記]
もっとしっかりとした出力を目指してみました。(恐らくこれが最善かと・・・)

コード:

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
	RECT rcClient, rc;
	static int flagSIZE = FALSE;

	switch (msg)
	{
	case WM_SIZE:
		switch (wp)
		{
		case SIZE_MAXIMIZED: // 最大化
		case SIZE_RESTORED: // 通常のサイズ変更
			GetClientRect(hWnd, &rcClient); // クライエント領域の大きさを取得

			if (rcClient.right > rcClient.bottom) // 比率を合わせる
			{
				rcClient.right = rcClient.bottom / 3 * 4;
			}
			else
			{
				rcClient.bottom = rcClient.right / 3 * 4;
			}

			// ウィンドウ領域に合わせる(タイトルバー等も考慮した大きさに)
			AdjustWindowRectEx(&rcClient, GetWindowLong(hWnd, GWL_STYLE), FALSE, GetWindowLong(hWnd, GWL_EXSTYLE));

			SendMessage(hWnd, WM_SIZING, WMSZ_LEFT, (LPARAM)&rcClient); // ウィンドウの比率を合わせる(rcClientのleft, topともに0ですがこのDXライブラリにおいては問題はありません)
			flagSIZE = TRUE;
			break;
		}
		break;
	case WM_PAINT:
		if (flagSIZE) // サイズ変更が起きていたら
		{
			HDC hdc;
			PAINTSTRUCT ps;
			HBRUSH hBrush, hOldBrush;

			hdc = BeginPaint(hWnd, &ps); // クライエント領域全体を黒く塗る
			{
				hBrush = CreateSolidBrush(RGB(0, 0, 0));
				hOldBrush = (HBRUSH)SelectObject(hdc, hBrush);

				GetClientRect(hWnd, &rc);
				Rectangle(hdc, 0, 0, rc.right, rc.bottom);
			
				SelectObject(hdc, hOldBrush);
				DeleteObject(hBrush);
			}
			EndPaint(hWnd, &ps);
			flagSIZE = FALSE;
		}
		return CallWindowProc((WNDPROC)dxWndProc, hWnd, msg, wp, lp);
	default:
		return CallWindowProc((WNDPROC)dxWndProc, hWnd, msg, wp, lp);
	}

	return (DefWindowProc(hWnd, msg, wp, lp));
}

dragon-spirit

Re: DXライブラリでのウインドウ最大化について

#6

投稿記事 by dragon-spirit » 14年前

おおおおおおできました!!!!!!!!!!!!
bitter_foxさんの方法を試したところできました。
ありがとうございました。
完璧です。

閉鎖

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