Remove the olsr-specific duplicated types (win32)
[olsrd.git] / gui / win32 / Main / MyDialog2.cpp
1 /*
2  * The olsr.org Optimized Link-State Routing daemon (olsrd)
3  * Copyright (c) 2004, Thomas Lopatic (thomas@lopatic.de)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without 
7  * modification, are permitted provided that the following conditions 
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright 
11  *   notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright 
13  *   notice, this list of conditions and the following disclaimer in 
14  *   the documentation and/or other materials provided with the 
15  *   distribution.
16  * * Neither the name of olsr.org, olsrd nor the names of its 
17  *   contributors may be used to endorse or promote products derived 
18  *   from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Visit http://www.olsr.org for more information.
34  *
35  * If you find this software useful feel free to make a donation
36  * to the project. For more information see the website or contact
37  * the copyright holders.
38  *
39  */
40
41 #include "stdafx.h"
42 #include "Frontend.h"
43 #include "MyDialog2.h"
44
45 #ifdef _DEBUG
46 #define new DEBUG_NEW
47 #undef THIS_FILE
48 static char THIS_FILE[] = __FILE__;
49 #endif
50
51 #define MAXIF 100
52
53 MyDialog2::MyDialog2(CWnd* pParent)
54         : CDialog(MyDialog2::IDD, pParent)
55 {
56         Conf = NULL;
57
58         //{{AFX_DATA_INIT(MyDialog2)
59         //}}AFX_DATA_INIT\r
60 }
61
62 void MyDialog2::SetDebugLevel(int Level)
63 {
64         char LevelText[2];
65
66         LevelText[0] = (char)(Level + '0');
67         LevelText[1] = 0;
68
69         DebugLevel = Level;
70         m_DebugLevel.SetPos(Level);
71         m_DebugLevelText.SetWindowText(LevelText);
72 }
73
74 BOOL MyDialog2::Create(CWnd *Parent)
75 {
76         return CDialog::Create(MyDialog2::IDD, Parent);
77 }
78
79 void MyDialog2::DoDataExchange(CDataExchange* pDX)
80 {
81         CDialog::DoDataExchange(pDX);
82         //{{AFX_DATA_MAP(MyDialog2)
83         DDX_Control(pDX, IDC_COMBO3, m_LqAlgo);\r
84         DDX_Control(pDX, IDC_COMBO1, m_TcRed);\r
85         DDX_Control(pDX, IDC_EDIT15, m_MprCov);\r
86         DDX_Control(pDX, IDC_RADIO2, m_EtxRadio2);\r
87         DDX_Control(pDX, IDC_RADIO1, m_EtxRadio1);\r
88         DDX_Control(pDX, IDC_CHECK4, m_EtxCheck);\r
89         DDX_Control(pDX, IDC_CHECK3, m_Ipv6Check);\r
90         DDX_Control(pDX, IDC_CHECK2, m_InternetCheck);\r
91         DDX_Control(pDX, IDC_CHECK1, m_HystCheck);\r
92         DDX_Control(pDX, IDC_CHECK5, m_FishEyeCheck);\r
93         DDX_Control(pDX, IDC_EDIT13, m_HystThresholdHigh);\r
94         DDX_Control(pDX, IDC_EDIT12, m_HystThresholdLow);\r
95         DDX_Control(pDX, IDC_EDIT11, m_HystScaling);\r
96         DDX_Control(pDX, IDC_EDIT10, m_HnaHold);\r
97         DDX_Control(pDX, IDC_EDIT9, m_MidHold);\r
98         DDX_Control(pDX, IDC_EDIT7, m_PollInt);\r
99         DDX_Control(pDX, IDC_EDIT6, m_TcHold);\r
100         DDX_Control(pDX, IDC_EDIT5, m_TcInt);\r
101         DDX_Control(pDX, IDC_EDIT4, m_HnaInt);\r
102         DDX_Control(pDX, IDC_EDIT3, m_MidInt);\r
103         DDX_Control(pDX, IDC_EDIT2, m_HelloHold);\r
104         DDX_Control(pDX, IDC_EDIT1, m_HelloInt);\r
105         DDX_Control(pDX, IDC_LIST1, m_InterfaceList);\r
106         DDX_Control(pDX, IDC_TEXT1, m_DebugLevelText);\r
107         DDX_Control(pDX, IDC_SLIDER2, m_DebugLevel);\r
108         //}}AFX_DATA_MAP\r
109 }
110
111 BEGIN_MESSAGE_MAP(MyDialog2, CDialog)
112         //{{AFX_MSG_MAP(MyDialog2)
113         ON_WM_HSCROLL()
114         ON_BN_CLICKED(IDC_CHECK1, OnHystCheck)
115         ON_BN_CLICKED(IDC_BUTTON4, OnOpenButton)
116         ON_BN_CLICKED(IDC_BUTTON5, OnSaveButton)
117         ON_BN_CLICKED(IDC_BUTTON1, OnResetButton)
118         ON_BN_CLICKED(IDC_CHECK4, OnEtxCheck)
119         ON_BN_CLICKED(IDC_RADIO1, OnEtxRadio1)
120         ON_BN_CLICKED(IDC_RADIO2, OnEtxRadio2)
121         ON_BN_CLICKED(IDOK, OnOK)
122         ON_BN_CLICKED(IDCANCEL, OnCancel)
123         //}}AFX_MSG_MAP
124 END_MESSAGE_MAP()
125
126 void MyDialog2::OnOK()
127 {
128 }
129
130 void MyDialog2::OnCancel()
131 {
132 }
133
134 void MyDialog2::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
135 {
136         if (pScrollBar == (CScrollBar *)&m_DebugLevel)
137                 SetDebugLevel(m_DebugLevel.GetPos());
138         
139         CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
140 }
141
142 void MyDialog2::Reset(void)
143 {
144         char PathName[MAX_PATH + 50];
145         char *Walker;
146         int i;
147
148         ::GetModuleFileName(NULL, PathName, MAX_PATH);
149
150         for (Walker = PathName; *Walker != 0; Walker++);
151         
152         while (*Walker != '\\')
153                 Walker--;
154
155         lstrcpy(Walker + 1, "Default.olsr");
156
157         if (OpenConfigFile(PathName) < 0)
158                 return;
159
160         m_Ipv6Check.SetCheck(FALSE);
161
162         if (Conf->interfaces == NULL)
163         {
164                 for (i = 0; i < Interfaces->GetSize(); i++)
165                 {
166                         if ((*IsWlan)[i] == "-")
167                                 m_InterfaceList.SetCheck(i, FALSE);
168
169                         else
170                                 m_InterfaceList.SetCheck(i, TRUE);
171                 }
172         }
173 }
174
175 BOOL MyDialog2::OnInitDialog() 
176 {
177         int i;
178
179         CDialog::OnInitDialog();
180         
181         m_DebugLevel.SetRange(0, 9, TRUE);
182
183         m_InterfaceList.SetExtendedStyle(m_InterfaceList.GetExtendedStyle() |
184                         LVS_EX_CHECKBOXES);
185
186         for (i = 0; i < Interfaces->GetSize(); i++)
187         {
188                 m_InterfaceList.InsertItem(i,
189                 (*Interfaces)[i] + " - " + (*Addresses)[i]);
190         }
191
192         MIB_IPFORWARDROW IpFwdRow;
193
194         if (::GetBestRoute(0, 0, &IpFwdRow) != NO_ERROR)
195                 m_InternetCheck.EnableWindow(FALSE);
196
197         m_MprCov.LimitText(1);
198
199         Reset();
200
201         return TRUE;
202 }
203
204 void MyDialog2::OnHystCheck() 
205 {
206         BOOL EnaDis = m_HystCheck.GetCheck();
207
208         m_HystThresholdLow.EnableWindow(EnaDis);
209         m_HystThresholdHigh.EnableWindow(EnaDis);
210         m_HystScaling.EnableWindow(EnaDis);
211 }
212
213 void MyDialog2::OnEtxCheckWorker() 
214 {
215         BOOL EnaDis = m_EtxCheck.GetCheck();
216
217         m_EtxRadio1.EnableWindow(EnaDis);
218         m_EtxRadio2.EnableWindow(EnaDis);
219         m_FishEyeCheck.EnableWindow(EnaDis);
220 }
221
222 void MyDialog2::OnEtxCheck()
223 {
224         OnEtxCheckWorker();
225
226         AfxMessageBox("WARNING - This parameter breaks compliance with the OLSR standard.\n\n"
227                 "Make sure that either all nodes in your network use ETX or all nodes in your network don't use ETX.\n\n"
228                 "DO NOT MIX NODES WITH DIFFERENT ETX SETTINGS!");
229 }
230
231 int MyDialog2::OpenConfigFile(CString PathName)
232 {
233         struct ip_prefix_list *Hna;
234         struct olsr_if *Int, *PrevInt;
235         struct olsr_msg_params *MsgPar;
236         int NumInt = m_InterfaceList.GetItemCount();
237         int i;
238         CString IntName;
239         CString Conv;
240
241         if (Conf != NULL)
242                 olsrd_free_cnf(Conf);
243
244         Conf = olsrd_parse_cnf(PathName);
245
246         if (Conf == NULL)
247                 return -1;
248
249         for (i = 0; i < NumInt; i++)
250                 m_InterfaceList.SetCheck(i, FALSE);
251
252         for (Int = Conf->interfaces; Int != NULL; Int = Int->next)
253         {
254                 IntName = Int->name;
255                 IntName.MakeUpper();
256
257                 for (i = 0; i < NumInt; i++)
258                 {
259                         if (m_InterfaceList.GetItemText(i, 0).Mid(0, 4) == IntName)
260                                 m_InterfaceList.SetCheck(i, TRUE);
261                 }
262         }
263
264         Int = Conf->interfaces;
265
266         MsgPar = &Int->cnf->hello_params;
267
268         Conv.Format("%.2f", MsgPar->emission_interval);
269         m_HelloInt.SetWindowText(Conv);
270
271         Conv.Format("%.2f", MsgPar->validity_time);
272         m_HelloHold.SetWindowText(Conv);
273
274         MsgPar = &Int->cnf->tc_params;
275         
276         Conv.Format("%.2f", MsgPar->emission_interval);
277         m_TcInt.SetWindowText(Conv);
278
279         Conv.Format("%.2f", MsgPar->validity_time);
280         m_TcHold.SetWindowText(Conv);
281
282         MsgPar = &Int->cnf->mid_params;
283         
284         Conv.Format("%.2f", MsgPar->emission_interval);
285         m_MidInt.SetWindowText(Conv);
286
287         Conv.Format("%.2f", MsgPar->validity_time);
288         m_MidHold.SetWindowText(Conv);
289
290         MsgPar = &Int->cnf->hna_params;
291         
292         Conv.Format("%.2f", MsgPar->emission_interval);
293         m_HnaInt.SetWindowText(Conv);
294
295         Conv.Format("%.2f", MsgPar->validity_time);
296         m_HnaHold.SetWindowText(Conv);
297
298         SetDebugLevel(Conf->debug_level);
299
300         Conv.Format("%.2f", Conf->pollrate);
301         m_PollInt.SetWindowText(Conv);
302
303         Conv.Format("%d", Conf->mpr_coverage);
304         m_MprCov.SetWindowText(Conv);
305
306         m_TcRed.SetCurSel(Conf->tc_redundancy);\r
307 \r
308         m_LqAlgo.SetCurSel(m_LqAlgo.FindStringExact(-1, Conf->lq_algorithm));
309
310         m_HystCheck.SetCheck(Conf->use_hysteresis);
311
312         Conv.Format("%.2f", Conf->hysteresis_param.scaling);
313         m_HystScaling.SetWindowText(Conv);
314
315         Conv.Format("%.2f", Conf->hysteresis_param.thr_high);
316         m_HystThresholdHigh.SetWindowText(Conv);
317
318         Conv.Format("%.2f", Conf->hysteresis_param.thr_low);
319         m_HystThresholdLow.SetWindowText(Conv);
320
321         OnHystCheck();
322
323         m_FishEyeCheck.SetCheck(Conf->lq_fish > 0);
324
325         m_EtxCheck.SetCheck(Conf->lq_level > 0);
326
327 #if 0\r
328         Conv.Format("%d", Conf->lq_wsize);\r
329         m_EtxWindowSize.SetWindowText(Conv);\r
330 #endif
331
332         m_EtxRadio1.SetCheck(Conf->lq_level == 1);
333         m_EtxRadio2.SetCheck(Conf->lq_level == 0 || Conf->lq_level == 2);
334
335         OnEtxCheckWorker();
336
337         m_InternetCheck.SetCheck(FALSE);
338
339         for (Hna = Conf->hna_entries; Hna != NULL; Hna = Hna->next)
340                 if (0 == Hna->net.prefix_len &&
341                         m_InternetCheck.IsWindowEnabled())
342                 m_InternetCheck.SetCheck(TRUE);
343
344         PrevInt = NULL;
345
346         for (Int = Conf->interfaces; Int != NULL; Int = Int->next)
347         {
348                 IntName = Int->name;
349
350                 if (IntName.CompareNoCase("GUI") == 0)
351                         break;
352
353                 PrevInt = Int;
354         }
355
356         if (Int != NULL)
357         {
358                 if (PrevInt == NULL)
359                         Conf->interfaces = Int->next;
360
361                 else
362                         PrevInt->next = Int->next;
363
364                 win32_olsrd_free(Int);
365         }
366
367         return 0;
368 }
369
370 static struct olsr_if *AddInterface(struct olsrd_config **Conf, CString Name)
371 {
372         struct olsr_if *Int;
373
374         Int = (struct olsr_if *)win32_olsrd_malloc(sizeof (struct olsr_if));
375
376         if (Int == NULL)
377         {
378                 AfxMessageBox("Cannot allocate memory.");
379                 return NULL;
380         }
381
382         Int->name = (char *)win32_olsrd_malloc(Name.GetLength() + 1);
383
384         if (Int->name == NULL)
385         {
386                 win32_olsrd_free(Int);
387
388                 AfxMessageBox("Cannot allocate memory.");
389                 return NULL;
390         }
391
392         ::lstrcpy(Int->name, Name);
393
394         Int->config = NULL;
395         Int->configured = false;
396         Int->interf = NULL;
397
398         Int->cnf = get_default_if_config();
399
400         Int->next = (*Conf)->interfaces;
401         (*Conf)->interfaces = Int;
402
403         return Int;
404 }
405
406 int MyDialog2::SaveConfigFile(CString PathName, int Real)
407 {
408         struct olsr_if *Int, *PrevInt;
409         struct olsr_msg_params *MsgPar;
410         CString Conv;
411         struct ip_prefix_list *Hna, *NewHna, *PrevHna;
412         int NumInt = m_InterfaceList.GetItemCount();
413         int i;
414         CString IntName, IntName2;
415         struct ip_prefix_list *IpcHost;
416         union olsr_ip_addr Local;
417
418         PrevInt = NULL;
419
420         // remove interfaces that we do not want
421         
422         for (Int = Conf->interfaces; Int != NULL; Int = Int->next)
423         {
424                 IntName = Int->name;
425                 IntName.MakeUpper();
426
427                 for (i = 0; i < NumInt; i++)
428                         if (m_InterfaceList.GetItemText(i, 0).Mid(0, 4) == IntName)
429                                 break;
430
431                 if (i == NumInt || !m_InterfaceList.GetCheck(i))
432                 {
433                         if (PrevInt != NULL)
434                                 PrevInt->next = Int->next;
435
436                         else
437                                 Conf->interfaces = Int->next;
438                 }
439         }
440         
441         // add missing interfaces
442         
443         for (i = 0; i < NumInt; i++)
444         {
445                 if (!m_InterfaceList.GetCheck(i))
446                         continue;
447
448                 IntName2 = m_InterfaceList.GetItemText(i, 0).Mid(0, 4);
449
450                 for (Int = Conf->interfaces; Int != NULL; Int = Int->next)
451                 {
452                         IntName = Int->name;
453                         IntName.MakeUpper();
454
455                         if (IntName2 == IntName)
456                                 break;
457                 }
458
459                 if (Int == NULL)
460                         AddInterface(&Conf, m_InterfaceList.GetItemText(i, 0).Mid(0, 4));
461         }
462
463         // add dummy interface, if there aren't any real interfaces
464
465         if (Conf->interfaces == NULL && Real != 0)
466                 AddInterface(&Conf, "GUI");
467
468         // per-interface settings
469
470         for (Int = Conf->interfaces; Int != NULL; Int = Int->next)
471         {
472                 MsgPar = &Int->cnf->hello_params;
473
474                 m_HelloInt.GetWindowText(Conv);
475                 MsgPar->emission_interval = (float)atof(Conv);
476
477                 m_HelloHold.GetWindowText(Conv);
478                 MsgPar->validity_time = (float)atof(Conv);
479
480                 MsgPar = &Int->cnf->tc_params;
481
482                 m_TcInt.GetWindowText(Conv);
483                 MsgPar->emission_interval = (float)atof(Conv);
484
485                 m_TcHold.GetWindowText(Conv);
486                 MsgPar->validity_time = (float)atof(Conv);
487
488                 MsgPar = &Int->cnf->mid_params;
489
490                 m_MidInt.GetWindowText(Conv);
491                 MsgPar->emission_interval = (float)atof(Conv);
492
493                 m_MidHold.GetWindowText(Conv);
494                 MsgPar->validity_time = (float)atof(Conv);
495
496                 MsgPar = &Int->cnf->hna_params;
497
498                 m_HnaInt.GetWindowText(Conv);
499                 MsgPar->emission_interval = (float)atof(Conv);
500
501                 m_HnaHold.GetWindowText(Conv);
502                 MsgPar->validity_time = (float)atof(Conv);
503         }
504
505         // global settings
506
507         Conf->debug_level = DebugLevel;
508
509         m_PollInt.GetWindowText(Conv);
510         Conf->pollrate = (float)atof(Conv);
511
512         Conf->tc_redundancy = (unsigned char)m_TcRed.GetCurSel();
513
514         i = m_LqAlgo.GetCurSel();\r
515         Conf->lq_algorithm = NULL;\r
516         if (0 <= i)\r
517         {\r
518                 CString str;\r
519                 m_LqAlgo.GetLBText(i, str);\r
520                 Conf->lq_algorithm = strdup((LPCTSTR)str);\r
521         }\r
522 \r
523         m_MprCov.GetWindowText(Conv);
524         Conf->mpr_coverage = (unsigned char)atoi(Conv);
525
526         Conf->use_hysteresis = m_HystCheck.GetCheck() ? true : false;
527
528         m_HystScaling.GetWindowText(Conv);
529         Conf->hysteresis_param.scaling = (float)atof(Conv);
530
531         m_HystThresholdHigh.GetWindowText(Conv);
532         Conf->hysteresis_param.thr_high = (float)atof(Conv);
533
534         m_HystThresholdLow.GetWindowText(Conv);
535         Conf->hysteresis_param.thr_low = (float)atof(Conv);
536
537         if (!m_EtxCheck.GetCheck())
538                 Conf->lq_level = 0;
539
540         else if (m_EtxRadio1.GetCheck())
541                 Conf->lq_level = 1;
542
543         else
544                 Conf->lq_level = 2;
545
546         if (!m_FishEyeCheck.GetCheck())
547                 Conf->lq_fish = 0;
548
549         else
550                 Conf->lq_fish = 1;
551
552         PrevHna = NULL;
553
554         // check for a default gateway HNA4 entry
555
556         for (Hna = Conf->hna_entries; Hna != NULL; Hna = Hna->next)
557         {
558                 if (0 == Hna->net.prefix_len)
559                         break;
560
561                 PrevHna = Hna;
562         }
563
564         // add default gateway HNA entry
565
566         if (m_InternetCheck.GetCheck() && Hna == NULL)
567         {
568                 NewHna = (struct ip_prefix_list * )
569                         win32_olsrd_malloc(sizeof (struct ip_prefix_list));
570
571                 if (NewHna == NULL)
572                 {
573                         AfxMessageBox("Cannot allocate memory.");
574                         return -1;
575                 }
576
577                 memset(NewHna, 0, sizeof (struct ip_prefix_list));
578
579                 NewHna->next = Conf->hna_entries;
580                 Conf->hna_entries = NewHna;
581         }
582
583         // remove default gateway HNA4 entry
584
585         if (!m_InternetCheck.GetCheck() && Hna != NULL)
586         {
587                 if (PrevHna == NULL)
588                         Conf->hna_entries = Hna->next;
589
590                 else
591                         PrevHna->next = Hna->next;
592
593                 win32_olsrd_free(Hna);
594         }
595
596         if (AF_INET == Conf->ip_version)
597         {
598                 Local.v4.s_addr = ::inet_addr("127.0.0.1");
599         }
600         else
601         {
602                 memset(&Local, 0, sizeof(Local));
603                 Local.v6.u.Byte[15] = 1;
604         }
605
606         for (IpcHost = Conf->ipc_nets; IpcHost != NULL; IpcHost = IpcHost->next)
607                 if (0 == memcmp(&IpcHost->net.prefix, &Local, Conf->ipsize))
608                         break;
609
610         if (IpcHost == NULL && Real == 0)
611         {
612                 IpcHost = (struct ip_prefix_list *)
613                         win32_olsrd_malloc(sizeof (struct ip_prefix_list));
614
615                 if (IpcHost == NULL)
616                 {
617                         AfxMessageBox("Cannot allocate memory.");
618                         return -1;
619                 }
620
621                 IpcHost->net.prefix = Local;
622                 IpcHost->net.prefix_len = (uint8_t)Conf->ipsize;
623
624                 IpcHost->next = Conf->ipc_nets;
625                 Conf->ipc_nets = IpcHost;
626
627                 Conf->ipc_connections++;
628         }
629
630         // write configuration file
631
632         if (olsrd_write_cnf(Conf, PathName) < 0)
633                 return -1;
634
635         return 0;
636 }
637
638 void MyDialog2::OnSaveButton()
639 {
640         CFileDialog FileDialog(FALSE);
641         CString FileName = "Default.olsr";
642         CString PathName;
643
644         FileDialog.m_ofn.lpstrFilter = "Configuration file (*.olsr)\0*.olsr\0";
645         FileDialog.m_ofn.nFilterIndex = 1;
646
647         FileDialog.m_ofn.lpstrFile = FileName.GetBuffer(500);
648         FileDialog.m_ofn.nMaxFile = 500;
649
650         if (FileDialog.DoModal() == IDOK)
651         {
652                 PathName = FileDialog.GetPathName();
653
654                 if (SaveConfigFile(PathName, 1) < 0)
655                         AfxMessageBox("Cannot save configuration file '" + PathName + "'.");
656         }
657
658         FileName.ReleaseBuffer();
659 }
660
661 void MyDialog2::OnOpenButton()
662 {
663         CFileDialog FileDialog(TRUE);
664         CString FileName = "Default.olsr";
665         CString PathName;
666
667         FileDialog.m_ofn.lpstrFilter = "Configuration file (*.olsr)\0*.olsr\0";
668         FileDialog.m_ofn.nFilterIndex = 1;
669
670         FileDialog.m_ofn.lpstrFile = FileName.GetBuffer(500);
671         FileDialog.m_ofn.nMaxFile = 500;
672
673         if (FileDialog.DoModal() == IDOK)
674         {
675                 PathName = FileDialog.GetPathName();
676
677                 if (OpenConfigFile(PathName) < 0)
678                         AfxMessageBox("Cannot open configuration file '" + PathName + "'.");
679         }
680
681         FileName.ReleaseBuffer();
682 }
683
684 void MyDialog2::OnResetButton() 
685 {
686         Reset();
687 }
688
689 void MyDialog2::OnEtxRadio1() 
690 {
691         m_EtxRadio2.SetCheck(FALSE);
692 }
693
694 void MyDialog2::OnEtxRadio2() 
695 {
696         m_EtxRadio1.SetCheck(FALSE);
697 }