标签: richedit

原始 Win32 中的丰富编辑控件

Rich Edit Controls 的文档是否真的像看起来那么糟糕(错误?)?现在我正在手动调用 LoadLibrary("riched20.dll") 以便显示 Rich Edit Control。Rich Edit 的文档在第一个使用 Rich Edit 控件的代码示例中没有很好地说明这一点。

它谈到调用 InitCommonControlsEx() 来添加视觉样式,但没有提到要传入哪些标志。

有没有更好的方法来加载 Rich Edit 控件?

http://msdn.microsoft.com/en-us/library/bb787877(VS.85).aspx

这是我可以编写的唯一代码以使其工作:

#include "Richedit.h"
#include "commctrl.h"

INITCOMMONCONTROLSEX icex;
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_USEREX_CLASSES;  //Could be 0xFFFFFFFF and it still wouldn't work
InitCommonControlsEx(&icex);  //Does nothing for Rich Edit controls

LoadLibrary("riched20.dll");  //Manually?  For real?
hWndRichEdit = CreateWindowEx(
    ES_SUNKEN,
    RICHEDIT_CLASS,
    "",
    WS_BORDER | WS_VISIBLE | WS_CHILD,
    2, 2, 100, 24,
    hWnd, (HMENU) ID_RICH_EDIT, hInst, NULL);
Run Code Online (Sandbox Code Playgroud)

windows winapi richedit

5
推荐指数
1
解决办法
8359
查看次数

检测点击RichEdit中的URL

我正在尝试更新RichEdit,以便它检测URL并允许单击它以在浏览器中打开.检测URL很简单,我只需使用以下代码来自http://www.scalabium.com/faq/dct0146.htm

mask := SendMessage(MNote.Handle, EM_GETEVENTMASK, 0, 0);
  SendMessage(MNote.Handle, EM_SETEVENTMASK, 0, mask or ENM_LINK);
  SendMessage(MNote.Handle, EM_AUTOURLDETECT, Integer(True), 0); 
Run Code Online (Sandbox Code Playgroud)

但第二部分对我不起作用.他们提供以下代码来捕获EN_LINK消息并对其进行处理:

type
  TForm1 = class(TForm)
  protected
    procedure WndProc(var Message: TMessage); override;
  end;
...

procedure TForm1.WndProc(var Message: TMessage);
var
  p: TENLink;
  strURL: string;
begin
  if (Message.Msg = WM_NOTIFY) then
  begin
    if (PNMHDR(Message.LParam).code = EN_LINK) then
    begin
      p := TENLink(Pointer(TWMNotify(Message).NMHdr)^);
      if (p.msg = WM_LBUTTONDOWN) then
      begin
        SendMessage(RichEdit1.Handle, EM_EXSETSEL, 0, LongInt(@(p.chrg)));
        strURL := RichEdit1.SelText;
        ShellExecute(Handle, 'open', PChar(strURL), 0, 0, SW_SHOWNORMAL);
      end
    end
  end;

  inherited;
end; …
Run Code Online (Sandbox Code Playgroud)

delphi url events message richedit

5
推荐指数
1
解决办法
3663
查看次数

显示亚洲字符(使用Unicode):在RichEdit控件中显示时与使用ExtTextOut相比,字符间距有所不同

这张照片说明了我的困境:

图片1

所有字符看起来都一样大小,但是在RichEdit控件中显示时,与我使用ExtTextOut时相比,它们之间的间距是不同的。

我想呈现与RichEdit控件中相同的字符(理想情况下),以保留换行位置。

谁能告诉我:

a)哪个更正确的表示形式?

b)为什么RichEdit控件显示的文本在亚洲字符之间没有空格?

c)有什么方法可以使ExtTextOut在绘制这些字符时重现RichEdit控件的行为?

d)如果我正在使用亚洲版本的Windows,这会有什么不同吗?

也许我很乐观,但是如果有人可以提供任何提示,我将非常感兴趣。

如果有帮助:

这是我的文字:

???????????1 2 3 4 5 6 7 8 9 0
Run Code Online (Sandbox Code Playgroud)

向亚洲读者表示歉意,这只是为了测试我们的Unicode实现,我什至不知道字符取自哪种语言,更不用说它们是否意味着任何意义了

为了通过将这些字符粘贴到RichEdit控件(例如,写字板)中来查看效果,您可能会发现必须滑动它们并将字体设置为“ Arial”。

我获得的富文本为:

{\ rtf1 \ ansi \ ansicpg1252 \ deff0 \ deflang2057 {\ fonttbl {\ f0 \ fnil \ fcharset0 Arial;}} {\ colortbl; \ red0 \ green0 \ blue0;} \ viewkind4 \ uc1 \ pard \ sa200 \ sl276 \ slmult1 \ lang9 \ fs22 \ u24555?\ u30340?\ u26837?\ u33394?\ u29392?\ u29432?\ u36339?\ …

windows unicode rtf richedit textout

5
推荐指数
1
解决办法
995
查看次数

为什么在 OnChange 事件中调用 Delete 时会出现 RichEdit 行插入错误?

我已经用谷歌搜索并检查了许多地方的解决方案,但我发现的所有案例都不同或涉及比简单地添加或删除行更高级的东西。基本上,我想做一种滚动丰富的编辑(另一种方法是将插入符号移到底部,我已经找到了解决方案)。

我正在向它添加行并检查富编辑Lines.CountOnChange事件,一旦它达到大于 15 我想调用的值Lines.Delete(0),但是我收到错误:

RichEdit line insertion error
Run Code Online (Sandbox Code Playgroud)

有人能告诉我我在这里做错了什么吗?

delphi richedit delphi-xe2

5
推荐指数
1
解决办法
1万
查看次数

为什么EM_SETTEXTMODE不起作用?

我试图用EM_SETTEXTMODE一个RichEdit在Delphi 7控制.

只需创建一个新项目,添加一个TRichEdit控件和一个TButton控件,并将以下代码添加到按钮的单击处理程序:

  SendMessage(RichEdit1.Handle, WM_SETTEXT, 0, LPARAM(PChar('')));
  Button1.Caption := IntToStr(SendMessage(RichEdit1.Handle, EM_GETTEXTMODE, 0, 0));
  Button1.Caption := Button1.Caption + ' ' + IntToStr(SendMessage(RichEdit1.Handle, EM_SETTEXTMODE, TM_PLAINTEXT, 0));
  Button1.Caption := Button1.Caption + ' ' + IntToStr(SendMessage(RichEdit1.Handle, EM_GETTEXTMODE, 0, 0));
Run Code Online (Sandbox Code Playgroud)

38 0 38单击按钮后,按钮的标题设置为,意味着文本模式根本没有变化 - 最初是38(TM_RICHTEXT or TM_SINGLELEVELUNDO or TM_MULTICODEPAGE),然后SETTEXTMODE是成功(0),但即使在此之后它仍然是38.

根据文档的建议,RichEdit在使用之前清除文本EM_SETTEXTMODE.

我已尝试设置不同的值,EM_SETTEXTMODE它始终保持不变38.

我注意到,即使控件在调用之前包含文本,它也会EM_SETTEXTMODE返回0(成功)RichEdit. …

delphi winapi richedit windows-messages trichedit

5
推荐指数
1
解决办法
565
查看次数

如何在Win32 RichEdit中插入不带下划线的超链接?

我添加了一个到RichEdit的链接,使用CFM_LINK/CHARFORMAT2结构。但我不知道如何消除下划线效果。我试过:

SendMessage(richEditHWND, EM_AUTOURLDETECT, FALSE, NULL);
SendMessage(richEditHWND, EM_SETEDITSTYLEEX, 0, SES_EX_HANDLEFRIENDLYURL);

CHARFORMAT2 cf2;
memset(&cf2, 0, sizeof(CHARFORMAT2));
cf2.dwMask = CFM_LINK| CFM_UNDERLINE | CFM_COLOR | CFM_LINKPROTECTED;
cf2.dwEffects = CFE_LINK| CFE_UNDERLINE | CFE_LINKPROTECTED;
cf2.crTextColor = RGB(255, 0, 0);
cf2.bUnderlineType = CFU_UNDERLINENONE;
SendMessage(richEditHWND, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
Run Code Online (Sandbox Code Playgroud)

但这不起作用。
另一种方法是将下划线颜色设置为白色,即RichEdit的背景颜色,但这是一种hacky方法,使像q,j,...这样的字符被分割,在选择文本时也显示该线。
那么这样做的正确方法是什么?
注意:我正在使用RICHEDIT50W类。

c++ winapi richedit hyperlink underline

5
推荐指数
1
解决办法
1103
查看次数

5
推荐指数
1
解决办法
3905
查看次数

EM_GETTEXTEX - 错误记录返回值?

根据 MSDN,EM_GETTEXTEX返回以下内容:

The return value is the number of TCHARs copied into the
output buffer, including the null terminator.
Run Code Online (Sandbox Code Playgroud)

现在看一下下面的代码:

GETTEXTLENGTHEX gtl;
GETTEXTEX gt;
int len;
TCHAR *buf;

memset(&gtl, 0, sizeof(GETTEXTLENGTHEX));
gtl.flags = GTL_DEFAULT;
gtl.codepage = 1200;

len = SendMessage(hEditWnd, EM_GETTEXTLENGTHEX, (WPARAM) &gtl, 0);

printf("LEN: %d\n", len);

buf = malloc((len + 1) * sizeof(TCHAR));

memset(&gt, 0, sizeof(GETTEXTEX));
gt.cb = (len + 1) * sizeof(TCHAR);
gt.flags = GT_DEFAULT;
gt.codepage = 1200;

len = SendMessage(hEditWnd, EM_GETTEXTEX, (WPARAM) &gt, (LPARAM) buf); …
Run Code Online (Sandbox Code Playgroud)

c winapi richedit

5
推荐指数
1
解决办法
467
查看次数

当出现拼写检查下划线时,富编辑控件发送 EN_CHANGE

假设您刚刚在启用拼写检查的丰富编辑控件中设置了一些文本,并且该文本存在一些拼写错误。一瞬间过去了,拼写检查将启动,然后拼写错误的文本将带有下划线。但猜猜看:丰富的编辑控件实际上EN_CHANGE只会针对下划线事件发送通知(假设您已通过执行以下操作注册了通知SendMessage(hwnd, EM_SETEVENTMASK, 0, (LPARAM)ENM_CHANGE))。

有没有解决方法可以避免这种行为?我有一个对话框,其中包含一些启用拼写检查的丰富编辑控件。我还想知道编辑事件何时发生,这样我就知道何时启用“保存”按钮。因此,仅获取EN_CHANGE拼写检查下划线事件的通知是一个问题。

我考虑过的一种选择是 EN_CHANGE完全禁用通知,然后在子类化的丰富编辑控件中自行触发它们。例如,当有 a 时WM_CHAR,它会 EN_CHANGE显式发送通知等。但这似乎是一个问题,因为有许多类型的事件应该触发更改,例如删除、复制/粘贴等,我可能会无法正确捕获所有这些。

我考虑过的另一个选择是EN_CHANGE动态启用和禁用通知。例如,仅在有焦点时启用它们,并在焦点被终止时禁用它们。但这似乎也有问题,因为丰富的编辑在设置文本时可能已经具有焦点。然后会出现拼写检查下划线,并且EN_CHANGE会发送不需要的通知。

我想也可以使用计时器,但我认为这很容易出错。

有人还有其他想法吗?

这是一个可重现的示例。只需运行它,它就会说发生了一些变化:

#include <Windows.h>
#include <atlbase.h>
#include <atlwin.h>
#include <atltypes.h>
#include <Richedit.h>

class CMyWindow :
    public CWindowImpl<CMyWindow, CWindow, CWinTraits<WS_VISIBLE>>
{
public:
    CMyWindow()
    {
    }

BEGIN_MSG_MAP(CMyWindow)
    MESSAGE_HANDLER(WM_CREATE, OnCreate)
    COMMAND_CODE_HANDLER(EN_CHANGE, OnChange)
END_MSG_MAP()

private:
    LRESULT OnCreate(UINT, WPARAM, LPARAM, BOOL& bHandled)
    {
        bHandled = FALSE;

        LoadLibrary(L"Msftedit.dll");

        CRect rc;
        GetClientRect(&rc);
        m_wndRichEdit.Create(MSFTEDIT_CLASS, m_hWnd, &rc,
            NULL, WS_VISIBLE | WS_CHILD | WS_BORDER); …
Run Code Online (Sandbox Code Playgroud)

c++ winapi atl richedit richedit-control

5
推荐指数
1
解决办法
574
查看次数

如何在富编辑控件上实现鼠标单击URL

我在对话框中添加了一个只读的富编辑2.0控件(代码使用的是C windows API,该对话框是使用函数DialogBox创建的)

在对话框回调中,在WM_INITDIALOG,我添加以下代码以启用URL检测,并启用事件ENM_LINK被发送到父对话框而不是富编辑控件本身:

LRESULT mask = SendMessage(hWndText, EM_GETEVENTMASK, 0, 0); //hWndText is rich edit control
SendMessage(hWndText, EM_SETEVENTMASK, 0, mask | ENM_LINK);
::SendMessage(hWndText, EM_AUTOURLDETECT, TRUE, NULL);  
Run Code Online (Sandbox Code Playgroud)

在最初启动对话框时启用URL检测时遇到了一些麻烦(这似乎是一个已知的问题或行为,因为丰富的编辑控件只能启用对已修改文本的URL检测).但是,我通过在每个WM_PAINT事件上再次设置对话框文本来解决此问题.

代码通常有效.我还实现了以下代码,当鼠标悬停在url上时,在浏览器中启动URL:

case WM_NOTIFY:
    plink = (ENLINK *) lParam;
    switch(LOWORD(wParam))
    {   
        case IDC_DISPLAY_TEXT_2: //this is ID for my rich edit control
            szURL =m_strDisplay.Mid(plink->chrg.cpMin, plink->chrg.cpMax - plink->chrg.cpMin);          
            LaunchURL(szURL); //function to launch the url with default browser
            break;
        default:
            break;
    }
Run Code Online (Sandbox Code Playgroud)

每当我将鼠标悬停在网址上时,我似乎都会收到WM_NOTIFY事件.然而,当我点击它时,我总是得到相同的事件鼠标悬停在上面.

根据ENLINK的结构,我应该在NMHDR结构中获得更详细的NM事件,但是值plink-> nmhdr.code始终是1803,甚至不是NM_HOVER(其定义的值是(NM_FIRST-13)而NM_FIRST是( 0U-0U),因此我的64位机器上的NM_HOVER值为4294967283).我知道我在这里遗漏了一些东西.有人会在这里点灯吗?如何为富编辑控件获取鼠标单击事件?

c c++ winapi richedit

4
推荐指数
1
解决办法
2715
查看次数