获取颜色属性,而ColorDialog仍然打开,确认对话框之前? [英] Get color property while ColorDialog still open, before confirming the dialog?
问题描述
我想要做的是当一个ColorDialog打开时,在Colordialog的完全打开模式中获取临时选择的颜色。
What I want to do is while a ColorDialog is opened, get the temporal selected color in the "full open" mode of the Colordialog.
图像我有一个白色的图片框和一个ColorDialog打开选择红色的颜色,我想要的是改变图片框的背景颜色为选定的颜色(红色),而不按确定按钮确认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...
这可能与默认的ColorDialog有关?
This is possibly to do with the default ColorDialog?
这是我试过的: / p>
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
推荐答案
免责声明:只是因为我们可以,并不意味着我们应该!
此示例专门设计为使用在
。它依赖于以下事实:对话框中的红色:,绿色:和蓝色: FullOpen
模式下的ColorDialog 编辑
控件随着颜色更改,以及每次更新这些控件时发送 WM_CTLCOLOREDIT
(这也适用于手动输入这些值时)。我们必须在每次使用它时创建一个 MyColorDialog
的新实例,以便这些控件的窗口句柄正确。
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.
下面的 WindowsEnumerator
类基于Bob的(TheLearnedOne)工作此处。
The WindowsEnumerator
class below is based on Bob's (TheLearnedOne) work here.
*我
这在VS2010 Premium的Win8 Pro上进行了测试。我不需要为其他版本的Windows中的ColorDialog做任何更改:
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仍然打开,确认对话框之前?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!