Win32APIのTextOutで変数を表示する方法が分かりません

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

Win32APIのTextOutで変数を表示する方法が分かりません

#1

投稿記事 by sujiniku » 1年前

ゲームプログラミングで、RPGで、所持金などのパラメーターを画面表示させたいのですが、変数をウィンドウ内に文字表示する方法が分かりません。Win32 APIを用いて開発しています。

コード:

_stprintf(p, TEXT("money = %d"), your_money);
TextOut(hdc, 420, 320, p , lstrlen(p));
上のコードだと、Visual Studio のエラー一覧で
「 '_swprintf': This function or variable may be unsafe. 」
と出てしまい、コンパイルエラーになってしまいます。

一方、

コード:

_itoa(your_money, p ,10);
TextOut(hdc, 420, 320, p , lstrlen(p));
これだと、エラー一覧で
「 型 "TCHAR *" の引数は型"char *" のパラメーターと互換性がありません 」
と出てしまい、コンパイルエラーになってしまいます。

Math

Re: Win32APIのTextOutで変数を表示する方法が分かりません

#2

投稿記事 by Math » 1年前

このような感じでしょうか
Windows10,C++Builder(10.2.3) Community Editionを使用しています。
cx.bat

コード:

bcc64 -tW g1.cpp

g1.exe

pause
g1.cpp

コード:

#include <windows.h>
#include <stdio.h>

#define WIDTH	200
#define HEIGHT	100

LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	HDC hdc;
	PAINTSTRUCT ps;
	HBITMAP hBitmap;
	static HDC hMemDC;

	RECT rec;

	switch(uMsg) {
		case WM_CREATE:

			hdc=GetDC(hWnd);
			hBitmap=CreateCompatibleBitmap(hdc,WIDTH,HEIGHT);
			hMemDC=CreateCompatibleDC(hdc);
			ReleaseDC(hWnd,hdc);
			SelectObject(hMemDC,hBitmap);
			DeleteObject(hBitmap);

			SetTimer(hWnd,1,10,NULL);
			return 0;
		case WM_DESTROY:
			KillTimer(hWnd,1);
			DeleteDC(hMemDC);
			PostQuitMessage(0);
			return 0;
		case WM_TIMER:
			InvalidateRect(hWnd,NULL,FALSE); //背景を非消去
			return 0;
		case WM_PAINT:
			//背景画像
			SelectObject(hMemDC,GetStockObject(BLACK_BRUSH));
			Rectangle(hMemDC,0,0,WIDTH,HEIGHT);
			//素材画像
			SelectObject(hMemDC,GetStockObject(WHITE_BRUSH));
			Rectangle(hMemDC, 10,10, 40,40);
			Rectangle(hMemDC,110,10,140,40);
			SelectObject(hMemDC,GetStockObject(GRAY_BRUSH));
			Rectangle(hMemDC, 60,60, 90,90);
			Rectangle(hMemDC,160,60,190,90);

        TextOut( hMemDC, 10, 30, "Hello World! 今日は世界!", 25 );
        SetTextColor( hMemDC, RGB( 255, 0, 255 ) );
        rec.top = 50;
        rec.left = 10;
        rec.right = 300;
        rec.bottom = 100;
        DrawText( hMemDC, "AAAAA\nBBBBB", -1, &rec,DT_WORDBREAK | DT_CENTER );

printf(" debug print --- ");

			hdc=BeginPaint(hWnd,&ps);

			BitBlt(hdc,0,0,WIDTH,HEIGHT,hMemDC,0,0,SRCCOPY);
			EndPaint(hWnd,&ps);
			return 0;
	}
	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR lpCmdLine,int nCmdShow)
{
	WNDCLASS wc;
	MSG msg;

	wc.style	 = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc	 = WindowProc;
	wc.cbClsExtra	 = 0;
	wc.cbWndExtra	 = 0;
	wc.hInstance	 = hInstance;
	wc.hIcon	 = LoadIcon(NULL,IDI_APPLICATION);
	wc.hCursor	 = LoadCursor(NULL,IDC_ARROW);
	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wc.lpszMenuName	 = NULL;
	wc.lpszClassName = __FILE__;
	if(!RegisterClass(&wc)) return 0;

	HWND hWnd=CreateWindow(
		__FILE__,"Win32Windows",
		WS_OVERLAPPEDWINDOW | WS_VISIBLE,
		10,50, //Left,Top
		640,400, //Width,Height
		NULL,NULL,hInstance,NULL);
	if(hWnd==NULL) return 0;

	BOOL bRet;
	/////////////////////////////////////////////////////////////
	//コンソールを作成し,標準出力に割り当てる
	AllocConsole();
	freopen("CONOUT$", "w", stdout); //標準出力をコンソールにする

printf(" debug print = %d",nCmdShow);

	while((bRet=GetMessage(&msg,NULL,0,0))!=0){
		if(bRet==-1) break;
		DispatchMessage(&msg);
	}

	return (int)msg.wParam;
}
実行

コード:

F:\z18g_cx\0729>bcc64 -tW g1.cpp
Embarcadero C++ 7.30 for Win64 Copyright (c) 2012-2017 Embarcadero Technologies, Inc.
g1.cpp:
Turbo Incremental Link64 6.90 Copyright (c) 1997-2017 Embarcadero Technologies, Inc.

F:\z18g_cx\0729>g1.exe
なおVisualStudioの場合先頭に
#define _CRT_SECURE_NO_WARNINGS
を書くといいでしょう。

Math

Re: Win32APIのTextOutで変数を表示する方法が分かりません

#3

投稿記事 by Math » 1年前

あ,数字を文字に変換でしたね!いま忙しいので後日。

アバター
sujiniku
記事: 39
登録日時: 1年前

Re: Win32APIのTextOutで変数を表示する方法が分かりません

#4

投稿記事 by sujiniku » 1年前

RPGの主人公の所持金が最初は100ゴールドだとして、それがゲーム中に増減して(例えば宝箱からお金を獲得して)200Gになったり(買い物による出費で所持金が減り)30Gになったりする事になるのですが、
その所持金を例えば買い物などの際に、「現在の所持金 100」みたいに画面表示したいのです。
所持金は増減するので、変数であらわす必要があると考えています。
C#のNetFrameworkならToStringで変換できるのは知ってますが、しかし私が現在開発しようとしているのはwin32 API で動作するアプリなので、Net Framework のメソッドは使えません。

現在、取り掛かってるのは所持金の変数だけですが、将来的にはHPやMP、ダメージ表示や武器防具の攻撃力・守備力などのパラメータも画面表示したいとも思っています。もちろん、これらのパラメータの数値はゲーム中に増減します。
なので、win32APIアプリで変数を画面に出力する方法を知りたいのです。これが出来ないと、ゲームにならないので。

Math

Re: Win32APIのTextOutで変数を表示する方法が分かりません

#5

投稿記事 by Math » 1年前

Win32 API ですよ
VS2017でもVS2008でも動作確認ずみです
C++でC#はありません
g1.cppだけですよ

アバター
sujiniku
記事: 39
登録日時: 1年前

Re: Win32APIのTextOutで変数を表示する方法が分かりません

#6

投稿記事 by sujiniku » 1年前

Net Framework うんぬんってのは、単に私の知識レベルを説明しただけです。誤解させて申し訳ございません。

なお、作成したいゲームはコンソールアプリではなく、GUIウィンドウのアプリです。
C言語のprintfでコンソールに変数表示する方法なら、私でも知ってますので。

Bull
記事: 127
登録日時: 5年前

Re: Win32APIのTextOutで変数を表示する方法が分かりません

#7

投稿記事 by Bull » 1年前

とりあえず "error C4996" で検索してみましょう。いろいろ対策があります。

プロジェクトのプロパティーで、SDL チェックをいいえ (/sdl-) にすると、エラーではなく警告 (warning)になります。
プロプロセッサの定義に _CRT_SECURE_NO_WARNINGS を追加すれば、警告も出なくなります。
_stprintf_s() 関数、または _sntprintf_s() 関数を使う方法もありますが、それぞれ _stprintf() 関数とはパラメーターが異なりますので、注意して下さい。
個人的には、例外を回避しやすい _sntprintf_s() 関数の方が好きです。

アバター
へにっくす
記事: 628
登録日時: 7年前
住所: 東京都

Re: Win32APIのTextOutで変数を表示する方法が分かりません

#8

投稿記事 by へにっくす » 1年前

sujiniku さんが書きました:
1年前
上のコードだと、Visual Studio のエラー一覧で
「 '_swprintf': This function or variable may be unsafe. 」
と出てしまい、コンパイルエラーになってしまいます。
これはMathさんが指摘している通り

コード:

#define _CRT_SECURE_NO_WARNINGS
の一行をファイルの先頭に記述すれば出なくなります。
Bullさんの言う通り、プロジェクトの設定でも可能です。
CRT のセキュリティ機能 - MSDN - Microsoft


sujiniku さんが書きました:
1年前
これだと、エラー一覧で
「 型 "TCHAR *" の引数は型"char *" のパラメーターと互換性がありません 」
と出てしまい、コンパイルエラーになってしまいます。
_stprintf関数を使用する場合、TCHAR型を使います
pの型はchar*になっていませんか。
TCHAR*かLPTSTRにしないといけません。
TCHAR型のススメ
sprintf、_sprintf_l、swprintf、_swprintf_l、__swprintf_l - MSDN - Microsoft
written by へにっくす

アバター
へにっくす
記事: 628
登録日時: 7年前
住所: 東京都

Re: Win32APIのTextOutで変数を表示する方法が分かりません

#9

投稿記事 by へにっくす » 1年前

へにっくす さんが書きました:
1年前
Bullさんの言う通り、プロジェクトの設定でも可能です。
→追加。 Visual Studio 2017 で scanf() がエラー(C4996)になるときは
written by へにっくす

アバター
sujiniku
記事: 39
登録日時: 1年前

Re: Win32APIのTextOutで変数を表示する方法が分かりません

#10

投稿記事 by sujiniku » 1年前

皆様、解説、ありがとうございます。

とりあえず、下記のコードを試したところ、変数を文字表示することに成功しました。

コード:

_stprintf_s(p, 200,TEXT("money = %d"), your_money);
TextOut(hdc, 420, 320, p, lstrlen(p));
なお変数 p の宣言は

コード:

TCHAR p[MAX_LENGTH] = TEXT("はじめから");
で事前に初期化して宣言してあります。

なお、ずっと将来のハナシですが、完成後にはソース公開&無料配布などをしたいので、
個人的な都合ですが、なるべくVisual Studio の設定に依存する処理は使いたくないと思ってますので、
プロジェクトの設定を変更する方法は控えたいと思います。(配布されたアプリを使うユーザーに、設定変更の手間を掛けさせたくないので。)
せっかく紹介していただいた方法なのに、申し訳ございません。

皆様の紹介してくださった参考リンクなどを、これから読みたいと思います。心配してくださった皆様を安心させようと先に報告しようと思ったので、読む前に報告させて頂きました。これから、お読みしたいと思います。

コードは動作はしたけど、まだ私は理解できてないので、もしかしたら今後もこの件で、この掲示板スレッドで質問するかもしれません。

アバター
へにっくす
記事: 628
登録日時: 7年前
住所: 東京都

Re: Win32APIのTextOutで変数を表示する方法が分かりません

#11

投稿記事 by へにっくす » 1年前

sujiniku さんが書きました:
1年前
なお変数 p の宣言は

コード:

TCHAR p[MAX_LENGTH] = TEXT("はじめから");
で事前に初期化して宣言してあります。
おっとすみません。
これは_itoaの引数がchar*だからですね。
_itoaじゃなく、_itotを使います。
_itoa、_i64toa、_ui64toa、_itow、_i64tow、_ui64tow
written by へにっくす

アバター
sujiniku
記事: 39
登録日時: 1年前

Re: Win32APIのTextOutで変数を表示する方法が分かりません

#12

投稿記事 by sujiniku » 1年前

_itot_s で下記コードで動作する事も確認しました。

コード:

_itot_s(your_money , p, 200, 10);
TextOut(hdc, 420, 280, TEXT("所持金"), lstrlen( TEXT("所持金") ));
TextOut(hdc, 420, 320, p, lstrlen(p));
ここら辺の話題、当掲示板での質問前にはググッテも私にはなかなかヒントが見つからなかったので、皆様の解説、ほんと役立ちます。

taka500

Re: Win32APIのTextOutで変数を表示する方法が分かりません

#13

投稿記事 by taka500 » 1年前

これなら整数だけでなく浮動小数点数も表示いけるみたい
TextOutを書いていた部分をこれにします

コード:

#include <windows.h>
#include <stdio.h>
#include <tchar.h>

int FormatTextOut(HDC hdc, int x, int y, TCHAR * szFormat, ... )
{
	TCHAR szBuf[1024];
	va_list pList;
	va_start(pList, szFormat);
	_vsntprintf_s(szBuf, _ARRAYSIZE(szBuf), _TRUNCATE, szFormat, pList);
	va_end(pList);
	TextOut(hdc, x, y, szBuf, lstrlen(szBuf));
	return 0;
}

アバター
usao
記事: 1552
登録日時: 6年前

Re: Win32APIのTextOutで変数を表示する方法が分かりません

#14

投稿記事 by usao » 1年前

オフトピック
stringstreamとかじゃいかんのだろうか?

返信

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