ChooseColor dialog with a COLORDLGPROC hook
Imports System Imports System.Drawing Imports System.Runtime.InteropServices Imports System.Windows.Forms Public Class Form1 Inherits Form Private btnPickColor As Button Private lblColor As Label Public Sub New() Text = "COLORDLGPROC Hook Example" Size = New Size(320, 150) btnPickColor = New Button() With { .Text = "Pick Color...", .Location = New Point(10, 10), .AutoSize = True } AddHandler btnPickColor.Click, AddressOf OnPickColor lblColor = New Label() With { .Text = "Selected Color: None", .Location = New Point(10, 50), .AutoSize = True } Controls.Add(btnPickColor) Controls.Add(lblColor) End Sub ' Delegate type for hook procedure Private Delegate Function ColorDlgProc(hWnd As IntPtr, msg As Integer, wParam As IntPtr, lParam As IntPtr) As Integer ' Hold a reference to the delegate to avoid GC Private Shared hookDelegate As ColorDlgProc = AddressOf MyColorHook ' CHOOSECOLOR struct (interop-safe version)Private Structure CHOOSECOLOR2 Public lStructSize As Integer Public hwndOwner As IntPtr Public hInstance As IntPtr Public rgbResult As Integer Public lpCustColors As IntPtr Public Flags As Integer Public lCustData As IntPtr Public lpfnHook As IntPtr Public lpTemplateName As IntPtr End Structure ' Constants Private Const CC_RGBINIT As Integer = &H1 Private Const CC_FULLOPEN As Integer = &H2 Private Const CC_ENABLEHOOK As Integer = &H10 Private Const WM_INITDIALOG As Integer = &H110 ' Win32 API declarations Private Shared Function ChooseColor(ByRef cc As CHOOSECOLOR2) As Boolean End Function Private Shared Function SetWindowText(hWnd As IntPtr, lpString As String) As Boolean End Function ' Hook procedure to modify the dialog Private Shared Function MyColorHook(hWnd As IntPtr, msg As Integer, wParam As IntPtr, lParam As IntPtr) As Integer If msg = WM_INITDIALOG Then SetWindowText(hWnd, "Custom Color Dialog 🎨") End If Return 0 End Function ' Show the color picker dialog with hook Private Sub OnPickColor(sender As Object, e As EventArgs) Dim customColors(15) As Integer ' 16 color slots Dim gch = GCHandle.Alloc(customColors, GCHandleType.Pinned) Try Dim cc As New CHOOSECOLOR2() cc.lStructSize = Marshal.SizeOf(GetType(CHOOSECOLOR2)) cc.hwndOwner = Me.Handle cc.lpCustColors = gch.AddrOfPinnedObject() cc.rgbResult = ColorTranslator.ToWin32(Color.LightGreen) cc.Flags = CC_RGBINIT Or CC_FULLOPEN Or CC_ENABLEHOOK cc.lpfnHook = Marshal.GetFunctionPointerForDelegate(hookDelegate) If ChooseColor(cc) Then Dim selectedColor As Color = ColorTranslator.FromWin32(cc.rgbResult) lblColor.Text = $"Selected Color: R={selectedColor.R} G={selectedColor.G} B={selectedColor.B}" lblColor.ForeColor = selectedColor Else MessageBox.Show("Color dialog canceled.") End If Finally gch.Free() End Try End Sub Public Shared Sub Main() Application.EnableVisualStyles() Application.Run(New Form1()) End Sub End Class
Download 'Custom Color Dialog.vb':
📥 Download custom-color-dialog.vb