gpt4 book ai didi

c# - CreateWindowEx 和 RegisterClass C#

转载 作者:行者123 更新时间:2023-11-30 19:25:08 26 4
gpt4 key购买 nike

我想创建一个新类,然后显示一个包含指定类的窗口。我为此编写了以下代码:

    namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
[DllImport("user32.dll")]
static extern bool UpdateWindow(IntPtr hWnd);

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll", SetLastError = true, EntryPoint = "CreateWindowEx")]
public static extern IntPtr CreateWindowEx(
int dwExStyle,
string lpClassName,
string lpWindowName,
int dwStyle,
int x,
int y,
int nWidth,
int nHeight,
IntPtr hWndParent,
IntPtr hMenu,
IntPtr hInstance,
IntPtr lpParam);
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
static extern System.UInt16 RegisterClassW(
[System.Runtime.InteropServices.In] ref WNDCLASSEX lpWndClass
);
struct WNDCLASSEX
{
[MarshalAs(UnmanagedType.U4)]
public int cbSize;
[MarshalAs(UnmanagedType.U4)]
public int style;
public IntPtr lpfnWndProc; // not WndProc
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;
}
[DllImport("user32.dll")]
static extern IntPtr DefWindowProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);

public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{


}

private void button1_Click(object sender, EventArgs e)
{
WNDCLASSEX wind_class = new WNDCLASSEX();
wind_class.cbSize = Marshal.SizeOf(typeof(WNDCLASSEX));
wind_class.style = 0x00020000;
wind_class.hbrBackground = (IntPtr) 5;
wind_class.cbClsExtra = 0;
wind_class.cbWndExtra = 0;
wind_class.hInstance = Marshal.GetHINSTANCE(GetType().Module);
wind_class.hIcon = this.Icon.Handle;
wind_class.hCursor = IntPtr.Zero;
wind_class.lpszMenuName = string.Empty;
wind_class.lpszClassName = "MyClass";
wind_class.lpfnWndProc = DefWindowProc(IntPtr.Zero, 0, IntPtr.Zero, IntPtr.Zero);
RegisterClassW(ref wind_class);
IntPtr lolo = CreateWindowEx(0, "MyClass", "MyClass",0,0,0,30,40,IntPtr.Zero,IntPtr.Zero,IntPtr.Zero,IntPtr.Zero);
ShowWindow(lolo, 1);
UpdateWindow(lolo);
}
}
}

但它无法正常工作。它不显示窗口。当我用我的类名用 Spy++ 搜索时,它找不到任何结果..

我在网络上搜索并在我的代码中做了一些编辑,但它们没有用。

我的问题在哪里!?

问候。

最佳答案

普通的 Win32 与 Win32 C 相比毫无乐趣,与 .NET 相比也不那么有趣。但无论如何,它可能在极少数情况下有用。这里有一个 C# 类,它应该做你想做的事。首先,对您的软件进行一般性说明。在 Win32 中,您应该始终检查系统调用的返回码,如果出现错误,请调用 GetLastError() 以获取有关失败的更详细信息。如果您检查了 RegisterClass 函数的结果但它失败了,您就会知道如果不修复该函数就无法继续。

以下是一个可以用作进一步研究模板的类,它应该可以成功注册并创建一个可调整大小的窗口。此外,一些简单的操作(如双击)在自定义窗口过程中进行处理。对于代码的某些部分,请转到 this该网站是我在网络上发现的少数几个展示有效内容的网站之一。

CreateWindowEx 很棘手,因为您不能将字符串作为类名,而是 RegisterClassEx 的结果。使用的常量主要在 C 头文件 winuser.h 中找到。为了能够用这种方法做一些有用的事情,主要的绘画必须“手工”完成,通过适本地操作设备上下文是一项繁琐而乏味的工作。当然,这一切都不会出现在下面的例子中。可以调用类的“创建”方法,例如从 Windows 窗体按钮单击。命名空间名称当然是任意选择的。 WinForm 项目是 x86 32 位、.NET 4.0。

玩得开心!

namespace Win32FromForms
{
delegate IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);

class Win32Window
{
const UInt32 WS_OVERLAPPEDWINDOW = 0xcf0000;
const UInt32 WS_VISIBLE = 0x10000000;
const UInt32 CS_USEDEFAULT = 0x80000000;
const UInt32 CS_DBLCLKS = 8;
const UInt32 CS_VREDRAW = 1;
const UInt32 CS_HREDRAW = 2;
const UInt32 COLOR_WINDOW = 5;
const UInt32 COLOR_BACKGROUND = 1;
const UInt32 IDC_CROSS = 32515;
const UInt32 WM_DESTROY = 2;
const UInt32 WM_PAINT = 0x0f;
const UInt32 WM_LBUTTONUP = 0x0202;
const UInt32 WM_LBUTTONDBLCLK = 0x0203;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct WNDCLASSEX
{
[MarshalAs(UnmanagedType.U4)]
public int cbSize;
[MarshalAs(UnmanagedType.U4)]
public int 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 WndProc delegWndProc = myWndProc;

[DllImport("user32.dll")]
static extern bool UpdateWindow(IntPtr hWnd);

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
static extern bool DestroyWindow(IntPtr hWnd);


[DllImport("user32.dll", SetLastError = true, EntryPoint = "CreateWindowEx")]
public static extern IntPtr CreateWindowEx(
int dwExStyle,
UInt16 regResult,
//string lpClassName,
string lpWindowName,
UInt32 dwStyle,
int x,
int y,
int nWidth,
int nHeight,
IntPtr hWndParent,
IntPtr hMenu,
IntPtr hInstance,
IntPtr lpParam);

[DllImport("user32.dll", SetLastError = true, EntryPoint = "RegisterClassEx")]
static extern System.UInt16 RegisterClassEx([In] ref WNDCLASSEX lpWndClass);

[DllImport("kernel32.dll")]
static extern uint GetLastError();

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

[DllImport("user32.dll")]
static extern void PostQuitMessage(int nExitCode);

//[DllImport("user32.dll")]
//static extern sbyte GetMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin,
// uint wMsgFilterMax);

[DllImport("user32.dll")]
static extern IntPtr LoadCursor(IntPtr hInstance, int lpCursorName);

[DllImport("user32.dll")]
static extern bool TranslateMessage([In] ref MSG lpMsg);

[DllImport("user32.dll")]
static extern IntPtr DispatchMessage([In] ref MSG lpmsg);


internal bool create()
{
WNDCLASSEX wind_class = new WNDCLASSEX();
wind_class.cbSize = Marshal.SizeOf(typeof(WNDCLASSEX));
wind_class.style = (int)(CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ) ; //Doubleclicks are active
wind_class.hbrBackground = (IntPtr) COLOR_BACKGROUND +1 ; //Black background, +1 is necessary
wind_class.cbClsExtra = 0;
wind_class.cbWndExtra = 0;
wind_class.hInstance = Marshal.GetHINSTANCE(this.GetType().Module); ;// alternative: Process.GetCurrentProcess().Handle;
wind_class.hIcon = IntPtr.Zero;
wind_class.hCursor = LoadCursor(IntPtr.Zero, (int)IDC_CROSS);// Crosshair cursor;
wind_class.lpszMenuName = null;
wind_class.lpszClassName = "myClass";
wind_class.lpfnWndProc = Marshal.GetFunctionPointerForDelegate(delegWndProc);
wind_class.hIconSm = IntPtr.Zero;
ushort regResult = RegisterClassEx(ref wind_class);

if (regResult == 0)
{
uint error = GetLastError();
return false;
}
string wndClass = wind_class.lpszClassName;

//The next line did NOT work with me! When searching the web, the reason seems to be unclear!
//It resulted in a zero hWnd, but GetLastError resulted in zero (i.e. no error) as well !!??)
//IntPtr hWnd = CreateWindowEx(0, wind_class.lpszClassName, "MyWnd", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 30, 40, IntPtr.Zero, IntPtr.Zero, wind_class.hInstance, IntPtr.Zero);

//This version worked and resulted in a non-zero hWnd
IntPtr hWnd = CreateWindowEx(0, regResult, "Hello Win32", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 300, 400, IntPtr.Zero, IntPtr.Zero, wind_class.hInstance, IntPtr.Zero);

if (hWnd == ((IntPtr)0))
{
uint error = GetLastError();
return false;
}
ShowWindow(hWnd, 1);
UpdateWindow(hWnd);
return true;

//The explicit message pump is not necessary, messages are obviously dispatched by the framework.
//However, if the while loop is implemented, the functions are called... Windows mysteries...
//MSG msg;
//while (GetMessage(out msg, IntPtr.Zero, 0, 0) != 0)
//{
// TranslateMessage(ref msg);
// DispatchMessage(ref msg);
//}
}

private static IntPtr myWndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
switch (msg)
{
// All GUI painting must be done here
case WM_PAINT:
break;

case WM_LBUTTONDBLCLK :
MessageBox.Show("Doubleclick");
break;

case WM_DESTROY:
DestroyWindow(hWnd);

//If you want to shutdown the application, call the next function instead of DestroyWindow
//PostQuitMessage(0);
break;

default:
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
}
}

关于c# - CreateWindowEx 和 RegisterClass C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30986829/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com