尝试创建窗口时得到1407

问题描述 投票:0回答:1

我已经开始学习winAPI,并尝试在c#中使用winAPI创建窗口,但我总是收到1407错误,“找不到窗口类”。我已经为 lpClassNamelpWindowName 编写了 [MarshalAs(UnmanagedType.LPWStr)] 但没有帮助

但是 Window 类注册返回 49856 代码。

这是我的代码:


    [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    static extern ushort RegisterClassEx(ref WNDCLASSEX lpwcx);

    [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    static extern IntPtr CreateWindowExW(
        uint dwExStyle,
        [MarshalAs(UnmanagedType.LPWStr)]
        string lpClassName,
        [MarshalAs(UnmanagedType.LPWStr)]
        string lpWindowName,
        uint dwStyle,
        int x,
        int y,
        int nWidth,
        int nHeight,
        IntPtr hWndParent,
        IntPtr hMenu,
        IntPtr hInstance,
        IntPtr lpParam);

    [DllImport("user32.dll")]
    static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

    [DllImport("user32.dll")]
    static extern IntPtr DefWindowProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern IntPtr GetModuleHandle(string lpModuleName);

    [StructLayout(LayoutKind.Sequential)]
    public struct WNDCLASSEX
    {
        public uint cbSize;
        public uint style;
        public IntPtr lpfnWndProc;
        public int cbClsExtra;
        public int cbWndExtra;
        public IntPtr hInstance;
        public IntPtr hIcon;
        public IntPtr hCursor;
        public IntPtr hbrBackground;
        public string lpszMenuName;
        public string lpszClassName;
        public IntPtr hIconSm;
    }

    private static IntPtr WindowProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
    {
        if (msg == 0x0010)
        {
            Environment.Exit(0);
        }
        return DefWindowProc(hWnd, msg, wParam, lParam);
    }

    static void Main()
    {
        const string CLASS_NAME = "SampleWindowClass";

        IntPtr hInstance = GetModuleHandle(null);

        WNDCLASSEX wc = new WNDCLASSEX
        {
            cbSize = (uint)Marshal.SizeOf(typeof(WNDCLASSEX)),
            style = 0,
            lpfnWndProc = Marshal.GetFunctionPointerForDelegate(new WndProcDelegate(WindowProc)),
            hInstance = hInstance,
            hbrBackground = (IntPtr)1,
            lpszClassName = CLASS_NAME, // Имя класса
            hIconSm = IntPtr.Zero,
            hIcon = IntPtr.Zero,
            hCursor = IntPtr.Zero,
            cbClsExtra = 0,
            cbWndExtra = 0,
            lpszMenuName = null
        };

        ushort classAtom = RegisterClassEx(ref wc);
        if (classAtom == 0)
        {
            int errorCode = Marshal.GetLastWin32Error();
            Console.WriteLine("Class registration error: " + errorCode);
            return;
        }

        IntPtr hwnd = CreateWindowExW(
            0,
            CLASS_NAME,
            "Learn to Program Windows",
            0x00040000,
            100,
            100,
            500,
            500,
            IntPtr.Zero,
            IntPtr.Zero,
            hInstance,
            IntPtr.Zero
        );

        if (hwnd == IntPtr.Zero)
        {
            int errorCode = Marshal.GetLastWin32Error();
            Console.WriteLine("Window creation error: " + errorCode);
            return;
        }

        ShowWindow(hwnd, 1);
    }

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

可能是什么问题?

c# winapi
1个回答
0
投票

由于

WNDCLASSEX.lpszMenuName
WNDCLASSEX.lpszClassName
是结构体的成员,因此结构体中字符串的编组规则适用于此处。由于您没有为结构指定任何此类规则,因此应用默认规则。来自文档https://learn.microsoft.com/en-us/dotnet/standard/native-interop/customize-struct-marshalling#customizing-string-field-marshalling

默认情况下,.NET 将字符串编组为指向以 null 结尾的字符串的指针。编码取决于 System.Runtime.InteropServices.StructLayoutAttribute 中的 StructLayoutAttribute.CharSet 字段的值。 如果未指定属性,则编码默认为 ANSI 编码。

因此,基本上 WNDCLASSEX 结构中的字符串被编组为 ANSI 字符串。但是您调用

RegisterClassEx
函数的 Unicode 版本,该函数需要宽/Unicode 字符串。轰隆隆!

将 WNDCLASSEX [StructLayout] 属性的

CharSet
参数设置为 Unicode 以解决代码中的此特定错误。我不知道您的代码中是否还潜藏着其他问题,但是这个问题对我来说相对容易发现......

© www.soinside.com 2019 - 2024. All rights reserved.