使用c#创建windows窗口(基于api)

来源:互联网 发布:ff14雅修特拉捏脸数据 编辑:程序博客网 时间:2024/05/16 08:14

看到这个标题,你也许会惊讶:c#也能这样创建?是的,没错,大多数使用API来创建窗口的是c/c++,当然也有其他的语言,但是几乎没有看到使用c#来创建的(不包括.net框架的),因为.net有着非常高效的开发方式,所以大部分人选择了规避。

传统的win32窗口程序入口点是 WinMain 函数,但是我们在使用c#开发程序的时候,无论是控制台还是窗口应用程序,入口点永远是 Main 函数,我们熟悉的 HINSTANCE 这些参数不见了,至于去了哪里不是这篇文章所探究的,没有了 hInstance 这个参数我们是无法创建的,但是.net框架依然能够使用我们平时所创建的窗体跑起来,说明这个参数在Main函数之前被获取到了,我花了点时间查阅了很多资料,在网上找到了解决办法,有 Marshal 这样的一个类,里面有个静态函数 GetHINSTANCE,参数是Module,这样一来似乎找到了解决方案,确实如此,至于 Module 的获取办法更是简单了 typeof(你的类名).Module,障碍清除了,接下来就好办多了,按照正常的创建流程来写,不过你必须得事先声明API函数才行。接下来,笔者带你创建一个窗口程序。

1.创建一个控制台应用程序,修改项目的属性,改为窗口应用程序。

2.在你的 Main 函数里面添加一些代码:

static void Main(string[] args){            Type t = typeof(Program);            Module m = t.Module;            IntPtr hInstance = Marshal.GetHINSTANCE(m); }

记得添加命名空间:

using System.Runtime.InteropServices;using System.Reflection;

接下来是注册窗口类,不过还得先声明好窗口类

struct WNDCLASS     {       public ClassStyle style;       public WNDPROC proc;       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;    }

我们注意到窗口类的第2个字段是个函数地址,那么对应.net的是委托类型,这个WNDPROC声明如下:

public delegate int WNDPROC(IntPtr hwnd,uint uMsg,IntPtr wParam,IntPtr lParam);
然后声明API函数:

[DllImport("user32.dll", EntryPoint = "RegisterClassA")]public static extern IntPtr RegisterClass(ref WNDCLASS cls);
再然后你仅仅只是对这个结构进行填充再注册:

 WNDCLASS cls = new WNDCLASS();            cls.cbClsExtra = 0;            cls.cbWndExtra = 0;            cls.hbrBackground = IntPtr.Zero;            cls.hCursor = IntPtr.Zero;            cls.hIcon = IntPtr.Zero;            cls.hIconSm = IntPtr.Zero;            cls.hInstance = hInstance;            cls.lpszClassName = "DotNet_Window";            cls.lpszMenuName = null;            cls.proc = WindowProc;            cls.style = ClassStyle.CS_VREDRAW|ClassStyle.CS_HREDRAW;           RegisterClass(ref cls);//注册窗口类
...
当然了,代码不是到此结束,因为接下来的代码仅仅只是照搬创建win32窗口的流程,所以笔者不打算继续讲,有需要的可以去下载源码。

源码地址:点击打开链接