自定义扩展颜色对话框
这个是我利用底层钩子技术扩展的一个颜色对话框,下面就分析代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing;
using CustomCommonDialog;
using AlphaSliderControl;
using System.Diagnostics;
namespace CustomCommonDialog
{
public class FColorDialog : ColorDialog
{
//API函数:获取指定句柄的类名
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern int GetClassName(IntPtr hwnd, char[] className, int maxCount);
//API函数:根据指定句柄,寻找下一个句柄
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetWindow(IntPtr hwnd, int uCmd);
//API函数:设置指定句柄对象的Text值
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern bool SetWindowText(IntPtr hwnd, char[] lpString);
bool ButtonTextChanged = false;
// the CHOOSECOLOR structure, used to control the appearance and behaviour of the OpenFileDialog
private Panel _panelAlpha= new Panel();
public FColorDialog()
{
Button b = new Button();
b.Text = "自定义按钮";
b.Click += new System.EventHandler(OnBtnClick);
_panelAlpha.Controls.Add(b);
_panelAlpha.Width = 100;
_panelAlpha.BackColor = Color.Green;
base.FullOpen = true;
}
private void OnBtnClick(object sender, EventArgs e)
{
MessageBox.Show("Button was clicked");
base.Color = Color.Red;
}
//查找句柄为hWnd的窗口内的控件,并把第一个类名为"Button"的空件的名字修改
public void FixButtonText(IntPtr hWnd)
{
//如果句柄hWnd为空,则取消操作
if (hWnd == IntPtr.Zero) return;
try
{
//API函数GetWindow的参数:查找下一个同级句柄
int GW_HWNDNEXT = 2;
//API函数GetWindow的参数:查找子级句柄的第一个句柄
int GW_CHILD = 5;
//获取hWnd的第一个子控件句柄
IntPtr pWnd = GetWindow(hWnd, GW_CHILD);
while (pWnd != IntPtr.Zero)
{
char[] className = new char[255];
int classNamelength = GetClassName(pWnd, className, 255);
string classNameStr = new string(className, 0, classNamelength); //获取句柄对应的类名
//如果是Button类,则修改文字
if (classNameStr == "Button")
{
SetWindowText(pWnd, ("Febotion.com\0").ToCharArray());
//标记修改完成
ButtonTextChanged = true;
break;
}
else
{
//不是Button类,则继续寻找下一个控件句柄
pWnd = GetWindow(pWnd, GW_HWNDNEXT);
}
}
}
catch { }
}
//重载ColorDialog的消息钩子
protected override IntPtr HookProc(IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam)
{
// return if invalid window
if (hWnd == IntPtr.Zero)
return IntPtr.Zero;
//如果消息句柄不为0,且修改完成标记不为true,则执行修改函数
if (hWnd != IntPtr.Zero && !ButtonTextChanged)
{
FixButtonText(hWnd);
}
switch (msg)
{
case WindowMessage.InitDialog:
{
POINT topLeft = new POINT();
POINT bottomRight = new POINT();
//设定当前需要扩展的面板的母面板为HWND句柄
NativeMethods.SetParent(_panelAlpha.Handle, hWnd);
RECT rc = new RECT();
//根据母面板的句柄获取当前母面板的大小的矩形
NativeMethods.GetWindowRect(hWnd, ref rc);
//设置空间的位置
topLeft.X = rc.right;
topLeft.Y = rc.top;
NativeMethods.ScreenToClient(hWnd, ref topLeft);
bottomRight.X = rc.right;
bottomRight.Y = rc.bottom;
NativeMethods.ScreenToClient(hWnd, ref bottomRight);
//设置子面板的高度
_panelAlpha.Height = rc.bottom - rc.top;
Rectangle rcClient = _panelAlpha.ClientRectangle;
//改变面板的大小
NativeMethods.MoveWindow(hWnd, rc.left, rc.top, bottomRight.X + rcClient.Width+11 , bottomRight.Y + 35 , true);
return IntPtr.Zero;
}
// WM_SIZE - the OpenFileDialog has been resized, so we'll resize the content and user-supplied
// panel to fit nicely
case WindowMessage.Size:
{
PlaceCustomControls(hWnd);
return IntPtr.Zero;
//break;
}
}
return base.HookProc(hWnd, msg, wparam, lparam);
}
// <summary>
/// Layout the content of the ChooseColorDialog, according to the overall size of the dialog
/// </summary>
/// <param name="hWnd">handle of window that received the WM_SIZE message</param>
private void PlaceCustomControls( IntPtr hWnd )
{
IntPtr hWndParent = NativeMethods.GetParent( hWnd );
NativeMethods.SetParent( _panelAlpha.Handle, hWnd);
RECT rc = new RECT();
NativeMethods.GetWindowRect( hWnd, ref rc );
POINT topLeft;
topLeft.X = rc.right;
topLeft.Y = rc.top;
NativeMethods.ScreenToClient( hWnd, ref topLeft );
POINT bottomRight;
bottomRight.X = rc.right;
bottomRight.Y = rc.bottom;
NativeMethods.ScreenToClient( hWnd, ref bottomRight );
Rectangle rcClient = _panelAlpha.ClientRectangle;// .ClientRectangle();
NativeMethods.MoveWindow(_panelAlpha.Handle, rc.right - rc.left - rcClient.Width - 10, 0, rcClient.Width, rcClient.Height, true);
}
}
}
转自:http://zhouweigang01.blog.163.com/blog/static/934090720071030154147/