-
Notifications
You must be signed in to change notification settings - Fork 8.5k
/
Copy pathfind.cpp
103 lines (87 loc) · 3.38 KB
/
find.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "precomp.h"
#include "find.h"
#include "resource.h"
#include "window.hpp"
#include "../../host/dbcs.h"
#include "../../host/handle.h"
#include "../buffer/out/search.h"
#include "../inc/ServiceLocator.hpp"
#pragma hdrstop
using namespace Microsoft::Console::Interactivity;
INT_PTR CALLBACK FindDialogProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
// This bool is used to track which option - up or down - was used to perform the last search. That way, the next time the
// find dialog is opened, it will default to the last used option.
static auto reverse = true;
static SearchFlag flags{ SearchFlag::CaseInsensitive };
static std::wstring lastFindString;
static Search searcher;
switch (Message)
{
case WM_INITDIALOG:
SetWindowLongPtrW(hWnd, DWLP_USER, lParam);
CheckRadioButton(hWnd, ID_CONSOLE_FINDUP, ID_CONSOLE_FINDDOWN, (reverse ? ID_CONSOLE_FINDUP : ID_CONSOLE_FINDDOWN));
CheckDlgButton(hWnd, ID_CONSOLE_FINDCASE, WI_IsFlagClear(flags, SearchFlag::CaseInsensitive));
CheckDlgButton(hWnd, ID_CONSOLE_FINDREGEX, WI_IsFlagSet(flags, SearchFlag::RegularExpression));
SetDlgItemTextW(hWnd, ID_CONSOLE_FINDSTR, lastFindString.c_str());
return TRUE;
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDOK:
{
auto length = SendDlgItemMessageW(hWnd, ID_CONSOLE_FINDSTR, WM_GETTEXTLENGTH, 0, 0);
lastFindString.resize(length);
length = GetDlgItemTextW(hWnd, ID_CONSOLE_FINDSTR, lastFindString.data(), gsl::narrow_cast<int>(length + 1));
lastFindString.resize(length);
WI_UpdateFlag(flags, SearchFlag::CaseInsensitive, IsDlgButtonChecked(hWnd, ID_CONSOLE_FINDCASE) == 0);
WI_UpdateFlag(flags, SearchFlag::RegularExpression, IsDlgButtonChecked(hWnd, ID_CONSOLE_FINDREGEX) != 0);
reverse = IsDlgButtonChecked(hWnd, ID_CONSOLE_FINDDOWN) == 0;
LockConsole();
auto Unlock = wil::scope_exit([&] { UnlockConsole(); });
if (searcher.IsStale(gci.renderData, lastFindString, flags))
{
searcher.Reset(gci.renderData, lastFindString, flags, reverse);
}
else
{
searcher.FindNext(reverse);
}
if (searcher.SelectCurrent())
{
return TRUE;
}
std::ignore = gci.GetActiveOutputBuffer().SendNotifyBeep();
break;
}
case IDCANCEL:
EndDialog(hWnd, 0);
searcher = Search{};
return TRUE;
default:
break;
}
break;
}
default:
break;
}
return FALSE;
}
void DoFind()
{
auto& g = ServiceLocator::LocateGlobals();
const auto pWindow = ServiceLocator::LocateConsoleWindow();
UnlockConsole();
if (pWindow != nullptr)
{
const auto hwnd = pWindow->GetWindowHandle();
++g.uiDialogBoxCount;
DialogBoxParamW(g.hInstance, MAKEINTRESOURCE(ID_CONSOLE_FINDDLG), hwnd, FindDialogProc, (LPARAM) nullptr);
--g.uiDialogBoxCount;
}
}