WinAPIで文字出し中に見つけた、くっだらない疑問

アバター
TOMY
記事: 53
登録日時: 12年前
住所: 愛知県
連絡を取る:

WinAPIで文字出し中に見つけた、くっだらない疑問

投稿記事 by TOMY » 10年前

勉強し続けるという意欲を継続的に提示できるように初歩的な勉強中、プログラムを組みながらふと疑問に思った。
wsprintfで書式指定するつもりが、改行できない
wsprintfじゃ \n( \はyenマークです)が使えないのかしら。(%d)とかは使えるのにね。何故が出力すると(↑)に変換されてしまう。・・・うえ?
まぁ解決手段は考えれば他にもあるからそこまで深刻な問題ってわけでもないけど。
ちなみに伝統と実績の『猫でもわかる第四版』をみながらたらたらと適当にやってたものです。
以下ソースコード

CODE:

#include


//プロトタイプ宣言
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
ATOM InitApp(HINSTANCE);
BOOL InitInstance(HINSTANCE, int);

//ウィンドウクラス
TCHAR szClassName[] = TEXT("sample01");

//windowsプログラムのエントリーポイント
int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow)
{
	MSG msg;
	BOOL bRet;

	if(!InitApp(hCurInst))return false;
	if(!InitInstance(hCurInst, nCmdShow))return false;

	//メッセージ取得
	while((bRet = GetMessage(&msg, NULL, 0, 0)) != 0){
		if(bRet == -1){
			break;
		}else{
			TranslateMessage(&msg);			//メッセージを変換
			DispatchMessage(&msg);			//メッセージを送出

		}
	}
	return (int)msg.wParam;
}


//ウィンドウクラスの登録
ATOM InitApp(HINSTANCE hInst)
{
	WNDCLASSEX wc;
	wc.cbSize = sizeof(WNDCLASSEX);				//構造体のサイズ
	wc.style  = CS_HREDRAW | CS_VREDRAW;		       //クラスのスタイル
	wc.lpfnWndProc = WndProc;					//プロシージャ名
	wc.cbClsExtra  = 0;							//補助メモリ
	wc.cbWndExtra  = 0;							//補助メモリ
	wc.hInstance   = hInst;						//インスタンス
	//アイコン
	wc.hIcon = (HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
	//カーソル
	wc.hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
	//背景ブラシ
	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wc.lpszMenuName  = NULL;					//メニュー名
	wc.lpszClassName = szClassName;				//クラス名
	//小さいアイコン
	wc.hIconSm = (HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
	
	return (RegisterClassEx(&wc));
}

//ウィンドウの生成
BOOL InitInstance(HINSTANCE hInst,int nCmdShow)
{
	HWND hWnd;
	hWnd = CreateWindow(szClassName,			//クラス名
			TEXT("猫4版_P13_空ウィンドウ雛形"),	//ウィンドウ名
			WS_OVERLAPPEDWINDOW,				//ウィンドウスタイル
			CW_USEDEFAULT,						//x位置
			CW_USEDEFAULT,						//y位置
			CW_USEDEFAULT,						//ウィンドウ幅
			CW_USEDEFAULT,						//ウィンドウ高さ
			NULL,								//親ウィンドウのハンドル。小屋を作るときはNULL
			NULL,								//メニューハンドル、クラスメニューを使うときはNULL
			hInst,								//インスタンスハンドル
			NULL								//ウィンドウ作成データ
			);
	if(!hWnd)return false;
	ShowWindow(hWnd, nCmdShow);					//ウィンドウの表示状態を設定
	UpdateWindow(hWnd);							//ウィンドウを更新
	return true;
}


//ウィンドウプロシージャ(callback関数)・・・・・最重要!!!!!!!
//windowsプログラムはただ処理順にソースを書くのではなく、
//受け取ったメッセージごとに合わせた処理を書く。
//(下のswitch文[WM_XXXXX]の部分が受け取ったメッセージに該当)
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
	//表示する文字列の宣言
	PAINTSTRUCT ps;
	HDC			hdc;
	LPCSTR		lpszStr = TEXT("猫でもわかる\nWindowsプログラミング。");		//TEXTマクロについてはP419
	//デバッグ用に使いたいときはwsprintfを使う。猫4P123
	//実験(wsprintfの使用)-------------------------------------------------------------
	TCHAR StrOutPut[256];						//文字列と書式設定格納するアレ
        //書式指定のテスト
	wsprintf(StrOutPut,TEXT("デデンデッデデンデン\nデデンデッデデンデン_× %d \nバトルフィールド作業中に聞いてたので・・・\n"),4);

	//end------------------------------------------------------------------------------
	switch(msg){
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);			//デバイスコンテキストを取得
		//TextOutは\系が使用できない。
		TextOut(hdc, 10, 10, lpszStr, lstrlen(lpszStr));						//文字列を描画
		//wsprintfを用いての文字列出力-------------------------------------------------
		TextOut(hdc, 50, 50, StrOutPut, lstrlen(StrOutPut));
		//-----------------------------------------------------------------------------
		EndPaint(hWnd, &ps);					//描画を終了
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return (DefWindowProc(hWnd, msg, wp, lp));
	}
	return 0;
}
何故か次の日かったるい仕事の日に限って前日の夜の勉強の意欲が上がる。
ちなみにゲーム制作は絶賛停滞中です。

アバター
TOMY
記事: 53
登録日時: 12年前
住所: 愛知県
連絡を取る:

Re: WinAPIで文字出し中に見つけた、くっだらない疑問

投稿記事 by TOMY » 10年前

なぜかyen記号が文字化けしてバックスラッシュになっちまうな。なんでだろ?ブラウザが原因かな?

アバター
へにっくす
記事: 634
登録日時: 12年前

Re: WinAPIで文字出し中に見つけた、くっだらない疑問

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

wsprintfに\nが使えないのではなく、
TextOutに\nが使えないのです。改行とかのコントロール文字は認識しませんよ。
改行も認識させたいのであれば、DrawTextを使ってください。

また、TCHARを使うのは、Ansi系とUnicode系の切り替えを容易にするためのものですが
LPSTR/LPCSTRが混じってるので、中途半端です。ちゃんと統一しましょうね。

アバター
みけCAT
記事: 6734
登録日時: 13年前

Re: WinAPIで文字出し中に見つけた、くっだらない疑問

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

TOMY さんが書きました:なぜかyen記号が文字化けしてバックスラッシュになっちまうな。なんでだろ?ブラウザが原因かな?
マジレスするとフォントが原因だと思います。

アバター
みけCAT
記事: 6734
登録日時: 13年前

Re: WinAPIで文字出し中に見つけた、くっだらない疑問

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

「TextOutは\系が使用できない。」とは何を表しているのですか?
C言語のエスケープシーケンスはTextOutに使用する文字列かどうかには関係なく働き、
TextOutは(少なくてもWindows Vistaのデフォルトでは)エスケープシーケンスの変換をしないようです。

CODE:

#include 

const LPCSTR szWindowClass = "SAMPLE_CLASS";
const LPCSTR szWindowTitle = "test";

LRESULT CALLBACK WndProc(HWND hWnd, UINT message,WPARAM wParam, LPARAM lParam) {
	PAINTSTRUCT ps;
	HDC hdc;
	RECT rt;
	const char* test01 = "test\x30\x31nano";
	const char* test02 = "test\\x30\\x32nano";

	switch (message) {
		case WM_COMMAND:
			switch (LOWORD(wParam)) {
				default:
					return DefWindowProc(hWnd, message, wParam, lParam);
			}
			break;
		case WM_PAINT:
			hdc = BeginPaint(hWnd, &ps);
			GetClientRect(hWnd, &rt);
			TextOut(hdc,100,100,test01,lstrlen(test01));
			TextOut(hdc,100,150,test02,lstrlen(test02));
			EndPaint(hWnd, &ps);
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
	}

	return 0;
}

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
		LPSTR lpCmdLine,int nCmdShow) {
	MSG msg;
	WNDCLASSEX wcex;
	HWND hWnd;

	wcex.cbSize = sizeof(WNDCLASSEX); 

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= (WNDPROC)WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(NULL,IDI_APPLICATION);
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= NULL;
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= NULL;

	RegisterClassEx(&wcex);

	hWnd = CreateWindow(szWindowClass,
		szWindowTitle, WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
		NULL, NULL, hInstance, NULL);

	if (!hWnd) 
		return FALSE;

	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	while (GetMessage(&msg, NULL, 0, 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}

アバター
TOMY
記事: 53
登録日時: 12年前
住所: 愛知県
連絡を取る:

Re: WinAPIで文字出し中に見つけた、くっだらない疑問

投稿記事 by TOMY » 10年前

ただウィンドウに文字を出すというだけの内容の日記に色々な回答本当に有難うございます。
文字関連は本当に闇が深い・・・

ISLe
記事: 2650
登録日時: 13年前

Re: WinAPIで文字出し中に見つけた、くっだらない疑問

投稿記事 by ISLe » 10年前

わたしのようなおっさんは、(BASICを卒業して)最初に文字を表示するのにVRAMに直接データを書き込んでいました。
なので逆に制御文字が常に機能するという発想がないですね。
むしろ制御文字が機能する場面というのは非常に限定されていると思います。
最後に編集したユーザー ISLe on 2013年12月23日(月) 14:41 [ 編集 1 回目 ]