Skip to content

Commit 3eb8fc4

Browse files
committed
1 parent d0a79bc commit 3eb8fc4

File tree

2 files changed

+167
-210
lines changed

2 files changed

+167
-210
lines changed

external/npp/URLCtrl.cpp

Lines changed: 137 additions & 163 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,39 @@
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
}
5549
void 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

7672
void 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

8491
void 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

Comments
 (0)