Страницы

Поиск по вопросам

вторник, 24 декабря 2019 г.

WinAPI перетаскивание формы, предупреждение CA1901, CA1060 NativeMethods

#c_sharp #winforms #winapi


Реализовал перетаскивание формы за тело при помощи WinAPI:

public partial class FormMain : Form
{
    [DllImport("user32", CharSet = CharSet.Auto)]
    internal extern static bool PostMessage(IntPtr hWnd, uint Msg, uint WParam, uint
LParam);

    [DllImport("user32", CharSet = CharSet.Auto)]
    internal extern static bool ReleaseCapture();

    const uint WM_SYSCOMMAND = 0x0112;
    const uint DOMOVE = 0xF012;
    const uint DOSIZE = 0xF008;

    public FormMain()
    {
        InitializeComponent();
    }


    private void FormMain_MouseDown(object sender, MouseEventArgs e)
    {
        ReleaseCapture();
        PostMessage(this.Handle, WM_SYSCOMMAND, DOMOVE, 0);
    }
}


при анализе кода получил 2 предупреждения: 


Предупреждение  CA1060  Так как метод является методом P/Invoke, 'FormMain.PostMessage(IntPtr,
uint, uint, uint)' должен быть определен в классе с именем NativeMethods, SafeNativeMethods
или UnsafeNativeMethods.


Как правильно реализовать класс NativeMethods ?

Решено, спасибо Uranus

public partial class FormMain : Form
{
    public static class NativeMethods
    {
        [DllImport("user32", CharSet = CharSet.Auto)]
        internal extern static bool PostMessage(IntPtr hWnd, uint Msg, uint WParam,
uint LParam);

        [DllImport("user32", CharSet = CharSet.Auto)]
        internal extern static bool ReleaseCapture();
    }
    const uint WM_SYSCOMMAND = 0x0112;
    const uint DOMOVE = 0xF012;
    const uint DOSIZE = 0xF008;

    public FormMain()
    {
        InitializeComponent();
    }


    private void FormMain_MouseDown(object sender, MouseEventArgs e)
    {
        NativeMethods.ReleaseCapture();
        NativeMethods.PostMessage(this.Handle, WM_SYSCOMMAND, DOMOVE, DOSIZE);
    }
}



Предупреждение  CA1901  Как объявлено в вашем коде, параметр 'WParam' для P/Invoke
'FormMain.PostMessage(IntPtr, uint, uint, uint)' будет иметь размер 4 байт для 64-разрядных
платформ. Это неправильно, поскольку текущее объявление в машинном коде для данного
API указывает, что его размер должен быть 8 байт для 64-разрядных платформ. Обратитесь
к документации MSDN Platform SDK и выясните, какой тип данных следует использовать
вместо 'uint'.


Помогите с устранением CA1901 реализацией констант для UintPtr, спасибо.
Спустя несколько часов, начинаю думать, что ошибка в студии а не в моём коде.


  Предупреждение    CA1901  Как объявлено в вашем коде, параметр 'Msg' для P/Invoke
'FormMain.NativeMethods.PostMessage(IntPtr, UIntPtr, UIntPtr, UIntPtr)' будет иметь
размер 8 байт для 64-разрядных платформ. Это неправильно, поскольку текущее объявление
в машинном коде для данного API указывает, что его размер должен быть 4 байт для 64-разрядных
платформ. Обратитесь к документации MSDN Platform SDK и выясните, какой тип данных
следует использовать вместо 'UIntPtr'.


Это замкнутый круг ? или всё-же есть панацея, по прежнему прошу помочь.
    


Ответы

Ответ 1



Нужно было сделать приведение типов uint к IntPtr. public static class NativeMethods { [DllImport("user32", CharSet = CharSet.Auto)] internal extern static bool PostMessage(IntPtr hWnd, uint Msg, IntPtr WParam, IntPtr LParam); [DllImport("user32", CharSet = CharSet.Auto)] internal extern static bool ReleaseCapture(); } const uint WM_SYSCOMMAND = 0x0112; const uint DOMOVE = 0xF012; const uint DOSIZE = 0xF008; private void FormMain_MouseDown(object sender, MouseEventArgs e) { NativeMethods.ReleaseCapture(); NativeMethods.PostMessage(this.Handle, WM_SYSCOMMAND, (IntPtr)DOMOVE, (IntPtr)0); }

Ответ 2



Просто объявите статический класс с именем NativeMethods и перенесите туда PostMessage и ReleaseCapture заменив internal на public. Согласно описанию в документации, рекомендуется заменить фиксированный тип uint на платформо-зависимый UIntPtr.

Комментариев нет:

Отправить комментарий