教えて下さい。
例えばスクリーンの座標(0,0)-(2,1)にラインを引く場合、
以下のように書いています。
コード: 全て選択
MoveToEx(hMemDC,0,0, ByVal NULL)
LineTo(hMemDC,2,1)
SetPixel(hMemDC,2,1,penColor)
InvalidateRect(hMainWnd, ByVal NULL, FALSE)
Sleep(1)
時々このライン描画がセットするピクセルの位置が違う
ことに気付きました。
ある時は、
■■□
□□■
のように描画され(これを①とします。■がラインの描画点です)、
また別の時には
■□□
□■■
と描画されます(これを②とします)。
確かにどちらでも(0,0)-(2,1)の座標を繋ぐラインには
なっているのですが、ただ印象としては②の描画
は少し不自然なのではないかという気がします。
しかも実行速度も①と②ではかなり差があり(一回の描画では
違いは分からないのですがループさせるなどして何度も実行
させていると違いは顕著です。元々この速度の違いから
描画点の違いに気が付きました)、
何か自分のプログラムが不正な処理を書いているのでは
と思うようになりました。
(①は描画としては正しいように感じるのですがこのラインが現れる
とき、しはしば描画速度が(あるいはプログラム自体の速度かも
しれませんが)非常に遅くなるときがあります。)
どのような条件下で①と②が場合分けされるのか
何とか捕らえようと思ったのですがそれが
中々掴めず、この現象が自分の環境以外でも現れるものなのか、
それとも自分の環境だけなのかそれすらもハッキリしない
状況で、それでここでお訊き出来ればと思いました。
比較の為に、同時にプロンプトウインドウにもラインを描画する
プログラムを書きました。(AB4.24/プロジェクト)
ここにソースが表示されます。 [ここをクリックすると内容が表示されます]
このプログラムはメイン・ウインドウとプロンプト・ウインドウコード: 全て選択
'-----------------------------------------------------------------------------
' イベント プロシージャ
'-----------------------------------------------------------------------------
' このファイルには、ウィンドウ [MainWnd] に関するイベントをコーディングします。
' ウィンドウ ハンドル: hMainWnd
#prompt
' TODO: この位置にグローバルな変数、構造体、定数、関数を定義します。
Dim clientRc As RECT 'メインウインドウのクライアントエリア・サイズ
Dim hMemDC As HDC 'メモリ・ビットマップのDCハンドル
Dim hMemBmp As HBITMAP 'メモリ・ビットマップハンドル
Dim hThread1 As HANDLE 'スレッド1のハンドル
Dim thread1_ID As DWord 'スレッド1のID
'-----------------------------------------------------------------------------
' ウィンドウメッセージを処理するためのコールバック関数
Function MainWndProc(hWnd As HWND, dwMsg As DWord, wParam As WPARAM, lParam As LPARAM) As DWord
' TODO: この位置にウィンドウメッセージを処理するためのコードを記述します。
' イベントプロシージャの呼び出しを行います。
MainWndProc=EventCall_MainWnd(hWnd,dwMsg,wParam,lParam)
End Function
'-----------------------------------------------------------------------------
' ここから下は、イベントプロシージャを記述するための領域になります。
'
'●デストロイ・イベント
'
Sub MainWnd_Destroy()
Line2_1_Test_DestroyObjects()
PostQuitMessage(0)
End Sub
'
'●ペイント・イベント
'
Sub MainWnd_Paint(hDC As HDC)
BitBlt(hDC,0,0,clientRc.right,clientRc.bottom,hMemDC,0,0,SRCCOPY)
End Sub
'
' ●クリエイト・イベント
'
Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
Dim hDC As HDC
Dim hBrush As HBRUSH
Dim hOldBrush As HBRUSH
'クライアント・エリアの大きさ取得
GetClientRect(hMainWnd,clientRc)
' メモリ・ビットマップの作成
hDC=GetDC(hMainWnd)
hMemDC=CreateCompatibleDC(hDC)
hMemBmp=CreateCompatibleBitmap(hDC, clientRc.right, clientRc.bottom)
SelectObject(hMemDC,hMemBmp)
ReleaseDC(hMainWnd,hDC)
'メモリBmpのクリア
hBrush=CreateSolidBrush(RGB(0,0,0))
hOldBrush=SelectObject(hMemDC,hBrush)
FillRect(hMemDC,clientRc,hBrush)
SelectObject(hMemDC,hOldBrush)
DeleteObject(hBrush)
'スレッドの定義
hThread1=CreateThread(ByVal 0,0,AddressOf(MainOperation),0,0,VarPtr(thread1_ID))
End Sub
'
'
'●スレッド1 ライン描画
'
Function MainOperation(dwDummy As DWord) As DWord
Dim penColor As DWord
Dim hPen As HPEN
Dim hOldPen As HPEN
'---- メインウインドウへの描画 ----
penColor=RGB(255,255,255)
hPen=CreatePen(PS_SOLID,0,penColor)
hOldPen=SelectObject(hMemDC,hPen)
MoveToEx(hMemDC,0,0, ByVal NULL)
LineTo(hMemDC,2,1)
SetPixel(hMemDC,2,1,penColor)
InvalidateRect(hMainWnd, ByVal NULL, FALSE)
Sleep(1)
SelectObject(hMemDC,hOldPen)
DeleteObject(hPen)
'---- prompt画面への描画 ----
Line(0,0)-(2,1),7
End Function
それぞれにLine(0,0)-(2,1)のラインを引きます。
どちらのウインドウに①、②のどのラインが描画される
のは不確定です。
時にはメインに①が、プロンプトに②が描画され、
また別の時にはメインに②が、プロンプトに①が描画されます。
両方のウインドウに①が描画されることもあります。
出来れば①の描画を速度を落とすことなく安定的に実行させたいと
思うのですが、
このようなライン描画の違いについて、お気づきのことが
ありましたら是非教えて下さい。
(環境)
AB 4.24/WinMe/Pentium3