Repository navigation
Expand file tree
/
Copy pathc-sharp-create-unregular-window.html
More file actions
490 lines (390 loc) · 21.7 KB
/
Copy pathc-sharp-create-unregular-window.html
File metadata and controls
490 lines (390 loc) · 21.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
<!DOCTYPE html>
<html>
<head>
<!-- [[! Document Settings ]] -->
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!-- [[! Page Meta ]] -->
<title>C#创建不规则窗体(控件)</title>
<meta name="description" content="与机器,人,神共舞 - 编程,读书,思考,旅行,与机器对话,与人交谈,对神发问,探索,体验人生美丽的风景" />
<meta name="HandheldFriendly" content="True" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="shortcut icon" href="/assets/images/favicon.ico" >
<!-- [[! Styles'n'Scripts ]] -->
<link rel="stylesheet" type="text/css" href="/assets/css/screen.css" />
<link rel="stylesheet" type="text/css"
href="//fonts.googleapis.com/css?family=Merriweather:300,700,700italic,300italic|Open+Sans:700,400" />
<link rel="stylesheet" type="text/css" href="/assets/css/syntax.css" />
<!-- [[! Ghost outputs important style and meta data with this tag ]] -->
<link rel="canonical" href="/" />
<meta name="referrer" content="origin" />
<link rel="next" href="/page2/" />
<meta property="og:site_name" content="与机器,人,神共舞" />
<meta property="og:type" content="website" />
<meta property="og:title" content="与机器,人,神共舞" />
<meta property="og:description" content="编程,读书,思考,旅行,与机器对话,与人交谈,对神发问,探索,体验人生美丽的风景" />
<meta property="og:url" content="/" />
<meta property="og:image" content="/assets/images/cover1.jpg" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="与机器,人,神共舞" />
<meta name="twitter:description" content="编程,读书,思考,旅行,与机器对话,与人交谈,对神发问,探索,体验人生美丽的风景" />
<meta name="twitter:url" content="/" />
<meta name="twitter:image:src" content="/assets/images/cover1.jpg" />
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "Website",
"publisher": "Tao's Page",
"url": "/",
"image": "/assets/images/cover1.jpg",
"description": "编程,读书,思考,旅行,与机器对话,与人交谈,对神发问,探索,体验人生美丽的风景"
}
</script>
<meta name="generator" content="Jekyll 3.0.0" />
<link rel="alternate" type="application/rss+xml" title="与机器,人,神共舞" href="/rss.xml" />
</head>
<body class="home-template nav-closed">
<div class="nav">
<h3 class="nav-title">Menu</h3>
<a href="#" class="nav-close">
<span class="hidden">Close</span>
</a>
<ul>
<li class="nav-home " role="presentation"><a href="/">Home</a></li>
<li class="nav-about " role="presentation"><a href="/about.html">About</a></li>
<li class="nav-fables " role="presentation"><a href="/tag/machine/">Machine</a></li>
<li class="nav-speeches " role="presentation"><a href="/tag/human/">Human</a></li>
<li class="nav-fiction " role="presentation"><a href="/tag/god/">God</a></li>
<li class="nav-author " role="presentation"><a href="/author/hetao/">Author</a></li>
</ul>
<a class="subscribe-button icon-feed" href="/vocab.html">Apps</a>
</div>
<span class="nav-cover"></span>
<div class="site-wrapper">
<!-- [[! Everything else gets inserted here ]] -->
<!-- default -->
<!-- The comment above "< default" means - insert everything in this file into -->
<!-- the [body] of the default.hbs template, which contains our header/footer. -->
<!-- Everything inside the #post tags pulls data from the post -->
<!-- #post -->
<header class="main-header post-head no-cover">
<nav class="main-nav clearfix">
</nav>
</header>
<main class="content" role="main">
<article class="post tag-machine">
<header class="post-header">
<h1 class="post-title">C#创建不规则窗体(控件)</h1>
<section class="post-meta">
<!-- <a href='/'>Tao He</a> -->
<time class="post-date" datetime="2012-09-05">05 Sep 2012</time>
<!-- [[tags prefix=" on "]] -->
on
<a href='/tag/machine'>Machine</a>
</section>
</header>
<section class="post-content">
<p>创建不规则窗体和控件这个过程包含了大量的图形编程工作,不同的计算机因内存和显卡的不同可能会导致最终的效果有所不同 。创建不规则窗体具体步骤:</p>
<h4 id="先创建一个具有不规则形状的位图文件">先创建一个具有不规则形状的位图文件</h4>
<ol>
<li>
<p>用任何画图程序创建不规则形状的位图。</p>
</li>
<li>
<p>用一种颜色画出一个不规则的区域作为程序的窗体,并用另一种颜色画出该位图的背景。</p>
</li>
</ol>
<p>3.保存位图文件。</p>
<h4 id="下面创建窗体在vsnet中创建一个新的工程">下面创建窗体:在VS.net中创建一个新的工程</h4>
<ul>
<li>
<p>首先,设置窗体的背景从而建立窗体形状。</p>
<ul>
<li>
<p>将FormBorderStyle属性设置为None。</p>
</li>
<li>
<p>将BackgroundImage属性设置为你创建的图片文件。</p>
</li>
<li>
<p>将TransparencyKey属性设置为图片文件的背景颜色值。该属性使得位图的背景部分不可见,从而窗体就呈现出一个不规则形。</p>
</li>
<li>
<p>保存工程,按Ctrl+F5可以运行此程序。</p>
</li>
</ul>
</li>
</ul>
<h4 id="实现关闭功能以及移动窗体的功能">实现关闭功能以及移动窗体的功能</h4>
<ul>
<li>
<p>实现窗体的关闭及移动:</p>
<ul>
<li>
<p>往窗体上拖放一个按钮控件。</p>
</li>
<li>
<p>在属性对话框中,将该控件的Text属性设置为”关闭”。</p>
</li>
<li>
<p>双击按钮添加一个Click事件处理函数,添加如下代码:</p>
</li>
</ul>
</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>private void button1_Click(object sender, System.EventArgs e)
{
this.Close();
}
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>* 添加以下代码来创建一个Point对象,该对象(作为一个变量)决定在什么情况下移动窗体。
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>private Point mouse_offset;
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>* 创建窗体的MouseDown事件的事件处理函数。为该事件添加代码后,用户就可以在任何位置移动窗体了。代码如下
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
mouse_offset = new Point(-e.X, -e.Y);
}
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>* 创建窗体的MouseMove事件的事件处理函数。当鼠标左键被按下,同时鼠标被移动时,窗体的Location属性就被设置为新的位置了,这样窗体就被用户拖动了。 ``` private void Form1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) {
if (e.Button == MouseButtons.Left)
{
Point mousePos = Control.MousePosition;
mousePos.Offset(mouse_offset.X, mouse_offset.Y);
Location = mousePos;
} } ```
</code></pre></div></div>
<h4 id="利用windows-api重绘窗体">利用Windows API重绘窗体</h4>
<p>所用到的函数:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> [ DllImportAttribute("gdi32.dll" )]
public static extern IntPtr CreateRoundRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, int nWidthEllipse, int nHeightEllipse);
[ DllImportAttribute("gdi32.dll" )]
static extern int CombineRgn( IntPtr hrgnDest, IntPtr hrgnSrc1, IntPtr hrgnSrc2, int fnCombineMode);
[ DllImportAttribute("gdi32.dll" )]
static extern int CombineRgn( IntPtr hrgnSrc1, IntPtr hrgnSrc2, int fnCombineMode);
[ DllImportAttribute("user32.dll" )]
public static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw);
</code></pre></div></div>
<p>在窗体的构造函数中添加如下定制代码:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> IntPtr smallRegion = CreateRoundRectRgn(6, 22, 149, 78, 20, 20);
IntPtr largeRegion = CreateRoundRectRgn(3, 3, this .Width - 18, this.Height - 1, 20, 20);
IntPtr destRegion = CreateRoundRectRgn(0, 0, this .Width, this.Height, 10, 10);
int i = CombineRgn(destRegion, largeRegion, smallRegion, 2);
SetWindowRgn( this.Handle, destRegion, true);
</code></pre></div></div>
<h4 id="创建不规则控件实现方法">创建不规则控件实现方法</h4>
<p>在窗体上画一个自定义形状的控件时,需要精确的告知窗体在什么位置以及如何画该控件。GraphicsPath类代表了一系列用来画图的直线和曲线。首先,指定一个GraphicsPath类的对象并告知它要画什么图形。然后,将控件的Region属性设置为上述GraphicsPath类的对象。这样就可以创建任何自定义形状的控件了。</p>
<h5 id="创建不规则控件具体步骤">创建不规则控件具体步骤</h5>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>1. 创建一个GraphicsPath类的实例对象。
2. 指定好该对象的各项细节(如大小、形状等等)。
3. 将控件的Region属性设置为上面建立的GraphicsPath类的实例对象。
</code></pre></div></div>
<h5 id="下面举一个例子创建一个像文本的按钮控件">下面举一个例子:创建一个像文本的按钮控件:</h5>
<ul>
<li>
<p>拖放一个按钮控件到窗体上。</p>
</li>
<li>
<p>在属性对话框中进行如下设置:</p>
<ul>
<li>
<p>将Name属性设置为CustomButton。</p>
</li>
<li>
<p>将BackColor属性设置为一个和窗体背景颜色不同的颜色值。</p>
</li>
<li>
<p>将其Text属性设置为空字符串。</p>
</li>
</ul>
</li>
<li>
<p>添加窗体的Paint事件的事件处理函数。</p>
</li>
<li>
<p>添加以下代码,用GraphicsPath类的实例对象来画控件。下面的代码以一串字符串的形式画该按钮控件,同时,程序还设置了字符串的字体、大小、风格等属性。字符串被赋给GraphicsPath类的实例对象。然后,该实例对象就被设置为按钮控件的Region属性。这样一个自定义形状的控件就完成了。</p>
</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>private void CustomButton_Paint(object sender,
System.Windows.Forms.PaintEventArgs e)
{
//初始化一个GraphicsPath类的对象
System.Drawing.Drawing2D.GraphicsPath myGraphicsPath = new
System.Drawing.Drawing2D.GraphicsPath();
//确定一个字符串,该字符串就是控件的形状
string stringText = Click Me!;
//确定字符串的字体
FontFamily family = new FontFamily(Arial);
//确定字符串的风格
int fontStyle = (int)FontStyle.Bold;
//确定字符串的高度
int emSize = 35;
//确定字符串的起始位置,它是从控件开始计算而非窗体
PointF origin = new PointF(0, 0);
//一个StringFormat对象来确定字符串的字间距以及对齐方式
StringFormat format = new StringFormat(StringFormat.GenericDefault);
//用AddString方法创建字符串
myGraphicsPath.AddString(stringText, family, fontStyle, emSize, origin, format);
//将控件的Region属性设置为上面创建的GraphicsPath对象
CustomButton.Region = new Region(myGraphicsPath);
}
</code></pre></div></div>
<ul>
<li>创建按钮的Click事件的事件处理函数。添加该处理函数来改变控件的背景颜色,从而证实控件原来的那些功能没有被削减。</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>private void CustomButton_Click(object sender, System.EventArgs e)
{
CustomButton.BackColor = Color.BlanchedAlmond;
}
</code></pre></div></div>
<h5 id="进一步优化效果">进一步优化效果</h5>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>以上我们运用了GraphicsPath类的实例对象来创建了自定义形状的一个按钮控件。不过我们用的是文本字符串形式的一个形状,是否可以用三角形或是圆形等形状呢?答案是肯定的。.Net Framework能为我们提供一些预先定义好了的形状以供我们在程序中使用。通过运用这些,你可以创造出几乎任意形状的控件,你还可以把它们结合起来使用以发挥更大的功能。 下面的实例就运用了四个椭圆,当它们被运用到控件上后,看起来就像人的眼睛,很有意思吧。
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>private void button1_Paint(object sender,
System.Windows.Forms.PaintEventArgs e)
{
System.Drawing.Drawing2D.GraphicsPath myGraphicsPath = new
System.Drawing.Drawing2D.GraphicsPath();
myGraphicsPath.AddEllipse(new Rectangle(0, 0, 125, 125));
myGraphicsPath.AddEllipse(new Rectangle(75, 75, 20, 20));
myGraphicsPath.AddEllipse(new Rectangle(120, 0, 125, 125));
myGraphicsPath.AddEllipse(new Rectangle(145, 75, 20, 20));
//改变按钮的背景颜色使之能被容易辨认
button1.BackColor = Color.Chartreuse;
button1.Size = new System.Drawing.Size(256, 256);
button1.Region = new Region(myGraphicsPath);
}
</code></pre></div></div>
<p>最后,你还得搞清楚窗体类是从System.Windows.Forms.Control类继承而来的。也就是说,由窗体设计器提供给你的窗体最终还是一个控件。因此,你能用位图文件创建一个不规则的窗体,你还能用GraphicsPath类对象来像创建自定义形状的控件那样创建不规则的窗体。有兴趣的读者不妨用此方法一试效果。 最后再举一个更好的例子:一个和微软的Windows Media Player 7的界面差不多的界面。创建步骤如下:</p>
<p>1.将某种颜色设置为窗体的背景颜色,然后将窗体的TransparenceKey属性设置为那种颜色,同时将窗体的FormBorderStyle属性设置为None。</p>
<p>2.重载<code class="language-plaintext highlighter-rouge">Form_Paint()</code>函数:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>protected override void OnPaint(PaintEventArgs e)
</code></pre></div></div>
<p>或是</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>this.Paint += new System.Windows.Form.PaintEventHandler(Form_Paint)。
</code></pre></div></div>
<p>3.程序的主体部分的函数如下:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>private void Form_Paint(object sender, PaintEventArgs e) {
Graphics g = e.Graphics;
Rectangle mainRect = new Rectangle(0, 0, 695, 278);
Region mainRegion = new Region(mainRect);
e.Graphics.SetClip(mainRegion, CombineMode.Replace);
Point point1 = new Point(0, 32);
Point point2 = new Point(9, 20);
Point point3 = new Point(21, 13);
Point point4 = new Point(34, 9);
// 创建一个以点为元素的数组
Point[] curvePoints = { point1, point2, point3, point4 };
// 创建一个GraphicsPath对象并添加一条曲线
GraphicsPath myPath = new GraphicsPath();
myPath.AddCurve(curvePoints, 0, 3, 0.8f);
myPath.AddLine(36, 9, 378, 9);
point1.X=378;point1.Y=9;
point2.X=387;point2.Y=5;
point3.X=394;point3.Y=0;
Point[] curvePoints2 = { point1, point2, point3 };
myPath.AddCurve(curvePoints2, 0, 2, 0.8f);
myPath.AddLine(394, 0, 0, 0);
Region ExcludeRegion3 = new Region(myPath);
e.Graphics.ExcludeClip(ExcludeRegion3);
GraphicsPath myPath3 = new GraphicsPath();
point1.X=0;point1.Y=180;
point2.X=19;point2.Y=198;
point3.X=62;point3.Y=204;
point4.X=83;point4.Y=221;
Point point5 = new Point(93, 248);
Point point6 = new Point(102, 267);
Point point7 = new Point(125, 278);
Point[] curvePoints3 = { point1, point2, point3, point4,
point5, point6, point7 };
myPath3.AddCurve(curvePoints3, 0, 6, 0.8f);
myPath3.AddLine(125, 278, 90, 300);
myPath3.AddLine(90, 300, 0, 300);
Region ExcludeRegion2 = new Region(myPath3);
e.Graphics.ExcludeClip(ExcludeRegion2);
point1.X=454;point1.Y=0;
point2.X=470;point2.Y=12;
point3.X=481;point3.Y=34;
Point[] curvePoints4 = { point1, point2, point3 };
GraphicsPath myPath2 = new GraphicsPath();
myPath2.AddCurve(curvePoints4, 0, 2, 0.8f);
myPath2.AddLine(481, 30, 481, 76);
myPath2.AddLine(481, 76, 495, 76);
myPath2.AddLine(495, 76, 495, 0);
Region ExcludeRegion4 = new Region(myPath2);
e.Graphics.ExcludeClip(ExcludeRegion4);
GraphicsPath myPath5 = new GraphicsPath();
point1.X=481;point1.Y=76;
point2.X=494;point2.Y=115;
point3.X=481;point3.Y=158;
Point[] curvePoints5 = { point1, point2, point3 };
myPath5.AddCurve(curvePoints5, 0, 2, 0.8f);
myPath5.AddLine(481, 158, 481, 279);
myPath5.AddLine(481, 255, 495, 279);
myPath5.AddLine(495, 279, 495, 0);
Region ExcludeRegion6 = new Region(myPath5);
e.Graphics.ExcludeClip(ExcludeRegion6);
point1.X=480;point1.Y=250;
point2.X=469;point2.Y=264;
point3.X=446;point3.Y=278;
Point[] curvePoints6 = { point1, point2, point3 };
GraphicsPath myPath4 = new GraphicsPath();
myPath4.AddCurve(curvePoints6, 0, 2, 0.8f);
myPath4.AddLine(450, 277, 495, 279);
Region ExcludeRegion5 = new Region(myPath4);
e.Graphics.ExcludeClip(ExcludeRegion5);
e.Graphics.DrawImage(img, 0, 0, 695,278);
// 重设剪切好的区域
e.Graphics.ResetClip();
}
</code></pre></div></div>
</section>
<footer class="post-footer">
<!-- Everything inside the #author tags pulls data from the author -->
<!-- #author-->
<!-- Add Disqus Comments -->
</footer>
</article>
</main>
<aside class="read-next">
<!-- [[! next_post ]] -->
<a class="read-next-story no-cover" href="/implement-single-sign-on-using-cas">
<section class="post">
<h2>CAS实现单点登录</h2>
<p>单点登录(Single Sign-On,SSO)是一种身份验证过程,允许用户使用一个帐户登录多个应用程序或系统,而无需为每个应用程序分别登录。中央认证服务(Central Authentication Service,CAS)是一种广泛使用的开源解决方案,用于实现单点登录。 #### CAS的基本原理 CAS的工作原理基于票证(ticket)机制。其流程如下: 1. **用户访问应用程序**:用户尝试访问一个需要认证的应用程序。 2. **重定向到CAS服务器**:该应用程序将用户重定向到CAS认证服务器。 3. **用户认证**:用户在CAS认证服务器上进行身份验证(如输入用户名和密码)。 4. **生成票证**:CAS服务器验证用户身份成功后,生成一个票证,并将用户重定向回最初的应用程序,同时附带票证。...</p>
</section>
</a>
<!-- [[! /next_post ]] -->
<!-- [[! prev_post ]] -->
<a class="read-next-story prev no-cover" href="/sorted-array-vs-unsorted-array">
<section class="post">
<h2>Why is processing a sorted array faster than processing an unsorted array</h2>
<p>As a C++ developer, understanding why processing a sorted array is often faster than an...</p>
</section>
</a>
<!-- [[! /prev_post ]] -->
</aside>
<!-- /post -->
<footer class="site-footer clearfix">
<section class="copyright"><a href="/">与机器,人,神共舞</a> © 2024</section>
</footer>
</div>
<!-- [[! Ghost outputs important scripts and data with this tag ]] -->
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<!-- [[! The main JavaScript file for Casper ]] -->
<script type="text/javascript" src="/assets/js/jquery.fitvids.js"></script>
<script type="text/javascript" src="/assets/js/index.js"></script>
<!-- Add Google Analytics -->
<!-- Google Analytics Tracking code -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-78960009-1', 'auto');
ga('send', 'pageview');
</script>
</body>
</html>