I have a project is use GetPixel
to analysis the rgb color where i selected pixel, the code below is working fine on single monitor, but for multi monitors,
not matter GetDC(GetDesktopWindow)
or GetDC(0)
the dc only contain the desktop on primary monitor (i use GetDeviceCaps
HORZRES
and VERTRES
to check this).
i used EnumDisplayMonitors()
it shows the width and height of virtual desktop is 3610x1875, it is right (i have two monitors), but i use GetDC(0)
return dc is only 2560x1440 which is my primary monitor size only, so where is my secondary monitor...
what i want exactly is:
get a DC (device context) of entire desktop window (virtual desktop) for multi monitors on VB6.
i searched this 'This is by design with compatibility with older applications. It always returns the rectangle of the primary monitor.' from here, maybe this is why, but how to fix this.
any idea is welcome, thank you!
edited: thank for @RemyLebeau to help me to clear that only one desktop window on system even system has multi monitors.
Form1.frm, there is Text1, Text2, Text3, Timer1 (set Interval to 50) on form
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
Module1.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