source: trunk/Utilities/GpsLocationConverter/MainDialog.h @ 40

Last change on this file since 40 was 40, checked in by roman, 10 years ago

batch conversion for multiple values

  • Property svn:keywords set to Id
File size: 23.7 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2008-2011
3// Created by Roman Ryltsov roman@alax.info
4//
5// $Id: MainDialog.h 40 2011-11-14 15:35:37Z roman $
6
7#pragma once
8
9#include "AboutDialog.h"
10
11////////////////////////////////////////////////////////////
12// CMainDialog
13
14class CMainDialog : 
15        public CAxDialogImpl<CMainDialog>
16{
17public:
18        enum { IDD = IDD_MAIN };
19
20BEGIN_MSG_MAP_EX(CMainDialog)
21        CHAIN_MSG_MAP(CAxDialogImpl<CMainDialog>)
22        MSG_WM_INITDIALOG(OnInitDialog)
23        MSG_WM_DESTROY(OnDestroy)
24        MSG_WM_CHANGECBCHAIN(OnChangeCbChain)
25        MSG_WM_DRAWCLIPBOARD(OnDrawClipboard)
26        MSG_WM_SYSCOMMAND(OnSysCommand)
27        COMMAND_ID_HANDLER_EX(IDCANCEL, OnCommand)
28        NOTIFY_RANGE_CODE_HANDLER_EX(IDC_MAIN_DEGREES_LATITUDE, IDC_MAIN_DEGREESMINUTESSECONDS_LONGITUDELATITUDE, CRoHyperStatic::NC_ANCHORCLICKED, OnStaticAnchorClicked)
29        MSG_WM_HOTKEY(OnHotKey)
30        REFLECT_NOTIFICATIONS()
31END_MSG_MAP()
32
33public:
34
35        ////////////////////////////////////////////////////////
36        // CLocation
37
38        class CLocation
39        {
40        public:
41
42                ////////////////////////////////////////////////////
43                // CStrings
44
45                class CStrings
46                {
47                public:
48                        CString m_psTexts[12];
49                        CString m_sGoogleMapsLocation;
50                        CString m_sYandexMapsLocation;
51                        CString m_sBingMapsLocation;
52                        CString m_sYahooMapsLocation;
53                        CString m_sOpenStreetMapLocation;
54                        CString m_sWikiMapiaLocation;
55
56                public:
57                // CStrings
58                        CStrings() throw()
59                        {
60                        }
61                        CStrings(const CLocation& Location)
62                        {
63                                if(!Location.IsValid())
64                                        return;
65                                #pragma region Degrees
66                                {
67                                        const CString sLatitude = _StringHelper::FormatNumber(Location.m_fLatitude, 6, FALSE);
68                                        const CString sLongitude = _StringHelper::FormatNumber(Location.m_fLongitude, 6, FALSE);
69                                        m_psTexts[0] = sLatitude;
70                                        m_psTexts[1] = sLongitude;
71                                        m_psTexts[2] = AtlFormatString(_T("%s, %s"), sLatitude, sLongitude);
72                                        m_psTexts[3] = AtlFormatString(_T("%s, %s"), sLongitude, sLatitude);
73                                        m_sGoogleMapsLocation = AtlFormatString(_T("http://maps.google.com/maps/?ll=%s,%s"), sLatitude, sLongitude);
74                                        m_sYandexMapsLocation = AtlFormatString(_T("http://maps.yandex.ru/?ll=%s,%s&z=%d"), sLongitude, sLatitude, 19);
75                                        m_sBingMapsLocation = AtlFormatString(_T("http://www.bing.com/maps/?v=2&cp=%s~%s&lvl=%d"), sLatitude, sLongitude, 17);
76                                        m_sYahooMapsLocation = AtlFormatString(_T("http://maps.yahoo.com/#lat=%s&lon=%s&zoom=%d"), sLatitude, sLongitude, 17);
77                                        m_sOpenStreetMapLocation = AtlFormatString(_T("http://www.openstreetmap.org/?lat=%s&lon=%s&zoom=%d"), sLatitude, sLongitude, 17);
78                                        m_sWikiMapiaLocation = AtlFormatString(_T("http://wikimapia.org/#lat=%s&lon=%s&z=%d"), sLatitude, sLongitude, 17);
79                                }
80                                #pragma endregion
81                                #pragma region Degrees, Minutes
82                                {
83                                        CString sLatitude, sLongitude;
84                                        #pragma region Latitude
85                                        sLatitude.Append((Location.m_fLatitude >= 0) ? _T("N ") : _T("S "));
86                                        DOUBLE fPartialLatitude = abs(Location.m_fLatitude);
87                                        const INT nPartialLatitude = (INT) fPartialLatitude;
88                                        sLatitude.AppendFormat(_T("%02d "), nPartialLatitude);
89                                        const DOUBLE fPartialLatitudeMinute = (fPartialLatitude - nPartialLatitude) * 60;
90                                        const INT nPartialLatitudeMinute = (INT) fPartialLatitudeMinute;
91                                        sLatitude.AppendFormat(_T("%02d"), nPartialLatitudeMinute);
92                                        sLatitude.AppendFormat(_T(".%03d"), (INT) ((fPartialLatitudeMinute - nPartialLatitudeMinute) * 1000 + 0.5 - 1E-6));
93                                        #pragma endregion
94                                        #pragma region Latitude
95                                        sLongitude.Append((Location.m_fLongitude >= 0) ? _T("E ") : _T("W "));
96                                        DOUBLE fPartialLongitude = abs(Location.m_fLongitude);
97                                        const INT nPartialLongitude = (INT) fPartialLongitude;
98                                        sLongitude.AppendFormat(_T("%03d "), nPartialLongitude);
99                                        const DOUBLE fPartialLongitudeMinute = (fPartialLongitude - nPartialLongitude) * 60;
100                                        const INT nPartialLongitudeMinute = (INT) fPartialLongitudeMinute;
101                                        sLongitude.AppendFormat(_T("%02d"), nPartialLongitudeMinute);
102                                        sLongitude.AppendFormat(_T(".%03d"), (INT) ((fPartialLongitudeMinute - nPartialLongitudeMinute) * 1000 + 0.5 - 1E-6));
103                                        #pragma endregion
104                                        m_psTexts[4] = sLatitude;
105                                        m_psTexts[5] = sLongitude;
106                                        m_psTexts[6] = AtlFormatString(_T("%s, %s"), sLatitude, sLongitude);
107                                        m_psTexts[7] = AtlFormatString(_T("%s, %s"), sLongitude, sLatitude);
108                                }
109                                #pragma endregion
110                                #pragma region Degrees, Minutes, Seconds
111                                {
112                                        CString sLatitude, sLongitude;
113                                        #pragma region Latitude
114                                        sLatitude.Append((Location.m_fLatitude >= 0) ? _T("N ") : _T("S "));
115                                        DOUBLE fPartialLatitude = abs(Location.m_fLatitude);
116                                        const INT nPartialLatitude = (INT) fPartialLatitude;
117                                        sLatitude.AppendFormat(_T("%02d "), nPartialLatitude);
118                                        const DOUBLE fPartialLatitudeMinute = (fPartialLatitude - nPartialLatitude) * 60;
119                                        const INT nPartialLatitudeMinute = (INT) fPartialLatitudeMinute;
120                                        sLatitude.AppendFormat(_T("%02d "), nPartialLatitudeMinute);
121                                        const DOUBLE fPartialLatitudeSecond = (fPartialLatitudeMinute - nPartialLatitudeMinute) * 60;
122                                        const INT nPartialLatitudeSecond = (INT) fPartialLatitudeSecond;
123                                        sLatitude.AppendFormat(_T("%02d"), nPartialLatitudeSecond);
124                                        sLatitude.AppendFormat(_T(".%02d"), (INT) ((fPartialLatitudeSecond - nPartialLatitudeSecond) * 100 + 0.5 - 1E-6));
125                                        #pragma endregion
126                                        #pragma region Latitude
127                                        sLongitude.Append((Location.m_fLongitude >= 0) ? _T("E ") : _T("W "));
128                                        DOUBLE fPartialLongitude = abs(Location.m_fLongitude);
129                                        INT nPartialLongitude = (INT) fPartialLongitude;
130                                        sLongitude.AppendFormat(_T("%03d "), nPartialLongitude);
131                                        DOUBLE fPartialLongitudeMinute = (fPartialLongitude - nPartialLongitude) * 60;
132                                        INT nPartialLongitudeMinute = (INT) fPartialLongitudeMinute;
133                                        sLongitude.AppendFormat(_T("%02d "), nPartialLongitudeMinute);
134                                        const DOUBLE fPartialLongitudeSecond = (fPartialLongitudeMinute - nPartialLongitudeMinute) * 60;
135                                        const INT nPartialLongitudeSecond = (INT) fPartialLongitudeSecond;
136                                        sLongitude.AppendFormat(_T("%02d"), nPartialLongitudeSecond);
137                                        sLongitude.AppendFormat(_T(".%02d"), (INT) ((fPartialLongitudeSecond - nPartialLongitudeSecond) * 100 + 0.5 - 1E-6));
138                                        #pragma endregion
139                                        m_psTexts[ 8] = sLatitude;
140                                        m_psTexts[ 9] = sLongitude;
141                                        m_psTexts[10] = AtlFormatString(_T("%s, %s"), sLatitude, sLongitude);
142                                        m_psTexts[11] = AtlFormatString(_T("%s, %s"), sLongitude, sLatitude);
143                                }
144                                #pragma endregion
145                        }
146                };
147
148        public:
149                BOOL m_bValid;
150                DOUBLE m_fLatitude;
151                DOUBLE m_fLongitude;
152
153        public:
154        // CLocation
155                CLocation() throw() :
156                        m_bValid(FALSE)
157                {
158                }
159                CLocation(DOUBLE fLatitude, DOUBLE fLongitude) throw() :
160                        m_fLatitude(fLatitude),
161                        m_fLongitude(fLongitude),
162                        m_bValid(TRUE)
163                {
164                }
165                BOOL IsValid() const throw()
166                {
167                        return m_bValid;
168                }
169                VOID SetLocation(DOUBLE fLatitude, DOUBLE fLongitude) throw()
170                {
171                        m_fLatitude = fLatitude;
172                        m_fLongitude = fLongitude;
173                        m_bValid = TRUE;
174                }
175                BOOL Parse(const CString& sText)
176                {
177                        m_bValid = FALSE;
178                        if(sText.GetLength() >= (4 << 10)) // 4K
179                                return FALSE;
180                        CRoReMatchContext MatchContext;
181                        #pragma region Google Maps
182                        static CAtlStaticRegExp<> g_ExpressionA(_T("^ *(http://)?[^/]*maps.google[^/]*/.+?") _T("ll={[\\.0-9]+},{[\\.0-9]+}"), FALSE);
183                        if(g_ExpressionA.Match(sText, &MatchContext))
184                        {
185                                DOUBLE fLatitude, fLongitude;
186                                if(!AtlStringToDouble(MatchContext.GetMatchString(0), fLatitude) || !AtlStringToDouble(MatchContext.GetMatchString(1), fLongitude))
187                                        return FALSE;
188                                SetLocation(fLatitude, fLongitude);
189                                return TRUE;
190                        }
191                        #pragma endregion
192                        #pragma region Yandex Maps
193                        static CAtlStaticRegExp<> g_ExpressionB(_T("^ *(http://)?[^/]*maps.yandex[^/]*/.+?") _T("ll={[\\.0-9]+}(,|(\\%2C)){[\\.0-9]+}"), FALSE);
194                        if(g_ExpressionB.Match(sText, &MatchContext))
195                        {
196                                DOUBLE fLatitude, fLongitude;
197                                if(!AtlStringToDouble(MatchContext.GetMatchString(0), fLongitude) || !AtlStringToDouble(MatchContext.GetMatchString(1), fLatitude))
198                                        return FALSE;
199                                SetLocation(fLatitude, fLongitude);
200                                return TRUE;
201                        }
202                        #pragma endregion
203                        // TODO: Recognize Bing, Yahoo, OpenStreetMap and WikiMapia URLs
204                        // NOTE: Russian Å is often confused with English E, so we take both
205                        #pragma region Degrees and Minutes
206#define LATITUDE_SYMBOL         _T("{[NSCÞ]}")
207#define LONGITUDE_SYMBOL        _T("{[EWÂÇÅ]}")
208#define VALUE                           _T("{[0-9]+}[^0-9]+?{[0-9]+\\.[0-9]+}")
209#define OPTIONAL_WHITESPACE     _T("[\t ]*")
210#define SEPARATOR                       _T("[^0-9\\.]+?")
211                        static CAtlStaticRegExp<> g_ExpressionD0(_T("^") OPTIONAL_WHITESPACE LATITUDE_SYMBOL OPTIONAL_WHITESPACE VALUE SEPARATOR LONGITUDE_SYMBOL OPTIONAL_WHITESPACE VALUE _T(""), FALSE);
212                        static CAtlStaticRegExp<> g_ExpressionD1(_T("^") OPTIONAL_WHITESPACE LONGITUDE_SYMBOL OPTIONAL_WHITESPACE VALUE SEPARATOR LATITUDE_SYMBOL OPTIONAL_WHITESPACE VALUE _T(""), FALSE);
213                        static CAtlStaticRegExp<> g_ExpressionD2(_T("^") OPTIONAL_WHITESPACE VALUE OPTIONAL_WHITESPACE LATITUDE_SYMBOL SEPARATOR VALUE OPTIONAL_WHITESPACE LONGITUDE_SYMBOL _T(""), FALSE);
214                        static CAtlStaticRegExp<> g_ExpressionD3(_T("^") OPTIONAL_WHITESPACE VALUE OPTIONAL_WHITESPACE LATITUDE_SYMBOL SEPARATOR VALUE OPTIONAL_WHITESPACE LONGITUDE_SYMBOL _T(""), FALSE);
215#undef LATITUDE_SYMBOL
216#undef LONGITUDE_SYMBOL
217#undef VALUE
218#undef OPTIONAL_WHITESPACE
219#undef SEPARATOR
220                        INT nLayoutD = -1;
221                        if(g_ExpressionD0.Match(sText, &MatchContext))
222                                nLayoutD = 0;
223                        else if(g_ExpressionD1.Match(sText, &MatchContext))
224                                nLayoutD = 1;
225                        else if(g_ExpressionD2.Match(sText, &MatchContext))
226                                nLayoutD = 2;
227                        else if(g_ExpressionD3.Match(sText, &MatchContext))
228                                nLayoutD = 3;
229                        if(nLayoutD >= 0)
230                        {
231                                static const SIZE_T g_pnMap[4][6] = 
232                                {
233                                        { 0, 1, 2, 3, 4, 5, },
234                                        { 3, 4, 5, 0, 1, 2, },
235                                        { 2, 0, 1, 5, 3, 4, },
236                                        { 5, 3, 4, 2, 0, 1, },
237                                };
238                                const INT nLatitudeSign = (MatchContext.GetMatchString(g_pnMap[nLayoutD][0]).FindOneOf(_T("SsÞþ")) >= 0) ? -1 : 1;
239                                const INT nLongitudeSign = (MatchContext.GetMatchString(g_pnMap[nLayoutD][3]).FindOneOf(_T("WwÇç")) >= 0) ? -1 : 1;
240                                INT nLatitudeDegrees, nLongitudeDegrees;
241                                DOUBLE fLatitudeMinutes, fLongitudeMinutes;
242                                if(FALSE ||
243                                        !AtlStringToInteger(MatchContext.GetMatchString(g_pnMap[nLayoutD][1]), nLatitudeDegrees) || 
244                                        !AtlStringToDouble(MatchContext.GetMatchString(g_pnMap[nLayoutD][2]), fLatitudeMinutes) || 
245                                        !AtlStringToInteger(MatchContext.GetMatchString(g_pnMap[nLayoutD][4]), nLongitudeDegrees) ||
246                                        !AtlStringToDouble(MatchContext.GetMatchString(g_pnMap[nLayoutD][5]), fLongitudeMinutes) ||
247                                        FALSE)
248                                        return FALSE;
249                                _A(fLatitudeMinutes >= 0 && fLongitudeMinutes >= 0);
250                                if(fLatitudeMinutes >= 60.0 || fLongitudeMinutes >= 60.0)
251                                        return FALSE;
252                                const DOUBLE fLatitude = nLatitudeSign * (nLatitudeDegrees + fLatitudeMinutes / 60.0);
253                                const DOUBLE fLongitude = nLongitudeSign * (nLongitudeDegrees + fLongitudeMinutes / 60.0);
254                                SetLocation(fLatitude, fLongitude);
255                                return TRUE;
256                        }
257                        #pragma endregion
258                        #pragma region Degrees, Minutes and Seconds
259#define LATITUDE_SYMBOL         _T("{[NSCÞ]}")
260#define LONGITUDE_SYMBOL        _T("{[EWÂÇÅ]}")
261#define VALUE                           _T("{[0-9]+}[^0-9]+?{[0-9]+}[^0-9\\.]+?{[0-9]+(\\.([0-9]+)?)?}")
262#define OPTIONAL_WHITESPACE     _T("[\t ]*")
263#define SEPARATOR                       _T("[^0-9\\.]+?")
264                        static CAtlStaticRegExp<> g_ExpressionE0(_T("^") OPTIONAL_WHITESPACE LATITUDE_SYMBOL OPTIONAL_WHITESPACE VALUE SEPARATOR LONGITUDE_SYMBOL OPTIONAL_WHITESPACE VALUE _T(""), FALSE);
265                        static CAtlStaticRegExp<> g_ExpressionE1(_T("^") OPTIONAL_WHITESPACE LONGITUDE_SYMBOL OPTIONAL_WHITESPACE VALUE SEPARATOR LATITUDE_SYMBOL OPTIONAL_WHITESPACE VALUE  _T(""), FALSE);
266                        static CAtlStaticRegExp<> g_ExpressionE2(_T("^") OPTIONAL_WHITESPACE VALUE OPTIONAL_WHITESPACE LATITUDE_SYMBOL SEPARATOR VALUE OPTIONAL_WHITESPACE LONGITUDE_SYMBOL _T(""), FALSE);
267                        static CAtlStaticRegExp<> g_ExpressionE3(_T("^") OPTIONAL_WHITESPACE VALUE OPTIONAL_WHITESPACE LONGITUDE_SYMBOL SEPARATOR VALUE OPTIONAL_WHITESPACE LATITUDE_SYMBOL _T(""), FALSE);
268#undef LATITUDE_SYMBOL
269#undef LONGITUDE_SYMBOL
270#undef VALUE
271#undef OPTIONAL_WHITESPACE
272#undef SEPARATOR
273                        INT nLayoutE = -1;
274                        if(g_ExpressionE0.Match(sText, &MatchContext))
275                                nLayoutE = 0;
276                        else if(g_ExpressionE1.Match(sText, &MatchContext))
277                                nLayoutE = 1;
278                        else if(g_ExpressionE2.Match(sText, &MatchContext))
279                                nLayoutE = 2;
280                        else if(g_ExpressionE3.Match(sText, &MatchContext))
281                                nLayoutE = 3;
282                        if(nLayoutE >= 0)
283                        {
284                                static const SIZE_T g_pnMap[4][8] = 
285                                {
286                                        { 0, 1, 2, 3, 4, 5, 6, 7, },
287                                        { 4, 5, 6, 7, 0, 1, 2, 3, },
288                                        { 3, 0, 1, 2, 7, 4, 5, 6, },
289                                        { 7, 4, 5, 6, 3, 0, 1, 2, },
290                                };
291                                const INT nLatitudeSign = (MatchContext.GetMatchString(g_pnMap[nLayoutE][0]).FindOneOf(_T("SsÞþ")) >= 0) ? -1 : 1;
292                                const INT nLongitudeSign = (MatchContext.GetMatchString(g_pnMap[nLayoutE][4]).FindOneOf(_T("WwÇç")) >= 0) ? -1 : 1;
293                                INT nLatitudeDegrees, nLongitudeDegrees;
294                                INT nLatitudeMinutes, nLongitudeMinutes;
295                                DOUBLE fLatitudeSeconds, fLongitudeSeconds;
296                                if(FALSE ||
297                                        !AtlStringToInteger(MatchContext.GetMatchString(g_pnMap[nLayoutE][1]), nLatitudeDegrees) || 
298                                        !AtlStringToInteger(MatchContext.GetMatchString(g_pnMap[nLayoutE][2]), nLatitudeMinutes) || 
299                                        !AtlStringToDouble(MatchContext.GetMatchString(g_pnMap[nLayoutE][3]), fLatitudeSeconds) || 
300                                        !AtlStringToInteger(MatchContext.GetMatchString(g_pnMap[nLayoutE][5]), nLongitudeDegrees) ||
301                                        !AtlStringToInteger(MatchContext.GetMatchString(g_pnMap[nLayoutE][6]), nLongitudeMinutes) ||
302                                        !AtlStringToDouble(MatchContext.GetMatchString(g_pnMap[nLayoutE][7]), fLongitudeSeconds) ||
303                                        FALSE)
304                                        return FALSE;
305                                _A(nLatitudeMinutes >= 0 && nLongitudeMinutes >= 0);
306                                if(nLatitudeMinutes >= 60 || nLongitudeMinutes >= 60)
307                                        return FALSE;
308                                _A(fLatitudeSeconds >= 0 && fLongitudeSeconds >= 0);
309                                if(fLatitudeSeconds >= 60 || fLongitudeSeconds >= 60)
310                                        return FALSE;
311                                const DOUBLE fLatitude = nLatitudeSign * (nLatitudeDegrees + (nLatitudeMinutes + fLatitudeSeconds / 60.0) / 60.0);
312                                const DOUBLE fLongitude = nLongitudeSign * (nLongitudeDegrees + (nLongitudeMinutes + fLongitudeSeconds / 60.0) / 60.0);
313                                SetLocation(fLatitude, fLongitude);
314                                return TRUE;
315                        }
316                        #pragma endregion
317                        #pragma region Degrees, Latitude and Longitude
318                        static CAtlStaticRegExp<> g_ExpressionC(_T("^ *") _T("{-?[0-9]+\\.[0-9]+}") _T("[^0-9\\.]+") _T("{-?[0-9]+\\.[0-9]+}"), FALSE);
319                        if(g_ExpressionC.Match(sText, &MatchContext))
320                        {
321                                DOUBLE fLatitude, fLongitude;
322                                if(!AtlStringToDouble(MatchContext.GetMatchString(0), fLatitude) || !AtlStringToDouble(MatchContext.GetMatchString(1), fLongitude))
323                                        return FALSE;
324                                SetLocation(fLatitude, fLongitude);
325                                return TRUE;
326                        }
327                        #pragma endregion
328                        return FALSE;
329                }
330        };
331
332        ////////////////////////////////////////////////////////
333        // CLocationArray
334
335        class CLocationArray : 
336                public CRoArrayT<CLocation>
337        {
338        public:
339        // CLocationArray
340                SIZE_T GetValidCount() const throw()
341                {
342                        SIZE_T nCount = 0;
343                        for(SIZE_T nIndex = 0; nIndex < GetCount(); nIndex++)
344                                if(GetAt(nIndex).IsValid())
345                                        nCount++;
346                        return nCount;
347                }
348                BOOL FindFirstValidIndex(SIZE_T* pnIndex = NULL) const throw()
349                {
350                        for(SIZE_T nIndex = 0; nIndex < GetCount(); nIndex++)
351                                if(GetAt(nIndex).IsValid())
352                                {
353                                        if(pnIndex)
354                                                *pnIndex = nIndex;
355                                        return TRUE;
356                                }
357                        return FALSE;
358                }
359                CString GetText(SIZE_T nTextIndex) const
360                {
361                        //_A(nTextIndex < DIM(CLocation::CStrings::m_psTexts));
362                        CRoArrayT<CString> Array;
363                        for(SIZE_T nIndex = 0; nIndex < GetCount(); nIndex++)
364                        {
365                                const CLocation& Location = GetAt(nIndex);
366                                CString sText;
367                                if(Location.IsValid())
368                                        sText = CLocation::CStrings(Location).m_psTexts[nTextIndex];
369                                _W(Array.Add(sText) >= 0);
370                        }
371                        return _StringHelper::Join(Array, _T("\r\n"));
372                }
373        };
374
375private:
376        CRoIconStatic m_IntroductionStatic;
377        CRoHyperStatic m_pStatics[12];
378        CRoHyperStatic m_GoogleMapsStatic;
379        CRoHyperStatic m_YandexMapsStatic;
380        CRoHyperStatic m_BingMapsStatic;
381        CRoHyperStatic m_YahooMapsStatic;
382        CRoHyperStatic m_OpenStreetMapStatic;
383        CRoHyperStatic m_WikiMapiaStatic;
384        BOOL m_bSetClipboardTextActive;
385        CWindow m_NextClipboardViewerWindow;
386        CLocationArray m_LocationArray;
387
388public:
389// CMainDialog
390        CMainDialog()
391        {
392        }
393        VOID SetLocation(const CLocation& Location)
394        {
395                CLocation::CStrings Strings(Location);
396                for(SIZE_T nIndex = 0; nIndex < 12; nIndex++)
397                        m_pStatics[nIndex].SetWindowText(AtlFormatString(_T("<A HREF=\"%s\">%s</A> (F%d)"), Strings.m_psTexts[nIndex], Strings.m_psTexts[nIndex], nIndex + 1));
398                m_GoogleMapsStatic.SetWindowText(AtlFormatString(_T("<A TITLE=\"Open in Google Maps\" HREF=\"%s\">%s</A>"), Strings.m_sGoogleMapsLocation, Strings.m_sGoogleMapsLocation));
399                m_YandexMapsStatic.SetWindowText(AtlFormatString(_T("<A TITLE=\"Open in Yandex Maps\" HREF=\"%s\">%s</A>"), Strings.m_sYandexMapsLocation, Strings.m_sYandexMapsLocation));
400                m_BingMapsStatic.SetWindowText(AtlFormatString(_T("<A TITLE=\"Open in Bing Maps\" HREF=\"%s\">%s</A>"), Strings.m_sBingMapsLocation, Strings.m_sBingMapsLocation));
401                m_YahooMapsStatic.SetWindowText(AtlFormatString(_T("<A TITLE=\"Open in Yahoo Maps\" HREF=\"%s\">%s</A>"), Strings.m_sYahooMapsLocation, Strings.m_sYahooMapsLocation));
402                m_OpenStreetMapStatic.SetWindowText(AtlFormatString(_T("<A TITLE=\"Open in Open Street Map\" HREF=\"%s\">%s</A>"), Strings.m_sOpenStreetMapLocation, Strings.m_sOpenStreetMapLocation));
403                m_WikiMapiaStatic.SetWindowText(AtlFormatString(_T("<A TITLE=\"Open in WikiMapia\" HREF=\"%s\">%s</A>"), Strings.m_sWikiMapiaLocation, Strings.m_sWikiMapiaLocation));
404        }
405        BOOL Parse(CString sText)
406        {
407                CLocationArray LocationArray;
408                if(sText.GetLength() < 32 << 10) // 32 KB
409                {
410                        if(sText.Find(_T('\n')) >= 0)
411                        {
412                                sText.Replace(_T("\r\n"), _T("\n"));
413                                CRoArrayT<CString> Array;
414                                if(_StringHelper::Split(sText, _T('\n'), Array))
415                                        for(SIZE_T nIndex = 0; nIndex < Array.GetCount(); nIndex++)
416                                        {
417                                                CLocation Location;
418                                                Location.Parse(Array[nIndex]);
419                                                _W(LocationArray.Add(Location) >= 0);
420                                        }
421                                if(!LocationArray.GetValidCount())
422                                        LocationArray.RemoveAll();
423                        } else
424                        {
425                                CLocation Location;
426                                if(Location.Parse(sText))
427                                        _W(LocationArray.Add(Location) >= 0);
428                        }
429                }
430                SIZE_T nFirstValidIndex;
431                if(!LocationArray.FindFirstValidIndex(&nFirstValidIndex))
432                        return FALSE;
433                const CLocation& Location = LocationArray[nFirstValidIndex];
434                SetLocation(Location);
435                SwapMemory(&m_LocationArray, &LocationArray);
436                return TRUE;
437        }
438        BOOL Parse(LPCTSTR pszText)
439        {
440                return Parse(CString(pszText));
441        }
442
443// Window message handelrs
444        LRESULT OnInitDialog(HWND, LPARAM)
445        {
446                SetIcon(AtlLoadIconImage(IDI_MODULE, LR_DEFAULTCOLOR, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)), TRUE);
447                SetIcon(AtlLoadIconImage(IDI_MODULE, LR_DEFAULTCOLOR, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)), FALSE);
448                CMenuHandle Menu = GetSystemMenu(FALSE);
449                _W(Menu.AppendMenu(MF_SEPARATOR));
450                _W(Menu.AppendMenu(MF_STRING, ID_APP_ABOUT, _T("&About...")));
451                _W(m_IntroductionStatic.SubclassWindow(GetDlgItem(IDC_MAIN_INTRODUCTION)));
452                for(SIZE_T nIndex = 0; nIndex < 12; nIndex++)
453                        _W(m_pStatics[nIndex].SubclassWindow(GetDlgItem(IDC_MAIN_DEGREES_LATITUDE + nIndex)));
454                _W(m_GoogleMapsStatic.SubclassWindow(GetDlgItem(IDC_MAIN_GOOGLEMAPS)));
455                _W(m_YandexMapsStatic.SubclassWindow(GetDlgItem(IDC_MAIN_YANDEXMAPS)));
456                _W(m_BingMapsStatic.SubclassWindow(GetDlgItem(IDC_MAIN_BINGMAPS)));
457                _W(m_YahooMapsStatic.SubclassWindow(GetDlgItem(IDC_MAIN_YAHOOMAPS)));
458                _W(m_OpenStreetMapStatic.SubclassWindow(GetDlgItem(IDC_MAIN_OPENSTREETMAP)));
459                _W(m_WikiMapiaStatic.SubclassWindow(GetDlgItem(IDC_MAIN_WIKIMAPIA)));
460                _W(CenterWindow());
461                m_bSetClipboardTextActive = FALSE;
462                m_NextClipboardViewerWindow = SetClipboardViewer();
463                for(SIZE_T nIndex = 0; nIndex < 12; nIndex++)
464                        _W(RegisterHotKey(m_hWnd, (INT) nIndex, MOD_CONTROL | MOD_SHIFT, VK_F1 + nIndex));
465#if _DEVELOPMENT
466                //SetText(_T("http://maps.google.com.ua/maps/ms?msid=206853065838475655514.0004af0a0899ed541f5f2&msa=0&ll=45.296505,35.771999&spn=0.039547,0.095272"));
467                //SetText(_T("http://maps.yandex.ru/?ll=13.376147%2C45.797846&spn=2.820740%2C1.127727&z=9&l=map"));
468#endif // _DEVELOPMENT
469                return TRUE;
470        }
471        LRESULT OnDestroy() throw()
472        {
473                for(SIZE_T nIndex = 0; nIndex < 12; nIndex++)
474                        _W(UnregisterHotKey(m_hWnd, (INT) nIndex));
475                _W(ChangeClipboardChain(m_NextClipboardViewerWindow));
476                return 0;
477        }
478        LRESULT OnChangeCbChain(CWindow RemovedWindow, CWindow NextWindow)
479        {
480                if(m_NextClipboardViewerWindow == RemovedWindow)
481                        m_NextClipboardViewerWindow = NextWindow;
482                else if(m_NextClipboardViewerWindow)
483                        m_NextClipboardViewerWindow.SendMessage(WM_CHANGECBCHAIN, (WPARAM) (HWND) RemovedWindow, (LPARAM) (HWND) NextWindow);
484                return 0;
485        }
486        LRESULT OnDrawClipboard()
487        {
488                if(m_bSetClipboardTextActive)
489                        return 0;
490                if(OpenClipboard()) 
491                {
492                        _ATLTRY
493                        {
494                                if(IsClipboardFormatAvailable(CF_UNICODETEXT))
495                                {
496                                        CGlobalMemoryWeakHandle DataHandle = (HGLOBAL) GetClipboardData(CF_UNICODETEXT);
497                                        __E(DataHandle);
498                                        CGlobalMemoryHandle::CLockT<WCHAR> pszData(DataHandle);
499                                        if(Parse(CW2CT(pszData)))
500                                        {
501                                                FLASHWINFO FlashWindowInformation = { sizeof FlashWindowInformation, m_hWnd, FLASHW_CAPTION, 5 };
502                                                _W(FlashWindowEx(&FlashWindowInformation));
503                                                //MessageBeep(MB_OK);
504                                        }
505                                }
506                        }
507                        _ATLCATCHALL()
508                        {
509                                _W(CloseClipboard());
510                                _ATLRETHROW;
511                        }
512                        _W(CloseClipboard());
513                }
514                return 0;
515        }
516        LRESULT OnSysCommand(UINT nCommand, CPoint)
517        {
518                switch(nCommand)
519                {
520                case ID_APP_ABOUT:
521                        {
522                                CAboutDialog Dialog;
523                                Dialog.DoModal(m_hWnd);
524                        }
525                        break;
526                default:
527                        SetMsgHandled(FALSE);
528                }
529                return 0;
530        }
531        LRESULT OnCommand(UINT, INT nIdentifier, HWND)
532        {
533                _W(EndDialog(nIdentifier));
534                return 0;
535        }
536        LRESULT OnStaticAnchorClicked(NMHDR* pHeader)
537        {
538                CRoHyperStatic::NMANCHORCLICKED* pHeaderEx = (CRoHyperStatic::NMANCHORCLICKED*) pHeader;
539                CString sLocation = pHeaderEx->pszLocation;
540                #pragma region Update with Multiple Value Text
541                if(pHeaderEx->Header.idFrom >= IDC_MAIN_DEGREES_LATITUDE && pHeaderEx->Header.idFrom <= IDC_MAIN_DEGREESMINUTESSECONDS_LONGITUDELATITUDE)
542                        if(m_LocationArray.GetValidCount() > 0)
543                                sLocation = m_LocationArray.GetText(pHeaderEx->Header.idFrom - IDC_MAIN_DEGREES_LATITUDE);
544                #pragma endregion
545                m_bSetClipboardTextActive = TRUE;
546                SetClipboardText(m_hWnd, sLocation);
547                m_bSetClipboardTextActive = FALSE;
548                pHeaderEx->bShellExecuteLocation = FALSE;
549                MessageBeep(MB_OK);
550                return 0;
551        }
552        LRESULT OnHotKey(INT nIdentifier, UINT nModifierFlags, UINT nVirtualKey)
553        {
554                nModifierFlags; nVirtualKey;
555                if(nIdentifier < 12)
556                {
557#if TRUE
558                        if(m_LocationArray.GetValidCount() > 0)
559                        {
560                                CRoArrayT<CString> Array;
561                                for(SIZE_T nIndex = 0; nIndex < m_LocationArray.GetCount(); nIndex++)
562                                {
563                                        const CLocation& Location = m_LocationArray[nIndex];
564                                        CString sText;
565                                        if(Location.IsValid())
566                                                sText = CLocation::CStrings(Location).m_psTexts[nIdentifier];
567                                        _W(Array.Add(sText) >= 0);
568                                }
569                                m_bSetClipboardTextActive = TRUE;
570                                SetClipboardText(m_hWnd, _StringHelper::Join(Array, _T("\r\n")));
571                                m_bSetClipboardTextActive = FALSE;
572                                MessageBeep(MB_OK);
573                        }
574#else
575                        CString sText;
576                        m_pStatics[nIdentifier].GetWindowText(sText);
577                        CRoReMatchContext MatchContext;
578                        static CAtlStaticRegExp<> g_Expression(_T("HREF=\"{.+?}\""), FALSE);
579                        if(g_Expression.Match(sText, &MatchContext))
580                        {
581                                m_bSetClipboardTextActive = TRUE;
582                                SetClipboardText(m_hWnd, MatchContext.GetMatchString(0));
583                                m_bSetClipboardTextActive = FALSE;
584                                MessageBeep(MB_OK);
585                        }
586#endif
587                }
588                return 0;
589        }
590};
Note: See TracBrowser for help on using the repository browser.