OSDN Git Service

7538984be60da03bf5751555072c164eacdf4fc2
[tdcgexplorer/tso2mqo.git] / Form1.cs
1 using System;\r
2 using System.Collections.Generic;\r
3 using System.ComponentModel;\r
4 using System.Data;\r
5 using System.Drawing;\r
6 using System.IO;\r
7 using System.Text;\r
8 using System.Windows.Forms;\r
9 using Microsoft.Win32;\r
10 \r
11 namespace Tso2MqoGui\r
12 {\r
13     public partial class Form1 : Form\r
14     {\r
15         public string   OutPath\r
16         {\r
17             get { return tbPath.Text; }\r
18             set { tbPath.Text= value; }\r
19         }\r
20 \r
21         public Form1()\r
22         {\r
23             InitializeComponent();\r
24         }\r
25 \r
26         private void Form1_Load(object sender, EventArgs e)\r
27         {\r
28             RegistryKey reg = Application.UserAppDataRegistry.CreateSubKey("Config");\r
29             OutPath = (string)reg.GetValue("OutPath", Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));\r
30             tabControl1.SelectedIndex = (int)reg.GetValue("TabPage", 0);\r
31             tbMqoIn.Text = (string)reg.GetValue("MqoIn", "");\r
32             tbTso.Text = (string)reg.GetValue("Tso", "");\r
33             tbTsoEx.Text = (string)reg.GetValue("TsoEx", "");\r
34             tbMergeTso.Text = (string)reg.GetValue("MergeTso", "");\r
35             rbRefBone.Checked = (int)reg.GetValue("RefBone", 1) == 1;\r
36             rbOneBone.Checked = (int)reg.GetValue("OneBone", 0) == 1;\r
37             rbBoneNone.Checked = (int)reg.GetValue("BoneNone", 1) == 1;\r
38             rbBoneRokDeBone.Checked = (int)reg.GetValue("BoneRokDeBone", 0) == 1;\r
39             cbMakeSub.Checked = (int)reg.GetValue("MakeSub", 1) == 1;\r
40             cbCopyTSO.Checked = (int)reg.GetValue("CopyTSO", 1) == 1;\r
41             cbShowMaterials.Checked = (int)reg.GetValue("ShowMaterials", 0) == 1;\r
42 \r
43             reg             = Application.UserAppDataRegistry.CreateSubKey("Form1");\r
44             Bounds          = new Rectangle(\r
45                 (int)reg.GetValue("Left",     0),\r
46                 (int)reg.GetValue("Top",      0),\r
47                 (int)reg.GetValue("Width",  640),\r
48                 (int)reg.GetValue("Height", 320));\r
49 \r
50             EnableControlStuff();\r
51 \r
52             Config  config  = Config.Instance;\r
53         }\r
54 \r
55         private void Form1_FormClosed(object sender, FormClosedEventArgs e)\r
56         {\r
57             RegistryKey reg = Application.UserAppDataRegistry.CreateSubKey("Config");\r
58             reg.SetValue("OutPath", OutPath);\r
59             reg.SetValue("TabPage", tabControl1.SelectedIndex);\r
60             reg.SetValue("MqoIn", tbMqoIn.Text);\r
61             reg.SetValue("Tso", tbTso.Text);\r
62             reg.SetValue("TsoEx", tbTsoEx.Text);\r
63             reg.SetValue("MergeTso", tbMergeTso.Text);\r
64             reg.SetValue("RefBone", rbRefBone.Checked ? 1 : 0);\r
65             reg.SetValue("OneBone", rbOneBone.Checked ? 1 : 0);\r
66             reg.SetValue("BoneNone", rbBoneNone.Checked ? 1 : 0);\r
67             reg.SetValue("BoneRokDeBone", rbBoneRokDeBone.Checked ? 1 : 0);\r
68             reg.SetValue("MakeSub", cbMakeSub.Checked ? 1 : 0);\r
69             reg.SetValue("CopyTSO", cbCopyTSO.Checked ? 1 : 0);\r
70             reg.SetValue("ShowMaterials", cbShowMaterials.Checked ? 1 : 0);\r
71 \r
72             reg= Application.UserAppDataRegistry.CreateSubKey("Form1");\r
73 \r
74             if((this.WindowState & FormWindowState.Minimized) == FormWindowState.Minimized)\r
75             {\r
76                 reg.SetValue("Top",    RestoreBounds.Top);\r
77                 reg.SetValue("Left",   RestoreBounds.Left);\r
78                 reg.SetValue("Width",  RestoreBounds.Width);\r
79                 reg.SetValue("Height", RestoreBounds.Height);\r
80             } else\r
81             {\r
82                 reg.SetValue("Top",    Top);\r
83                 reg.SetValue("Left",   Left);\r
84                 reg.SetValue("Width",  Width);\r
85                 reg.SetValue("Height", Height);\r
86             }\r
87 \r
88             Config.Save();\r
89         }\r
90 \r
91         private void Form1_DragDrop(object sender, DragEventArgs e)\r
92         {\r
93             try\r
94             {\r
95                 if(!e.Data.GetDataPresent(DataFormats.FileDrop))\r
96                     return;\r
97 \r
98                 string[]    files   = (string[])e.Data.GetData(DataFormats.FileDrop);\r
99 \r
100                 if(files.Length == 0)\r
101                     return;\r
102 \r
103                 switch(tabControl1.SelectedIndex)\r
104                 {\r
105                 case 0:\r
106                     foreach(string i in files)\r
107                     {\r
108                         if(Path.GetExtension(i).ToUpper() == ".TSO")\r
109                             OpenTSOFile(i);\r
110                     }\r
111 \r
112                     break;\r
113 \r
114                 case 1:\r
115                     switch (Path.GetExtension(files[0]).ToUpper())\r
116                     {\r
117                         case ".TSO": tbTso.Text = files[0]; break;\r
118                         case ".MQO": tbMqoIn.Text = files[0]; break;\r
119                     }\r
120 \r
121                     break;\r
122 \r
123                 case 2:\r
124                     AddMergeTso(files);\r
125                     break;\r
126                 }\r
127             } catch(Exception ex)\r
128             {\r
129                 Util.ProcessError(ex);\r
130             }\r
131         }\r
132 \r
133         private void Form1_DragEnter(object sender, DragEventArgs e)\r
134         {\r
135             if(!e.Data.GetDataPresent(DataFormats.FileDrop))\r
136                 return;\r
137 \r
138             e.Effect    = DragDropEffects.Copy;\r
139         }\r
140 \r
141         private void tbMergeTso_DragDrop(object sender, DragEventArgs e)\r
142         {\r
143             if(!e.Data.GetDataPresent(DataFormats.FileDrop))\r
144                 return;\r
145 \r
146             string[]    files   = (string[])e.Data.GetData(DataFormats.FileDrop);\r
147 \r
148             switch(Path.GetExtension(files[0]).ToUpper())\r
149             {\r
150             case ".TSO":    tbMergeTso.Text= files[0];  break;\r
151             }\r
152         }\r
153 \r
154         private void tbMergeTso_DragEnter(object sender, DragEventArgs e)\r
155         {\r
156             if(!e.Data.GetDataPresent(DataFormats.FileDrop))\r
157                 return;\r
158 \r
159             e.Effect    = DragDropEffects.Copy;\r
160         }\r
161 \r
162         private void OpenTSOFile(string file)\r
163         {\r
164             string dir = OutPath;\r
165 \r
166             if (cbMakeSub.Checked)\r
167             {\r
168                 dir = Path.Combine(dir, Path.GetFileNameWithoutExtension(file));\r
169 \r
170                 if (!Directory.Exists(dir))\r
171                     Directory.CreateDirectory(dir);\r
172             }\r
173 \r
174             string mqo_path = Path.Combine(dir, Path.ChangeExtension(Path.GetFileName(file), ".mqo"));\r
175             string importinfo_path = Path.Combine(dir, Path.ChangeExtension(Path.GetFileName(file), ".xml"));\r
176 \r
177             try\r
178             {\r
179                 label2.BackColor = Color.Tomato;\r
180                 label2.ForeColor = Color.White;\r
181                 label2.Text = "Processing";\r
182                 label2.Invalidate();\r
183                 label2.Update();\r
184 \r
185                 // モデル、テクスチャの作成\r
186                 using (MqoWriter mqo = new MqoWriter(mqo_path))\r
187                 {\r
188                     TSOFile tso = new TSOFile(file);\r
189                     tso.ReadAll();\r
190 \r
191                     if (rbBoneRokDeBone.Checked) mqo.BoneMode = MqoBoneMode.RokDeBone;\r
192 \r
193                     mqo.Write(tso);\r
194                     mqo.Close();\r
195 \r
196                     ImportInfo ii = new ImportInfo();\r
197 \r
198                     // テクスチャ情報\r
199                     foreach (TSOTex i in tso.textures)\r
200                         ii.textures.Add(new ImportTextureInfo(i));\r
201 \r
202                     // エフェクトの作成\r
203                     foreach (TSOEffect i in tso.effects)\r
204                     {\r
205                         ii.effects.Add(new ImportEffectInfo(i));\r
206                         File.WriteAllText(Path.Combine(dir, i.Name), i.code, Encoding.Default);\r
207                     }\r
208 \r
209                     // マテリアルの作成\r
210                     foreach (TSOMaterial i in tso.materials)\r
211                     {\r
212                         ii.materials.Add(new ImportMaterialInfo(i));\r
213                         File.WriteAllText(Path.Combine(dir, i.Name), i.code, Encoding.Default);\r
214                     }\r
215 \r
216                     ImportInfo.Save(importinfo_path, ii);\r
217                 }\r
218 \r
219                 if (cbCopyTSO.Checked)\r
220                 {\r
221                     string tso_path = Path.Combine(dir, Path.GetFileName(file));\r
222 \r
223                     if (file != tso_path)\r
224                         File.Copy(file, tso_path, true);\r
225                 }\r
226             }\r
227             finally\r
228             {\r
229                 label2.BackColor = SystemColors.Control;\r
230                 label2.BackColor = label2.Parent.BackColor;\r
231                 label2.ForeColor = SystemColors.ControlText;\r
232                 label2.Text = "Drop TSO File Here!";\r
233             }\r
234         }\r
235 \r
236         private void OpenMQOFile(string file)\r
237         {\r
238             TSOGenerateConfig config = new TSOGenerateConfig();\r
239             config.ShowMaterials = cbShowMaterials.Checked;\r
240 \r
241             if (rbRefBone.Checked)\r
242             {\r
243                 TSOGeneratorRefBone gen = new TSOGeneratorRefBone();\r
244                 gen.Generate(file, tbTso.Text, tbTsoEx.Text, config);\r
245             }\r
246             else\r
247             if (rbOneBone.Checked)\r
248             {\r
249                 TSOGeneratorOneBone gen = new TSOGeneratorOneBone();\r
250 \r
251                 foreach (ListViewItem i in lvObject.Items)\r
252                 {\r
253                     if (i.SubItems[1].Text == "")\r
254                     {\r
255                         MessageBox.Show("すべてのオブジェクトにボーンを設定してください");\r
256                         return;\r
257                     }\r
258 \r
259                     gen.ObjectBoneNames.Add(i.SubItems[0].Text, i.SubItems[1].Text);\r
260                 }\r
261 \r
262                 gen.Generate(file, tbTso.Text, tbTsoEx.Text, config);\r
263             }\r
264             else\r
265             {\r
266             }\r
267         }\r
268 #region tso->mqo UI\r
269         private void button1_Click(object sender, EventArgs e)\r
270         {\r
271             FolderBrowserDialog dlg = new FolderBrowserDialog();\r
272             dlg.SelectedPath    = OutPath;\r
273 \r
274             if(dlg.ShowDialog() == DialogResult.OK)\r
275                 OutPath = dlg.SelectedPath;\r
276         }\r
277 #endregion\r
278 #region mqo->tso UI\r
279         private void radioButton1_CheckedChanged(object sender, EventArgs e)\r
280         {\r
281             EnableControlStuff();\r
282         }\r
283 \r
284         private void radioButton2_CheckedChanged(object sender, EventArgs e)\r
285         {\r
286             EnableControlStuff();\r
287         }\r
288 \r
289         private void EnableControlStuff()\r
290         {\r
291             gbBone.Enabled  = rbOneBone.Checked;\r
292         }\r
293 \r
294         private void BuildBoneTree(TreeNodeCollection nodes, TSONode node)\r
295         {\r
296             TreeNode    tn  = nodes.Add(node.ShortName);\r
297             tn.Tag          = node;\r
298 \r
299             if(node.children != null)\r
300             foreach(TSONode i in node.children)\r
301                 BuildBoneTree(tn.Nodes, i);\r
302         }\r
303 \r
304         private void SaveAssign()\r
305         {\r
306             foreach(ListViewItem i in lvObject.Items)\r
307             {\r
308                 string  obj = i.SubItems[0].Text;\r
309                 string  bone= i.SubItems[1].Text;\r
310 \r
311                 if(Config.Instance.object_bone_map.ContainsKey(obj))\r
312                         Config.Instance.object_bone_map[obj]    = bone;\r
313                 else    Config.Instance.object_bone_map.Add(obj, bone);\r
314             }\r
315         }\r
316 \r
317         private void bRefMqoIn_Click(object sender, EventArgs e)\r
318         {\r
319             try\r
320             {\r
321                 OpenFileDialog  dlg = new OpenFileDialog();\r
322                 dlg.Filter  = "Metasequoia File(*.mqo)|*.mqo";\r
323                 dlg.FileName= tbMqoIn.Text;\r
324 \r
325                 if(dlg.ShowDialog() == DialogResult.OK)\r
326                     tbMqoIn.Text    = dlg.FileName;\r
327             } catch(Exception ex)\r
328             {\r
329                 Util.ProcessError(ex);\r
330             }\r
331         }\r
332 \r
333         private void bRefTso_Click(object sender, EventArgs e)\r
334         {\r
335             try\r
336             {\r
337                 OpenFileDialog  dlg = new OpenFileDialog();\r
338                 dlg.Filter  = "TSO File(*.tso)|*.tso";\r
339                 dlg.FileName= tbTso.Text;\r
340 \r
341                 if(dlg.ShowDialog() == DialogResult.OK)\r
342                     tbTso.Text      = dlg.FileName;\r
343             } catch(Exception ex)\r
344             {\r
345                 Util.ProcessError(ex);\r
346             }\r
347         }\r
348 \r
349         private void bRefTsoEx_Click(object sender, EventArgs e)\r
350         {\r
351             try\r
352             {\r
353                 SaveFileDialog  dlg = new SaveFileDialog();\r
354                 dlg.Filter  = "TSO File(*.tso)|*.tso";\r
355                 dlg.FileName= tbTsoEx.Text;\r
356 \r
357                 if(dlg.ShowDialog() == DialogResult.OK)\r
358                     tbTsoEx.Text    = dlg.FileName;\r
359             } catch(Exception ex)\r
360             {\r
361                 Util.ProcessError(ex);\r
362             }\r
363         }\r
364 \r
365         private void bRefresh_Click(object sender, EventArgs e)\r
366         {\r
367             try\r
368             {\r
369                 // 一旦現状を保存\r
370                 SaveAssign();\r
371 \r
372                 // オブジェクト\r
373                 MqoFile mqo = new MqoFile();\r
374                 mqo.Load(tbMqoIn.Text);\r
375                 lvObject.Items.Clear();\r
376 \r
377                 foreach(MqoObject i in mqo.Objects)\r
378                 {\r
379                     ListViewItem    item= lvObject.Items.Add(i.name);\r
380                     item.Tag            = i;\r
381                     string          bone;\r
382 \r
383                     if(Config.Instance.object_bone_map.TryGetValue(i.name, out bone))\r
384                             item.SubItems.Add(bone);\r
385                     else    item.SubItems.Add("");\r
386                 }\r
387 \r
388                 // ボーン構造\r
389                 TSOFile tso = new TSOFile(tbTso.Text);\r
390                 tso.ReadAll();\r
391                 tvBone.Visible  = false;\r
392                 tvBone.Nodes.Clear();\r
393                 BuildBoneTree(tvBone.Nodes, tso.nodes[0]);\r
394                 tvBone.ExpandAll();\r
395                 tvBone.Nodes[0].EnsureVisible();\r
396             } catch(Exception ex)\r
397             {\r
398                 Util.ProcessError(ex);\r
399             } finally\r
400             {\r
401                 tvBone.Visible  = true;\r
402             }\r
403 \r
404         }\r
405 \r
406         private void bSelectAll_Click(object sender, EventArgs e)\r
407         {\r
408             foreach(ListViewItem i in lvObject.Items)\r
409                 i.Selected  = true;\r
410         }\r
411 \r
412         private void bDeselectAll_Click(object sender, EventArgs e)\r
413         {\r
414             foreach(ListViewItem i in lvObject.Items)\r
415                 i.Selected  = false;\r
416         }\r
417 \r
418         private void bAssign_Click(object sender, EventArgs e)\r
419         {\r
420             try\r
421             {\r
422                 TreeNode    n   = tvBone.SelectedNode;\r
423 \r
424                 if(n == null)\r
425                 {\r
426                     MessageBox.Show("割り当てるボーンを選択してください");\r
427                     return;\r
428                 }\r
429 \r
430                 foreach(ListViewItem i in lvObject.SelectedItems)\r
431                     i.SubItems[1].Text  = n.Text;\r
432 \r
433                 SaveAssign();\r
434             } catch(Exception ex)\r
435             {\r
436                 Util.ProcessError(ex);\r
437             }\r
438         }\r
439 \r
440         private void bOk_Click(object sender, EventArgs e)\r
441         {\r
442             Color c = tabPage2.BackColor;\r
443 \r
444             try\r
445             {\r
446                 tabPage2.BackColor = Color.Tomato;\r
447                 tabPage2.Update();\r
448                 string file = tbMqoIn.Text;\r
449                 OpenMQOFile(file);\r
450             }\r
451             catch (Exception ex)\r
452             {\r
453                 Util.ProcessError(ex);\r
454             }\r
455             finally\r
456             {\r
457                 tabPage2.BackColor = c;\r
458             }\r
459         }\r
460 #endregion\r
461 #region Merge UI\r
462         private void AddMergeTso(string[] files)\r
463         {\r
464             foreach(string i in files)\r
465             {\r
466                 if(Path.GetExtension(files[0]).ToUpper() != ".TSO")\r
467                     continue;\r
468 \r
469                 if(tvMerge.Nodes.Find(i, false).Length == 0)\r
470                 {\r
471                     TreeNode    node= tvMerge.Nodes.Add(i);\r
472                     node.Name       = i;\r
473                     node.Checked    = true;\r
474 \r
475                     TSOFile     tso = new TSOFile(i);\r
476                     tso.ReadAll();\r
477 \r
478                     foreach(TSOMesh j in tso.meshes)\r
479                     {\r
480                         TreeNode    mesh= node.Nodes.Add(j.Name);\r
481                         mesh.Name       = j.Name;\r
482                         mesh.Checked    = true;\r
483                     }\r
484                 }\r
485             }\r
486         }\r
487 \r
488         private void bMerge_Click(object sender, EventArgs e)\r
489         {\r
490             Color   c   = tabPage2.BackColor;\r
491 \r
492             try\r
493             {\r
494                 tabPage2.BackColor  = Color.Tomato;\r
495                 List<TSOMesh>                               meshes      = new List<TSOMesh>();\r
496                 Dictionary<string, Pair<TSOMaterial, int>>  materialmap = new Dictionary<string, Pair<TSOMaterial, int>>();\r
497                 Dictionary<string, TSOTex>                  textures    = new Dictionary<string, TSOTex>();\r
498                 TSOFile                                     last        = null;\r
499 \r
500                 foreach(TreeNode i in tvMerge.Nodes)\r
501                 {\r
502                     TSOFile tso = new TSOFile(i.Text);\r
503                     last        = tso;\r
504                     ulong   mtls= 0;\r
505                     ulong   mask= 1;\r
506                     tso.ReadAll();\r
507 \r
508                     foreach(TSOMesh j in tso.meshes)\r
509                     {\r
510                         TreeNode[]  found   = i.Nodes.Find(j.Name, false);\r
511 \r
512                         if(found.Length == 0 || !found[0].Checked)\r
513                             continue;\r
514 \r
515                         foreach(TSOSubMesh k in j.sub)\r
516                             mtls    |=1ul << k.spec;\r
517 \r
518                         meshes.Add(j);\r
519                     }\r
520 \r
521                     foreach(TSOMaterial j in tso.materials)\r
522                     {\r
523                         if((mask & mtls) != 0)\r
524                         {\r
525                             if(!materialmap.ContainsKey(j.Name))\r
526                             {\r
527                                 Pair<TSOMaterial, int>  value   = new Pair<TSOMaterial,int>(j, materialmap.Count);\r
528                                 materialmap.Add(j.Name, value);\r
529 \r
530                                 if(!textures.ContainsKey(j.ColorTex))\r
531                                 {\r
532                                     TSOTex  tex = tso.texturemap[j.ColorTex];\r
533                                     textures.Add(tex.Name, tex);\r
534                                 }\r
535 \r
536                                 if(!textures.ContainsKey(j.ShadeTex))\r
537                                 {\r
538                                     TSOTex  tex = tso.texturemap[j.ShadeTex];\r
539                                     textures.Add(tex.Name, tex);\r
540                                 }\r
541                             }\r
542                         }\r
543 \r
544                         mask    <<=1;\r
545                     }\r
546                 }\r
547 \r
548                 using(FileStream fs= File.OpenWrite(tbMergeTso.Text))\r
549                 {\r
550                     fs.SetLength(0);\r
551 \r
552                     List<TSOTex>    texlist = new List<TSOTex>(textures.Values);\r
553                     TSOMaterial[]   mtllist = new TSOMaterial[materialmap.Count];\r
554 \r
555                     foreach(var i in materialmap.Values)\r
556                         mtllist[i.Second]   = i.First;\r
557 \r
558                     foreach(TSOMesh i in meshes)\r
559                     {\r
560                         foreach(TSOSubMesh j in i.sub)\r
561                         {\r
562                             TSOMaterial mtl = i.file.materials[j.spec];\r
563                             j.spec          = materialmap[mtl.Name].Second;\r
564                         }\r
565                     }\r
566 \r
567                     foreach(TSOTex i in texlist)\r
568                         TSOFile.ExchangeChannel(i.data, i.depth);\r
569 \r
570                     BinaryWriter    bw  = new BinaryWriter(fs);\r
571                     TSOWriter.WriteHeader(bw);\r
572                     TSOWriter.Write(bw, last.nodes);\r
573                     TSOWriter.Write(bw, texlist.ToArray());\r
574                     TSOWriter.Write(bw, last.effects);\r
575                     TSOWriter.Write(bw, mtllist);\r
576                     TSOWriter.Write(bw, meshes.ToArray());\r
577                 }\r
578             } catch(Exception ex)\r
579             {\r
580                 Util.ProcessError(ex);\r
581             } finally\r
582             {\r
583                 tabPage2.BackColor  = c;\r
584             }\r
585         }\r
586 \r
587         private void bMergeAdd_Click(object sender, EventArgs e)\r
588         {\r
589             try\r
590             {\r
591                 OpenFileDialog  dlg = new OpenFileDialog();\r
592                 dlg.Filter      = "TSO File(*.tso)|*.tso";\r
593                 dlg.Multiselect = true;\r
594 \r
595                 if(dlg.ShowDialog() == DialogResult.OK)\r
596                     AddMergeTso(dlg.FileNames);\r
597             } catch(Exception ex)\r
598             {\r
599                 Util.ProcessError(ex);\r
600             }\r
601         }\r
602 \r
603         private void bMergeDel_Click(object sender, EventArgs e)\r
604         {\r
605             if(tvMerge.SelectedNode != null\r
606             && tvMerge.SelectedNode.Level == 0)\r
607                 tvMerge.SelectedNode.Remove();\r
608         }\r
609 \r
610         private void bMergeReset_Click(object sender, EventArgs e)\r
611         {\r
612             tvMerge.Nodes.Clear();\r
613         }\r
614 \r
615         private void bRefMergeTso_Click(object sender, EventArgs e)\r
616         {\r
617             try\r
618             {\r
619                 SaveFileDialog  dlg = new SaveFileDialog();\r
620                 dlg.Filter  = "TSO File(*.tso)|*.tso";\r
621                 dlg.FileName= tbMergeTso.Text;\r
622 \r
623                 if(dlg.ShowDialog() == DialogResult.OK)\r
624                     tbMergeTso.Text = dlg.FileName;\r
625             } catch(Exception ex)\r
626             {\r
627                 Util.ProcessError(ex);\r
628             }\r
629         }\r
630 \r
631         public static bool  bTvMerge_AfterCheck = false;\r
632 \r
633         private void tvMerge_AfterCheck(object sender, TreeViewEventArgs e)\r
634         {\r
635             if(bTvMerge_AfterCheck)\r
636                 return;\r
637 \r
638             bTvMerge_AfterCheck = true;\r
639 \r
640             try\r
641             {\r
642                 if(e.Node.Level == 0)\r
643                 {\r
644                     foreach(TreeNode i in e.Node.Nodes)\r
645                         i.Checked   = e.Node.Checked;\r
646                 } else\r
647                 {\r
648                     bool    check   = false;\r
649                   //bool    uncheck = false;\r
650 \r
651                     foreach(TreeNode i in e.Node.Parent.Nodes)\r
652                     if(i.Checked)   check   = true;\r
653                   //else            uncheck = true;\r
654 \r
655                     e.Node.Parent.Checked   = check;\r
656                 }\r
657             } finally\r
658             {\r
659                 bTvMerge_AfterCheck = false;\r
660             }\r
661         }\r
662 #endregion\r
663     }\r
664 \r
665     public class Util\r
666     {\r
667         public static void ProcessError(Exception e)\r
668         {\r
669             MessageBox.Show(e.ToString());\r
670         }\r
671     }\r
672 }\r