ab.com コミュニティ

ActiveBasicを通したコミュニケーション
現在時刻 - 2024年3月29日(金) 07:59

全ての表示時間は UTC+09:00 です




新しいトピックを投稿する  トピックへ返信する  [ 14 件の記事 ] 
作成者 メッセージ
投稿記事Posted: 2005年5月30日(月) 22:49 
表題の通りなのですが

'再描画要求を出す
'描画先のImageBox1のデバイスコンテキストを求める
Dim hImage As DWord
hImage=GetDC(GetDlgItem(hMainWnd,ImageBox1))
InvalidateRect(hImage,NULL,1)
とするとNULLが無効な識別子となってしまいます。

InvalidateRect(hMainWnd,ByVal 0,1)
とすると再描画は正常に終了しますが、他のコントロールも
またたきしてしまいます。よろしくお願いします。


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2005年5月30日(月) 22:49 
InvalidateRect関数の第一引数はウィンドウハンドルを指定するので、
hImage = GetDlgItem(hMainWnd, ImageBox1)
InvalidateRect(hImage, ByVal NULL, 1)
とするのがよいと思いますが。


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2005年5月30日(月) 22:49 
RESありがとうございます。

理屈がわかっていないため、いつも変な質問ばかりです。
さっそく試してみます。

ByVal NULL とは ByVal 0 と同じ事なのですか?


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2005年5月30日(月) 22:50 
> ByVal NULL とは ByVal 0 と同じ事なのですか?
そうです。どこかにConst NULL = 0と書かれているはずです。
(意味としてはポインタにのみ使うものですが)

関数呼び出し時にByValを付けているのはByRefとなっている引数に直接ポインタを渡したい場合です。


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2005年5月30日(月) 22:50 
解説の本を見ながら勉強していますが、いざ自分でコードを打ち始めると
つまづくことが多く、こちらの掲示板はバックサーチ(コードの切れ端)
もふくめ、私には宝の山です。高信期さんイグトランスさんありがとう
ございました。


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2005年5月30日(月) 22:51 
いろいろ試してみましたが、うまく行きませんでした。
該当部分を切り出して整理してみました。
画像の表示部分は、画像を切り替えたいためDispImage()に、
終了処理はMainWnd_Destroy()にわけました。

'ImageBox1のみ再描画要求を出したいので
InvalidateRect(hImage,ByVal 0,1)としましたが、表示できません。
InvalidateRect(hMainWnd,ByVal 0,1)では表示されます。

なぜ表示できないかということとあわせて、コマンドボタンを押す
イベントでDispImage()を実行するだけではなぜ表示されないのか
ということも疑問です。

長くなりますがコードは以下のようです。


'-----------------------------------------------------------------------------
' イベント プロシージャ
'-----------------------------------------------------------------------------
' このファイルには、ウィンドウ [MainWnd] に関するイベントをコーディングします。
' ウィンドウ ハンドル: hMainWnd
Dim hDC As DWord
Dim hResBmp As DWord
Dim hOldBmp As DWord
Dim hBuf As DWord
Dim udtBitmap As BITMAP
Dim hImage As Long
'-----------------------------------------------------------------------------
' ウィンドウメッセージを処理するためのコールバック関数

Function MainWndProc(hWnd As DWord, dwMsg As DWord, wParam As DWord, lParam As DWord) As DWord
' TODO: この位置にウィンドウメッセージを処理するためのコードを記述します。

' イベントプロシージャの呼び出しを行います。
MainWndProc=EventCall_MainWnd(hWnd,dwMsg,wParam,lParam)
End Function


'-----------------------------------------------------------------------------
' ここか'ら下は、イベントプロシージャを記述するための領域になります。
Sub MainWnd_Destroy()
ImageLabo_DestroyObjects()
PostQuitMessage(0)
'終了処理
SelectObject(hBuf,hOldBmp)
'⑧
'メモリデバイスコンテキストを解放する
DeleteDC(hBuf)
'ビットマップハンドルを破棄する
DeleteObject(hResBmp)
End Sub

Sub DispImage(filename2 as String)
hResBmp=LoadImage(GetModuleHandle(0),filename2,IMAGE_BITMAP,0,0,LR_LOADFROMFILE)
'←第2引数は適宜変更する
'③ビットマップのサイズを取得
GetObject(hResBmp,Len(udtBitmap),udtBitmap)
'④メモリデバイスコンテキストを作成する
hBuf=CreateCompatibleDC(hDC)
ReleaseDC(hMainWnd,hDC) '←Paintイベント内の場合は削除
'⑤メモリデバイスコンテキストにビットマップハンドルを割り当てる
hOldBmp=SelectObject(hBuf,hResBmp)
End Sub

'イベント#####################################################################
Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
'①コントロールのハンドル
' hImage=GetDC(GetDlgItem(hMainWnd,ImageBox1))
hImage=GetDlgItem(hMainWnd,ImageBox1)
'debug
End Sub


Sub MainWnd_Paint(hDC As DWord)
'描画先のImageBox1のデバイスコンテキストを求める この行をここにおかないとだめ
hDC=GetDC(GetDlgItem(hMainWnd,ImageBox1))
'⑥ 画像を描画  イメージを大きさを指定して 直接数値で
SetStretchBltMode( hDC, HALFTONE)
StretchBlt( hDC, 0, 0, 320, 240, hBuf, 0, 0, udtBitmap.bmWidth, udtBitmap.bmHeight, SRCCOPY)
End Sub


Sub MainWnd_CommandButton1_Click()
Dim buffer1[255] As Byte
lstrcpy(buffer1,"C:\image\402-291.bmp")

'ファイルのフルパスを表示
SetWindowText(GetDlgItem(hMainWnd,Static5),buffer1)
'イメージを表示
DispImage(buffer1)
'再描画要求を出す
InvalidateRect(hMainWnd,ByVal 0,1)
'InvalidateRect(hImage,ByVal 0,1)
End Sub


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2005年5月30日(月) 22:51 
> 'ImageBox1のみ再描画要求を出したいので
> InvalidateRect(hImage,ByVal 0,1)としましたが、表示できません。
> InvalidateRect(hMainWnd,ByVal 0,1)では表示されます。

横レス失礼します。

Dim udtRect As RECT
MoveWindow(GetDlgItem(hMainWnd,ImageBox1),10,10,100,100,1)
GetWindowRect(GetDlgItem(hMainWnd,ImageBox1),udtRect)
ScreenToClient(hMainWnd,ByVal VarPtr(udtRect))
ScreenToClient(hMainWnd,ByVal VarPtr(udtRect)+8)

これで、udtRectにはImageBox1の位置が返されるので、
このudtRectをInvalidateRectの第2引数に指定してみてください(第1引数はhMainWnd)。
※確かめもしていないのでうまく動作するかどうかわかりません(^^;


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2005年5月30日(月) 22:52 
Dim hImage As Long
hImage=GetDlgItem(hMainWnd,ImageBox1)
Dim rec As RECT
GetClientRect(hImage, rec)
InvalidateRect(hImage, rec, 1)
^^^^^^^^^
としていました。hiraさんのをみて修正しましたら
無事動きました。あと少しのところまできていたと思うと
とてもくやしい。

教えていただいたコードも試してみましたら。

1> Dim udtRect As RECT
2> MoveWindow(GetDlgItem(hMainWnd,ImageBox1),10,10,100,100,1)
3> GetWindowRect(GetDlgItem(hMainWnd,ImageBox1),udtRect)
4> ScreenToClient(hMainWnd,ByVal VarPtr(udtRect))
5> ScreenToClient(hMainWnd,ByVal VarPtr(udtRect)+8)

2の行だけでも(InvalidateRectがなくとも)再描画されました?
ヘルプを勉強してみます。

1+3+InvalidateRectもOKでした。

4と5の行はどんな働き?
いつもすばやいRESありがとうございます。


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2005年5月30日(月) 22:52 
> 1> Dim udtRect As RECT
> 2> MoveWindow(GetDlgItem(hMainWnd,ImageBox1),10,10,100,100,1)
> 3> GetWindowRect(GetDlgItem(hMainWnd,ImageBox1),udtRect)
> 4> ScreenToClient(hMainWnd,ByVal VarPtr(udtRect))
> 5> ScreenToClient(hMainWnd,ByVal VarPtr(udtRect)+8)
> > 2の行だけでも(InvalidateRectがなくとも)再描画されました?
> ヘルプを勉強してみます。

再描画をオンにしていますからね(最後の引数です)。
MoveWindowにしているのは、4行目・5行目で正しい値が返るのを確かめるため、わざと決まった場所に配置するようにしたためです。

> 1+3+InvalidateRectもOKでした。

動作したんですか?
私はこれで動くとは予想しなかったんですが…。

> 4と5の行はどんな働き?

スクリーン座標→クライアント座標の変換を行っています。
要するに、ディスプレイ全体を基準にした座標から、あるウィンドウを基準にした座標に変換するってことです。
2行に分けているのは、この関数がPOINTAPI型を要求しているため、(RECT×2と考えて)しかたなく2回呼び出しているだけのことです。

私もあまり詳しくはないですが、お力になれれば幸いです。


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2005年5月30日(月) 22:52 
おはようございます。
なんか解決した感が漂っていますがImageBoxの本来(?)の使い方をしていない
様に思えるので参考までに見てあげて下さい。

ImageBoxを使用する時はタイプを"ビットマップ"にしていると思いますが、
描画処理はImageBox自体に任せて何のビットマップを表示するかを指示する
だけにした方がスマートになります。
やり方は、

SendDlgItemMessage(hMainWnd,ImageBox1,STM_SETIMAGE,IMAGE_BITMAP,hBitmap)

これだけでImageBoxの内容が書き換えられてビットマップが表示されるように
なります。
この直後はサイズがビットマップのサイズになってしまいますので
MoveWindowなりSetWindowPosなりで調整して下さい。


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2005年5月30日(月) 22:53 
ノッチさん今日は、休みボケしてまして返事が遅れました。
教えていただいたコードでも試してみたいと思います。感謝です。
バックサーチで探してみたところ、1864で高信期さんも発言されて
いました。

最終的には、以前教えていただいたGDI+にグレードアップさせる
ため、その書式に合わせて切り貼りし、ようやくBMP表示まで来た
ところでして、本来の使い方でないところがあるようです。

機能的には表示を実現させたものの、前出のコードでは、ボタンの
クリックを繰り返すとメモリーがどんどんへり、ついには表示できな
くなってしまうことがわかり、破棄や開放がうまくないようでさらに
悩んでいおります。

BMP表示部分をすなおにペイント戻すところからチェック始めます。


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2005年5月30日(月) 22:57 
> 'ImageBox1のみ再描画要求を出したいので
> InvalidateRect(hImage,ByVal 0,1)としましたが、表示できません。
> InvalidateRect(hMainWnd,ByVal 0,1)では表示されます。

イメージボックスはスタティックコントロールの機能の一部なので
通常親ウィンドウの再描画が行われるときに一緒に再描画を行います。もともとスタティックは文字を表示するコントロールなので背景が描画されるまで手前に文字が表示できないと考えていただければ分かりやすいかと思います。

ビットマップをうまく自分の表示したいタイミングで表示する方法ですがスタティックコントロールをオーナードローするのが良いかとおもわれます。オーナードローが行われると親ウィンドウにWM_DRAWITEMメッセージが送られてくるのでこのメッセージを拾ってビットマップをイメージボックスに描画すればよいでしょう。

※イメージボックスではオーナードローが出来ないようです。
イメージボックスとスタティックは同じコントロールの筈なんですが。。。いつでもオーナードローが出来るのがイメージボックスと考えなのでしょうか?それにしてはイメージボックスの挙動が扱いにくいと思うんですけど。


通報する
ページトップ
   
投稿記事Posted: 2008年12月06日(土) 23:13 
オフライン

登録日時: 2005年7月19日(火) 07:02
記事: 183
お住まい: 宮城県
# スレの趣旨と違うコメントになります。すみません。


RADの「イメージボックス」を、初めてBMP表示用として使おうと思い、
しかしBMPの設定方法が分からずに困っておりました。
# というか、ありがたみが分からなかったです。
# 普通にデバイスコンテキストにBMPを貼り付ければ良いじゃないかと。


このスレで、ようやく「イメージボックスとは何者か?」が分かりました。
ありがとうございました。

スレの意図とは違うことへのレスで申し訳ありませんが、
似たように迷っている方への参考に、少し書かせていただきます。


 ・ABのRADの「イメージボックス」とは、「ピクチャーコントロール」のことであり、
  その実体はBMP表示スタイル(SS_BITMAP)を指定した「スタィックコントロール」。
  # 「イメージボックス」でググルと、余計なものばかり引っかかります^^;

 ・任意の画像ファイルを(動的に)表示するには、
  ビットマップハンドル(LoadBitmap()等で)にあらかじめ読み込んでおき、
  STM_SETIMAGEメッセージで設定する。
  # アイコン表示スタイルの場合は、リソース中のアイコンを静的に設定
  # していたので、悩まなかったのですが。。。

 ・再描画のタイミングは、通常のスタィックコントロールと一緒=親窓の再描画時。


【参考】
http://homepage2.nifty.com/c_lang/sdk4/sdk_349.htm
http://web.kyoto-inet.or.jp/people/yssk ... hap16.html


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2008年12月19日(金) 20:23 
あの、すいません。
画像でアニメーションのようなことがしたいんだったら、
ImageBoxのDCにBitBltするだけでもいけるとおもいます。
Dim hDC As HDC
Dim hMemDC As HDC,hBmp As HBITMAP
hDC=GetDC(GetDlgItem(hMainWnd,ImageBox1))
hMemDC=CreateCompatibleDC(hDC)
hBmp=LoadImage((略))
SelectObject(hMemDC,hBmp)
BitBlt(hDC,0,0,100,100,hMemDC,0,0,SRCCOPY)
これで更新されるとおもいます。


通報する
ページトップ
   
期間内表示:  ソート  
新しいトピックを投稿する  トピックへ返信する  [ 14 件の記事 ] 

全ての表示時間は UTC+09:00 です


オンラインデータ

このフォーラムを閲覧中のユーザー: Bing [Bot], Google [Bot] & ゲスト[9人]


トピック投稿:  可
返信投稿:  可
記事編集: 不可
記事削除: 不可
ファイル添付: 不可

検索:
ページ移動:  
Powered by phpBB® Forum Software © phpBB Limited
Japanese translation principally by ocean