这是“使用 C# 开发智能手机软件:推箱子” 系列文章的第二十四篇。在这篇文章中,介绍 Window/MainForm.cs 源程序文件。这个源程序文件是 MainForm 类的主体部分,该类继承自 System.Windows.Forms.Form 类,表示推箱子的主窗体,如下图所示:
下面就是 MainForm.cs 的源程序代码:
1
using
System;
2
using
System.ComponentModel;
3
using
System.Drawing;
4
using
System.Threading;
5
using
System.Windows.Forms;
6
using
Skyiv.Ben.PushBox.Common;
7
8
namespace
Skyiv.Ben.PushBox.Window
9
{
10
///
<summary>
11
///
程序的主窗体
12
///
</summary>
13
public
partial
class
MainForm : Form
14
{
15
Env env;
//
工作环境
16
17
public
MainForm()
18
{
19
env
=
new
Env();
20
InitializeComponent();
21
}
22
23
protected
override
void
OnLoad(EventArgs e)
24
{
25
base
.OnLoad(e);
26
miTopMost.Enabled
=
(Environment.OSVersion.Platform
!=
PlatformID.WinCE);
27
env.LoadConfig();
28
env.LoadGroup();
29
LoadLevel(
true
);
30
if
(env.IsSave) Restore(env.Steps);
31
}
32
33
protected
override
void
OnClosing(CancelEventArgs e)
34
{
35
if
(env.IsDesign
||
env.IsReplay)
36
{
37
MessageBox.Show(
"
正在“
"
+
(env.IsDesign
?
"
设计
"
:
"
回放
"
)
+
"
”,不能退出。请
"
+
38
(env.IsDesign
?
"
先“保存”或者“放弃”。
"
:
"
等待“回放”完成,或者停止回放。
"
),
"
提醒
"
);
39
e.Cancel
=
true
;
40
}
41
else
42
{
43
env.SaveConfig();
44
env.Dispose();
45
}
46
base
.OnClosing(e);
47
}
48
49
protected
override
void
OnResize(EventArgs e)
50
{
51
base
.OnResize(e);
52
ClientSizeChanged();
53
}
54
55
protected
override
void
OnKeyDown(KeyEventArgs e)
56
{
57
if
(
!
env.IsReplay
&&
!
env.IsDesign)
58
{
59
Direction dir
=
Direction.None;
60
switch
(e.KeyCode)
61
{
62
case
Keys.Right: dir
=
Direction.East;
break
;
63
case
Keys.Down: dir
=
Direction.South;
break
;
64
case
Keys.Left: dir
=
Direction.West;
break
;
65
case
Keys.Up: dir
=
Direction.North;
break
;
66
}
67
StepIt(dir,
true
);
68
e.Handled
=
true
;
69
}
70
base
.OnKeyDown(e);
71
}
72
73
protected
override
void
OnMouseDown(MouseEventArgs e)
74
{
75
base
.OnMouseDown(e);
76
if
(
!
env.IsReplay) env.ToPixel
=
new
Point(e.X, e.Y);
77
}
78
79
protected
override
void
OnClick(EventArgs e)
80
{
81
if
(env.IsDesign) Design();
82
else
if
(
!
env.IsReplay
&&
!
TryPush()) TryMove();
83
base
.OnClick(e);
84
}
85
86
protected
override
void
OnPaint(PaintEventArgs e)
87
{
88
base
.OnPaint(e);
89
env.Draw(e.Graphics, e.ClipRectangle);
90
}
91
92
private
void
miExit_Click(
object
sender, EventArgs e)
93
{
94
Close();
95
}
96
97
private
void
miOption_Click(
object
sender, EventArgs e)
98
{
99
using
(OptionDlg dlg
=
new
OptionDlg(TopMost))
100
{
101
dlg.MaxLevelSize
=
env.MaxLevelSize;
102
dlg.StepDelay
=
env.StepDelay;
103
dlg.ReplayDelay
=
env.ReplayDelay;
104
dlg.IsSave
=
env.IsSave;
105
if
(dlg.ShowDialog()
==
DialogResult.OK)
106
{
107
env.MaxLevelSize
=
dlg.MaxLevelSize;
108
env.StepDelay
=
dlg.StepDelay;
109
env.ReplayDelay
=
dlg.ReplayDelay;
110
env.IsSave
=
dlg.IsSave;
111
}
112
}
113
}
114
115
private
void
miErrorMsg_Click(
object
sender, EventArgs e)
116
{
117
using
(ErrorMsgDlg dlg
=
new
ErrorMsgDlg(TopMost))
118
{
119
dlg.ErrorMsg
=
env.ErrorMsg;
120
dlg.DebugMsg
=
env.DebugMsg;
121
dlg.ShowDialog();
122
}
123
}
124
125
private
void
miAbout_Click(
object
sender, EventArgs e)
126
{
127
using
(Form dlg
=
new
AboutDlg(TopMost))
128
{
129
dlg.ShowDialog();
130
}
131
}
132
133
private
void
miTopic_Click(
object
sender, EventArgs e)
134
{
135
using
(Form dlg
=
new
TopicDlg(TopMost))
136
{
137
dlg.ShowDialog();
138
}
139
}
140
141
private
void
miStatusbar_Click(
object
sender, EventArgs e)
142
{
143
miStatusbar.Checked
=
!
miStatusbar.Checked;
144
sbrMain.Visible
=
miStatusbar.Checked;
145
ClientSizeChanged();
146
}
147
148
private
void
miTopMost_Click(
object
sender, EventArgs e)
149
{
150
TopMost
=
miTopMost.Checked
=
!
miTopMost.Checked;
151
}
152
153
private
void
miRestartOrStopOrSave_Click(
object
sender, EventArgs e)
154
{
155
if
(env.IsDesign)
156
{
157
env.SaveDesign();
158
LoadLevel(
true
);
159
}
160
else
if
(env.IsReplay) workerThreadIsStop
=
true
;
161
else
LoadLevel(
false
);
162
}
163
164
private
void
miUndoOrCancel_Click(
object
sender, EventArgs e)
165
{
166
if
(env.IsDesign)
167
{
168
if
(env.Active
==
Action.Create) env.Level
=
env.LeveLOem;
169
LoadLevel(
true
);
170
}
171
else
172
{
173
for
(
bool
isFirst
=
true
; ; isFirst
=
false
)
174
{
175
if
(
!
isFirst
&&
env.StepDelay
>
0
) Thread.Sleep(env.StepDelay);
176
if
(Back())
break
;
177
}
178
}
179
}
180
181
private
void
miRecordOrBrick_Click(
object
sender, EventArgs e)
182
{
183
if
(env.IsDesign)
184
{
185
env.Pen
=
Block.Brick;
186
UpdateStatus();
187
}
188
else
189
{
190
env.Record();
191
UpdateStatus();
192
miRecordOrBrick.Enabled
=
false
;
193
Update();
194
}
195
}
196
197
private
void
miBackOrManOrBox_Click(
object
sender, EventArgs e)
198
{
199
if
(env.IsDesign)
200
{
201
env.Pen
=
env.HasWorker
?
Block.Box0 : Block.Man0;
202
UpdateStatus();
203
}
204
else
Back();
205
}
206
207
private
void
miConfig_Click(
object
sender, EventArgs e)
208
{
209
using
(ConfigDlg dlg
=
new
ConfigDlg(TopMost))
210
{
211
dlg.Groups
=
env.Groups;
212
if
(dlg.ShowDialog()
==
DialogResult.OK)
213
{
214
env.Init();
215
env.SaveConfig(dlg.Groups);
216
env.LoadConfig();
217
env.LoadGroup();
218
LoadLevel(
true
);
219
}
220
}
221
}
222
223
private
void
miTran_Click(
object
sender, EventArgs e)
224
{
225
env.Dispose();
226
using
(TranDlg dlg
=
new
TranDlg(TopMost))
227
{
228
dlg.MaxLevelSize
=
env.MaxLevelSize;
229
dlg.Groups
=
env.Groups;
230
dlg.ShowDialog();
231
}
232
env.Init();
233
env.LoadGroup();
234
LoadLevel(
true
);
235
}
236
237
private
void
miFirstLevel_Click(
object
sender, EventArgs e)
238
{
239
env.Level
=
0
;
240
LoadLevel(
true
);
241
}
242
243
private
void
miPrevLevel2OrSlot_Click(
object
sender, EventArgs e)
244
{
245
if
(env.IsDesign)
246
{
247
env.Pen
=
Block.Slot;
248
UpdateStatus();
249
}
250
else
251
{
252
if
(env.Level
<=
0
)
return
;
253
env.Level
--
;
254
LoadLevel(
true
);
255
}
256
}
257
258
private
void
miNextLevel2OrWall_Click(
object
sender, EventArgs e)
259
{
260
if
(env.IsDesign)
261
{
262
env.Pen
=
Block.Wall;
263
UpdateStatus();
264
}
265
else
266
{
267
if
(env.Level
>=
env.MaxLevel
-
1
)
return
;
268
env.Level
++
;
269
LoadLevel(
true
);
270
}
271
}
272
273
private
void
miLastLevel_Click(
object
sender, EventArgs e)
274
{
275
env.Level
=
env.MaxLevel
-
1
;
276
LoadLevel(
true
);
277
}
278
279
private
void
miSelectLevel_Click(
object
sender, EventArgs e)
280
{
281
using
(SelectLevelDlg dlg
=
new
SelectLevelDlg(TopMost))
282
{
283
dlg.MaxLevel
=
env.MaxLevel;
284
dlg.Level
=
env.Level;
285
if
(dlg.ShowDialog()
==
DialogResult.OK)
286
{
287
env.Level
=
dlg.Level;
288
LoadLevel(
true
);
289
}
290
}
291
}
292
293
private
void
miFirstGroup_Click(
object
sender, EventArgs e)
294
{
295
env.Group
=
0
;
296
env.LoadGroup();
297
LoadLevel(
true
);
298
}
299
300
private
void
miPrevGroup_Click(
object
sender, EventArgs e)
301
{
302
if
(env.Group
<=
0
)
return
;
303
env.Group
--
;
304
env.LoadGroup();
305
LoadLevel(
true
);
306
}
307
308
private
void
miNextGroup_Click(
object
sender, EventArgs e)
309
{
310
if
(env.Group
>
env.Groups.Length
-
1
)
return
;
311
env.Group
++
;
312
env.LoadGroup();
313
LoadLevel(
true
);
314
}
315
316
private
void
miLastGroup_Click(
object
sender, EventArgs e)
317
{
318
env.Group
=
env.Groups.Length
-
1
;
319
env.LoadGroup();
320
LoadLevel(
true
);
321
}
322
323
private
void
miSelectGroup_Click(
object
sender, EventArgs e)
324
{
325
using
(SelectGroupDlg dlg
=
new
SelectGroupDlg(TopMost))
326
{
327
dlg.Groups
=
env.Groups;
328
dlg.Group
=
env.Group;
329
if
(dlg.ShowDialog()
==
DialogResult.OK)
330
{
331
env.Group
=
dlg.Group;
332
env.LoadGroup();
333
LoadLevel(
true
);
334
}
335
}
336
}
337
}
338
}
几点说明:
- env 字段表示推箱子的工作环境,其类型为 Env,请参见:使用 C# 开发智能手机软件:推箱子(十一)。
- OnLoad 方法在主窗体装入时被调用,完成必要的初始化工作。首先根据本程序是否在智能手机上运行来决定是否禁用“前端显示”功能,然后依次读取配置文件,装入当前组,装入当前关,再根据需要恢复现场(即本程序上次退出时已经走过的步骤)。
- OnClosing 方法将在程序主窗体关闭(也就是退出本程序)时被调用,首先判断是否正在“设计”或者“回放”,如果是,则不允许退出本程序。否则,保护现场后退出本程序。
- OnResize 方法是主窗体尺寸发生变化时要采取的动作。在智能手机上主要是横屏和竖屏之间的切换。
- OnKeyDown 方法处理键盘动作,也就是处理上下左右四个方向键。这主要用于 Smartphone 的情况。如果是 Pocket PC Phone 或者计算机,一般会使用触摸屏或鼠标。
- OnMouseDown 方法在鼠标点击时记录其坐标。
- OnClick 方法处理鼠标点击动作。
- OnPaint 方法负责绘制程序的主窗体。
- miExit_Click 方法表示用户点击“菜单 -> 退出”时的动作,她只是简单地调用 Form 类的 Close 方法关闭程序主窗体,从而退出本程序。
- miOption_Click 方法表示用户点击“菜单 -> 选项”时的动作,她调用 OptionDlg 类来显示“选项”对话框,请参见:使用 C# 开发智能手机软件:推箱子(十五)。
- miErrorMsg_Click 方法表示用户点击“菜单 -> 帮助 -> 错误信息”时的动作,她调用 ErrorMsgDlg 类来显示“错误信息”对话框,请参见:使用 C# 开发智能手机软件:推箱子(十四)。
- miAbout_Click 方法表示用户点击“菜单 -> 帮助 -> 关于”时的动作,她调用 AboutDlg 类来显示“关于”对话框,请参见:使用 C# 开发智能手机软件:推箱子(十二)。
- miTopic_Click 方法表示用户点击“菜单 -> 帮助 -> 帮助主题”时的动作,她调用 TopicDlg 类来显示“帮助”对话框,请参见:使用 C# 开发智能手机软件:推箱子(十三)。
- miStatusbar_Click 方法表示用户点击“菜单 -> 状态栏”时的动作,用来切换是否显示状态栏。
- miTopMost_Click 方法表示用户点击“菜单 -> 前端显示”时的动作,用来切换本程序是否总是显示在最前面。注意:在智能手机上本功能被禁用,因为智能手机上的所有程序都是全屏的,以免本程序始终占据屏幕最前端而影响手机的使用。
- miConfig_Click 方法表示用户点击“菜单 -> 数据 -> 配置”时的动作,她调用 ConfigDlg 类来显示“配置”对话框,请参见:使用 C# 开发智能手机软件:推箱子(十六)。
- miTran_Click 方法表示用户点击“菜单 -> 数据 -> 转换”时的动作,她调用 TranDlg 类来显示“转换”对话框,请参见:使用 C# 开发智能手机软件:推箱子(十九)。
- miSelectLevel_Click 方法表示用户点击“菜单 -> 关 -> 选关”时的动作,她调用 SelectLevelDlg 类来显示“选关”对话框,请参见:使用 C# 开发智能手机软件:推箱子(十八)。
- miSelectGroup_Click 方法表示用户点击“菜单 -> 组 -> 选组”时的动作,她调用 SelectGroupDlg 类来显示“选组”对话框,请参见:使用 C# 开发智能手机软件:推箱子(十七)。
上一篇:
使用 C# 开发智能手机软件:推箱子(二十三)
返回目录