画像ファイルを描画したい

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

画像ファイルを描画したい

#1

投稿記事 by shiro4ao » 11年前

リモートにある画像をみれるフォトビューアみたいなソフトを作ろうとしています
TCPでのファイルの送信自体は流用したので上手く動いたのですが、
bmpファイルを受信側で読み込んで表示するのがうまくいきませんでした。

コード:

	// ビットマップをtemp2.bmpファイルからロード
	hBitmap = (HBITMAP)LoadImage( NULL, _T("temp2.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
	hDC = GetDC( hwnd );
	hCompatDC = CreateCompatibleDC( hDC );
	hPrevBitmap = (HBITMAP)SelectObject( hCompatDC, hBitmap );

コード:

	//WM_PAINTが来たら範囲を指定して描画してもらう	
	StretchBlt( hDC, 0,0,1280, 800, hCompatDC, 0, 0,1280,800, SRCCOPY );

上記のうち、「ビットマップをファイルからロード」の部分を受信スレッドで呼ぶと
表示できませんでした
試しに「ビットマップをファイルからロード」の部分をWM_CREATEで呼ぶと表示でき、
ウィンドウサイズを変えてもちゃんと描画できました

しかし、受信するたびにファイルを描画しないといけないのですが、
どのように変更すればいいでしょうか?

それとも根本的になにかおかしいのでしょうか?

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

Re: 画像ファイルを描画したい

#2

投稿記事 by ISLe » 11年前

スレッドとウィンドウメッセージキューは内部で結び付いているので、描画はウィンドウメッセージループのあるスレッドで行う必要があると思います。
受信スレッドからウィンドウに再描画を要求するユーザーメッセージを投げてウィンドウプロシージャで処理する形が良いのではないでしょうか。

あと、CreateCompatibleDCやSelectObjectは描画する都度行なうようにして、作りっぱなしは避けたほうが良いと思います。

アバター
shiro4ao
記事: 224
登録日時: 13年前
住所: 広島

Re: 画像ファイルを描画したい

#3

投稿記事 by shiro4ao » 11年前

ありがとうございます
データ受信スレッドからウィンドウメッセージWM_REFRESHを投げて
ウィンドウプロシージャ内でビットマップをロード、その他の準備をし
WM_PAINTが来たら描画させるようにしたら、画像が表示できました
ところが何もしていない(ウィンドウを動かさずサイズも変えない)のに
プロセッサがずーっと回り続けて居るようでした。
だいたい20%前後使用していました。

ウィンドウメッセージWM_REFRESHを投げた後、受信スレッドは終了しているので
ウィンドウプロシージャのあるメインスレッドがまわりっぱなしになるようなのですが
プロセッサが回り続けさせずに画像を表示させておく方法はありますか?

コード:

	// ビットマップをtemp2.bmpファイルからロードするウィンドウメッセージ
	case WM_REFRESH:
		{
			//  ビットマップをファイルからロードする
			hBitmap = (HBITMAP)LoadImage( NULL, _T("temp2.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
			hDC = GetDC( hwnd );
			hCompatDC = CreateCompatibleDC( hDC );
			hPrevBitmap = (HBITMAP)SelectObject( hCompatDC, hBitmap );
		}
		break;

コード:

	case WM_PAINT:
		// 描画させる
		StretchBlt( hDC, 0,0,1280, 800, hCompatDC, 0, 0,1280,800, SRCCOPY );
		break;

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

Re: 画像ファイルを描画したい

#4

投稿記事 by ISLe » 11年前

WM_PAINTメッセージでBeginPaint,EndPaintを使わないと無効領域がクリアされないので、WM_PAINTが連投されることになります。

描画にはBeginPaintが返すデバイスコンテキストを使ってください。
ルールに則れば、CreateCompatibleDC,SelectObjectしっぱなしは自ずとできないのです。

アバター
shiro4ao
記事: 224
登録日時: 13年前
住所: 広島

Re: 画像ファイルを描画したい

#5

投稿記事 by shiro4ao » 11年前

コード:

	case WM_PAINT:  // 再描画するタイミング
		hDC = BeginPaint(hWnd, &ps);
		StretchBlt( hDC, 0,0,1280, 800, hCompatDC, 0, 0,1280,800, SRCCOPY );
		EndPaint(hWnd, &ps);
		break;
BeginPaintとEndPaintのあいだに挿入するとプロセッサが落ち着きました
ありがとうございました。

一応、これで解決とさせていただきます。

閉鎖

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