- 題名: セカンダリモニタのhDCを取得したい
- 日時: 2006/03/23 9:41:41
- ID: 14985
- この記事の返信元:
- (なし)
- この記事への返信:
- [14986] Re[1]: セカンダリモニタのhDCを取得したい2006/03/23 10:36:18
- [14997] Re[1]: セカンダリモニタのhDCを取得したい2006/03/23 19:39:12
- ツリーを表示
渋木宏明(ひどり)様,ありがとうございます。 > 第二2引数の解説が無いけど、hMonitor でいいのかなあ? やってみました。すこし長いですけれど,リスト載せます。 結論を先に書きますが,ダメでした。やはりプライマリモニタにのみ描画されます。しかもセカンダリモニタの大きさにクリップされて。 ちなみに,g.Clear(Color.Black)とするとちゃんとセカンダリモニタが真っ黒に なるんです。 う〜ん。もしかして.NETのバグ? Option Strict On Imports System.Runtime.InteropServices Public Class Form1 <DllImport("user32.dll")> _ Private Shared Function GetDC( _ ByVal hWnd As IntPtr) _ As IntPtr End Function <DllImport("user32.dll")> _ Private Shared Function ReleaseDC( _ ByVal hWnd As IntPtr, _ ByVal hDC As IntPtr) _ As Integer End Function <DllImport("user32.dll")> _ Private Shared Function UpdateWindow( _ ByVal hWnd As IntPtr) _ As Boolean End Function <DllImport("user32.dll")> _ Private Shared Function RedrawWindow( _ ByVal hWnd As IntPtr, _ ByVal lprcUpdate As IntPtr, _ ByVal hrgnUpdate As IntPtr, _ ByVal flags As RDW) _ As Boolean End Function 'RedrawWindow() flags Private Enum RDW As Integer INVALIDATE = &H1 INTERNALPAINT = &H2 [ERASE] = &H4 VALIDATE = &H8 NOINTERNALPAINT = &H10 NOERASE = &H20 NOCHILDREN = &H40 ALLCHILDREN = &H80 UPDATENOW = &H100 ERASENOW = &H200 FRAME = &H400 NOFRAME = &H800 End Enum <DllImport("gdi32.dll")> _ Private Shared Function CreateDC( _ ByVal pszDriver As String, _ ByVal pszDevice As String, _ ByVal pszOutput As String, _ ByVal pInitData As IntPtr) _ As IntPtr End Function <DllImport("user32.dll")> _ Shared Function EnumDisplayMonitors( _ ByVal hdc As IntPtr, _ ByVal lprcClip As IntPtr, _ ByVal lpfnEnum As MonitorEnumProc, _ ByRef dwData As IntPtr) _ As Boolean End Function Delegate Function MonitorEnumProc( _ ByVal hMonitor As IntPtr, _ ByVal hdcMonitor As IntPtr, _ ByVal lprcMonitor As IntPtr, _ ByRef dwData As IntPtr) _ As Boolean Dim WithEvents Timer As New Timer Dim MonitorList As New List(Of IntPtr) Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load EnumDisplayMonitors(Nothing, Nothing, AddressOf EnumMonitors, IntPtr.Zero) Me.Timer.Interval = 10 Me.Timer.Enabled = True End Sub Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing Me.Timer.Enabled = False Me.RefreshDesktop() End Sub Private Function EnumMonitors(ByVal hMonitor As IntPtr, ByVal hdcMonitor As IntPtr, ByVal lprcMonitor As IntPtr, ByRef dwData As IntPtr) As Boolean Me.MonitorList.Add(hMonitor) Return True End Function Private Sub Timer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer.Tick Select Case Control.MouseButtons Case Windows.Forms.MouseButtons.Left Dim hDC As IntPtr = CreateDC(Screen.AllScreens(1).DeviceName, Nothing, Nothing, IntPtr.Zero) Using g As Graphics = Graphics.FromHdc(hDC, Me.MonitorList(1)) g.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality Dim p As Point = Control.MousePosition Const r As Integer = 5 g.FillEllipse(Brushes.Red, p.X - r, p.Y - r, r * 2, r * 2) End Using ReleaseDC(IntPtr.Zero, hDC) Case Windows.Forms.MouseButtons.Right Me.RefreshDesktop() End Select End Sub Private Sub RefreshDesktop() RedrawWindow(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, RDW.ALLCHILDREN Or RDW.UPDATENOW Or RDW.ERASE Or RDW.INVALIDATE Or RDW.INTERNALPAINT) UpdateWindow(IntPtr.Zero) End Sub End Class
分類:[.NET]
2006/03/23(Thu) 09:42:22 編集(投稿者)
たびたび似たようなスレッドをたてて申し訳ありません。
GetDC(IntPtr.Zero)でプライマリモニタのデバイスコンテキストハンドルが取得できることはわかったのですが,マルチディスプレイ環境でセカンダリモニタのデバイスコンテキストハンドルが取得できません。
Dim hDC As IntPtr = CreateDC("\\.\DISPLAY2", "\\.\DISPLAY2", Nothing, IntPtr.Zero)
とすると例外も発生せずハンドルが取得できるのですが,実際に描画しようとするとプライマリモニタに描画されます。それもセカンダリモニタの大きさにクリッピングされてです。(つまりプライマリが1600*1200,セカンダリが1024*768ならプライマリの1024*768に描画される)
座標はx:1200,y:0を原点にすると何も描かれず,x:0,y:0を原点にすると前述のようにプライマリの一部に描画されます。
GetDC(IntPtr.Zero)でプライマリモニタに描画するのと同じようにセカンダリモニタに描画する方法をご存じの方がいらっしゃいましたらご教授ください。