.NET CF C# 调用颜色选择对话框
一:函数原型:
返回值:
如果点了选择框的OK按钮,则返回值为非0. CHOOSECOLOR结构的rgbResult返回用户选择的颜色的RGB值。
如果用户取消或关闭选择框或出现错误,返回值为0。
二:调用参数
这里需要提到ChooseColor 函数的参数CHOOSECOLOR ,原型如下:
DWORD lStructSize;
HWND hwndOwner;
HINSTANCE hInstance;
COLORREF rgbResult;
COLORREF* lpCustColors;
DWORD Flags;
LPARAM lCustData;
LPCCHOOKPROC lpfnHook;
LPCTSTR lpTemplateName;
} CHOOSECOLOR, *LPCHOOSECOLOR;
// P/Invoke
[DllImport("commdlg.dll", EntryPoint = "ChooseColor")]
public static extern bool CreateColorDialog(CHOOSECOLOR chooseColor);
最初在设置这些参数的时候可真是费了一番周折。在用C++进行开发的时候,这个参数还是很好设置的,可以参考http://blog.csdn.net/wellwelcome/archive/2007/04/17/1567767.aspx,可是在.NET CF C#下转换就不是那么简单了,颇费一番周折才搞定,如下:
public class CHOOSECOLOR
{
private int lStructSize;
internal IntPtr hwndOwner; // 依托窗口
private IntPtr hInstance;
internal int rgbResult; // 通过该值获得选择的颜色值
internal IntPtr lpCustColors; // 用户自己定义的颜色,也就是现实在颜色框下方的两排
internal uint Flags; // 选择框的类型
private int lCustData;
private IntPtr lpfnHook;
private IntPtr lpTemplateName;
public CHOOSECOLOR()
{
this.lStructSize = Marshal.SizeOf(this);
this.hwndOwner = IntPtr.Zero;
this.hInstance = IntPtr.Zero;
this.rgbResult = 0xffffff;
this.lpCustColors = IntPtr.Zero;
this.Flags = 0;
this.lCustData = 0;
this.lpfnHook = IntPtr.Zero;
this.lpTemplateName = IntPtr.Zero;
}
}
[Flags]
public enum ColorFlags : uint
{
AnyColor = 0x100,
FullOpen = 2,
PreventFullOpen = 4,
RgbInit = 1,
SolidColor = 0x80
}
其实最主要只要关心四个参数hwndOwner, rgbResult, lpCustColors, Flags。上面的代码已经做了详细解释。
这里要特别说明一按下lpCustColors参数的设置,MSDN上说要必须要给它分配一个数组大小为16的DWORD(C#中uint, 不过此处指定为int)型静态数组,然后把该指针赋值给它。“静态”,我用红字标识了是说明它的全局固定性,因此这里就不得不提到GCHandle类型了。
以下为MSDN上的内容:
-------------------
GCHandle:
提供从非托管内存访问托管对象的方法。
GCHandle 类与 GCHandleType 枚举结合使用以创建对应于任何托管对象的句柄。此句柄可为以下四种类型之一:Weak、WeakTrackResurrection、Normal 或 Pinned。分配了句柄以后,在非托管客户端保留唯一的引用时,可以使用 GCHandle 防止垃圾回收器回收托管对象。如果没有这样的句柄,则在该对象代表非托管客户端完成工作以前,有可能被垃圾回收器回收。
还可以使用 GCHandle 创建一个固定对象,该对象返回一个内存地址,并防止垃圾回收器在内存中移动该对象。
-------------------
看完上面的描述相信您也就知道为什么我要提到静态和GCHandle了,也相信您也知道该怎么做了。
还有,因为GCHandle的静态全局性,所以在动态申请并且使用完该对象后一定要记得Free掉,否则那就是大罪过了。
// Do something
// 记得一定要释放!
custHandle.Free();
// 设置依托窗口
chsColor.hwndOwner = ColorDialog.GetActiveWindow();
// 设置Dialog类型
chsColor.Flags = ColorDialog.ColorFlags.AnyColor;
// 定制的颜色值(当然您也可以通过custHandle[index] = Color.FromArgb的方式对每个对象赋值)
chsColor.lpCustColors = custHandle.AddrOfPinnedObject();
// 这里有一点要说明, 如果点击'OK',则进入if内;否则如果点击'X'则不会进入if语句内
if (ColorDialog.CreateColorDialog(chsColor))
{
// 获得颜色值
this.BackColor = FromWin32(chsColor.rgbResult);
string strShow = string.Format("0x{0:X8}", chsColor.rgbResult);
System.Diagnostics.Debug.WriteLine(strShow);
this.Invalidate();
}
-------------------
图示:
--------------------------------------------------
李森 – listen |
声明: Announce: |
posted on 2009-09-10 10:29 listenlisten 阅读(3492) 评论(5) 编辑 收藏 举报