OSDN Git Service

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