Smart Box

[VB.net] 커서가 가르키는 곳 색상 알아내기(Thread, GetDC, GetPixel) 예제 본문

Programming/VB.net

[VB.net] 커서가 가르키는 곳 색상 알아내기(Thread, GetDC, GetPixel) 예제

프매씨 2015. 1. 29. 19:22




마우스 커서가 가르키고 있는 곳의 색상을 가져오기 위해서는 'MousePosition' 클래스를 활용해 마우스 커서 위치를 알아야 하며, Windows API인 GetDC를 이용해 핸들을 알아내고, 마우스 커서 위치와 알아낸 핸들을 가지고 GetPixel로 색상을 Hex RGB로 알아낼 수 있습니다.


GetPixel은 Hex RGB(16진수)값을 Decimal(10진수)로 반환하기 때문에 직접 Hex로 바꿔야 합니다. 여기선 Hex 클래스를 이용합니다. 또, 실시간으로 정보를 가져오기 위해 백그라운드 스래드(Threading.Thread)를 이용합니다. 타이머를 이용해도 되긴하지만, 타이머는 백그라운드 상에서 이벤트가 발생하지 않기 때문에 스레드를 이용하기로 했습니다.


아래 예제를 확인해보세요 :)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
Imports System.Runtime.InteropServices
 
Public Class Form1
 
    <DllImport("gdi32.dll", SetLastError:=True)> _
    Public Shared Function GetPixel(hdc As IntPtr, nXPos As Integer, nYPos As Integer) As UInteger
    End Function
    <DllImport("user32.dll")> _
    Public Shared Function GetDC(ByVal hwnd As IntPtr) As IntPtr
    End Function
    <DllImport("user32.dll")> _
    Public Shared Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function
    Dim Update_Thread As New Threading.Thread(AddressOf Cursor_Update)
    Delegate Sub SetTextCallback([text] As String)
 
    Sub Cursor_Update()
        Do
 
            Dim hdc As IntPtr = GetDC(IntPtr.Zero)
 
            Dim c As String = Hex(GetPixel(hdc, MousePosition.X, MousePosition.Y)) '// Dec -> Hex
 
            ReleaseDC(IntPtr.Zero, hdc)
 
            '// Hex -> Dec
            Dim R As Long = Val("&H" & Mid(c, 52)) 
            Dim G As Long = Val("&H" & Mid(c, 32))
            Dim B As Long = Val("&H" & Mid(c, 12))
 
            set_text("X-" & MousePosition.X & "/Y-" & MousePosition.Y & "/RGB-" & c & "/R-" & R & "/G-" & G & "/B-" & B)
 
        Loop
    End Sub
    Sub set_text(str As String)
        On Error Resume Next
        If Me.InvokeRequired = True Then
 
            Dim d As New SetTextCallback(AddressOf set_text)
            Me.Invoke(d, New Object() {[str]})
 
        Else
 
            Me.Text = str
            Me.BackColor = System.Drawing.Color.FromArgb(Split(Split(str, "/R-")(1), "/G-")(0), Split(Split(str, "/G-")(1), "/B-")(0), Split(str, "/B-")(1))
 
        End If
    End Sub
 
    Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
 
        Update_Thread.Abort()
 
    End Sub
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
 
        Update_Thread.SetApartmentState(Threading.ApartmentState.STA)
        Update_Thread.Start()
 
    End Sub
End Class
 
cs


예제를 자세히 보시면 Hex를 다시 Dec(10진수)로 변환하는 과정에 &H를 붙이는데요. VB.net에서는 &H 뒤에 있는 문자열을 Hex 값으로 인식합니다. 참고하세요 :)



Visual Studio 2013으로 작성한 위 예제 소스 프로젝트도 업로드 합니다.



WindowsApplication5.zip




Comments