本文介绍了获得色彩的特性,同时ColorDialog类仍处于打开状态,确认对话框之前?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要做的就是同时ColorDialog类打开后,即可在全开放模式的ColorDialog类的时间选择的颜色。

例如在这个图片我有一个白色的图片框和一个ColorDialog类是打开了红颜色的选择,我要的是改变PictureBox的背景色为所选择的颜色(红色),而pressing的确定按钮确认ColorDialog类,并得到了色彩效果...

这是可能做到的默认ColorDialog类?

这是我已经试过:

 公共类Form1中

    昏暗WithEvents就PicBox作为新的PictureBox
    昏暗ColorDlg作为新ColorDialog类

    私人小组Form1_Load的(发送者为对象,E作为EventArgs的)把手MyBase.Load
        PicBox.BackColor = Color.Blue
        ColorDlg.FullOpen = TRUE
        Me.Controls.Add(PicBox)
    结束小组

    私人小组PicBox_Click(发送者为对象,E作为EventArgs的)把手PicBox.Click
        ColorDlg.Color = sender.backcolor
        虽然没有ColorDlg.ShowDialog()= Windows.Forms.DialogResult.OK
            sender.BackColor = ColorDlg.Color
        结束在
        sender.BackColor = ColorDlg.Color
    结束小组

末级
 

解决方案

免责声明:正因为我们可以,并不意味着我们应该

这个例子是专门与 Col​​orDialog类 FullOpen 模式下工作。它依赖于一个事实,即红色,绿色和蓝色:修改实时更新的对话框中控件的颜色改变由用户,和一个事实,即 WM_CTLCOLOREDIT 终止那些控制是每次更新时(这也适用于当这些值被手动键入)发送。我们必须创建一个新的实例 MyColorDialog 我们要使用它,使窗口处理这些控件是正确的每一次。

WindowsEnumerator 类下面是根据Bob的(TheLearnedOne)工作的这里。

*我是 Idle_Mind 过在专家交换为好。

这是在VS2010 premium测试上的Win8专业版。我不,如果需要在其他版本的Windows进行了ColorDialog类的任何变化:

 公共类Form1中

    私人WithEvents就PicBox作为新的PictureBox
    私人WithEvents就ColorDlg作为MyColorDialog =无

    私人小组Form1_Load的(发送者为对象,E作为EventArgs的)把手MyBase.Load
        PicBox.BackColor = Color.Blue
        Me.Controls.Add(PicBox)
    结束小组

    私人小组PicBox_Click(发送者为对象,E作为EventArgs的)把手PicBox.Click
        ColorDlg =新MyColorDialog
        ColorDlg.Color = sender.backcolor
        如果ColorDlg.ShowDialog()= Windows.Forms.DialogResult.OK然后
            sender.BackColor = ColorDlg.Color
        结束如果
        ColorDlg =无
    结束小组

    私人小组ColorDlg_CurrentColor(c以的System.Drawing.Color)处理ColorDlg.CurrentColor
        PicBox.BackColor = C
    结束小组

末级

公共类MyColorDialog
    继承ColorDialog类

    公共事件CurrentColor(BYVAL c以彩色)

    私人常量GA_ROOT作为整数= 2
    私人常量WM_CTLCOLOREDIT作为整数=安培; H133

    公开声明函数GetAncestor库user32.dll中_
        (BYVAL的HWND作为IntPtr的,BYVAL gaFlags为整数)作为IntPtr的

    私人EditWindows方式列表(中ApiWindow)=无

    公共子新()
        Me.FullOpen = TRUE
    结束小组

    <System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand,名称:=FullTrust的)&GT; _
    受保护的覆盖功能HOOKPROC(BYVAL的HWND作为IntPtr的,BYVAL味精作为整数,BYVAL wParam中的IntPtr,BYVAL lParam中的IntPtr)作为IntPtr的
        选择案例味精
            案例WM_CTLCOLOREDIT
                如果IsNothing(EditWindows)然后
                    昏暗的主窗口作为IntPtr的= GetAncestor(HWND,GA_ROOT)
                    如果不mainWindow.Equals(IntPtr.Zero)然后
                        EditWindows =新名单(中ApiWindow)((新WindowsEnumerator).GetChildWindows(的主窗口,编辑))
                    结束如果
                结束如果

                如果不IsNothing(EditWindows)AndAlso EditWindows.Count = 6于是,
                    DIM strRed的String = WindowsEnumerator.WindowText(EditWindows(3).hWnd)
                    昏暗strGreen作为字符串= WindowsEnumerator.WindowText(EditWindows(4).hWnd)
                    昏暗strBlue作为字符串= WindowsEnumerator.WindowText(EditWindows(5).hWnd)

                    暗淡的红,绿,蓝作为整数
                    如果Integer.TryParse(strRed,红)。然后
                        如果Integer.TryParse(strGreen,绿),然后
                            如果Integer.TryParse(strBlue,蓝)然后
                                的RaiseEvent CurrentColor(Color.FromArgb(红,绿,蓝))
                            结束如果
                        结束如果
                    结束如果
                结束如果
        最终选择

        返回MyBase.HookProc(HWND,味精,的wParam,lParam的)
    端功能

末级

公共类ApiWindow
    公众的hWnd作为IntPtr的
    公共类名作为字符串
    公共MainWindowTitle作为字符串
末级

公共类WindowsEnumerator

    私人委托函数EnumCallBackDelegate(BYVAL HWND作为IntPtr的,BYVAL lParam的作为整数)作为整数

    私人声明函数EnumWindows的库USER32_
        (BYVAL lpEnumFunc作为EnumCallBackDelegate,BYVAL lParam的作为整数)作为整数

    私人声明函数EnumChildWindows库USER32_
        (BYVAL hWndParent作为IntPtr的,BYVAL lpEnumFunc作为EnumCallBackDelegate,BYVAL lParam的作为整数)作为整数

    私人声明函数GetClassName库USER32别名GetClassNameA_
        (BYVAL HWND作为IntPtr的,BYVAL lpClassName作为System.Text.StringBuilder,BYVAL nMaxCount为整数)作为整数

    私人声明函数IsWindowVisible库USER32(BYVAL HWND作为IntPtr的)作为整数

    私人声明函数的getParent库USER32(BYVAL HWND作为IntPtr的)作为整数

    私人声明SendMessage函数库USER32别名SendMessageA_
        (BYVAL HWND作为IntPtr的,BYVAL WMSG作为整数,wParam参数BYVAL作为整数,BYVAL lParam的作为整数)作为整数

    私人声明SendMessage函数库USER32别名SendMessageA_
        (BYVAL HWND作为IntPtr的,BYVAL WMSG作为整数,wParam参数BYVAL作为整数,BYVAL lParam中System.Text.StringBuilder)作为整数

    私人_listChildren作为新的列表(ApiWindow中)
    私人_listTopLevel作为新的列表(ApiWindow中)

    私人_topLevelClass作为字符串=的String.Empty
    私人_childClass作为字符串=的String.Empty

    公共重载函数GetTopLevelWindows()作为ApiWindow()
        EnumWindows的(AddressOf EnumWindowProc,和放大器; H0)
        返回_listTopLevel.ToArray
    端功能

    公共重载函数GetTopLevelWindows(BYVAL类名作为字符串)作为ApiWindow()
        _topLevelClass =的className
        返回Me.GetTopLevelWindows()
    端功能

    公共重载函数GetChildWindows(BYVAL HWND作为的Int32)作为ApiWindow()
        _listChildren.Clear()
        EnumChildWindows(HWND,AddressOf EnumChildWindowProc,和放大器; H0)
        返回_listChildren.ToArray
    端功能

    公共重载函数GetChildWindows(BYVAL HWND作为的Int32,BYVAL childClass作为字符串)作为ApiWindow()
        _childClass = childClass
        返回Me.GetChildWindows(HWND)
    端功能

    专用功能EnumWindowProc(BYVAL HWND作为的Int32,BYVAL lParam中的Int32)作为的Int32
        如果的getParent(HWND)= 0 AndAlso IsWindowVisible(HWND)然后
            昏暗的窗口ApiWindow = GetWindowIdentification(HWND)
            如果_topLevelClass.Length = 0 OrElse运算window.ClassName.ToLower()= _topLevelClass.ToLower(),然后
                _listTopLevel.Add(窗口)
            结束如果
        结束如果
        返回1
    端功能

    专用功能EnumChildWindowProc(BYVAL HWND作为的Int32,BYVAL lParam中的Int32)作为的Int32
        昏暗的窗口ApiWindow = GetWindowIdentification(HWND)
        如果_childClass.Length = 0 OrElse运算window.ClassName.ToLower()= _childClass.ToLower(),然后
            _listChildren.Add(窗口)
        结束如果
        返回1
    端功能

    专用功能GetWindowIdentification(BYVAL HWND为整数)作为ApiWindow
        昏暗classBuilder作为新System.Text.StringBuilder(64)
        GetClassName(HWND,classBuilder,64)

        昏暗的窗口作为新ApiWindow
        window.ClassName = classBuilder.ToString()
        window.MainWindowTitle = WindowText(HWND)
        window.hWnd = HWND
        返回窗口
    端功能

    公共共享功能WindowText(BYVAL HWND作为IntPtr的)作为字符串
        常量W_GETTEXT作为整数=安培;高清
        常量W_GETTEXTLENGTH作为整数=安培;何

        昏暗的SB作为新System.Text.StringBuilder
        昏暗的长度为整数= SendMessage消息(HWND,W_GETTEXTLENGTH,0,0)
        如果长度GT; 0然后
            SB =新System.Text.StringBuilder(长度+ 1)的
            SendMessage消息(HWND,W_GETTEXT,SB.Capacity,SB)
        结束如果
        返回SB.ToString
    端功能

末级
 

What I want to do is while a ColorDialog is opened, get the temporal selected color in the "full open" mode of the Colordialog.

For example in this image I have a white colored picturebox and a ColorDialog is opened with the "Red" color selected, what I want is to change the picturebox backcolor to the selected color (Red) without pressing the "ok" button to confirm the ColorDialog and to get the Color result...

This is possibly to do with the default ColorDialog?

This is what I've tried:

Public Class Form1

    Dim WithEvents PicBox As New PictureBox
    Dim ColorDlg As New ColorDialog

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        PicBox.BackColor = Color.Blue
        ColorDlg.FullOpen = True
        Me.Controls.Add(PicBox)
    End Sub

    Private Sub PicBox_Click(sender As Object, e As EventArgs) Handles PicBox.Click
        ColorDlg.Color = sender.backcolor
        While Not ColorDlg.ShowDialog() = Windows.Forms.DialogResult.OK
            sender.BackColor = ColorDlg.Color
        End While
        ' sender.BackColor = ColorDlg.Color
    End Sub

End Class
解决方案

Disclaimer: Just because we can, doesn't mean we should!

This example is specifically designed to work with the ColorDialog in the FullOpen mode. It relies on the fact that the "Red:", "Green:" and "Blue:" Edit controls in the dialog are updated in real-time as the color is changed by the user, and the fact that a WM_CTLCOLOREDIT is sent each time those controls are updated (this also applies to when those values are manually typed in). We have to create a new instance of MyColorDialog each time we want to use it so that the window handles to those controls are correct.

The WindowsEnumerator class below is based on Bob's (TheLearnedOne) work here.

*I'm Idle_Mind over at Experts-Exchange as well.

This was tested on Win8 Pro in VS2010 Premium. I don't if any changes would need to be made for the ColorDialog in other versions of Windows:

Public Class Form1

    Private WithEvents PicBox As New PictureBox
    Private WithEvents ColorDlg As MyColorDialog = Nothing

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        PicBox.BackColor = Color.Blue
        Me.Controls.Add(PicBox)
    End Sub

    Private Sub PicBox_Click(sender As Object, e As EventArgs) Handles PicBox.Click
        ColorDlg = New MyColorDialog
        ColorDlg.Color = sender.backcolor
        If ColorDlg.ShowDialog() = Windows.Forms.DialogResult.OK Then
            sender.BackColor = ColorDlg.Color
        End If
        ColorDlg = Nothing
    End Sub

    Private Sub ColorDlg_CurrentColor(c As System.Drawing.Color) Handles ColorDlg.CurrentColor
        PicBox.BackColor = c
    End Sub

End Class

Public Class MyColorDialog
    Inherits ColorDialog

    Public Event CurrentColor(ByVal c As Color)

    Private Const GA_ROOT As Integer = 2
    Private Const WM_CTLCOLOREDIT As Integer = &H133

    Public Declare Function GetAncestor Lib "user32.dll" _
        (ByVal hWnd As IntPtr, ByVal gaFlags As Integer) As IntPtr

    Private EditWindows As List(Of ApiWindow) = Nothing

    Public Sub New()
        Me.FullOpen = True
    End Sub

    <System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _
    Protected Overrides Function HookProc(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
        Select Case msg
            Case WM_CTLCOLOREDIT
                If IsNothing(EditWindows) Then
                    Dim mainWindow As IntPtr = GetAncestor(hWnd, GA_ROOT)
                    If Not mainWindow.Equals(IntPtr.Zero) Then
                        EditWindows = New List(Of ApiWindow)((New WindowsEnumerator).GetChildWindows(mainWindow, "Edit"))
                    End If
                End If

                If Not IsNothing(EditWindows) AndAlso EditWindows.Count = 6 Then
                    Dim strRed As String = WindowsEnumerator.WindowText(EditWindows(3).hWnd)
                    Dim strGreen As String = WindowsEnumerator.WindowText(EditWindows(4).hWnd)
                    Dim strBlue As String = WindowsEnumerator.WindowText(EditWindows(5).hWnd)

                    Dim Red, Green, Blue As Integer
                    If Integer.TryParse(strRed, Red) Then
                        If Integer.TryParse(strGreen, Green) Then
                            If Integer.TryParse(strBlue, Blue) Then
                                RaiseEvent CurrentColor(Color.FromArgb(Red, Green, Blue))
                            End If
                        End If
                    End If
                End If
        End Select

        Return MyBase.HookProc(hWnd, msg, wParam, lParam)
    End Function

End Class

Public Class ApiWindow
    Public hWnd As IntPtr
    Public ClassName As String
    Public MainWindowTitle As String
End Class

Public Class WindowsEnumerator

    Private Delegate Function EnumCallBackDelegate(ByVal hwnd As IntPtr, ByVal lParam As Integer) As Integer

    Private Declare Function EnumWindows Lib "user32" _
        (ByVal lpEnumFunc As EnumCallBackDelegate, ByVal lParam As Integer) As Integer

    Private Declare Function EnumChildWindows Lib "user32" _
        (ByVal hWndParent As IntPtr, ByVal lpEnumFunc As EnumCallBackDelegate, ByVal lParam As Integer) As Integer

    Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" _
        (ByVal hwnd As IntPtr, ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer) As Integer

    Private Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As IntPtr) As Integer

    Private Declare Function GetParent Lib "user32" (ByVal hwnd As IntPtr) As Integer

    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
        (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer

    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
        (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As System.Text.StringBuilder) As Integer

    Private _listChildren As New List(Of ApiWindow)
    Private _listTopLevel As New List(Of ApiWindow)

    Private _topLevelClass As String = String.Empty
    Private _childClass As String = String.Empty

    Public Overloads Function GetTopLevelWindows() As ApiWindow()
        EnumWindows(AddressOf EnumWindowProc, &H0)
        Return _listTopLevel.ToArray
    End Function

    Public Overloads Function GetTopLevelWindows(ByVal className As String) As ApiWindow()
        _topLevelClass = className
        Return Me.GetTopLevelWindows()
    End Function

    Public Overloads Function GetChildWindows(ByVal hwnd As Int32) As ApiWindow()
        _listChildren.Clear()
        EnumChildWindows(hwnd, AddressOf EnumChildWindowProc, &H0)
        Return _listChildren.ToArray
    End Function

    Public Overloads Function GetChildWindows(ByVal hwnd As Int32, ByVal childClass As String) As ApiWindow()
        _childClass = childClass
        Return Me.GetChildWindows(hwnd)
    End Function

    Private Function EnumWindowProc(ByVal hwnd As Int32, ByVal lParam As Int32) As Int32
        If GetParent(hwnd) = 0 AndAlso IsWindowVisible(hwnd) Then
            Dim window As ApiWindow = GetWindowIdentification(hwnd)
            If _topLevelClass.Length = 0 OrElse window.ClassName.ToLower() = _topLevelClass.ToLower() Then
                _listTopLevel.Add(window)
            End If
        End If
        Return 1
    End Function

    Private Function EnumChildWindowProc(ByVal hwnd As Int32, ByVal lParam As Int32) As Int32
        Dim window As ApiWindow = GetWindowIdentification(hwnd)
        If _childClass.Length = 0 OrElse window.ClassName.ToLower() = _childClass.ToLower() Then
            _listChildren.Add(window)
        End If
        Return 1
    End Function

    Private Function GetWindowIdentification(ByVal hwnd As Integer) As ApiWindow
        Dim classBuilder As New System.Text.StringBuilder(64)
        GetClassName(hwnd, classBuilder, 64)

        Dim window As New ApiWindow
        window.ClassName = classBuilder.ToString()
        window.MainWindowTitle = WindowText(hwnd)
        window.hWnd = hwnd
        Return window
    End Function

    Public Shared Function WindowText(ByVal hwnd As IntPtr) As String
        Const W_GETTEXT As Integer = &HD
        Const W_GETTEXTLENGTH As Integer = &HE

        Dim SB As New System.Text.StringBuilder
        Dim length As Integer = SendMessage(hwnd, W_GETTEXTLENGTH, 0, 0)
        If length > 0 Then
            SB = New System.Text.StringBuilder(length + 1)
            SendMessage(hwnd, W_GETTEXT, SB.Capacity, SB)
        End If
        Return SB.ToString
    End Function

End Class

这篇关于获得色彩的特性,同时ColorDialog类仍处于打开状态,确认对话框之前?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-03 23:32
查看更多