WinAPIで文字出し その2

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

WinAPIで文字出し その2

投稿記事 by TOMY » 11年前

前回の問題だった改行が出来ない原因がTextOutメソッドを知り、DrawTextで書いてみた。
結果は正常に動作したが、前にへにっくすさんに指摘された”LPSTR/LPCSTRが混じってる”が解決していない。
う~ん・・・どうしようか・・・・ 未だにこの2つの内部的な詳細が理解しきれていないのが辛い。
でもそれ以前に改行一つに2日以上掛けてる時点で俺のプログラムスキルって・・・

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;
	RECT		rc; 
	
	GetClientRect(hWnd,&rc);					//クライアント領域の矩形を取得
	
	//LPCSTR		lpszStr = TEXT("猫でもわかる\nWindowsプログラミング。");		//TEXTマクロについてはP419
	//デバッグ用に使いたいときはwsprintfを使う。猫4P123
	//実験(wsprintfの使用)-------------------------------------------------------------
	TCHAR StrOutPut[1024];						//文字列と書式設定格納するアレ
	wsprintf(StrOutPut,TEXT("How are you, GI Joe? \n It seems to me that most of you are poorly informed about the going of the war, \n to say nothing about a correct explanation of your presence over here. \n Nothing is more confused than to be ordered into a war to die or to be maimed for life without the faintest idea of what's going on.\n %d"),1975430);

	//end------------------------------------------------------------------------------
	switch(msg){
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);			//デバイスコンテキストを取得
		//TextOutは\系マクロが使用できない。
		//\nとか使いたかったらDrawTextを使用。(もしくはwsprintf)
		//TextOut(hdc, 10, 10, lpszStr, lstrlen(lpszStr));						//文字列を描画
		//wsprintfを用いての文字列出力-------------------------------------------------
		//TextOut(hdc, 50, 50, StrOutPut, lstrlen(StrOutPut));
		//DrawTextの引数に関しては猫4p49
		DrawText(hdc,StrOutPut, -1, &rc, DT_CENTER | DT_WORDBREAK);				//DrawTextなら\nによる改行も可能
		//-----------------------------------------------------------------------------
		EndPaint(hWnd, &ps);					//描画を終了
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return (DefWindowProc(hWnd, msg, wp, lp));
	}
	return 0;
}

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

Re: WinAPIで文字出し その2

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

WinMainのTCHAR版は_tWinMainですよ。

WinMain関数
http://gurigumi.s349.xrea.com/programmi ... ntro1.html

あと
ちょー気になったのが104行目
もしくはwsprintfって何? 描画関数じゃないんだけど!!
と思ったりw

頑張ってくださいね

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

Re: WinAPIで文字出し その2

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

TOMY さんが書きました:TextOutは\系マクロが使用できない。
何言ってるのですか?\系マクロって何ですか?エスケープシーケンスの動作はTextOutと関係ないことは前の日記で示しましたよね?
抜粋

CODE:

const char* test01 = "test\x30\x31nano";
const char* test02 = "test\\x30\\x32nano";

TextOut(hdc,100,100,test01,lstrlen(test01));
TextOut(hdc,100,150,test02,lstrlen(test02));
TOMY さんが書きました:デバッグ用に使いたいときはwsprintfを使う。
決めつけちゃっていいのですか?例えば実数値を表示するデバッグもwsprintfを使わないといけないのですか?
TOMY さんが書きました:文字列と書式設定格納するアレ
書式設定も格納するのですか?格納してもいいですけど、今のコードでは格納していないですよね?
文字列に書式を埋め込むというと、int $0x10の%ah=0x13,%al=0x03みたいなイメージを持ちました。

あとは、hIconSmに登録するアイコンの大きさを指定せずにLR_DEFAULTSIZEを使用してしまうと、
せっかく小さいアイコンを用意しても大きいアイコンが使用されてしまい、あまり嬉しくないことがあります。

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

Re: WinAPIで文字出し その2

投稿記事 by TOMY » 11年前

へにっくす さんが書きました: wsprintfって何?
wsprintfとは自分の使っている参考書だと、
「文字列を書式化する」と記載されています。
第一引数がLPTSTR型,
第二引数がLPCTSTR型,
第三引数以降がオブションの引数です。 (printfで言う%dとか%s使った後に記載する部分)
詳細な動作としては第二引数の書式に従ってオプション引数を使用し、第一引数に文字列を出力します。
(printf で言う第一引数とそれ以降の引数の情報をwsprintfの第一引数に出力する感じでしょうか。)

前にLPTSTR型とLPCTSTR型が混ざって統一感がないとおっしゃいましたが、こいつの引数がもっぱら原因です。

MSDN→ http://msdn.microsoft.com/ja-jp/library/cc364872.aspx
最後に編集したユーザー TOMY on 2013年12月24日(火) 14:18 [ 編集 1 回目 ]

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

Re: WinAPIで文字出し その2

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

とりあえずググりましょう。
[search=google]LPTSTR[/search]
これだけでLPCTSTRなどとの違いを解説したサイトが出てきました。

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

Re: WinAPIで文字出し その2

投稿記事 by TOMY » 11年前

・TCHAR = char
・LPCTSTR = const char*
・LPTSTR = char*
という考えでいいのでしょうかね・・・?
少なくてもLPCTSTRは色んなサイト見てる限り、読み取り専用と言う扱いと記載されているのが多いみたいですが・・・
上記の考えでいけば、LPCTSTR と LPTSTRが多少混ざっててもいいのかな・・・?

アバター
usao
記事: 1889
登録日時: 12年前

Re: WinAPIで文字出し その2

投稿記事 by usao » 11年前

Tがついてるの と ついてないの がプログラム内に混在していることを指摘されているのではないでしょうか.
TCHAR → 設定に合わせて char か wchar_t のどちらかになる感じ.(…とか言い切るとまた怒られそうだが)

しかし swprintf と wsprintf とがあるのだな…
(前者は sprintfのワイド文字版だろうけど,
 後者はよくわからん.ググると引数がLPTSTRとかになってるからWin32APIなのかな?)

#この日記だけものすごい横幅なのは,横長のコードがあるからなのか?

YuO
記事: 947
登録日時: 14年前

Re: WinAPIで文字出し その2

投稿記事 by YuO » 11年前

TOMY さんが書きました:・TCHAR = char
・LPCTSTR = const char*
・LPTSTR = char*
という考えでいいのでしょうかね・・・?
違いますね……。

[table=border-width: 1px; border-style: solid;][tr=border-width: 1px; border-style: solid;][td=border-width: 1px; border-style: solid;][/td][td=border-width: 1px; border-style: solid;]単純文字列[/td][td=border-width: 1px; border-style: solid;]ワイド文字列[/td][td=border-width: 1px; border-style: solid;]汎用マッピング文字列[/td][/tr]
[tr=border-width: 1px; border-style: solid;][td=border-width: 1px; border-style: solid;]文字定数の型 (C++)[/td][td=border-width: 1px; border-style: solid;]char[/td][td=border-width: 1px; border-style: solid;]wchar_t[/td][td=border-width: 1px; border-style: solid;][/td][/tr]
[tr=border-width: 1px; border-style: solid;][td=border-width: 1px; border-style: solid;]文字定数の型 (WINAPI)[/td][td=border-width: 1px; border-style: solid;]CHAR[/td][td=border-width: 1px; border-style: solid;]WCHAR[/td][td=border-width: 1px; border-style: solid;]TCHAR[/td][/tr]
[tr=border-width: 1px; border-style: solid;][td=border-width: 1px; border-style: solid;]文字定数リテラル[/td][td=border-width: 1px; border-style: solid;]'A'[/td][td=border-width: 1px; border-style: solid;]L'A'[/td][td=border-width: 1px; border-style: solid;]TEXT('A')[/td][/tr]
[tr=border-width: 1px; border-style: solid;][td=border-width: 1px; border-style: solid;]文字列リテラルの型 (C++)[/td][td=border-width: 1px; border-style: solid;]char [][/td][td=border-width: 1px; border-style: solid;]wchar_t [][/td][td=border-width: 1px; border-style: solid;]TCHAR [][/td][/tr]
[tr=border-width: 1px; border-style: solid;][td=border-width: 1px; border-style: solid;]文字列の型 (WINAPI)[/td][td=border-width: 1px; border-style: solid;]LPSTR[/td][td=border-width: 1px; border-style: solid;]LPWSTR[/td][td=border-width: 1px; border-style: solid;]LPTSTR[/td][/tr]
[tr=border-width: 1px; border-style: solid;][td=border-width: 1px; border-style: solid;]変更不可能な文字列の型 (WINAPI)[/td][td=border-width: 1px; border-style: solid;]LPCSTR[/td][td=border-width: 1px; border-style: solid;]LPCWSTR[/td][td=border-width: 1px; border-style: solid;]LPCTSTR[/td][/tr]
[tr=border-width: 1px; border-style: solid;][td=border-width: 1px; border-style: solid;]文字列リテラル[/td][td=border-width: 1px; border-style: solid;]"A"[/td][td=border-width: 1px; border-style: solid;]L"A"[/td][td=border-width: 1px; border-style: solid;]TEXT("A")[/td][/tr]
[tr=border-width: 1px; border-style: solid;][td=border-width: 1px; border-style: solid;]CRT関数[/td][td=border-width: 1px; border-style: solid;]strcpy, sprintf, etc.[/td][td=border-width: 1px; border-style: solid;]wcscpy, swprintf, etc.[/td][td=border-width: 1px; border-style: solid;]_tcscpy, _stprintf, etc.[/td][/tr]
[tr=border-width: 1px; border-style: solid;][td=border-width: 1px; border-style: solid;]Win32 API[/td][td=border-width: 1px; border-style: solid;]CreateWindowExA, GetMessageA, etc.[/td][td=border-width: 1px; border-style: solid;]CreateWindowExW, GetMessageW, etc.[/td][td=border-width: 1px; border-style: solid;]CreateWindowEx, GetMessage, etc.[/td][/tr][/table]
これらの文字列は,わかっていて故意に混ぜるのであれば問題ありませんが,
故意に混ぜられるだけの知識が無いと思うのであれば,どれか一つに統一するのが無難です。

個人的には,
  • Win32 APIを使わない場合は,単純文字列系の型や関数を使う
  • Win32 APIを使う場合には,汎用マッピング文字列系の型や関数を使うか,ワイド文字列系の型や関数を使う。
だと思っています。
オフトピック
現実的にNT系列とCE系列以外のWin32 APIが淘汰されている以上,A系APIを使う意義が無い。

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

Re: WinAPIで文字出し その2

投稿記事 by TOMY » 11年前

usao さんが書きました: #この日記だけものすごい横幅なのは,横長のコードがあるからなのか?
ごめんなさい。実際にウィンドウに表示する文字列をそのまま改行せずに記述してしまいました。

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

Re: WinAPIで文字出し その2

投稿記事 by ISLe » 11年前

いちおう、TEXTマクロはWin32 API、_TマクロはCRT、という対応になっているみたいです。

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

Re: WinAPIで文字出し その2

投稿記事 by TOMY » 11年前

みけCAT さんが書きました:
TOMY さんが書きました:TextOutは\系マクロが使用できない。
何言ってるのですか?\系マクロって何ですか?エスケープシーケンスの動作はTextOutと関係ないことは前の日記で示しましたよね?
ごめんなさい。その部分を消すの忘れてただけです。