C#利用win32API创建窗体
效果图
代码实现


1 using System;
2 using System.Runtime.InteropServices;
3 //using System.Windows.Forms;
4
5 namespace win32API
6 {
7 class Program
8 {
9 public const int COLOR_WINDOW = 5;
10 const uint WS_TABSTOP = 0x00010000;
11 const uint WS_VISIBLE = 0x10000000;
12 const uint WS_CHILD = 0x40000000;
13 const uint BS_DEFPUSHBUTTON = 0x0001;
14 const uint ES_AUTOHSCROLL = 0x0080;
15 const uint WM_COMMAND = 0x0111;
16 const uint BN_CLICKED = 0x0;
17
18 /// <summary>
19 /// 按钮
20 /// </summary>
21 static IntPtr hButton;
22
23 /// <summary>
24 /// 处理窗口消息
25 /// </summary>
26 /// <param name="hWnd">表示接收消息的窗口句柄(handle)。窗口句柄是操作系统分配给每个窗口的唯一标识符,用于识别窗口</param>
27 /// <param name="msg">表示接收到的消息类型。消息是操作系统或其他应用程序发送给窗口的通知或指令。</param>
28 /// <param name="wParam">表示与消息相关的附加信息,通常用于传递消息的参数。它的具体含义取决于接收到的消息类型。</param>
29 /// <param name="lParam">也是用于传递消息的参数,通常与 wParam 一起使用。它的具体含义也取决于接收到的消息类型。</param>
30 /// <returns></returns>
31 public static IntPtr WindowProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
32 {
33 switch (msg)
34 {
35 case 0x0010: // WM_CLOSE
36 NativeMethods.DestroyWindow(hWnd);
37 return IntPtr.Zero;
38 case 0x0002: // WM_DESTROY
39 return IntPtr.Zero;
40 Environment.Exit(0);// 处理按钮点击消息
41 case WM_COMMAND:
42 if (lParam == hButton && NativeMethods.HIWORD(wParam) == BN_CLICKED)
43 {
44 Button_Click(hWnd, wParam, lParam);
45 }
46 return IntPtr.Zero;
47 //默认
48 default:
49 return NativeMethods.DefWindowProc(hWnd, msg, wParam, lParam);
50 }
51 }
52
53 static void Main(string[] args)
54 {
55 NativeMethods.WNDCLASS wc = new NativeMethods.WNDCLASS();
56 wc.lpfnWndProc = WindowProc;
57 wc.lpszClassName = "MyWindowClass";
58 wc.hCursor = NativeMethods.LoadCursor(IntPtr.Zero, 32512); // 加载系统光标
59 wc.hbrBackground = (IntPtr)(COLOR_WINDOW + 1); // 设置背景颜色
60
61 ushort classAtom = NativeMethods.RegisterClass(ref wc);
62 if (classAtom == 0)
63 throw new Exception("Failed to register window class.");
64 //创建窗口
65 IntPtr hWnd = NativeMethods.CreateWindowEx(0, wc.lpszClassName, "Hello, win32API!", 0xCF0000, 100, 100, 800, 600, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
66 if (hWnd == IntPtr.Zero)
67 throw new Exception("Failed to create window.");
68 // 创建按钮
69 hButton = NativeMethods.CreateWindowEx(
70 0,
71 "BUTTON", // 按钮类名
72 "Click Me", // 按钮文本
73 WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // 按钮样式
74 10, // X 坐标
75 10, // Y 坐标
76 100, // 宽度
77 30, // 高度
78 hWnd, // 父窗口句柄
79 IntPtr.Zero,
80 Marshal.GetHINSTANCE(typeof(Program).Module),
81 IntPtr.Zero);
82
83 // 创建文本框
84 IntPtr hTextBox = NativeMethods.CreateWindowEx(
85 0,
86 "EDIT", // 文本框类名
87 "文本框", // 默认文本
88 WS_TABSTOP | WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL, // 文本框样式
89 10, // X 坐标
90 50, // Y 坐标
91 200, // 宽度
92 30, // 高度
93 hWnd, // 父窗口句柄
94 IntPtr.Zero,
95 Marshal.GetHINSTANCE(typeof(Program).Module),
96 IntPtr.Zero);
97 NativeMethods.ShowWindow(hWnd, 1); // 显示窗口
98 NativeMethods.UpdateWindow(hWnd); // 更新窗口
99
100 MSG msg;
101 while (NativeMethods.GetMessage(out msg, IntPtr.Zero, 0, 0))
102 {
103 NativeMethods.TranslateMessage(ref msg);
104 NativeMethods.DispatchMessage(ref msg);
105 }
106 }
107
108 // 处理按钮点击事件
109 private static void Button_Click(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
110 {
111 Console.WriteLine("Button clicked!");
112 //MessageBox.Show("Button clicked!");
113 }
114 }
115
116 [StructLayout(LayoutKind.Sequential)]
117 public struct MSG
118 {
119 public IntPtr hwnd;
120 public uint message;
121 public IntPtr wParam;
122 public IntPtr lParam;
123 public uint time;
124 public POINT pt;
125 }
126
127 [StructLayout(LayoutKind.Sequential)]
128 public struct POINT
129 {
130 public int x;
131 public int y;
132 }
133
134 public class NativeMethods
135 {
136 // 定义提取高16位的方法
137 public static int HIWORD(IntPtr n)
138 {
139 int v = n.ToInt32();
140 return (v >> 16) & 0xffff;
141 }
142 [DllImport("user32.dll", CharSet = CharSet.Unicode)]
143 public static extern IntPtr LoadCursor(IntPtr hInstance, int lpCursorName);
144
145 [DllImport("user32.dll", CharSet = CharSet.Unicode)]
146 public static extern ushort RegisterClass([In] ref WNDCLASS lpWndClass);
147
148 [DllImport("user32.dll", CharSet = CharSet.Unicode)]
149 public static extern bool GetMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax);
150
151 [DllImport("user32.dll", CharSet = CharSet.Unicode)]
152 public static extern IntPtr DispatchMessage([In] ref MSG lpmsg);
153
154 [DllImport("user32.dll", CharSet = CharSet.Unicode)]
155 public static extern bool TranslateMessage([In] ref MSG lpMsg);
156
157
158
159 // 窗口过程函数委托
160 public delegate IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
161
162 // 窗口类结构
163 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
164 public struct WNDCLASS
165 {
166 public uint style;
167 public WndProc lpfnWndProc;
168 public int cbClsExtra;
169 public int cbWndExtra;
170 public IntPtr hInstance;
171 public IntPtr hIcon;
172 public IntPtr hCursor;
173 public IntPtr hbrBackground;
174 public string lpszMenuName;
175 public string lpszClassName;
176 }
177
178 // 调用创建窗口的Win32 API
179 [DllImport("user32.dll", SetLastError = true,CharSet =CharSet.Unicode)]
180 public static extern IntPtr CreateWindowEx(
181 uint dwExStyle, string lpClassName, string lpWindowName, uint dwStyle,
182 int x, int y, int nWidth, int nHeight,
183 IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam);
184
185 [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
186 public static extern bool DestroyWindow(IntPtr hWnd);
187
188 [DllImport("user32.dll", CharSet = CharSet.Unicode)]
189 public static extern IntPtr DefWindowProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);
190
191 [DllImport("user32.dll", CharSet = CharSet.Unicode)]
192 public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
193
194 [DllImport("user32.dll", CharSet = CharSet.Unicode)]
195 public static extern bool UpdateWindow(IntPtr hWnd);
196 }
197
198 }
点击按钮就会事件响应
使用winform的MessageBox类项目设置
点击双击项目设置项目文件,加一个设置项
1 <Project Sdk="Microsoft.NET.Sdk">
2
3 <PropertyGroup>
4 <OutputType>Exe</OutputType>
5 <TargetFramework>net6.0-windows</TargetFramework>
6 <ImplicitUsings>enable</ImplicitUsings>
7 <Nullable>enable</Nullable>
8 <!--添加或修改这一项-->
9 <UseWindowsForms>true</UseWindowsForms>
10 </PropertyGroup>
11
12 </Project>
可以手动更改,也可以在项目上右键属性更改,结果都是反映到项目文件的修改
然后重新生成项目,就会发现以来里面添加了winform框架的引用
在引入名称空间using System.Windows.Forms;
在按钮事件处理中就能显示提示框了
1 // 处理按钮点击事件
2 private static void Button_Click(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
3 {
4 Console.WriteLine("Button clicked!");
5 MessageBox.Show("Button clicked!");
6 }
C#利用win32API创建窗体的更多相关文章
- java中利用JFrame创建窗体 【转】
1. 一个简单的swing public class Test(){ public static void main(String[] args){ JFrame frame = new JFrame ...
- Java中利用JFrame创建窗体
1. 一个简单例子: public class Test(){ public static void main(String[] args){ JFrame frame = new JFrame(); ...
- Qt创建窗体的过程
版权声明 本文为原创作品,请尊重作者的劳动成果.转载必须保持文章完整性,并以超链接形式注明原始作者“ tingsking18”和 主站点地址,方便其他朋友提问和指正. QT源码解析(一) QT创建窗口 ...
- QT源码解析(七)Qt创建窗体的过程,作者“ tingsking18 ”(真正的创建QPushButton是在show()方法中,show()方法又调用了setVisible方法)
前言:分析Qt的代码也有一段时间了,以前在进行QT源码解析的时候总是使用ue,一个函数名在QTDIR/src目录下反复的查找,然后分析函数之间的调用关系,效率实在是太低了,最近总结出一个更简便的方法, ...
- 【翻译】利用Qt设计师窗体在运行时创建用户界面(Creating a user interface from a Qt Designer form at run-time)
利用Qt设计师窗体在运行时创建用户界面 我们利用Calculator窗体例子中创建的窗体(Form)来展示当一个应用(application)已经生成后,是可以在其运行时产生与例子中相同的用户界面. ...
- 利用WPF创建含多种交互特性的无边框窗体
咳咳,标题一口气读下来确实有点累,让我先解释一下.另外文章底部有演示程序的下载. 本文介绍利用WPF创建一个含有以下特性的窗口: 有窗口阴影,比如QQ窗口外围只有几像素的阴影: 支持透明且无边框,为了 ...
- C# 学习笔记(一) Winform利用Assembly反射动态创建窗体
1. 添加Reflection //添加对Reflection程序集引用 using System.Reflection; // 引用窗体创建方法CreateForm,传入参数 private voi ...
- Ext JS 如何动态加载JavaScript创建窗体
JavaScript不需要编译即可运行,这让JavaScript构建的应用程序可以变得很灵活.我们可以根据需要动态从服务器加载JavaScript脚本来创建和控制UI来与用户交互.下面结合Ext JS ...
- Oracle Sales Cloud:管理沙盒(定制化)小细节1——利用公式创建字段并显示在前端页面
Oracle Sales Cloud(Oracle 销售云)是一套基于Oracle云端的CRM管理系统.由于 Oracle 销售云是基于 Oracle 云环境的,它与传统的管理系统相比,显著特点之一便 ...
- 利用Oracle创建表空间和用户
本文仅用于学习交流,商业用途请支持正版!转载请注明:http://www.cnblogs.com/mxbs/p/6217152.html 第一步,创建表空间 以SYS/sys账户和SYSDBA身份登录 ...
随机推荐
- Python 元组完全指南1
元组用于在单个变量中存储多个项目. mytuple = ("apple", "banana", "cherry") 元组是 Python 中 ...
- 保护C#代码的艺术:深入浅出代码混淆技术
摘要 在C#开发中,代码的保护是一个不可忽视的问题.本文深入探讨了几种常用的C#代码混淆工具,帮助开发者理解如何有效地保护代码不被反编译.同时,本文也对混淆技术的优缺点进行了分析,并提供了一些实际使用 ...
- 《C# in depth》第2章C#2.0中的更改(十五)——字面量
一.概念 在计算机编程中,Literals(字面量)是指在程序中直接表示数据的一种方式.它们是在代码中出现的固定值,与变量不同,它们没有名称或标识符. Literals 可以用于各种数据类型,包括整数 ...
- 力扣479(java)-最大回文数乘积(困难)
题目: 给定一个整数 n ,返回 可表示为两个 n 位整数乘积的 最大回文整数 .因为答案可能非常大,所以返回它对 1337 取余 . 示例 1: 输入:n = 2输出:987解释:99 x 91 = ...
- 基于开放共享的自主研发—MaxCompute 持续增强生态与开放性建设
简介: MaxCompute 是阿里巴巴自研的云原生数据仓库,同时也兼容大部分大数据生态系统.一个平台无法实现所有功能和解决所有问题,MaxCompute 需持续增强生态与开放性建设,方能走得更远. ...
- 科学地花钱:基于端智能的在线红包分配方案 (CIKM2020)
简介: 红包是电商平台重要的用户运营手段,本文将介绍1688基于端智能技术开发的two-stage红包分发方案.这一方案持续在线上生效,相较于原有算法有明显提升. 一.前言 本文是作者在1688进行新 ...
- OpenYurt 开箱测评 | 一键让原生 K8s 集群具备边缘计算能力
作者| 郑超 阿里云高级开发工程师 随着物联网技术以及 5G 技术的高速发展,将云计算的能力延伸至边缘设备端,并通过中心进行统一交付.管控,已成为云计算的重要发展趋势.为服务更多开发者把握这一趋势,5 ...
- Serverless JOB | 传统任务新变革
简介: SAE Job 重点解决了用户的效率和成本问题,在兼具传统任务使用体验和功能的同时按需使用,按量计费,做到低门槛任务上云,节省闲置资源成本. Job 作为一种运完即停的负载类型,在企业级开发中 ...
- KubeVela 1.3 发布:开箱即用的可视化应用交付平台,引入插件生态、权限认证、版本化等企业级新特性
简介:得益于 KubeVela 社区上百位开发者的参与和 30 多位核心贡献者的 500 多次代码提交, KubeVela 1.3 版本正式发布.相较于三个月前发布的 v1.2 版本[1],新版本在 ...
- 使用 Arthas 排查 SpringBoot 诡异耗时的 Bug
简介: 公司有个渠道系统,专门对接三方渠道使用,没有什么业务逻辑,主要是转换报文和参数校验之类的工作,起着一个承上启下的作用.最近,在优化接口的响应时间,优化了代码之后,但是时间还是达不到要求:有一个 ...