>ぴろあきさん、年寄りの冷や水さん
サンプルコードありがとうございました。
ぴろあきさんのコードは私にはかなり難しく、わからないところが
多々ありました。
年寄りの冷や水さんのコードはだいたい理解できたのですが、
「テスト表示」の部分が微妙です。
1.OLD_X = OLD_X + TTTの部分で、0.2秒間隔で80ずつxの値は
増加していくのでしょうか?
2.Ifの部分はOLD_X >10000とありますが、これは最終の処理を示しているんですか?
目盛りしか表示されなかったんですが、これでよかったのですか?
質問多くて、すいません。
初心者なりにがんばっています。
お助けください。
>ぴろあきさん
APIをあまり使ったことがないので、ネットで検索しまくり、ぴろあきさんのコードについてわからない部分を調べてみました。
しかし、まだまだわからないところが‥。
>If counter Mod pGrid = 0 Then
> Call MoveToEx(hDCh, pWidth - 2, 0, 0)
> Call LineTo(hDCh, pWidth - 2, pHeight)
> End If
なのですが、counterが25の倍数の時、線を引いているとことはわかりますが、なぜ幅のところで2を引いているのでしょうか?
また、頻繁にでてくるhDChなのですが、
> hDCh = CreateCompatibleDC(Picture1.hdc)
から、デバイスコンテキストのハンドルを持っている引数ということに
なるのでしょうか?
よろしくお願いします。
説明不足で申し訳ありませんでした。
フォームにタイマコントロールを配置してください。
またそのタイマコントロールのインターバルプロパティ
を1以上に設定してください。
ランダムな波形が表示されます。
返信ありがとうございます。
タイマーコントロールの設定とピクチャボックスを
フォームに配置したのですが、目盛りしか表示されません。。
波形表示するには、何か足りないのですかね?
>波形表示するには、何か足りないのですかね?
下記2行をForm_Loadの一番最後に移動すればよろしいかと。。。
Me.Timer1.Interval = 200
Me.Picture1.ForeColor = RGB(255, 255, 255)
>なぜ幅のところで2を引いているのでしょうか?
Call MoveToEx(hDCh, pWidth - 3, oldY, 0)
Call LineTo(hDCh, pWidth - 2, i)
上もそうですね。
これは、右端-3の位置から、右端-2の位置へ線を引いています。
なぜ、右端まで線を引かないのか?
なぜ、右端に目盛線を引かないのか?
というご質問ですよね?
まず、pWidthは端ですので何も描画できません。
最低でもpWidth - 1が描画するための右端になります。
(左端の0には描画できます)
0〜pWidth-1までに描画した画像をBitBltで左に移動するわけですが、
左に1移動しますので-1〜pWidth-2までに画像がコピーされます。
(当然-1は描画できません)
コピーされましたので、0〜pWidth-2までの画像は新たに入れ替わっています。
しかし、pWidth-1の画像はどうでしょう?
そのまま、残ってしまうんですよ。
このため、例えばpWidth-1に目盛線を描画すると、
右側が真っ黒になっていってしまいます。
これを避けるためのpWidth-2として余白を作っているのだと思われます。
>デバイスコンテキストのハンドルを持っている引数
hDChは、画像を保持しているメモリ空間へのハンドルとかなんとか。。。
デバイスコンテキストのハンドル(Picture1.hdc)を、
CreateCompatibleDC関数に引数として渡すことで、
『メモリ』デバイスコンテキストのハンドルを取得しているらしいです。
hDChは引数にもなりますが、正確には変数ですね。
つまり、デバイスコンテキストのハンドル→メモリデバイスコンテキストのハンドル
引数→変数ですね。
Pictureコントロール自体、メモリへの保持をしてくれるため、
これらは全てPicture1.hdcに置き換えても動作しますが、
おそらく高速化のためにこのようにしているのでしょう。
>ぴろあきさん
丁寧な解説ありがとうございます。
おおよその所はわかることができました。
>このため、例えばpWidth-1に目盛線を描画すると、
>右側が真っ黒になっていってしまいます。
>これを避けるためのpWidth-2として余白を作っているのだと思われます。
という部分の余白の意味がよくわからないのですが。
0〜pWidth-2までの画像は新たに入れ替わり、−1の部分の画像が
残ってしまうというところはわかるのですが、残った画像というのは
コピーされていない部分ですよね?
コピーと移動を組み合わせて、グラフを動かしていると思うのですが、
頭の中でぐちゃぐちゃになってなかなか想像できません。単に、私の
力不足ということなのでしょうが。
Y座標の始まりはpHeightHalfからはじまり、
→描画したのを左へ移動し、移動するまでに描いたグラフを
左へコピーという処理の流れでよいのでしょうか?
古いグラフと新しいグラフの見分けがうまくつかめないです。
あのサンプルには画像を消すっていう処理が全く入ってないんですよ。
あるのは上書きのみ。上書きしていない部分はそのまま残ります。
それを踏まえて、、、
>残った画像というのはコピーされていない部分ですよね?
コピーされています。
0〜pWidth-1までがコピーされて、
-1〜pWidth-2までに貼り付けられるんです。
-1〜pWidth-2までの画像は上書きされるので元の画像は消えますが、
pWidth-1の部分はコピーされたものの貼り付けされていないので残りますね?
ここまではOK?
次のタイマーイベントで、現在の画像がまたコピーされます。
0〜pWidth-1がコピーされて、
-1〜pWidth-2までに貼り付けられます。
ほら、pWidth-1とpWidth-2にある画像は同じモノですね。
上から何か(波形など)を書き加えることはできても、
消すという作業が入っていないので、どんどん積もっていってしまいます。
>古いグラフと新しいグラフの見分けがうまくつかめないです。
新しいグラフはこれ。
Call MoveToEx(hDCh, pWidth - 3, oldY, 0)
Call LineTo(hDCh, pWidth - 2, i)
分かり易くすればこう。
Picture1.Line (pWidth - 3, oldY)-(pWidth - 2, i)
ここでも、-2として余白を作っていますね。
これでもわからなければ、タイマーを止めちゃって、
コマンドボタンを2つ作って、下を実行して試してね。
Command1→Command2を交互にクリックすると、新しいグラフのみが現れるから。
Command1だけをクリックし続けるとどうなります?
余白を作るとどうなります?
この程度の事は自分でやってくれないと。。。
Private Sub Command1_Click()
Call API_Graph
End Sub
Private Sub Command2_Click()
Picture1.Cls
End Sub
Private Sub API_Graph()
Dim i As Integer
'Do
Call BitBlt(Picture1.hdc, _
0, _
0, _
pWidth - 1, _
pHeight, _
Picture1.hdc, _
1, _
0, _
SRCCOPY)
If counter Mod pGrid = 0 Then
' Call MoveToEx(Picture1.hdc, pWidth - 2, 0, 0)
' Call LineTo(Picture1.hdc, pWidth - 2, pHeight)
Call MoveToEx(Picture1.hdc, pWidth - 1, 0, 0)
Call LineTo(Picture1.hdc, pWidth - 1, pHeight)
End If
i = Sin(0.1 * counter) * _
(pHeightHalf - 1) + _
pHeightHalf
Call SelectObject(Picture1.hdc, hPenC)
Call MoveToEx(Picture1.hdc, pWidth - 2, oldY, 0)
Call LineTo(Picture1.hdc, pWidth - 1, i)
Call SelectObject(Picture1.hdc, hPenB)
Call BitBlt(Picture1.hdc, _
0, _
0, _
pWidth, _
pHeight, _
Picture1.hdc, _
0, _
0, _
SRCCOPY)
counter = counter + 1
oldY = i
DoEvents
'Loop
End Sub
>-1〜pWidth-2までの画像は上書きされるので元の画像は消えますが、
>pWidth-1の部分はコピーされたものの貼り付けされていないので残ります>ね?
>ここまではOK?
OKです。
コマンドボタン配置してやってみました。
経験がまだまだ浅くて、こういうやり方も思いつきませんでした。
余白の意味もだいたいわかりました。
本当にありがとうございます。
ツイート | ![]() |