在Compact Framework中创建参数

本文关键字:创建 参数 Framework Compact | 更新日期: 2023-09-27 17:59:12

我正在使用。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)?

在Compact Framework中创建参数

这些样式在创建窗口类时应用,据我所知,在紧凑的框架上无法更改。除了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);
    }
}