刘博顺修改

LBS_branch
L.Andrew 12 months ago
parent 1006a53e68
commit 2893ff7bb2

@ -23,231 +23,244 @@
#include "Common.h"
#include "Utf8.h"
// 引入命名空间
using namespace std;
// 定义 FindOption 类指针和静态变量 _options
FindOption * FindReplaceDlg::_env;
FindOption FindReplaceDlg::_options;
// 定义 SHIFTED 常量
#define SHIFTED 0x8000
// 向 Combo Box 中添加文本
void addText2Combo(const TCHAR * txt2add, HWND hCombo)
{
if (!hCombo) return;
if (!lstrcmp(txt2add, TEXT(""))) return;
auto i = ::SendMessage(hCombo, CB_FINDSTRINGEXACT, static_cast<WPARAM>(-1), reinterpret_cast<LPARAM>(txt2add));
if (i != CB_ERR) // found
{
::SendMessage(hCombo, CB_DELETESTRING, i, 0);
}
// 如果没有 Combo Box 或者 txt2add 为空,则返回
if (!hCombo) return;
if (!lstrcmp(txt2add, TEXT(""))) return;
// 查找是否已经存在该文本,如果存在则删除
auto i = ::SendMessage(hCombo, CB_FINDSTRINGEXACT, static_cast<WPARAM>(-1), reinterpret_cast<LPARAM>(txt2add));
if (i != CB_ERR) // found
{
::SendMessage(hCombo, CB_DELETESTRING, i, 0);
}
i = ::SendMessage(hCombo, CB_INSERTSTRING, 0, reinterpret_cast<LPARAM>(txt2add));
::SendMessage(hCombo, CB_SETCURSEL, i, 0);
// 将文本插入 Combo Box并设置为当前选中项
i = ::SendMessage(hCombo, CB_INSERTSTRING, 0, reinterpret_cast<LPARAM>(txt2add));
::SendMessage(hCombo, CB_SETCURSEL, i, 0);
}
// 从 Combo Box 中获取文本
generic_string getTextFromCombo(HWND hCombo)
{
TCHAR str[FINDREPLACE_MAXLENGTH] = { '\0' };
::SendMessage(hCombo, WM_GETTEXT, FINDREPLACE_MAXLENGTH - 1, reinterpret_cast<LPARAM>(str));
return generic_string(str);
TCHAR str[FINDREPLACE_MAXLENGTH] = { '\0' };
::SendMessage(hCombo, WM_GETTEXT, FINDREPLACE_MAXLENGTH - 1, reinterpret_cast<LPARAM>(str));
return generic_string(str);
}
// 删除编辑框中光标左边的单词
void delLeftWordInEdit(HWND hEdit)
{
TCHAR str[FINDREPLACE_MAXLENGTH] = { '\0' };
::SendMessage(hEdit, WM_GETTEXT, FINDREPLACE_MAXLENGTH - 1, reinterpret_cast<LPARAM>(str));
WORD cursor = 0;
::SendMessage(hEdit, EM_GETSEL, (WPARAM)&cursor, 0);
WORD wordstart = cursor;
while (wordstart > 0) {
TCHAR c = str[wordstart - 1];
if (c != ' ' && c != '\t')
break;
--wordstart;
}
while (wordstart > 0) {
TCHAR c = str[wordstart - 1];
if (c == ' ' || c == '\t')
break;
--wordstart;
}
if (wordstart < cursor) {
::SendMessage(hEdit, EM_SETSEL, (WPARAM)wordstart, (LPARAM)cursor);
::SendMessage(hEdit, EM_REPLACESEL, (WPARAM)TRUE, reinterpret_cast<LPARAM>(L""));
}
TCHAR str[FINDREPLACE_MAXLENGTH] = { '\0' };
::SendMessage(hEdit, WM_GETTEXT, FINDREPLACE_MAXLENGTH - 1, reinterpret_cast<LPARAM>(str));
WORD cursor = 0;
::SendMessage(hEdit, EM_GETSEL, (WPARAM)&cursor, 0);
WORD wordstart = cursor;
while (wordstart > 0) {
TCHAR c = str[wordstart - 1];
if (c != ' ' && c != '\t')
break;
--wordstart;
}
while (wordstart > 0) {
TCHAR c = str[wordstart - 1];
if (c == ' ' || c == '\t')
break;
--wordstart;
}
if (wordstart < cursor) {
::SendMessage(hEdit, EM_SETSEL, (WPARAM)wordstart, (LPARAM)cursor);
::SendMessage(hEdit, EM_REPLACESEL, (WPARAM)TRUE, reinterpret_cast<LPARAM>(L""));
}
}
// 运行交换按钮处理函数
LRESULT run_swapButtonProc(WNDPROC oldEditProc, HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_RBUTTONUP:
{
::SendMessage(GetParent(hwnd), message, wParam, lParam);
break;
}
default:
break;
}
return ::CallWindowProc(oldEditProc, hwnd, message, wParam, lParam);
switch (message)
{
case WM_RBUTTONUP:
{
::SendMessage(GetParent(hwnd), message, wParam, lParam);
break;
}
default:
break;
}
return ::CallWindowProc(oldEditProc, hwnd, message, wParam, lParam);
}
// 将扩展字符转换为字符串
int Searching::convertExtendedToString(const TCHAR * query, TCHAR * result, int length)
{ //query may equal to result, since it always gets smaller
int i = 0, j = 0;
int charLeft = length;
TCHAR current;
while (i < length)
{ //because the backslash escape quences always reduce the size of the generic_string, no overflow checks have to be made for target, assuming parameters are correct
current = query[i];
--charLeft;
if (current == '\\' && charLeft)
{ //possible escape sequence
++i;
--charLeft;
current = query[i];
switch(current)
{
case 'r':
result[j] = '\r';
break;
case 'n':
result[j] = '\n';
break;
case '0':
result[j] = '\0';
break;
case 't':
result[j] = '\t';
break;
case '\\':
result[j] = '\\';
break;
case 'b':
case 'd':
case 'o':
case 'x':
case 'u':
{
int size = 0, base = 0;
if (current == 'b')
{ //11111111
size = 8, base = 2;
}
else if (current == 'o')
{ //377
size = 3, base = 8;
}
else if (current == 'd')
{ //255
size = 3, base = 10;
}
else if (current == 'x')
{ //0xFF
size = 2, base = 16;
}
else if (current == 'u')
{ //0xCDCD
size = 4, base = 16;
}
if (charLeft >= size)
{
int res = 0;
if (Searching::readBase(query+(i+1), &res, base, size))
{
result[j] = static_cast<TCHAR>(res);
i += size;
break;
}
}
//not enough chars to make parameter, use default method as fallback
[[fallthrough]];
}
default:
{ //unknown sequence, treat as regular text
result[j] = '\\';
++j;
result[j] = current;
break;
}
}
}
else
{
result[j] = query[i];
}
++i;
++j;
}
result[j] = 0;
return j;
{ //query may equal to result, since it always gets smaller
int i = 0, j = 0;
int charLeft = length;
TCHAR current;
while (i < length)
{ //because the backslash escape quences always reduce the size of the generic_string, no overflow checks have to be made for target, assuming parameters are correct
current = query[i];
--charLeft;
if (current == '\\' && charLeft)
{ //possible escape sequence
++i;
--charLeft;
current = query[i];
switch(current)
{
case 'r':
result[j] = '\r';
break;
case 'n':
result[j] = '\n';
break;
case '0':
result[j] = '\0';
break;
case 't':
result[j] = '\t';
break;
case '\\':
result[j] = '\\';
break;
case 'b':
case 'd':
case 'o':
case 'x':
case 'u':
{
int size = 0, base = 0;
if (current == 'b')
{ //11111111
size = 8, base = 2;
}
else if (current == 'o')
{ //377
size = 3, base = 8;
}
else if (current == 'd')
{ //255
size = 3, base = 10;
}
else if (current == 'x')
{ //0xFF
size = 2, base = 16;
}
else if (current == 'u')
{ //0xCDCD
size = 4, base = 16;
}
if (charLeft >= size)
{
int res = 0;
if (Searching::readBase(query+(i+1), &res, base, size))
{
result[j] = static_cast<TCHAR>(res);
i += size;
break;
}
}
//not enough chars to make parameter, use default method as fallback
[[fallthrough]];
}
default:
{ //unknown sequence, treat as regular text
result[j] = '\\';
++j;
result[j] = current;
break;
}
}
}
else
{
result[j] = query[i];
}
++i;
++j;
}
result[j] = 0;
return j;
}
// 将字符串转换为指定进制的整数
bool Searching::readBase(const TCHAR * str, int * value, int base, int size)
{
int i = 0, temp = 0;
*value = 0;
TCHAR max = '0' + static_cast<TCHAR>(base) - 1;
TCHAR current;
while (i < size)
{
current = str[i];
if (current >= 'A')
{
current &= 0xdf;
current -= ('A' - '0' - 10);
}
else if (current > '9')
return false;
if (current >= '0' && current <= max)
{
temp *= base;
temp += (current - '0');
}
else
{
return false;
}
++i;
}
*value = temp;
return true;
int i = 0, temp = 0;
*value = 0;
TCHAR max = '0' + static_cast<TCHAR>(base) - 1;
TCHAR current;
while (i < size)
{
current = str[i];
if (current >= 'A')
{
current &= 0xdf;
current -= ('A' - '0' - 10);
}
else if (current > '9')
return false;
if (current >= '0' && current <= max)
{
temp *= base;
temp += (current - '0');
}
else
{
return false;
}
++i;
}
*value = temp;
return true;
}
// 在编辑框中显示查找结果
void Searching::displaySectionCentered(size_t posStart, size_t posEnd, ScintillaEditView * pEditView, bool isDownwards)
{
// Make sure target lines are unfolded
pEditView->execute(SCI_ENSUREVISIBLE, pEditView->execute(SCI_LINEFROMPOSITION, posStart));
pEditView->execute(SCI_ENSUREVISIBLE, pEditView->execute(SCI_LINEFROMPOSITION, posEnd));
// Jump-scroll to center, if current position is out of view
pEditView->execute(SCI_SETVISIBLEPOLICY, CARET_JUMPS | CARET_EVEN);
pEditView->execute(SCI_ENSUREVISIBLEENFORCEPOLICY, pEditView->execute(SCI_LINEFROMPOSITION, isDownwards ? posEnd : posStart));
// When searching up, the beginning of the (possible multiline) result is important, when scrolling down the end
pEditView->execute(SCI_GOTOPOS, isDownwards ? posEnd : posStart);
pEditView->execute(SCI_SETVISIBLEPOLICY, CARET_EVEN);
pEditView->execute(SCI_ENSUREVISIBLEENFORCEPOLICY, pEditView->execute(SCI_LINEFROMPOSITION, isDownwards ? posEnd : posStart));
// Adjust so that we see the entire match; primarily horizontally
pEditView->execute(SCI_SCROLLRANGE, posStart, posEnd);
// Move cursor to end of result and select result
pEditView->execute(SCI_GOTOPOS, posEnd);
pEditView->execute(SCI_SETANCHOR, posStart);
// Update Scintilla's knowledge about what column the caret is in, so that if user
// does up/down arrow as first navigation after the search result is selected,
// the caret doesn't jump to an unexpected column
pEditView->execute(SCI_CHOOSECARETX);
// 确保目标行未折叠
pEditView->execute(SCI_ENSUREVISIBLE, pEditView->execute(SCI_LINEFROMPOSITION, posStart));
pEditView->execute(SCI_ENSUREVISIBLE, pEditView->execute(SCI_LINEFROMPOSITION, posEnd));
// 跳跃滚动到中心位置,如果当前位置不在视图内
pEditView->execute(SCI_SETVISIBLEPOLICY, CARET_JUMPS | CARET_EVEN);
pEditView->execute(SCI_ENSUREVISIBLEENFORCEPOLICY, pEditView->execute(SCI_LINEFROMPOSITION, isDownwards ? posEnd : posStart));
// 当向上查找时,结果的开头很重要,而向下滚动时则是结尾
pEditView->execute(SCI_GOTOPOS, isDownwards ? posEnd : posStart);
pEditView->execute(SCI_SETVISIBLEPOLICY, CARET_EVEN);
pEditView->execute(SCI_ENSUREVISIBLEENFORCEPOLICY, pEditView->execute(SCI_LINEFROMPOSITION, isDownwards ? posEnd : posStart));
// 调整以便看到整个匹配;主要是水平方向
pEditView->execute(SCI_SCROLLRANGE, posStart, posEnd);
// 将光标移动到结果的结尾并选择结果
pEditView->execute(SCI_GOTOPOS, posEnd);
pEditView->execute(SCI_SETANCHOR, posStart);
// 更新 Scintilla 对插入符所在列的了解,以便如果用户在选择搜索结果后的首次导航时使用上/下箭头,则插入符不会跳到意外的列
pEditView->execute(SCI_CHOOSECARETX);
}
// 定义静态变量 originalFinderProc 和 originalComboEditProc
WNDPROC FindReplaceDlg::originalFinderProc = nullptr;
WNDPROC FindReplaceDlg::originalComboEditProc = nullptr;
// important : to activate all styles
const int STYLING_MASK = 255;

Loading…
Cancel
Save