ページ 11

WINAPIで、変数も表示できる、文字列表示についての質問

Posted: 2017年11月29日(水) 12:58
by sadora3
WINAPIで、printfのような関数を作ろうと、以下のようなプログラムを組みましたが、私の想定していた動作と違う動きをしました。

コード:

//インクルード
#include<Windows.h>
#include <stdio.h>

//定数定義
#define	CLASS_NAME "WinClass"
#define	WINDOW_NAME "WindowsSDK"
#define	SCREEN_WIDTH (800)
#define	SCREEN_HEIGHT (600)

//グローバル変数宣言
int Num = 5;

//プロトタイプ宣言
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void ShowText(HWND hWnd, char Str[256], ...);

//WinMain関数(エントリーポイント)
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
	WNDCLASSEX wcex = {
		sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0, 0, hInstance, NULL, LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_WINDOW + 1), NULL, CLASS_NAME, NULL
	};

	RegisterClassEx(&wcex);

	HWND hWnd = CreateWindowEx(
		0, CLASS_NAME, WINDOW_NAME, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL, hInstance, NULL
		);

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

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

	UnregisterClass(CLASS_NAME, wcex.hInstance);

	return (int)msg.wParam;
}

//ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
	switch(uMsg){
	case WM_DESTROY:
		PostQuitMessage(0);
		break;

	case WM_KEYDOWN:
		switch(wParam){
		case VK_SPACE:
			
			break;
		}
		break;

	case WM_PAINT:
		ShowText(hWnd, "%d", Num);
		break;

	default:
		Num++;
		break;
	}

	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

//文字列表示
void ShowText(HWND hWnd, char Str[256], ...){
	HDC hDc;
	PAINTSTRUCT Paint;
	va_list	argp;

	va_start(argp, Str);
	char pszBuf[256];
	int Len = vsprintf(pszBuf, Str, argp);

	hDc = BeginPaint(hWnd, &Paint);
	TextOut(hDc, 10, 10, (LPCSTR)pszBuf, Len);
	EndPaint(hWnd, &Paint);
}
私が想定していた動作では、画面上に描画される数値は、どんどん増えていくはずでした。
しかし、実際は、画面上に「26」と表示され、不動のままです。
おかしいと思い、54行にブレークポイントを置いて、プログラム実行中にスペースキーを押下してNumの値を確認しました。
そうしたら、Numの値は26ではなく、197でした。ちゃんと毎ループNumはインクリメントされています。
なぜ、描画される数値の更新はされないのでしょうか?
また、どうすれば描画が更新されるようになりますか?

また、もう一つ質問があります。
WINAPIとWINSDKの違いは何でしょうか?
上記のプログラムはどちらでしょうか?
私はグーグルなどで、「WINAPI 入門」と検索すると上記のプログラムの入門サイトが沢山出てくるので、上記のプログラムはWINAPIであると認識しているのですが、以下のサイトでは、WinSDKと書いてありました。
http://www.kumei.ne.jp/c_lang/index_sdk.html
一体どっちが正しいのでしょうか?

Re: WINAPIで、変数も表示できる、文字列表示についての質問

Posted: 2017年11月29日(水) 20:41
by YuO
sadora3 さんが書きました:なぜ、描画される数値の更新はされないのでしょうか?
また、どうすれば描画が更新されるようになりますか?
再描画させれば更新されます。
または,WM_PAINTに頼らずに描画すれば更新されます。

一般的な再描画要求は

コード:

InvalidateRect(hWnd, NULL, TRUE);
UpdateWindow(hWnd);
です。
これを行うと,WM_PAINTがメッセージキューに貯まります。
sadora3 さんが書きました:WINAPIとWINSDKの違いは何でしょうか?
SDK : Software Development Kit
API : Application Programming Interface
Windows自身がアプリケーションの為に用意しているのがWindows APIです。
そして,Windows APIを使って,プログラムを作るために用意されている製品がWindows SDKです。

RegisterClassEx,CreateWindowsEx,GetMessageなどの関数や,IUnknownなどのインターフェースはAPIです。
<windows.h>やリソースコンパイラ,spy++などはSDK (の一部) です。
sadora3 さんが書きました:上記のプログラムはどちらでしょうか?
CまたはC++のプログラムです。
APIもSDKも使う物であって,なるものではありません。

Re: WINAPIで、変数も表示できる、文字列表示についての質問

Posted: 2017年11月30日(木) 14:53
by sadora3
YuOさん回答ありがとうございます。

言われた通り、
InvalidateRect(hWnd, NULL, TRUE);
UpdateWindow(hWnd);
の2つを追加したら、描画の更新がされました。

WINAPIとWINSDKに関する説明もとても分かりやすかったです。
本当にありがとうございました。