wsprintfで中断してしまう

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
kabocha
記事: 6
登録日時: 9年前

wsprintfで中断してしまう

#1

投稿記事 by kabocha » 9年前

fpsを画面に表示させようと思い、wsprintfでfpsをlptStrに入れて、TextOutで表示しています。
code
#include <windows.h>
#include <mmsystem.h> // timeGetTime()のため


#pragma comment(lib, "winmm.lib") // VC++の場合、これでもリンク可能


LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // ウィンドウプロシージャ

void MainLoop(void);
void Wait(DWORD);
void FPSCount(DWORD*);
void Draw_Text(char*);

HWND hwnd;
const DWORD FPS = 60; // FPS設定
BOOL EndFlag = FALSE; // 終了フラグ
DWORD fps; // FPS計測値
//==============================================================================================
// Windows メイン処理
//==============================================================================================
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {

// ウィンドウクラスの登録
WNDCLASS wc;
ZeroMemory(&wc, sizeof(WNDCLASS));
wc.style = CS_HREDRAW | CS_VREDRAW; // ウィンドウスタイル
wc.lpfnWndProc = (WNDPROC)WndProc; // ウィンドウプロシージャ
wc.cbClsExtra = 0; // 補助領域サイズ
wc.cbWndExtra = 0; // 補助領域サイズ
wc.hInstance = hInstance; // インスタンスハンドル
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); // アイコン
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // マウスカーソル
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); // クライアント領域背景色
wc.lpszMenuName = NULL; // ウィンドウメニュー
wc.lpszClassName = TEXT("Windows"); // ウィンドウクラス名
if (!RegisterClass(&wc)) return 0;

// ウィンドウの作成
HWND hWnd = CreateWindow(
wc.lpszClassName, // ウィンドウクラス名
TEXT("タイトル"), // ウィンドウタイトル
WS_OVERLAPPEDWINDOW, // ウィンドウスタイル
CW_USEDEFAULT, // 表示X座標
CW_USEDEFAULT, // 表示Y座標
CW_USEDEFAULT, // 幅
CW_USEDEFAULT, // 高さ
NULL, // 親ウィンドウ
NULL, // ウィンドウメニュー
hInstance, // インスタンスハンドル
NULL); // WM_CREATE情報
hwnd = hWnd;
// ウィンドウの表示
ShowWindow(hWnd, nCmdShow); // 表示状態の設定
UpdateWindow(hWnd); // クライアント領域の更新

// ゲームメイン処理へ~
MainLoop();

return 0; // とりあえず0を返す
}

//==============================================================================================
// ウィンドウプロシージャ
//==============================================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {

switch (msg) {
case WM_DESTROY: // ウィンドウが破棄されたときの処理
// 終了メッセージ
PostQuitMessage(0);

EndFlag = TRUE;

return 0;

default: // デフォルト処理
return DefWindowProc(hWnd, msg, wParam, lParam);
}
}

//==============================================================================================
// ゲームメイン処理
//==============================================================================================

void Wait(DWORD wait_time) {
MSG msg;
DWORD start_time = timeGetTime();

do {
// メッセージ処理
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}

if (wait_time > 0) Sleep(1); // ちょっと休憩
} while (timeGetTime() < wait_time + start_time); // wait_time だけ回る
}

void FPSCount(DWORD *fps) {
static DWORD before_time = timeGetTime(); // 以前の時間
DWORD now_time = timeGetTime(); // 現在の時間
static DWORD fps_ctr = 0;

if (now_time - before_time >= 1000) {
// 初期化
before_time = now_time;
*fps = fps_ctr;
fps_ctr = 0;
}

fps_ctr++;
}

void MainLoop(void) {
HDC hdc;
PAINTSTRUCT ps;
LPTSTR lptStr = TEXT("aaaaa");
DWORD StartTime, EndTime, PassTime;

TIMECAPS Caps;

timeGetDevCaps(&Caps, sizeof(TIMECAPS)); // 性能取得
timeBeginPeriod(Caps.wPeriodMin); // 設定

hdc = GetDC(hwnd);
//メインループ
while (!EndFlag) {
StartTime = timeGetTime();
//ここから


EndTime = timeGetTime();
PassTime = EndTime - StartTime; // 経過時間の計算
(1000 / FPS > PassTime) ? Wait(1000 / FPS - PassTime) : Wait(0); // 待つ。

FPSCount(&fps); // FPS の計測
wsprintf(lptStr,TEXT("%d"),fps);
TextOut(hdc, 10, 10, lptStr, lstrlen(lptStr));
ReleaseDC(hwnd, hdc);
}

timeEndPeriod(Caps.wPeriodMin); // 後処理
}
/code

とすると、
0x74FC3566 (user32.dll) で例外がスローされました (プロジェクト.exe 内): 0xC0000005: 場所 0x01017C60 への書き込み中にアクセス違反が発生しました
と表示され、中断してしまいます。
コンパイラは、visualstudio 2015です。
どのようにすれば良いのか、説明してくださるとうれしいです。

参考URL:http://zahyou.6.ql.bz/cgame/fps_m.htm
http://wisdom.sakura.ne.jp/system/winap ... index.html

kabocha
記事: 6
登録日時: 9年前

Re: wsprintfで中断してしまう

#2

投稿記事 by kabocha » 9年前

コードの表示の方法をおそらく間違えたのでもう一度書きます すみません

fpsを画面に表示させようと思い、wsprintfでfpsをlptStrに入れて、TextOutで表示しています。

コード:

#include <windows.h>
#include <mmsystem.h> // timeGetTime()のため


#pragma comment(lib, "winmm.lib") // VC++の場合、これでもリンク可能


LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // ウィンドウプロシージャ

void MainLoop(void);
void Wait(DWORD);
void FPSCount(DWORD*);
void Draw_Text(char*);

HWND hwnd;
const DWORD FPS = 60; // FPS設定
BOOL EndFlag = FALSE; // 終了フラグ
DWORD fps; // FPS計測値
//==============================================================================================
	// Windows メイン処理
//==============================================================================================
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {

	// ウィンドウクラスの登録
WNDCLASS wc;
	ZeroMemory(&wc, sizeof(WNDCLASS));
	wc.style = CS_HREDRAW | CS_VREDRAW; // ウィンドウスタイル
wc.lpfnWndProc = (WNDPROC)WndProc; // ウィンドウプロシージャ
wc.cbClsExtra = 0; // 補助領域サイズ
wc.cbWndExtra = 0; // 補助領域サイズ
wc.hInstance = hInstance; // インスタンスハンドル
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); // アイコン
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // マウスカーソル
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); // クライアント領域背景色
wc.lpszMenuName = NULL; // ウィンドウメニュー
wc.lpszClassName = TEXT("Windows"); // ウィンドウクラス名
if (!RegisterClass(&wc)) return 0;

	// ウィンドウの作成
HWND hWnd = CreateWindow(
	wc.lpszClassName, // ウィンドウクラス名
TEXT("タイトル"), // ウィンドウタイトル
WS_OVERLAPPEDWINDOW, // ウィンドウスタイル
CW_USEDEFAULT, // 表示X座標
CW_USEDEFAULT, // 表示Y座標
CW_USEDEFAULT, // 幅
CW_USEDEFAULT, // 高さ
NULL, // 親ウィンドウ
NULL, // ウィンドウメニュー
hInstance, // インスタンスハンドル
NULL); // WM_CREATE情報
hwnd = hWnd;
	// ウィンドウの表示
ShowWindow(hWnd, nCmdShow); // 表示状態の設定
UpdateWindow(hWnd); // クライアント領域の更新

// ゲームメイン処理へ~
MainLoop();

	return 0; // とりあえず0を返す
}

//==============================================================================================
// ウィンドウプロシージャ
//==============================================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {

	switch (msg) {
	case WM_DESTROY: // ウィンドウが破棄されたときの処理
// 終了メッセージ
PostQuitMessage(0);

	EndFlag = TRUE;

	return 0;

	default: // デフォルト処理
return DefWindowProc(hWnd, msg, wParam, lParam);
	}
}

//==============================================================================================
// ゲームメイン処理
//==============================================================================================

void Wait(DWORD wait_time) {
	MSG msg;
	DWORD start_time = timeGetTime();

	do {
	// メッセージ処理
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
	TranslateMessage(&msg);
	DispatchMessage(&msg);
	}

	if (wait_time > 0) Sleep(1); // ちょっと休憩
} while (timeGetTime() < wait_time + start_time); // wait_time だけ回る
}

void FPSCount(DWORD *fps) {
	static DWORD before_time = timeGetTime(); // 以前の時間
DWORD now_time = timeGetTime(); // 現在の時間
static DWORD fps_ctr = 0;

	if (now_time - before_time >= 1000) {
	// 初期化
before_time = now_time;
	*fps = fps_ctr;
	fps_ctr = 0;
	}

	fps_ctr++;
}

void MainLoop(void) {
	HDC hdc;
	PAINTSTRUCT ps;
	LPTSTR lptStr = TEXT("aaaaa");
	DWORD StartTime, EndTime, PassTime;

	TIMECAPS Caps;

	timeGetDevCaps(&Caps, sizeof(TIMECAPS)); // 性能取得
timeBeginPeriod(Caps.wPeriodMin); // 設定

hdc = GetDC(hwnd);
	//メインループ
while (!EndFlag) {
	StartTime = timeGetTime();
	//ここから


EndTime = timeGetTime();
	PassTime = EndTime - StartTime; // 経過時間の計算
(1000 / FPS > PassTime) ? Wait(1000 / FPS - PassTime) : Wait(0); // 待つ。

FPSCount(&fps); // FPS の計測
wsprintf(lptStr,TEXT("%d"),fps);
	TextOut(hdc, 10, 10, lptStr, lstrlen(lptStr));
	ReleaseDC(hwnd, hdc);
	}

	timeEndPeriod(Caps.wPeriodMin); // 後処理
}
とすると、
0x74FC3566 (user32.dll) で例外がスローされました (プロジェクト.exe 内): 0xC0000005: 場所 0x01017C60 への書き込み中にアクセス違反が発生しました
と表示され、中断してしまいます。
コンパイラは、visualstudio 2015です。
どのようにすれば良いのか、説明してくださるとうれしいです。

参考URL:
http://zahyou.6.ql.bz/cgame/fps_m.htm
http://wisdom.sakura.ne.jp/system/winap ... index.html

kabocha
記事: 6
登録日時: 9年前

Re: wsprintfで中断してしまう

#3

投稿記事 by kabocha » 9年前

http://wisdom.sakura.ne.jp/system/winap ... index.html
URLができなかったのでもう一度書きます

何度もすみません

アバター
usao
記事: 1889
登録日時: 12年前
連絡を取る:

Re: wsprintfで中断してしまう

#4

投稿記事 by usao » 9年前

>LPTSTR lptStr = TEXT("aaaaa");
> ...
>wsprintf(lptStr,TEXT("%d"),fps);

lptStr は TEXT("aaaaa") を指してるわけですが,
ここは書き換えちゃいけないのでは(「リテラル」とか呼ぶのかな).

もっと普通に文字列用のバッファを用意すればいいのではないでしょうか.

コード:

TCHAR StrBuffer[6];  //※何要素あればいいのかわからんけど必要なサイズで.
...
wsprintf( StrBuffer, TEXT("%d"),fps );
とか.

kabocha
記事: 6
登録日時: 9年前

Re: wsprintfで中断してしまう

#5

投稿記事 by kabocha » 9年前

ありがとうございます。
lptStrをTCHAR StrBufferにしてみると、うまくコンパイルできました。

コード:

#include <windows.h>
#include <mmsystem.h> // timeGetTime()のため


#pragma comment(lib, "winmm.lib") // VC++の場合、これでもリンク可能


LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);       // ウィンドウプロシージャ

void MainLoop(void);
void Wait(DWORD);
void FPSCount(DWORD*);
void Draw_Text(char*);

HWND hwnd;
const DWORD FPS = 60; // FPS設定
BOOL EndFlag = FALSE; // 終了フラグ
DWORD fps; // FPS計測値
		   //==============================================================================================
		   // Windows メイン処理
		   //==============================================================================================
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {

	// ウィンドウクラスの登録
	WNDCLASS wc;
	ZeroMemory(&wc, sizeof(WNDCLASS));
	wc.style = CS_HREDRAW | CS_VREDRAW;             // ウィンドウスタイル
	wc.lpfnWndProc = (WNDPROC)WndProc;                    // ウィンドウプロシージャ
	wc.cbClsExtra = 0;                                   // 補助領域サイズ
	wc.cbWndExtra = 0;                                   // 補助領域サイズ
	wc.hInstance = hInstance;                           // インスタンスハンドル
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);     // アイコン
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);         // マウスカーソル
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);          // クライアント領域背景色
	wc.lpszMenuName = NULL;                                // ウィンドウメニュー
	wc.lpszClassName = TEXT("Windows");                     // ウィンドウクラス名
	if (!RegisterClass(&wc)) return 0;

	// ウィンドウの作成
	HWND hWnd = CreateWindow(
		wc.lpszClassName,                                   // ウィンドウクラス名
		TEXT("タイトル"),                                   // ウィンドウタイトル
		WS_OVERLAPPEDWINDOW,                                // ウィンドウスタイル
		CW_USEDEFAULT,                                      // 表示X座標
		CW_USEDEFAULT,                                      // 表示Y座標
		CW_USEDEFAULT,                                      // 幅
		CW_USEDEFAULT,                                      // 高さ
		NULL,                                               // 親ウィンドウ
		NULL,                                               // ウィンドウメニュー
		hInstance,                                          // インスタンスハンドル
		NULL);                                              // WM_CREATE情報
	hwnd = hWnd;
	// ウィンドウの表示
	ShowWindow(hWnd, nCmdShow);                             // 表示状態の設定
	UpdateWindow(hWnd);                                     // クライアント領域の更新

															// ゲームメイン処理へ~
	MainLoop();

	return 0; // とりあえず0を返す
}

//==============================================================================================
// ウィンドウプロシージャ
//==============================================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {

	switch (msg) {
	case WM_DESTROY:                                    // ウィンドウが破棄されたときの処理
														// 終了メッセージ
		PostQuitMessage(0);

		EndFlag = TRUE;

		return 0;

	default:                                            // デフォルト処理
		return DefWindowProc(hWnd, msg, wParam, lParam);
	}
}

//==============================================================================================
// ゲームメイン処理
//==============================================================================================

void Wait(DWORD wait_time) {
	MSG msg;
	DWORD start_time = timeGetTime();

	do {
		// メッセージ処理
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}

		if (wait_time > 0) Sleep(1); // ちょっと休憩
	} while (timeGetTime() < wait_time + start_time); // wait_time だけ回る
}

void FPSCount(DWORD *fps) {
	static DWORD before_time = timeGetTime(); // 以前の時間
	DWORD        now_time = timeGetTime(); // 現在の時間
	static DWORD fps_ctr = 0;

	if (now_time - before_time >= 1000) {
		// 初期化
		before_time = now_time;
		*fps = fps_ctr;
		fps_ctr = 0;
	}

	fps_ctr++;
}

void MainLoop(void) {
	HDC hdc;
	PAINTSTRUCT ps;
	TCHAR StrBuffer[6];
	DWORD StartTime, EndTime, PassTime;

	TIMECAPS Caps;

	timeGetDevCaps(&Caps, sizeof(TIMECAPS)); // 性能取得
	timeBeginPeriod(Caps.wPeriodMin); // 設定

	hdc = GetDC(hwnd);
	//メインループ
	while (!EndFlag) {
		StartTime = timeGetTime();
		//ここから


		EndTime = timeGetTime();
		PassTime = EndTime - StartTime; // 経過時間の計算
		(1000 / FPS > PassTime) ? Wait(1000 / FPS - PassTime) : Wait(0); // 待つ。

		FPSCount(&fps); // FPS の計測
		wsprintf(StrBuffer,TEXT("%d"),fps);
		TextOut(hdc, 10, 10, StrBuffer, lstrlen(StrBuffer));
	}
	ReleaseDC(hwnd, hdc);
	timeEndPeriod(Caps.wPeriodMin); // 後処理
}
上のソースコードです。
これで解決だと思います。
本当に有難うございます。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: wsprintfで中断してしまう

#6

投稿記事 by みけCAT » 9年前

kabocha さんが書きました:これで解決だと思います。
本当に有難うございます。
解決したのでしたら、「解決チェック」をお願いします。
解決チェックをするには、投稿画面の「送信」ボタンの右にある「解決!」にチェックを入れた状態で返信を投稿してください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

kabocha
記事: 6
登録日時: 9年前

Re: wsprintfで中断してしまう

#7

投稿記事 by kabocha » 9年前

日が空いてしまってすみません
初めての質問なのでわからないことがたくさんありました

閉鎖

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