首页 > 解决方案 > 如何在 vb6 上获取多显示器的桌面窗口句柄(每个或整个)?

问题描述

我有一个项目GetPixel用于分析我选择像素的 rgb 颜色,下面的代码在单显示器上工作正常,但对于多显示器,没关系GetDC(GetDesktopWindow)GetDC(0)dc 只包含主显示器上的桌面(我使用GetDeviceCaps HORZRESVERTRES检查这个)。

我用EnumDisplayMonitors()它显示虚拟桌面的宽度和高度是 3610x1875,它是正确的(我有两个显示器),但我使用GetDC(0)return dc 只有 2560x1440,这只是我的主显示器尺寸,所以我的辅助显示器在哪里......

我真正想要的是:

为 VB6 上的多显示器获取整个桌面窗口(虚拟桌面)的 DC(设备上下文)。

我搜索了这个'这是设计与旧应用程序的兼容性。它总是返回主监视器的矩形。从这里开始,也许这就是原因,但如何解决这个问题。

欢迎任何想法,谢谢!


编辑:感谢@RemyLebeau 帮助我清除系统上只有一个桌面窗口,即使系统有多个显示器。


Form1.frm,表格上有Text1、Text2、Text3、Timer1(设置Interval为50)

Private Declare Function GetDC Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function EnumDisplayMonitors Lib "user32" (ByVal HDC As Long, ByVal lprcClip As Long, ByVal lpfnEnum As Long, dwData As Any) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hWnd As Long, ByVal HDC As Long) As Long
Private Declare Function GetPixel Lib "gdi32" (ByVal HDC As Long, ByVal x As Long, ByVal y As Long) As Long
Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal HDC As Long, ByVal nIndex As Long) As Long
Const HORZRES As Integer = 8
Const VERTRES As Integer = 10

'this is new dc, will be Assignment on callback function
Public new_dc1 As Long
Public new_dc2 As Long

Private Sub Form_Load()    
    Dim shDC As Long
    shDC = GetDC(0)    
    Call EnumDisplayMonitors(shDC, 0, AddressOf MyPaintEnumProc, 0)
    ReleaseDC 0&, shDC    
End Sub
    
Private Sub Timer1_Timer()
    Dim pixel As Long
    Dim r As Integer
    Dim b As Integer
    Dim g As Integer
    pixel = GetPixel(new_dc1, 100, 100)
    r = pixel& Mod 256
    g = ((pixel And &HFF00) / 256&) Mod 256&
    b = (pixel And &HFF0000) / 65536
    
    Text2.Text = Now() & " Color is: r: " & r & " g: " & g & " b: " & b & vbCrLf
    Text3.Text = GetDeviceCaps(new_dc1, HORZRES) & "*" & GetDeviceCaps(new_dc1, VERTRES)
End Sub

模块1.bas

Public Declare Sub CopyMemory Lib "kernel32" _
   Alias "RtlMoveMemory" _
  (Destination As Any, _
   Source As Any, _
   ByVal Length As Long)

Public Type RECT
   Left    As Long
   Top     As Long
   Right   As Long
   Bottom  As Long
End Type

Public Function MyPaintEnumProc(ByVal HMONITOR As Long, _
                                ByVal HDC As Long, _
                                ByVal LPRECT As Long, _
                                ByVal LPARAM As Long) As Long

   Dim rc As RECT
   CopyMemory rc, ByVal LPRECT, Len(rc)

    'this is only debug purpose, i know this function will execute twice
    If Form1.new_dc1 = 0 Then
        Form1.new_dc1 = HDC 
    Else
        Form1.new_dc2 = HDC 
    End If
  
   Form1.Text1.Text = Form1.Text1.Text & HMONITOR & vbCrLf
   Form1.Text1.Text = Form1.Text1.Text & HDC & vbCrLf
   Form1.Text1.Text = Form1.Text1.Text & LPRECT & vbCrLf
   Form1.Text1.Text = Form1.Text1.Text & LPARAM & vbCrLf
   
   Form1.Text1.Text = Form1.Text1.Text & "rc.Left: " & rc.Left & vbCrLf
   Form1.Text1.Text = Form1.Text1.Text & "rc.Top: " & rc.Top & vbCrLf
   Form1.Text1.Text = Form1.Text1.Text & "rc.Weight: " & rc.Right - rc.Left & vbCrLf
   Form1.Text1.Text = Form1.Text1.Text & "rc.Height: " & rc.Bottom - rc.Top & vbCrLf & vbCrLf
   

   MyPaintEnumProc = 1

End Function

标签: winapivb6screencapturemonitor

解决方案


推荐阅读