11// This file is part of Notepad++ project
2- // Copyright (C)2003 Don HO <[email protected] >3- //
4- // This program is free software; you can redistribute it and/or
5- // modify it under the terms of the GNU General Public License
6- // as published by the Free Software Foundation; either
7- // version 2 of the License, or (at your option) any later version.
8- //
9- // Note that the GPL places important restrictions on "derived works", yet
10- // it does not provide a detailed definition of that term. To avoid
11- // misunderstandings, we consider an application to constitute a
12- // "derivative work" for the purpose of this license if it does any of the
13- // following:
14- // 1. Integrates source code from Notepad++.
15- // 2. Integrates/includes/aggregates Notepad++ into a proprietary executable
16- // installer, such as those produced by InstallShield.
17- // 3. Links to a library or executes a program that does any of the above.
2+ // Copyright (C)2021 Don HO <[email protected] >3+
4+ // This program is free software: you can redistribute it and/or modify
5+ // it under the terms of the GNU General Public License as published by
6+ // the Free Software Foundation, either version 3 of the License, or
7+ // at your option any later version.
188//
199// This program is distributed in the hope that it will be useful,
2010// but WITHOUT ANY WARRANTY; without even the implied warranty of
21- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2212// GNU General Public License for more details.
2313//
2414// You should have received a copy of the GNU General Public License
25- // along with this program; if not, write to the Free Software
26- // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15+ // along with this program. If not, see <https://www.gnu.org/licenses/>.
2716
2817
2918#include " URLCtrl.h"
19+ #include " NppDarkMode.h"
20+ #include " Parameters.h"
21+
3022
31- void URLCtrl::create (HWND itemHandle, const TCHAR * link, COLORREF linkColor)
23+ void URLCtrl::create (HWND itemHandle, const wchar_t * link, COLORREF linkColor)
3224{
3325 // turn on notify style
34- ::SetWindowLongPtr (itemHandle, GWL_STYLE, ::GetWindowLongPtr(itemHandle, GWL_STYLE) | SS_NOTIFY);
26+ ::SetWindowLongPtr (itemHandle, GWL_STYLE, ::GetWindowLongPtr(itemHandle, GWL_STYLE) | SS_NOTIFY);
3527
3628 // set the URL text (not the display text)
3729 if (link)
3830 _URL = link;
3931
4032 // set the hyperlink colour
41- _linkColor = linkColor;
33+ _linkColor = linkColor;
4234
4335 // set the visited colour
44- _visitedColor = RGB (128 , 0 , 128 );
36+ _visitedColor = RGB (128 ,0 , 128 );
4537
4638 // subclass the static control
4739 _oldproc = reinterpret_cast <WNDPROC>(::SetWindowLongPtr (itemHandle, GWLP_WNDPROC, reinterpret_cast <LONG_PTR>(URLCtrlProc)));
@@ -51,17 +43,19 @@ void URLCtrl::create(HWND itemHandle, const TCHAR* link, COLORREF linkColor)
5143
5244 // save hwnd
5345 _hSelf = itemHandle;
46+
47+ loadHandCursor ();
5448}
5549void URLCtrl::create (HWND itemHandle, int cmd, HWND msgDest)
5650{
5751 // turn on notify style
58- ::SetWindowLongPtr (itemHandle, GWL_STYLE, ::GetWindowLongPtr(itemHandle, GWL_STYLE) | SS_NOTIFY);
52+ ::SetWindowLongPtr (itemHandle, GWL_STYLE, ::GetWindowLongPtr(itemHandle, GWL_STYLE) | SS_NOTIFY);
5953
6054 _cmdID = cmd;
6155 _msgDest = msgDest;
6256
6357 // set the hyperlink colour
64- _linkColor = RGB (0 , 0 , 255 );
58+ _linkColor = RGB (0 ,0 , 255 );
6559
6660 // subclass the static control
6761 _oldproc = reinterpret_cast <WNDPROC>(::SetWindowLongPtr (itemHandle, GWLP_WNDPROC, reinterpret_cast <LONG_PTR>(URLCtrlProc)));
@@ -71,21 +65,34 @@ void URLCtrl::create(HWND itemHandle, int cmd, HWND msgDest)
7165
7266 // save hwnd
7367 _hSelf = itemHandle;
68+
69+ loadHandCursor ();
7470}
7571
7672void URLCtrl::destroy ()
7773{
7874 if (_hfUnderlined)
75+ {
7976 ::DeleteObject (_hfUnderlined);
80- if (_hCursor)
81- ::DestroyCursor (_hCursor);
77+ _hfUnderlined = nullptr ;
78+ }
79+ }
80+
81+ HCURSOR& URLCtrl::loadHandCursor ()
82+ {
83+ if (_hCursor == nullptr )
84+ {
85+ _hCursor = static_cast <HCURSOR>(::LoadImage (nullptr , MAKEINTRESOURCE (OCR_HAND), IMAGE_CURSOR, SM_CXCURSOR, SM_CYCURSOR, LR_SHARED));
86+ }
87+
88+ return _hCursor;
8289}
8390
8491void URLCtrl::action ()
8592{
8693 if (_cmdID)
8794 {
88- ::SendMessage (_msgDest ? _msgDest : _hParent, WM_COMMAND, _cmdID, 0 );
95+ ::SendMessage (_msgDest? _msgDest: _hParent, WM_COMMAND, _cmdID, 0 );
8996 }
9097 else
9198 {
@@ -95,168 +102,135 @@ void URLCtrl::action()
95102 ::UpdateWindow (_hSelf);
96103
97104 // Open a browser
98- if (_URL != TEXT ( " " ))
105+ if (!_URL. empty ( ))
99106 {
100- ::ShellExecute (NULL , TEXT( " open" ) , _URL.c_str(), NULL, NULL, SW_SHOWNORMAL);
107+ ::ShellExecute (NULL , L " open" , _URL.c_str(), NULL, NULL, SW_SHOWNORMAL);
101108 }
102109 else
103110 {
104- TCHAR szWinText[MAX_PATH];
111+ wchar_t szWinText[MAX_PATH] = { ' \0 ' } ;
105112 ::GetWindowText (_hSelf, szWinText, MAX_PATH);
106- ::ShellExecute (NULL , TEXT( " open" ) , szWinText, NULL, NULL, SW_SHOWNORMAL);
113+ ::ShellExecute (NULL , L " open" , szWinText, NULL , NULL , SW_SHOWNORMAL);
107114 }
108115 }
109116}
110117
111- COLORREF URLCtrl::getCtrlBgColor (HWND hWnd )
118+ LRESULT URLCtrl::runProc (HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam )
112119{
113- COLORREF crRet = CLR_INVALID;
114- if (hWnd && IsWindow (hWnd))
115- {
116- RECT rc;
117- if (GetClientRect (hWnd, &rc))
118- {
119- HDC hDC = GetDC (hWnd);
120- if (hDC)
120+ switch (Message)
121+ {
122+ // Free up the structure we allocated
123+ case WM_NCDESTROY:
124+ // HeapFree(GetProcessHeap(), 0, url);
125+ break ;
126+
127+ // Paint the static control using our custom
128+ // colours, and with an underline text style
129+ case WM_PAINT:
130+ {
131+ DWORD dwStyle = static_cast <DWORD>(::GetWindowLongPtr (hwnd, GWL_STYLE));
132+ DWORD dwDTStyle = DT_SINGLELINE;
133+
134+ // Test if centered horizontally or vertically
135+ if (dwStyle & SS_CENTER) dwDTStyle |= DT_CENTER;
136+ if (dwStyle & SS_RIGHT) dwDTStyle |= DT_RIGHT;
137+ if (dwStyle & SS_CENTERIMAGE) dwDTStyle |= DT_VCENTER;
138+
139+ RECT rect{};
140+ ::GetClientRect (hwnd, &rect);
141+
142+ PAINTSTRUCT ps{};
143+ HDC hdc = ::BeginPaint (hwnd, &ps);
144+
145+ if ((_linkColor == _visitedColor) || (_linkColor == NppDarkMode::getDarkerTextColor ()))
121146 {
122- HDC hdcMem = CreateCompatibleDC (hDC);
123- if (hdcMem)
124- {
125- HBITMAP hBmp = CreateCompatibleBitmap (hDC,
126- rc.right , rc.bottom );
127- if (hBmp)
128- {
129- HGDIOBJ hOld = SelectObject (hdcMem, hBmp);
130- if (hOld)
131- {
132- if (SendMessage (hWnd, WM_ERASEBKGND, reinterpret_cast <WPARAM>(hdcMem), 0 ))
133- {
134- crRet = GetPixel (hdcMem, 2 , 2 ); // 0, 0 is usually on the border
135- }
136- SelectObject (hdcMem, hOld);
137- }
138- DeleteObject (hBmp);
139- }
140- DeleteDC (hdcMem);
141- }
142- ReleaseDC (hWnd, hDC);
147+ _linkColor = NppDarkMode::isEnabled () ? NppDarkMode::getDarkerTextColor () : _visitedColor;
148+ ::SetTextColor (hdc, _linkColor);
149+ }
150+ else if (NppDarkMode::isEnabled ())
151+ {
152+ ::SetTextColor (hdc, NppDarkMode::getLinkTextColor());
153+ }
154+ else
155+ {
156+ ::SetTextColor (hdc, _linkColor);
143157 }
144- }
145- }
146- return crRet;
147- }
148-
149- LRESULT URLCtrl::runProc (HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
150- {
151- switch (Message)
152- {
153- // Free up the structure we allocated
154- case WM_NCDESTROY:
155- // HeapFree(GetProcessHeap(), 0, url);
156- break ;
157-
158- // Paint the static control using our custom
159- // colours, and with an underline text style
160- case WM_PAINT:
161- {
162- DWORD dwStyle = static_cast <DWORD>(::GetWindowLongPtr (hwnd, GWL_STYLE));
163- DWORD dwDTStyle = DT_SINGLELINE;
164-
165- // Test if centered horizontally or vertically
166- if (dwStyle & SS_CENTER) dwDTStyle |= DT_CENTER;
167- if (dwStyle & SS_RIGHT) dwDTStyle |= DT_RIGHT;
168- if (dwStyle & SS_CENTERIMAGE) dwDTStyle |= DT_VCENTER;
169-
170- RECT rect;
171- ::GetClientRect (hwnd, &rect);
172-
173- PAINTSTRUCT ps;
174- HDC hdc = ::BeginPaint (hwnd, &ps);
175-
176- ::SetTextColor (hdc, _linkColor);
177-
178- ::SetBkColor (hdc, getCtrlBgColor(GetParent(hwnd))); // /*::GetSysColor(COLOR_3DFACE)*/);
179-
180- // Create an underline font
181- if (_hfUnderlined == 0 )
182- {
183- // Get the default GUI font
184- LOGFONT lf;
185- HFONT hf = (HFONT)::GetStockObject (DEFAULT_GUI_FONT);
186158
187- // Add UNDERLINE attribute
188- GetObject (hf, sizeof lf, &lf);
189- lf.lfUnderline = TRUE ;
159+ ::SetBkColor (hdc, getCtrlBgColor(GetParent(hwnd))); // /*::GetSysColor(COLOR_3DFACE)*/);
190160
191- // Create a new font
192- _hfUnderlined = ::CreateFontIndirect (&lf);
193- }
161+ // Create an underline font
162+ if (_hfUnderlined == nullptr )
163+ {
164+ // Get the default GUI font
165+ LOGFONT lf{ DPIManagerV2::getDefaultGUIFontForDpi (::GetParent (hwnd)) };
166+ lf.lfUnderline = TRUE ;
194167
195- HANDLE hOld = SelectObject (hdc, _hfUnderlined);
168+ // Create a new font
169+ _hfUnderlined = ::CreateFontIndirect (&lf);
170+ }
196171
197- // Draw the text!
198- TCHAR szWinText[MAX_PATH];
199- ::GetWindowText (hwnd, szWinText, MAX_PATH);
200- ::DrawText (hdc, szWinText, -1 , &rect, dwDTStyle);
172+ HANDLE hOld = SelectObject (hdc, _hfUnderlined);
201173
202- ::SelectObject (hdc, hOld);
174+ // Draw the text!
175+ wchar_t szWinText[MAX_PATH] = { ' \0 ' };
176+ ::GetWindowText (hwnd, szWinText, MAX_PATH);
177+ ::DrawText (hdc, szWinText, -1 , &rect, dwDTStyle);
203178
204- ::EndPaint (hwnd, &ps );
179+ ::SelectObject (hdc, hOld );
205180
206- return 0 ;
207- }
181+ ::EndPaint (hwnd, &ps);
208182
209- case WM_SETTEXT:
210- {
211- LRESULT ret = ::CallWindowProc (_oldproc, hwnd, Message, wParam, lParam);
212- ::InvalidateRect (hwnd, 0 , 0 );
213- return ret;
214- }
215- // Provide a hand cursor when the mouse moves over us
216- case WM_SETCURSOR:
217- case WM_MOUSEMOVE:
218- {
219- if (_hCursor == 0 )
220- _hCursor = LoadCursor (NULL , IDC_HAND);
183+ return 0 ;
184+ }
221185
222- SetCursor (_hCursor);
223- return TRUE ;
224- }
186+ case WM_SETTEXT:
187+ {
188+ LRESULT ret = ::CallWindowProc (_oldproc, hwnd, Message, wParam, lParam);
189+ ::InvalidateRect (hwnd, 0 , 0 );
190+ return ret;
191+ }
192+ // Provide a hand cursor when the mouse moves over us
193+ // case WM_SETCURSOR:
194+ case WM_MOUSEMOVE:
195+ {
196+ ::SetCursor (loadHandCursor());
197+ return TRUE ;
198+ }
225199
226- case WM_LBUTTONDOWN:
227- _clicking = true ;
228- break ;
200+ case WM_LBUTTONDOWN:
201+ _clicking = true ;
202+ break ;
229203
230- case WM_LBUTTONUP:
231- if (_clicking)
232- {
233- _clicking = false ;
204+ case WM_LBUTTONUP:
205+ if (_clicking)
206+ {
207+ _clicking = false ;
234208
235- action ();
236- }
209+ action ();
210+ }
237211
238- break ;
212+ break ;
239213
240214 // Support using space to activate this object
241- case WM_KEYDOWN:
242- if (wParam == VK_SPACE)
243- _clicking = true ;
244- break ;
215+ case WM_KEYDOWN:
216+ if (wParam == VK_SPACE)
217+ _clicking = true ;
218+ break ;
245219
246- case WM_KEYUP:
247- if (wParam == VK_SPACE && _clicking)
248- {
249- _clicking = false ;
250-
251- action ();
252- }
253- break ;
220+ case WM_KEYUP:
221+ if (wParam == VK_SPACE && _clicking)
222+ {
223+ _clicking = false ;
254224
255- // A standard static control returns HTTRANSPARENT here, which
256- // prevents us from receiving any mouse messages. So, return
257- // HTCLIENT instead.
258- case WM_NCHITTEST:
259- return HTCLIENT;
260- }
261- return ::CallWindowProc (_oldproc, hwnd, Message, wParam, lParam);
225+ action ();
226+ }
227+ break ;
228+
229+ // A standard static control returns HTTRANSPARENT here, which
230+ // prevents us from receiving any mouse messages. So, return
231+ // HTCLIENT instead.
232+ case WM_NCHITTEST:
233+ return HTCLIENT;
234+ }
235+ return ::CallWindowProc (_oldproc, hwnd, Message, wParam, lParam);
262236}
0 commit comments