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

Last change on this file since 937 was 137, checked in by roman, 11 years ago

Added missing forwarding for WM_DRAWCLIPBOARD (thanks to David Ching)

  • Property svn:keywords set to Id
File size: 24.4 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2008-2011
3// Created by Roman Ryltsov roman@alax.info
4//
5// $Id: MainDialog.h 137 2012-10-15 19:18:03Z 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                        #define OPTIONAL_PROTOCOL       _T("(https?://)?[^/]*")
183                        #define VALUE                           _T("{\\-?[\\.0-9]+}")
184                                static CAtlStaticRegExp<> g_ExpressionA(_T("^ *") OPTIONAL_PROTOCOL _T("maps.google[^/]*/.+?") _T("ll=") VALUE _T(",") VALUE, FALSE);
185                        #undef OPTIONAL_PROTOCOL
186                        #undef VALUE
187                        if(g_ExpressionA.Match(sText, &MatchContext))
188                        {
189                                DOUBLE fLatitude, fLongitude;
190                                if(!AtlStringToDouble(MatchContext.GetMatchString(0), fLatitude) || !AtlStringToDouble(MatchContext.GetMatchString(1), fLongitude))
191                                        return FALSE;
192                                SetLocation(fLatitude, fLongitude);
193                                return TRUE;
194                        }
195                        #pragma endregion
196                        #pragma region Yandex Maps
197                        #define OPTIONAL_PROTOCOL       _T("(https?://)?[^/]*")
198                        #define VALUE                           _T("{\\-?[\\.0-9]+}")
199                                static CAtlStaticRegExp<> g_ExpressionB(_T("^ *") OPTIONAL_PROTOCOL _T("maps.yandex[^/]*/.+?") _T("ll=") VALUE _T("(,|(\\%2C))") VALUE, FALSE);
200                        #undef OPTIONAL_PROTOCOL
201                        #undef VALUE
202                        if(g_ExpressionB.Match(sText, &MatchContext))
203                        {
204                                DOUBLE fLatitude, fLongitude;
205                                if(!AtlStringToDouble(MatchContext.GetMatchString(0), fLongitude) || !AtlStringToDouble(MatchContext.GetMatchString(1), fLatitude))
206                                        return FALSE;
207                                SetLocation(fLatitude, fLongitude);
208                                return TRUE;
209                        }
210                        #pragma endregion
211                        // TODO: Recognize Bing, Yahoo, OpenStreetMap and WikiMapia URLs
212                        // NOTE: Russian Å is often confused with English E, so we take both
213                        #pragma region Degrees and Minutes
214#define LATITUDE_SYMBOL         _T("{[NSCÞ]}")
215#define LONGITUDE_SYMBOL        _T("{[EWÂÇÅ]}")
216#define VALUE                           _T("{[0-9]+}[^0-9]+?{[0-9]+\\.[0-9]+}")
217#define OPTIONAL_WHITESPACE     _T("[\t ]*")
218#define SEPARATOR                       _T("[^0-9\\.]+?")
219                        static CAtlStaticRegExp<> g_ExpressionD0(_T("^") OPTIONAL_WHITESPACE LATITUDE_SYMBOL OPTIONAL_WHITESPACE VALUE SEPARATOR LONGITUDE_SYMBOL OPTIONAL_WHITESPACE VALUE _T(""), FALSE);
220                        static CAtlStaticRegExp<> g_ExpressionD1(_T("^") OPTIONAL_WHITESPACE LONGITUDE_SYMBOL OPTIONAL_WHITESPACE VALUE SEPARATOR LATITUDE_SYMBOL OPTIONAL_WHITESPACE VALUE _T(""), FALSE);
221                        static CAtlStaticRegExp<> g_ExpressionD2(_T("^") OPTIONAL_WHITESPACE VALUE OPTIONAL_WHITESPACE LATITUDE_SYMBOL SEPARATOR VALUE OPTIONAL_WHITESPACE LONGITUDE_SYMBOL _T(""), FALSE);
222                        static CAtlStaticRegExp<> g_ExpressionD3(_T("^") OPTIONAL_WHITESPACE VALUE OPTIONAL_WHITESPACE LATITUDE_SYMBOL SEPARATOR VALUE OPTIONAL_WHITESPACE LONGITUDE_SYMBOL _T(""), FALSE);
223#undef LATITUDE_SYMBOL
224#undef LONGITUDE_SYMBOL
225#undef VALUE
226#undef OPTIONAL_WHITESPACE
227#undef SEPARATOR
228                        INT nLayoutD = -1;
229                        if(g_ExpressionD0.Match(sText, &MatchContext))
230                                nLayoutD = 0;
231                        else if(g_ExpressionD1.Match(sText, &MatchContext))
232                                nLayoutD = 1;
233                        else if(g_ExpressionD2.Match(sText, &MatchContext))
234                                nLayoutD = 2;
235                        else if(g_ExpressionD3.Match(sText, &MatchContext))
236                                nLayoutD = 3;
237                        if(nLayoutD >= 0)
238                        {
239                                static const SIZE_T g_pnMap[4][6] = 
240                                {
241                                        { 0, 1, 2, 3, 4, 5, },
242                                        { 3, 4, 5, 0, 1, 2, },
243                                        { 2, 0, 1, 5, 3, 4, },
244                                        { 5, 3, 4, 2, 0, 1, },
245                                };
246                                const INT nLatitudeSign = (MatchContext.GetMatchString(g_pnMap[nLayoutD][0]).FindOneOf(_T("SsÞþ")) >= 0) ? -1 : 1;
247                                const INT nLongitudeSign = (MatchContext.GetMatchString(g_pnMap[nLayoutD][3]).FindOneOf(_T("WwÇç")) >= 0) ? -1 : 1;
248                                INT nLatitudeDegrees, nLongitudeDegrees;
249                                DOUBLE fLatitudeMinutes, fLongitudeMinutes;
250                                if(FALSE ||
251                                        !AtlStringToInteger(MatchContext.GetMatchString(g_pnMap[nLayoutD][1]), nLatitudeDegrees) || 
252                                        !AtlStringToDouble(MatchContext.GetMatchString(g_pnMap[nLayoutD][2]), fLatitudeMinutes) || 
253                                        !AtlStringToInteger(MatchContext.GetMatchString(g_pnMap[nLayoutD][4]), nLongitudeDegrees) ||
254                                        !AtlStringToDouble(MatchContext.GetMatchString(g_pnMap[nLayoutD][5]), fLongitudeMinutes) ||
255                                        FALSE)
256                                        return FALSE;
257                                _A(fLatitudeMinutes >= 0 && fLongitudeMinutes >= 0);
258                                if(fLatitudeMinutes >= 60.0 || fLongitudeMinutes >= 60.0)
259                                        return FALSE;
260                                const DOUBLE fLatitude = nLatitudeSign * (nLatitudeDegrees + fLatitudeMinutes / 60.0);
261                                const DOUBLE fLongitude = nLongitudeSign * (nLongitudeDegrees + fLongitudeMinutes / 60.0);
262                                SetLocation(fLatitude, fLongitude);
263                                return TRUE;
264                        }
265                        #pragma endregion
266                        #pragma region Degrees, Minutes and Seconds
267#define LATITUDE_SYMBOL         _T("{[NSCÞ]}")
268#define LONGITUDE_SYMBOL        _T("{[EWÂÇÅ]}")
269#define VALUE                           _T("{[0-9]+}[^0-9]+?{[0-9]+}[^0-9\\.]+?{[0-9]+(\\.([0-9]+)?)?}")
270#define OPTIONAL_WHITESPACE     _T("[\t ]*")
271#define SEPARATOR                       _T("[^0-9\\.]+?")
272                        static CAtlStaticRegExp<> g_ExpressionE0(_T("^") OPTIONAL_WHITESPACE LATITUDE_SYMBOL OPTIONAL_WHITESPACE VALUE SEPARATOR LONGITUDE_SYMBOL OPTIONAL_WHITESPACE VALUE _T(""), FALSE);
273                        static CAtlStaticRegExp<> g_ExpressionE1(_T("^") OPTIONAL_WHITESPACE LONGITUDE_SYMBOL OPTIONAL_WHITESPACE VALUE SEPARATOR LATITUDE_SYMBOL OPTIONAL_WHITESPACE VALUE  _T(""), FALSE);
274                        static CAtlStaticRegExp<> g_ExpressionE2(_T("^") OPTIONAL_WHITESPACE VALUE OPTIONAL_WHITESPACE LATITUDE_SYMBOL SEPARATOR VALUE OPTIONAL_WHITESPACE LONGITUDE_SYMBOL _T(""), FALSE);
275                        static CAtlStaticRegExp<> g_ExpressionE3(_T("^") OPTIONAL_WHITESPACE VALUE OPTIONAL_WHITESPACE LONGITUDE_SYMBOL SEPARATOR VALUE OPTIONAL_WHITESPACE LATITUDE_SYMBOL _T(""), FALSE);
276#undef LATITUDE_SYMBOL
277#undef LONGITUDE_SYMBOL
278#undef VALUE
279#undef OPTIONAL_WHITESPACE
280#undef SEPARATOR
281                        INT nLayoutE = -1;
282                        if(g_ExpressionE0.Match(sText, &MatchContext))
283                                nLayoutE = 0;
284                        else if(g_ExpressionE1.Match(sText, &MatchContext))
285                                nLayoutE = 1;
286                        else if(g_ExpressionE2.Match(sText, &MatchContext))
287                                nLayoutE = 2;
288                        else if(g_ExpressionE3.Match(sText, &MatchContext))
289                                nLayoutE = 3;
290                        if(nLayoutE >= 0)
291                        {
292                                static const SIZE_T g_pnMap[4][8] = 
293                                {
294                                        { 0, 1, 2, 3, 4, 5, 6, 7, },
295                                        { 4, 5, 6, 7, 0, 1, 2, 3, },
296                                        { 3, 0, 1, 2, 7, 4, 5, 6, },
297                                        { 7, 4, 5, 6, 3, 0, 1, 2, },
298                                };
299                                const INT nLatitudeSign = (MatchContext.GetMatchString(g_pnMap[nLayoutE][0]).FindOneOf(_T("SsÞþ")) >= 0) ? -1 : 1;
300                                const INT nLongitudeSign = (MatchContext.GetMatchString(g_pnMap[nLayoutE][4]).FindOneOf(_T("WwÇç")) >= 0) ? -1 : 1;
301                                INT nLatitudeDegrees, nLongitudeDegrees;
302                                INT nLatitudeMinutes, nLongitudeMinutes;
303                                DOUBLE fLatitudeSeconds, fLongitudeSeconds;
304                                if(FALSE ||
305                                        !AtlStringToInteger(MatchContext.GetMatchString(g_pnMap[nLayoutE][1]), nLatitudeDegrees) || 
306                                        !AtlStringToInteger(MatchContext.GetMatchString(g_pnMap[nLayoutE][2]), nLatitudeMinutes) || 
307                                        !AtlStringToDouble(MatchContext.GetMatchString(g_pnMap[nLayoutE][3]), fLatitudeSeconds) || 
308                                        !AtlStringToInteger(MatchContext.GetMatchString(g_pnMap[nLayoutE][5]), nLongitudeDegrees) ||
309                                        !AtlStringToInteger(MatchContext.GetMatchString(g_pnMap[nLayoutE][6]), nLongitudeMinutes) ||
310                                        !AtlStringToDouble(MatchContext.GetMatchString(g_pnMap[nLayoutE][7]), fLongitudeSeconds) ||
311                                        FALSE)
312                                        return FALSE;
313                                _A(nLatitudeMinutes >= 0 && nLongitudeMinutes >= 0);
314                                if(nLatitudeMinutes >= 60 || nLongitudeMinutes >= 60)
315                                        return FALSE;
316                                _A(fLatitudeSeconds >= 0 && fLongitudeSeconds >= 0);
317                                if(fLatitudeSeconds >= 60 || fLongitudeSeconds >= 60)
318                                        return FALSE;
319                                const DOUBLE fLatitude = nLatitudeSign * (nLatitudeDegrees + (nLatitudeMinutes + fLatitudeSeconds / 60.0) / 60.0);
320                                const DOUBLE fLongitude = nLongitudeSign * (nLongitudeDegrees + (nLongitudeMinutes + fLongitudeSeconds / 60.0) / 60.0);
321                                SetLocation(fLatitude, fLongitude);
322                                return TRUE;
323                        }
324                        #pragma endregion
325                        #pragma region Degrees, Latitude and Longitude
326                        static CAtlStaticRegExp<> g_ExpressionC(_T("^ *") _T("{-?[0-9]+\\.[0-9]+}") _T("[^0-9\\.]+") _T("{-?[0-9]+\\.[0-9]+}"), FALSE);
327                        if(g_ExpressionC.Match(sText, &MatchContext))
328                        {
329                                DOUBLE fLatitude, fLongitude;
330                                if(!AtlStringToDouble(MatchContext.GetMatchString(0), fLatitude) || !AtlStringToDouble(MatchContext.GetMatchString(1), fLongitude))
331                                        return FALSE;
332                                SetLocation(fLatitude, fLongitude);
333                                return TRUE;
334                        }
335                        #pragma endregion
336                        return FALSE;
337                }
338        };
339
340        ////////////////////////////////////////////////////////
341        // CLocationArray
342
343        class CLocationArray : 
344                public CRoArrayT<CLocation>
345        {
346        public:
347        // CLocationArray
348                SIZE_T GetValidCount() const throw()
349                {
350                        SIZE_T nCount = 0;
351                        for(SIZE_T nIndex = 0; nIndex < GetCount(); nIndex++)
352                                if(GetAt(nIndex).IsValid())
353                                        nCount++;
354                        return nCount;
355                }
356                BOOL FindFirstValidIndex(SIZE_T* pnIndex = NULL) const throw()
357                {
358                        for(SIZE_T nIndex = 0; nIndex < GetCount(); nIndex++)
359                                if(GetAt(nIndex).IsValid())
360                                {
361                                        if(pnIndex)
362                                                *pnIndex = nIndex;
363                                        return TRUE;
364                                }
365                        return FALSE;
366                }
367                CString GetText(SIZE_T nTextIndex) const
368                {
369                        //_A(nTextIndex < DIM(CLocation::CStrings::m_psTexts));
370                        CRoArrayT<CString> Array;
371                        for(SIZE_T nIndex = 0; nIndex < GetCount(); nIndex++)
372                        {
373                                const CLocation& Location = GetAt(nIndex);
374                                CString sText;
375                                if(Location.IsValid())
376                                        sText = CLocation::CStrings(Location).m_psTexts[nTextIndex];
377                                _W(Array.Add(sText) >= 0);
378                        }
379                        return _StringHelper::Join(Array, _T("\r\n"));
380                }
381        };
382
383private:
384        CRoIconStatic m_IntroductionStatic;
385        CRoHyperStatic m_pStatics[12];
386        CRoHyperStatic m_GoogleMapsStatic;
387        CRoHyperStatic m_YandexMapsStatic;
388        CRoHyperStatic m_BingMapsStatic;
389        CRoHyperStatic m_YahooMapsStatic;
390        CRoHyperStatic m_OpenStreetMapStatic;
391        CRoHyperStatic m_WikiMapiaStatic;
392        BOOL m_bSetClipboardTextActive;
393        CWindow m_NextClipboardViewerWindow;
394        CLocationArray m_LocationArray;
395
396public:
397// CMainDialog
398        CMainDialog()
399        {
400        }
401        VOID SetLocation(const CLocation& Location)
402        {
403                CLocation::CStrings Strings(Location);
404                for(SIZE_T nIndex = 0; nIndex < 12; nIndex++)
405                        m_pStatics[nIndex].SetWindowText(AtlFormatString(_T("<A HREF=\"%s\">%s</A> (F%d)"), Strings.m_psTexts[nIndex], Strings.m_psTexts[nIndex], nIndex + 1));
406                m_GoogleMapsStatic.SetWindowText(AtlFormatString(_T("<A TITLE=\"Open in Google Maps\" HREF=\"%s\">%s</A>"), Strings.m_sGoogleMapsLocation, Strings.m_sGoogleMapsLocation));
407                m_YandexMapsStatic.SetWindowText(AtlFormatString(_T("<A TITLE=\"Open in Yandex Maps\" HREF=\"%s\">%s</A>"), Strings.m_sYandexMapsLocation, Strings.m_sYandexMapsLocation));
408                m_BingMapsStatic.SetWindowText(AtlFormatString(_T("<A TITLE=\"Open in Bing Maps\" HREF=\"%s\">%s</A>"), Strings.m_sBingMapsLocation, Strings.m_sBingMapsLocation));
409                m_YahooMapsStatic.SetWindowText(AtlFormatString(_T("<A TITLE=\"Open in Yahoo Maps\" HREF=\"%s\">%s</A>"), Strings.m_sYahooMapsLocation, Strings.m_sYahooMapsLocation));
410                m_OpenStreetMapStatic.SetWindowText(AtlFormatString(_T("<A TITLE=\"Open in Open Street Map\" HREF=\"%s\">%s</A>"), Strings.m_sOpenStreetMapLocation, Strings.m_sOpenStreetMapLocation));
411                m_WikiMapiaStatic.SetWindowText(AtlFormatString(_T("<A TITLE=\"Open in WikiMapia\" HREF=\"%s\">%s</A>"), Strings.m_sWikiMapiaLocation, Strings.m_sWikiMapiaLocation));
412        }
413        BOOL Parse(CString sText)
414        {
415                CLocationArray LocationArray;
416                if(sText.GetLength() < 32 << 10) // 32 KB
417                {
418                        if(sText.Find(_T('\n')) >= 0)
419                        {
420                                sText.Replace(_T("\r\n"), _T("\n"));
421                                CRoArrayT<CString> Array;
422                                if(_StringHelper::Split(sText, _T('\n'), Array))
423                                        for(SIZE_T nIndex = 0; nIndex < Array.GetCount(); nIndex++)
424                                        {
425                                                CLocation Location;
426                                                Location.Parse(Array[nIndex]);
427                                                _W(LocationArray.Add(Location) >= 0);
428                                        }
429                                if(!LocationArray.GetValidCount())
430                                        LocationArray.RemoveAll();
431                        } else
432                        {
433                                CLocation Location;
434                                if(Location.Parse(sText))
435                                        _W(LocationArray.Add(Location) >= 0);
436                        }
437                }
438                SIZE_T nFirstValidIndex;
439                if(!LocationArray.FindFirstValidIndex(&nFirstValidIndex))
440                        return FALSE;
441                const CLocation& Location = LocationArray[nFirstValidIndex];
442                SetLocation(Location);
443                SwapMemory(&m_LocationArray, &LocationArray);
444                return TRUE;
445        }
446        BOOL Parse(LPCTSTR pszText)
447        {
448                return Parse(CString(pszText));
449        }
450
451// Window message handelrs
452        LRESULT OnInitDialog(HWND, LPARAM)
453        {
454                SetIcon(AtlLoadIconImage(IDI_MODULE, LR_DEFAULTCOLOR, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)), TRUE);
455                SetIcon(AtlLoadIconImage(IDI_MODULE, LR_DEFAULTCOLOR, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)), FALSE);
456                CMenuHandle Menu = GetSystemMenu(FALSE);
457                _W(Menu.AppendMenu(MF_SEPARATOR));
458                _W(Menu.AppendMenu(MF_STRING, ID_APP_ABOUT, _T("&About...")));
459                _W(m_IntroductionStatic.SubclassWindow(GetDlgItem(IDC_MAIN_INTRODUCTION)));
460                for(SIZE_T nIndex = 0; nIndex < 12; nIndex++)
461                        _W(m_pStatics[nIndex].SubclassWindow(GetDlgItem(IDC_MAIN_DEGREES_LATITUDE + nIndex)));
462                _W(m_GoogleMapsStatic.SubclassWindow(GetDlgItem(IDC_MAIN_GOOGLEMAPS)));
463                _W(m_YandexMapsStatic.SubclassWindow(GetDlgItem(IDC_MAIN_YANDEXMAPS)));
464                _W(m_BingMapsStatic.SubclassWindow(GetDlgItem(IDC_MAIN_BINGMAPS)));
465                _W(m_YahooMapsStatic.SubclassWindow(GetDlgItem(IDC_MAIN_YAHOOMAPS)));
466                _W(m_OpenStreetMapStatic.SubclassWindow(GetDlgItem(IDC_MAIN_OPENSTREETMAP)));
467                _W(m_WikiMapiaStatic.SubclassWindow(GetDlgItem(IDC_MAIN_WIKIMAPIA)));
468                _W(CenterWindow());
469                m_bSetClipboardTextActive = FALSE;
470                m_NextClipboardViewerWindow = SetClipboardViewer();
471                #if !defined(_DEBUG)
472                for(SIZE_T nIndex = 0; nIndex < 12; nIndex++)
473                        _W(RegisterHotKey(m_hWnd, (INT) nIndex, MOD_CONTROL | MOD_SHIFT, VK_F1 + nIndex));
474                #endif // !defined(_DEBUG)
475                #if _DEVELOPMENT
476                //Parse(_T("http://maps.google.com.ua/maps/ms?msid=206853065838475655514.0004af0a0899ed541f5f2&msa=0&ll=45.296505,35.771999&spn=0.039547,0.095272"));
477                //Parse(_T("http://maps.yandex.ru/?ll=13.376147%2C45.797846&spn=2.820740%2C1.127727&z=9&l=map"));
478                //Parse(_T("https://maps.google.com/maps?q=ll=36.257978,-115.236111&spn=0.094126,0.157585&sll=33.809282,-117.915442&sspn=0.09699,0.157585&oq=las+vegax&t=h&hnear=Las+Vegas,+Clark,+Nevada&z=13"));
479                #endif // _DEVELOPMENT
480                return TRUE;
481        }
482        LRESULT OnDestroy() throw()
483        {
484                #if !defined(_DEBUG)
485                for(SIZE_T nIndex = 0; nIndex < 12; nIndex++)
486                        _W(UnregisterHotKey(m_hWnd, (INT) nIndex));
487                #endif // !defined(_DEBUG)
488                _W(ChangeClipboardChain(m_NextClipboardViewerWindow));
489                return 0;
490        }
491        LRESULT OnChangeCbChain(CWindow RemovedWindow, CWindow NextWindow)
492        {
493                if(m_NextClipboardViewerWindow == RemovedWindow)
494                        m_NextClipboardViewerWindow = NextWindow;
495                else if(m_NextClipboardViewerWindow)
496                        m_NextClipboardViewerWindow.SendMessage(WM_CHANGECBCHAIN, (WPARAM) (HWND) RemovedWindow, (LPARAM) (HWND) NextWindow);
497                return 0;
498        }
499        LRESULT OnDrawClipboard()
500        {
501                if(m_bSetClipboardTextActive)
502                        return 0;
503                if(OpenClipboard()) 
504                {
505                        _ATLTRY
506                        {
507                                if(IsClipboardFormatAvailable(CF_UNICODETEXT))
508                                {
509                                        CGlobalMemoryWeakHandle DataHandle = (HGLOBAL) GetClipboardData(CF_UNICODETEXT);
510                                        __E(DataHandle);
511                                        CGlobalMemoryHandle::CLockT<WCHAR> pszData(DataHandle);
512                                        if(Parse(CW2CT(pszData)))
513                                        {
514                                                FLASHWINFO FlashWindowInformation = { sizeof FlashWindowInformation, m_hWnd, FLASHW_CAPTION, 5 };
515                                                _W(FlashWindowEx(&FlashWindowInformation));
516                                                //MessageBeep(MB_OK);
517                                        }
518                                }
519                        }
520                        _ATLCATCHALL()
521                        {
522                                _W(CloseClipboard());
523                                _ATLRETHROW;
524                        }
525                        _W(CloseClipboard());
526                }
527                if(m_NextClipboardViewerWindow)
528                        m_NextClipboardViewerWindow.SendMessage(WM_DRAWCLIPBOARD, m_pCurrentMsg->wParam, m_pCurrentMsg->lParam);
529                return 0;
530        }
531        LRESULT OnSysCommand(UINT nCommand, CPoint)
532        {
533                switch(nCommand)
534                {
535                case ID_APP_ABOUT:
536                        {
537                                CAboutDialog Dialog;
538                                Dialog.DoModal(m_hWnd);
539                        }
540                        break;
541                default:
542                        SetMsgHandled(FALSE);
543                }
544                return 0;
545        }
546        LRESULT OnCommand(UINT, INT nIdentifier, HWND)
547        {
548                _W(EndDialog(nIdentifier));
549                return 0;
550        }
551        LRESULT OnStaticAnchorClicked(NMHDR* pHeader)
552        {
553                CRoHyperStatic::NMANCHORCLICKED* pHeaderEx = (CRoHyperStatic::NMANCHORCLICKED*) pHeader;
554                CString sLocation = pHeaderEx->pszLocation;
555                #pragma region Update with Multiple Value Text
556                if(pHeaderEx->Header.idFrom >= IDC_MAIN_DEGREES_LATITUDE && pHeaderEx->Header.idFrom <= IDC_MAIN_DEGREESMINUTESSECONDS_LONGITUDELATITUDE)
557                        if(m_LocationArray.GetValidCount() > 0)
558                                sLocation = m_LocationArray.GetText(pHeaderEx->Header.idFrom - IDC_MAIN_DEGREES_LATITUDE);
559                #pragma endregion
560                m_bSetClipboardTextActive = TRUE;
561                SetClipboardText(m_hWnd, sLocation);
562                m_bSetClipboardTextActive = FALSE;
563                pHeaderEx->bShellExecuteLocation = FALSE;
564                MessageBeep(MB_OK);
565                return 0;
566        }
567        LRESULT OnHotKey(INT nIdentifier, UINT nModifierFlags, UINT nVirtualKey)
568        {
569                nModifierFlags; nVirtualKey;
570                if(nIdentifier < 12)
571                {
572#if TRUE
573                        if(m_LocationArray.GetValidCount() > 0)
574                        {
575                                CRoArrayT<CString> Array;
576                                for(SIZE_T nIndex = 0; nIndex < m_LocationArray.GetCount(); nIndex++)
577                                {
578                                        const CLocation& Location = m_LocationArray[nIndex];
579                                        CString sText;
580                                        if(Location.IsValid())
581                                                sText = CLocation::CStrings(Location).m_psTexts[nIdentifier];
582                                        _W(Array.Add(sText) >= 0);
583                                }
584                                m_bSetClipboardTextActive = TRUE;
585                                SetClipboardText(m_hWnd, _StringHelper::Join(Array, _T("\r\n")));
586                                m_bSetClipboardTextActive = FALSE;
587                                MessageBeep(MB_OK);
588                        }
589#else
590                        CString sText;
591                        m_pStatics[nIdentifier].GetWindowText(sText);
592                        CRoReMatchContext MatchContext;
593                        static CAtlStaticRegExp<> g_Expression(_T("HREF=\"{.+?}\""), FALSE);
594                        if(g_Expression.Match(sText, &MatchContext))
595                        {
596                                m_bSetClipboardTextActive = TRUE;
597                                SetClipboardText(m_hWnd, MatchContext.GetMatchString(0));
598                                m_bSetClipboardTextActive = FALSE;
599                                MessageBeep(MB_OK);
600                        }
601#endif
602                }
603                return 0;
604        }
605};
Note: See TracBrowser for help on using the repository browser.