-1

当我做:

SendMessage(editControlHWND, EM_EXGETSEL, 0, (LPARAM)&charRange);

我得到选定的文本范围。但是,我想知道插入符号在此选择中的位置,即在末尾或开头。

即,用户是否选择了“向后”文本,就像从右向左拖动一样。

EM_EXGETSEL中的数字总是较小cpMin,因此显然与选择顺序无关。

在这种情况下,我显然无法获得插入符号位置EM_EXGETSEL进行比较,因为已经选择了一大块东西。

有什么方法可以获取插入符号的当前个人位置(以便我可以将其与 cpMin/cpMax 进行比较)?或者,是否有任何方法可以确定插入符号在选定文本块中的位置?

编辑:

我对为什么要这样做的解释: 我以编程方式将文本插入到只读 RichEdit 控件中,用户可以从中选择文本。但是,当在末尾添加文本时,它必须将插入符号移到末尾并插入文本,这可能在选择文本/用户当前正在选择文本时发生。

麻烦的是最后一个。在以编程方式输入文本之前和之后,我使用EM_EXGETSELand来获取和设置选定的文本。EM_EXSETSEL默认情况下,EM_EXGETSEL总是将较小的数字放在 中cpMin,这意味着如果用户当前正在向后选择文本(即从右到左),并且将文本添加到控件中,则选择区域中插入符号的位置会从开头变为最后,因为我将这些数字直接输入EM_EXSETSEL. 我知道它EM_EXSETSEL能够向后选择(我已经用 in 中的较大数字和 in 中cpMin的较小数字对此进行了测试cpMax),但EM_EXGETSEL没有表明用户已经向后选择了文本。

因此,我需要知道插入符号的位置以将其与之进行比较cpMincpMax检查它是在选择的开头还是结尾,并采取相应的行动。

4

4 回答 4

1

刚刚在调查同样的问题时遇到了这篇文章。

我能够通过跟踪对 EN_SELCHANGE 通知的选择的更改并比较 WM_LBUTTONUP 的结果来解决问题。

于 2016-02-20T16:02:19.700 回答
0

似乎EM_LINEFROMCHARand EM_LINEINDEXwith (WPARAM == -1) 可以使用。

于 2013-08-23T10:35:30.930 回答
0

我设法做到了这一点,尽管由于我对子类化的概念缺乏了解,到达那里有点复杂。><

当我选择文本时,我使用 Spy++ 查看正在发送的消息。

这显然是专门的EM_GETPASSWORDCHAR消息。

所以我做了:

case EM_GETPASSWORDCHAR:
    {
        if(hwnd == editControlHwnd)
        {
            CHARRANGE tempCharRange;
            SendMessage(editControlHwnd, EM_EXGETSEL, 0, (LPARAM)&tempCharRange);
            SetSelectionDirection(tempCharRange.cpMin, tempCharRange.cpMax);
            return CallWindowProc(oldWndProc, hwnd, uMsg, wParam, lParam);
        }
    }

和:

void SubWindow::SetSelectionDirection(int newCpMin, int newCpMax) //Set selectionDirection to false if selecting backwards, true if selecting forwards
{
    if((newCpMin != prevCpMin) && (newCpMax == prevCpMax))
        selectionDirection = false;
    else if((newCpMin == prevCpMin) && (newCpMax != prevCpMax))
        selectionDirection = true;

    prevCpMin = newCpMin;
    prevCpMax = newCpMax;
}

其中bool selectionDirection;,int prevCpMin;int prevCpMax;是私有类成员变量。

这样,我将新选择的区域与之前选择的区域进行比较,以查看哪一端已更改,哪一端未更改。

我不知道我在这里所做的是否是一种真正解决这个问题的坏方法,但如果有更好的方法来做到这一点,我还没有找到。这就是为什么我将其发布为答案,以防它帮助处于我位置的其他人。

于 2013-08-24T18:45:32.290 回答
0

没有简单的方法可以做到这一点。EM_GETSELEM_EXGETSEL返回当前选择的范围。只有在没有选择的情况下,它们才会返回插入符号的位置。

请注意,插入符号不能位于选定文本块中 - 它始终位于末尾或开头。

您可以通过对控件进行子类化并EM_GETSEL在任何键或鼠标输入后查询和存储插入符号的位置来相当容易地实现解决方案。例如

LRESULT WINAPI EditControlSubclassProc(...)
{
    LRESULT lRes = CallWindowProc(...); // call original window procedure
    if ((uMsg >= WM_KEYFIRST && uMsg <= WM_KEYLAST)
    ||  (uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST))
    {
        DWORD dwStart, dwEnd;
        SendMessage(hWnd, EM_GETSEL, (WPARAM)&dwStart, (LPARAM)&dwEnd);
        if (dwStart == dwEnd)
        {
            // no current selection, so simply store the position of the caret
            g_dwCaretPos = dwStart;
        }
    }
    return lRes;
}

这样,您将始终知道上次没有导致选择的输入时插入符号的位置。然后,您可以将其与选择的范围进行比较,以确定选择锚定在哪一端,因此知道插入符号在另一端。

于 2013-08-23T00:58:43.790 回答