Compact Framework中的CreateParams

时间:2015-06-23 09:18:14

标签: c# compact-framework

我正在使用.NET Compact Framework并希望子类化PictureBox控件(在这种情况下,从PictureBox控件的特定实例中删除CS_DBLCLKS样式)。下面的代码适用于.NET标准,但不适用于Compact Framework:

using System;
using System.Windows.Forms;

namespace NoDblClick
{
    public partial class NoDblClickPicControl : PictureBox
    {
        private const int CS_DBLCLKS = 0x008;
        public NoDblClickPicControl()
        {
        }

        protected override CreateParams CreateParams
        {
            get
            {
                // No compile, missing directive or assembly directive
                CreateParams cp = base.CreateParams;
                cp.ClassStyle &= ~CS_DBLCLKS;
                return cp;
            }
        }
    }
}

如何让它在Compact Framework上运行?也许我可以PInvoke功能(来自coredll.dll说)?

1 个答案:

答案 0 :(得分:2)

这些样式在创建窗口类时应用,据我所知,无法在紧凑框架上更改。除了CreateParams之外,完整的框架允许重新创建窗口句柄,这在紧凑的框架上也是不可能的。

您可以手动过滤发送到控件的消息,并将双击消息转换回鼠标按下消息:

public partial class NoDblClickPicControl : PictureBox
{
    private const int WM_LBUTTONDBLCLK = 0x0203;
    private const int WM_LBUTTONDOWN = 0x0201;
    private const int GWL_WNDPROC = -4;

    [DllImport("coredll.dll", SetLastError = true)]
    private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr newWndProc);
    [DllImport("coredll.dll", SetLastError = true)]
    private static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);

    private delegate IntPtr WndProcDelegate(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);

    private IntPtr prevWndProc;
    private WndProcDelegate @delegate;

    protected override void OnHandleCreated(EventArgs e)
    {
        base.OnHandleCreated(e);
        @delegate = new WndProcDelegate(MyWndProc);
        prevWndProc = SetWindowLong(Handle, GWL_WNDPROC, Marshal.GetFunctionPointerForDelegate(@delegate));
    }

    protected override void OnHandleDestroyed(EventArgs e)
    {
        base.OnHandleDestroyed(e);
        SetWindowLong(Handle, GWL_WNDPROC, prevWndProc);
    }

    private IntPtr MyWndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
    {
        if (msg == WM_LBUTTONDBLCLK)
        {
            msg = WM_LBUTTONDOWN;
        }

        return CallWindowProc(prevWndProc, hWnd, msg, wParam, lParam);
    }
}