nShowCmdを取得する関数はないのでしょうか?

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

nShowCmdを取得する関数はないのでしょうか?

#1

投稿記事 by MoNoQLoREATOR » 14年前

現在、別ウインドウに情報を表示するプログラムを書いていす。
ウインドウ関係の処理を行うクラスと、実際に情報を表示させる処理を行うクラスを作って、簡単に利用できるようにしようと考えたのですが、利用する際にわざわざnShowCmdを渡すのは頻雑です。
nShowCmdを取得できる関数はないのでしょうか?
► スポイラーを表示
また、現在のコードは上記のようになっているのですが、できれば WindowProc() 関数を newwin クラスの中に入れてしまいたいです。しかしウインドウプロシージャ関数をクラスの中に入れてしまうと、 W N D C L A S S E X 構造体の lpfnWndProc メンバ変数に関数ポインタを渡すことができませんでした。

そして、 ウインドウを作成してからしばらく経つと、水色に設定したはずの背景が灰色になり、画面がリフレッシュされなくなります。whileループで SetWindowText() 関数を呼び出しまくっているのが原因だということはわかったのですが、これは解決できるのでしょうか?

ご教授よろしくお願い致します。

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: nShowCmdを取得する関数はないのでしょうか?

#2

投稿記事 by ISLe » 14年前

MoNoQLoREATOR さんが書きました:ウインドウ関係の処理を行うクラスと、実際に情報を表示させる処理を行うクラスを作って、簡単に利用できるようにしようと考えたのですが、利用する際にわざわざnShowCmdを渡すのは頻雑です。
nShowCmdを取得できる関数はないのでしょうか?
WinMainのnShowCmd引数は、アプリケーションに指定されたウィンドウの初期状態(最大化・最小化・通常)を受け取るためのものですから、小ウィンドウにそのまま渡すとあまりよろしくないです。
メインウィンドウの状態に応じて、適切なパラメータをShowWindowに与えてください。
いちおう説明しておくとnShowCmdを使わなくてもSW_SHOWDEFAULTを指定すると同じことになるようです。
MoNoQLoREATOR さんが書きました:また、現在のコードは上記のようになっているのですが、できれば WindowProc() 関数を newwin クラスの中に入れてしまいたいです。しかしウインドウプロシージャ関数をクラスの中に入れてしまうと、 W N D C L A S S E X 構造体の lpfnWndProc メンバ変数に関数ポインタを渡すことができませんでした。
staticではないメンバ関数は暗黙の引数thisがあります。
なのでstaticメンバ関数にして何らかの方法でthisポインタを渡してやる必要があります。
「ウィンドウプロシージャ クラス」で検索すればいろんな方法が見付かると思います。
MoNoQLoREATOR さんが書きました:そして、 ウインドウを作成してからしばらく経つと、水色に設定したはずの背景が灰色になり、画面がリフレッシュされなくなります。whileループで SetWindowText() 関数を呼び出しまくっているのが原因だということはわかったのですが、これは解決できるのでしょうか?
WM_CTLCOLORSTATICメッセージが来る度にブラシを作り、解放していないからです。

アバター
MoNoQLoREATOR
記事: 284
登録日時: 15年前
住所: 東京

Re: nShowCmdを取得する関数はないのでしょうか?

#3

投稿記事 by MoNoQLoREATOR » 14年前

ありがとうございます。ブラシの問題以外は解決できました!

↓ソースコード
► スポイラーを表示
static関数はこのようなケースで使用するのですね。static関数の存在は聞いたことがありましたが、絶対に使わないだろうと思ってすぐに忘れました^^;

それはそうと、現在使用しているブラシのハンドルを得る関数を発見したので、ブラシを削除する際に使ってみたのですが、ちゃんと全てのブラシを削除できているのでしょうか?
※追記
whileループの中身がコメントアウトされていました。やっぱり画面がリフレッシュされなくなりました。どうやらブラシを削除できていないようです。


ブラシの設定の仕組みが未だにさっぱりわからないので、よくわかりません。ブラシの設定はどの段階で行われているのですか?
25行目~39行目の return (BOOL)hBrush; を return true; や return false; に変えると背景色が変わらなくなったので、ウインドウプロシージャから返ってきた値を親ウインドウが処理した段階で設定されるのでしょうか?
でも、返しているのはBOOL値だから絶対にtrueかfalseなわけですし、CreateSolidBrush()関数をいちいち呼び出さずに、保存しておいたハンドルを渡すだけでは設定されませんでしたし・・・。

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: nShowCmdを取得する関数はないのでしょうか?

#4

投稿記事 by ISLe » 14年前

CreateSolidBrushで新しくブラシが作成されて、そのブラシのハンドルを戻り値として受け取ります。
スタティックコントロールの背景とするためにそのハンドルをWM_CTLCOLORSTATICメッセージの戻り値として返します。
その時点でブラシハンドルを受け取った変数の寿命は尽き忘れ去られますが、作成されたブラシは解放されません。

ちなみにGetSysColorBrushというのはウィンドウズにプリセットされたブラシを利用するために呼び出すものです。
プリセットされたブラシは解放する必要が無く、解放しても何も起きません。
MoNoQLoREATOR さんが書きました:でも、返しているのはBOOL値だから絶対にtrueかfalseなわけですし、
ブラシハンドルはBOOL型じゃないですよ。
BOOL型にキャストしてる解説サイトもあるみたいですけどそれはたまたまうまく動いてるだけです。
ウィンドウプロシージャの戻り値の型であるLRESULTにキャストするのが正しいと思いますけど。
#MSDNのWM_CTLCOLORSTATICのページだとなぜかINT_PTRでキャストしてますけど中身は同じ。

ちなみにwindows.hで定義されているBOOLの中身はintです。
BOOL型のGetMessage関数が0、0以外と-1を返すという訳のわからない仕様になってるのは有名かと。
MoNoQLoREATOR さんが書きました:CreateSolidBrush()関数をいちいち呼び出さずに、保存しておいたハンドルを渡すだけでは設定されませんでしたし・・・。
それはおかしいですね。
こんなふうにしたら良いと思いますけど。

コード:

	static LRESULT CALLBACK WindowProc(HWND hwnd,UINT uiMsg,WPARAM wParam,LPARAM lParam) {
		COLORREF wORb[2] = {RGB(255,255,255), RGB(200,255,255)};

		static HBRUSH hCyanBrush = NULL;

		switch(uiMsg) {
		case WM_CTLCOLORSTATIC:
			int childID = (int)GetWindowLongPtr((HWND)lParam, GWLP_ID);

			// 背景色を水色に設定
			if(childID>=100 && childID<124) {
				if(childID%2) {
					SetBkColor( (HDC)wParam, RGB(255,255,255) );
					return (LRESULT)GetStockObject(WHITE_BRUSH);
				}
				else {
					SetBkColor( (HDC)wParam, RGB(200,255,255) );
					if (hCyanBrush == NULL) {
						hCyanBrush = CreateSolidBrush(RGB(200,255,255));
					}
					return (LRESULT)hCyanBrush;
				}
			}
			break;
		case WM_DESTROY:
			if (hCyanBrush != NULL) {
				DeleteObject(hCyanBrush);
				hCyanBrush = NULL;
			}
		}

		return DefWindowProc(hwnd, uiMsg, wParam, lParam);
	}
GetStockObjectもプリセットのGDIオブジェクトのハンドルを返すので解放する必要がありません。
それと、未知のウィンドウメッセージでもlParamをウィンドウハンドルとしてGetWindowLongPtrを呼ぶのは危険です。

アバター
MoNoQLoREATOR
記事: 284
登録日時: 15年前
住所: 東京

Re: nShowCmdを取得する関数はないのでしょうか?

#5

投稿記事 by MoNoQLoREATOR » 14年前

大変勉強になりました。

BOOL型はbool型と同じだとかってに考えていました。ということは、やはりウインドウプロシージャの返値を元に親ウインドウが背景色を設定しているのですね。

staticメンバ関数のなかでstatic変数を宣言すると実体を書く必要がないのですね。だから、グローバルな実体をつくらなくても済む・・・と。

解決できないだろうなと思っていたことまで解決できてしまい、驚きです。
本当にありがとうございました。

閉鎖

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