- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在 Delphi XE2 Starter Edition 中的 TRichEdit 控件中使用表。 (换句话说,我没有 XE2 的源代码 - 但我有 TurboDelphi 的源代码)。据我所知,默认的 RichEdit 控件不使用支持表格的 MS RichEdit 版本,因此我将其子类化以使用 MS RichEdit v4.1,如此处所述 1在这里 6 ,并且还对 JEDI TjvRichEdit 中的代码进行了建模。 (为了简洁起见,我没有包含确定除 v4.1 之外的 DLL 的 RichEdit 版本号的代码段,这是我从 JEDI 借来的。此处显示了简化版本。)
MSDN 博客 2指出支持 RTF 表的 Windows 消息是 MS RichEdit 4.1 版的一个未记录的功能,并且 EM_INSERTTABLE 消息自 Windows XP SP2 起就可用。有关哪些版本可用的详细信息,请参阅此处 3 .
此博客后的评论 2 ,由 David Kinder 于 2008 年 9 月 26 日发布,声明他能够使用我在下面显示的相同代码获取 EM_INSERTTABLE 消息以与 RichEdit v4.1 一起使用(除了他没有使用 Delphi)。
有关 EM_INSERTTABLE 消息及其支持结构的详细信息,请参阅 MSDN 文档 4 (其中声明它们是随 Windows 8 一起引入的,但显然早于至少两个主要操作系统版本)。另请注意,自从 Murray 撰写博客 2 以来,结构的定义已经发生了一些变化。 2008年。我搜索了互联网的两端,但找不到与RichEdit 4.1一起使用的MS richedit.h版本,并且包括当时存在的“未记录”结构TABLEROWPARMS和TABLECELLPARMS,因此我仅限于MSDN Win8 的文档 4和默里的博客 2因为据称它们存在于 Win XP 和 Win7 中。
这是我的自定义 RichEdit:
unit MyRichEdit;
//Customized RichEdit to use MS RichEdit v4.1
// Some stuff borrowed from Michael Lam's REdit (ca. 1998), found on the Torry page.
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls,
StdCtrls, ComCtrls, Printers, RichEdit;
type
{TableRowParms}
PTableRowParms = ^TTableRowParms;
_tableRowParms = packed record
cbRow : BYTE ; // Count of bytes in this structure
cbCell : BYTE ; // Count of bytes in TABLECELLPARMS
cCell : BYTE ; // Count of cells
cRow : BYTE ; // Count of rows
dxCellMargin : LONG ; // Cell left/right margin (\trgaph)
dxIndent : LONG ; // Row left (right if fRTL indent (similar to \trleft)
dyHeight : LONG ; // Row height (\trrh)
nAlignment{:3}: DWORD; // Row alignment (like PARAFORMAT::bAlignment, \trql, trqr, \trqc)
fRTL{:1} : DWORD; // Display cells in RTL order (\rtlrow)
fKeep{:1} : DWORD; // Keep row together (\trkeep}
fKeepFollow{:1} : DWORD; // Keep row on same page as following row (\trkeepfollow)
fWrap{:1} : DWORD; // Wrap text to right/left (depending on bAlignment) (see \tdfrmtxtLeftN, \tdfrmtxtRightN)
fIdentCells{:1} : DWORD; // lparam points at single struct valid for all cells
//cpStartRow : LONG ; // not in Murray's blog version, so commented here...
//bTableLevel : BYTE; // not in Murray's blog version
//iCell : BYTE; // not in Murray's blog version
end;
TABLEROWPARMS = _tableRowParms;
TTableRowParms = TABLEROWPARMS;
{TableCellParms}
PTableCellParms = ^TTableCellParms;
_tableCellParms = packed record
dxWidth : LONG ; // Cell width (\cellx)
nVertAlign{:2} : WORD ; // Vertical alignment (0/1/2 = top/center/bottom \clvertalt (def), \clvertalc, \clvertalb)
fMergeTop{:1} : WORD ; // Top cell for vertical merge (\clvmgf)
fMergePrev{:1} : WORD ; // Merge with cell above (\clvmrg)
fVertical{:1} : WORD ; // Display text top to bottom, right to left (\cltxtbrlv)
wShading : WORD ; // Shading in .01% (\clshdng) e.g., 10000 flips fore/back
dxBrdrLeft : SHORT ; // Left border width (\clbrdrl\brdrwN) (in twips)
dyBrdrTop : SHORT ; // Top border width (\clbrdrt\brdrwN)
dxBrdrRight : SHORT ; // Right border width (\clbrdrr\brdrwN)
dyBrdrBottom : SHORT ; // Bottom border width (\clbrdrb\brdrwN)
crBrdrLeft : COLORREF; // Left border color (\clbrdrl\brdrcf)
crBrdrTop : COLORREF; // Top border color (\clbrdrt\brdrcf)
crBrdrRight : COLORREF; // Right border color (\clbrdrr\brdrcf)
crBrdrBottom : COLORREF; // Bottom border color (\clbrdrb\brdrcf)
crBackPat : COLORREF; // Background color (\clcbpat)
crForePat : COLORREF; // Foreground color (\clcfpat)
end;
TABLECELLPARMS = _tableCellParms;
TTableCellParms = TABLECELLPARMS;
TMyRichEdit = class(ComCtrls.TRichEdit)
private
function GetRTF: string; // get the RTF string
procedure SetRTF(InRTF: string); // set the RTF string
protected
procedure CreateParams(var Params: TCreateParams); override;
published
property RTFText: string read GetRTF write SetRTF;
end;
//--------------------------------------------------------------
// GLOBAL VARIABLES
//--------------------------------------------------------------
var
RichEditVersion : Integer; //Version of the MS Windows RichEdit DLL
const
RichEdit10ModuleName = 'RICHED32.DLL';
RichEdit20ModuleName = 'RICHED20.DLL';
RichEdit41ModuleName = 'MSFTEDIT.DLL';
MSFTEDIT_CLASS = 'RichEdit50W'; //goes with RichEdit 4.1 (beginning with Win XP SP2)
EM_INSERTTABLE = WM_USER + 232;
implementation
function TMyRichEdit.GetRTF: string;
var FStream : TStringStream;
begin
// get the RTF string
FStream := TStringStream.Create; // RTF stream
FStream.Clear;
FStream.Position := 0;
Lines.SaveToStream(FStream);
Result := FStream.DataString;
FStream.Free; // free the RTF stream
end; //ok
procedure TMyRichEdit.SetRTF(InRTF: string);
var FStream : TStringStream;
begin
// set the RTF string
// LoadFromStream uses an EM_STREAMIN windows msg, which by default REPLACES the contents of a RichEdit.
FStream := TStringStream.Create; // RTF stream
FStream.Clear;
FStream.Position := 0;
FStream.WriteString(InRTF);
FStream.Position := 0;
Lines.LoadFromStream(FStream);
Self.Modified := false;
FStream.Free; // free the RTF stream
end; //ok
//===========================================================================
//Defaults: RICHEDIT_CLASS = 'RichEdit20W'; RICHEDIT_CLASS10A = 'RICHEDIT';
//It needs to use RichEdit50W for version 4.1, which I defined in a constant above as MSFTEDIT_CLASS.
procedure TMyRichEdit.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
If RichEditVersion = 1 then CreateSubClass(Params, RICHEDIT_CLASS10A)
else If RichEditVersion = 4 then CreateSubClass(Params, MSFTEDIT_CLASS)
else CreateSubClass(Params, RICHEDIT_CLASS);
end;
//================================================================
{Initialization Stuff}
//================================================================
var
GLibHandle: THandle = 0;
procedure InitRichEditDll;
begin
//Try to load MS RichEdit v 4.1 into memory...
RichEditVersion := 4;
GLibHandle := SafeLoadLibrary(RichEdit41ModuleName);
if (GLibHandle > 0) and (GLibHandle < HINSTANCE_ERROR) then
GLibHandle := 0; //this means it could not find the DLL or it didn't load right.
if GLibHandle = 0 then begin
RichEditVersion := 2;
GLibHandle := SafeLoadLibrary(RichEdit20ModuleName);
if (GLibHandle > 0) and (GLibHandle < HINSTANCE_ERROR) then
GLibHandle := 0;
if GLibHandle = 0 then begin
RichEditVersion := 1;
GLibHandle := SafeLoadLibrary(RichEdit10ModuleName);
if (GLibHandle > 0) and (GLibHandle < HINSTANCE_ERROR) then begin
RichEditVersion := 0;
GLibHandle := 0;
end;
end;
end;
end;
procedure FinalRichEditDll;
begin
if GLibHandle > 0 then
begin
FreeLibrary(GLibHandle);
GLibHandle := 0;
end;
end;
initialization
InitRichEditDll;
finalization
FinalRichEditDll;
End.
用法:
Uses … MyRichEdit …
type
TRichEdit = class(TMyRichEdit);
TfrmEdit = class(TForm)
…
memNotes: TRichEdit;
…
end;
procedure TfrmEdit.actTableAddExecute(Sender: TObject);
var
rows: TABLEROWPARMS;
cells: TABLECELLPARMS;
rc : LRESULT;
begin
//Insert a table into the RTF.
ZeroMemory(@rows,sizeof(rows));
rows.cbRow := sizeof(TABLEROWPARMS);
rows.cbCell := sizeof(TABLECELLPARMS);
rows.cCell := 3;
rows.cRow := 2;
rows.dxCellMargin := 5; //50
rows.nAlignment := 1;
rows.dyHeight := 100; //400
rows.fIdentCells := 1;
rows.fRTL := 0;
rows.fKeep := 1;
rows.fKeepFollow := 1;
rows.fWrap := 1;
//rows.cpStartRow := -1;
ZeroMemory(@cells,sizeof(cells));
cells.dxWidth := 600; //1000
cells.dxBrdrLeft := 1;
cells.dyBrdrTop := 1;
cells.dxBrdrRight := 1;
cells.dyBrdrBottom := 1;
cells.crBackPat := RGB(255,255,255);
cells.crForePat := RGB(0,0,0);
cells.nVertAlign := 0;
//cells.fMergeTop := 1;
//cells.fMergePrev := 1;
cells.fVertical := 1;
rc := SendMessage(memNotes.Handle,EM_INSERTTABLE, WPARAM(@rows),LPARAM(@cells));
//rc := memNotes.Perform(EM_INSERTTABLE, WPARAM(@rows),LPARAM(@cells));
end;
执行后,rc 包含 -2147024809 (E_INVALIDARG
)。我不太明白为什么会失败,或者消息参数有什么问题。作为免责声明,我是在 Delphi 中使用 RichEdit 的新手,但在发帖寻求帮助之前我尝试尽可能多地学习。
在我的广泛搜索中,我找到了这个网站5这可能有助于缩小问题范围。该站点托管一个名为 RTFLabel 的实用程序。下载 zip 文件并查看 richedit2.pas,其中他们解释说“richedit.h (2005 SDK) 中 CHARFORMAT2A 和 CHARFORMAT2W 的定义在 C 部分有错误”,并且他们需要插入一个新的虚拟值字段来“修复”结构的字节对齐,以使其在 Delphi 中正常工作。我感觉 TABLEROWPARMS 和 TABLECELLPARMS 结构之一或两者可能存在类似的对齐问题,从而导致此错误。
我需要一些帮助来弄清楚为什么 SendMessage
返回 E_INVALIDARG,以及我可以采取哪些措施来修复它。任何帮助将不胜感激!
-杰夫·艾勒
引用网站:
1 [http://fgaillard.com/2010/09/using-richedit-4-1-with-d2010/] 1
2 [http://blogs.msdn.com/b/murrays/archive/2008/09/15/richedit-s-nested-table-facility.aspx] 2
3 [http://blogs.msdn.com/b/murrays/archive/2006/10/14/richedit-versions.aspx] 3
4 [http://msdn.microsoft.com/en-us/library/windows/desktop/hh768373%28v=vs.85%29.aspx] 4
5 [http://flocke.vssd.de/prog/code/pascal/rtflabel/] 5
6 [Delphi 7 TRichTextEdit Text in a box not displaying correctly 6
最佳答案
这是正确的结构...
_tableRowParms = record
cbRow : BYTE; // Count of bytes in this structure
cbCell : BYTE; // Count of bytes in TABLECELLPARMS
cCell : BYTE; // Count of cells
cRow : BYTE; // Count of rows
dxCellMargin : LONGINT; // Cell left/right margin (\trgaph)
dxIndent : LONGINT; // Row left (right if fRTL indent (similar to \trleft)
dyHeight : LONGINT; // Row height (\trrh)
nParams : DWORD; // 0 - 2 bits - Row alignment (like PARAFORMAT::bAlignment, 1/2/3) (\trql, trqr, \trqc)
// 3 bit - Display cells in RTL order (\rtlrow)
// 4 bit - Keep row together (\trkeep}
// 5 bit - Keep row on same page as following row (\trkeepfollow)
// 6 bit - Wrap text to right/left (depending on bAlignment) (see \tdfrmtxtLeftN, \tdfrmtxtRightN)
// 7 bit - lparam points at single struct valid for all cells
cpStartRow : LONGINT; // The character position that indicates where to insert table. A value of –1 indicates the character position of the selection.
bTableLevel : BYTE; // The table nesting level (EM_GETTABLEPARMS only).
iCell : BYTE; // The index of the cell to insert or delete (EM_SETTABLEPARMS only).
end;
TABLEROWPARMS = _tableRowParms;
TTableRowParms = TABLEROWPARMS;
PTableRowParms = ^TTableRowParms;
_tableCellParms = record
dxWidth : LONGINT; // Cell width (\cellx)
nParams : Word; // 0 - 1 bits - Vertical alignment (0/1/2 = top/center/bottom) (\clvertalt (def), \clvertalc, \clvertalb)
// 2 bit - Top cell for vertical merge (\clvmgf)
// 3 bit - Merge with cell above (\clvmrg)
// 4 bit - Display text top to bottom, right to left (\cltxtbrlv)
// 5 bit - Start set of horizontally merged cells (\clmgf).
// 6 bit - Merge with the previous cell (\clmrg).
wShading : WORD; // Shading in .01% (\clshdng) e.g., 10000 flips fore/back
dxBrdrLeft : SHORT; // Left border width (\clbrdrl\brdrwN) (in twips)
dyBrdrTop : SHORT; // Top border width (\clbrdrt\brdrwN)
dxBrdrRight : SHORT; // Right border width (\clbrdrr\brdrwN)
dyBrdrBottom : SHORT; // Bottom border width (\clbrdrb\brdrwN)
crBrdrLeft : COLORREF; // Left border color (\clbrdrl\brdrcf)
crBrdrTop : COLORREF; // Top border color (\clbrdrt\brdrcf)
crBrdrRight : COLORREF; // Right border color (\clbrdrr\brdrcf)
crBrdrBottom : COLORREF; // Bottom border color (\clbrdrb\brdrcf)
crBackPat : COLORREF; // Background color (\clcbpat)
crForePat : COLORREF; // Foreground color (\clcfpat)
end;
TABLECELLPARMS = _tableCellParms;
TTableCellParms = TABLECELLPARMS;
PTableCellParms = ^TTableCellParms;
关于delphi - 在 Delphi 中使用 RichEdit 中的表格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22689517/
请在标记为重复之前阅读。 我正在创建一组依赖智能卡进行身份验证的应用程序。到目前为止,每个应用程序都单独控制智能卡读卡器。几周后,我的一些客户将同时使用多个应用程序。因此,我认为创建一个控制身份验证过
我想设置一个小程序,从数据库中检索信息,然后根据请求将该信息分发给另一个程序。例如,一个名为“Master”的程序将从数据库中检索数据并创建一个对象集合(列表、数组等,无论哪种效果最好),然后一个名为
我有两台电脑,都装有 XE2。我以为我在两者上安装了相同的安装,但在其中一个上安装第 3 方软件包时遇到问题,而另一个则正常。 无论如何,我希望两者都一样。最简单的人可能只是通过移入我的 Dropbo
有冲突吗? 最佳答案 所有新版本的 Delphi 始终可以安全地安装到旧版本的下一个版本。 每个新版本都应安装在其自己的目录中。 如果您要安装多个版本,请始终先安装最旧的版本,然后再安装最新版本。 我
快速提问:如果我从代码中删除 // 或 (* *) 中的注释,Delphi 2007 的执行时间会受到影响吗?最终结果是一个可能包含数千行注释的 EXE 文件。 最佳答案 编译器会简单地忽略注释,并且
我必须对照另一个文件检查文件的每一行。 如果第二个文件中存在第一个文件中的一行,则必须删除它。 现在,我正在使用2个列表框,并且“对于listbox1.items.count-1可以开始...” 我的
我正在尝试在访问数据库中添加一些数据。但是我有麻烦,因为这会返回错误: ADOQuery1 missing sql property 实现了对代码的几次修改,到目前为止没有任何效果。 我究竟做错了什么
我用Delphi 5编写了一个程序,在Windows 8 32位PC上可以正常运行。我发现在Windows 7 64位笔记本电脑上运行它最终会导致reallocmem错误,而该错误在32位PC上不会发
看来这是我需要的工具,用于提取XML并与TClientDataset连接。我已经在几篇文章和文档中看到了它,但是我无法在XE2组件列表中找到它-在任何地方!应该在哪里?是否在可能未安装的可选软件包中?
我正在寻找一个非常通用的TDBTree组件,我想听听一些建议。我正在特别寻找一种显示主记录和“ n”个链接表记录的记录。 (我的意思是来自各个表的记录)。例如,TDBTree将钩接到主表,明细表1,附
我需要将按钮制作成旋转三角形的形状(或者说是任何多边形)。谁能提供任何建议? 最佳答案 查看Win32 API CreatePolygonRgn()和SetWindowRgn()函数,以创建一个HRG
你好专家 我的JvPasswordForm1有一个旧的JVC组件。 似乎该组件不再存在:它替换为哪个组件? 重新获得 最佳答案 尝试查找TJvLoginDialog,TjvPassword已合并到其中
几天前,我已经设置了我的开发环境(在装有Win 7的VM和域上的用户的VM上安装了delphi 2009),并安装了我的组件(jedi's,devExpress,ADS等)。 今天,我启动机器,打开d
开始对控件进行子分类的正确位置/时间是什么? 恢复原始窗口proc的正确时间是几点? 现在我在表单创建过程中子类化: procedure TForm1.FormCreate(Sender: TObje
有人可以给我一些有关如何登录访问的网页(使用任何网络浏览器)的指示吗?我应该建立一个全球代理....钩住网络....吗?我需要记录的只是页面地址,而不是其中包含的信息。 我正在使用Delphi。 谢谢
我创建了一个像 TMyClass = class(TObject) private FList1: TObjectList; FList2: TObjectList; public end;
我有一个BPG文件,我已对其进行修改以用作我们公司的自动构建服务器的make文件。为了使其正常工作,我必须进行更改 用途*用途 'unit1.pas'中的unit1 * unit1 'unit2.pa
我将Delphi 7代码迁移到了Delphi XE4。我在Delphi XE4的LoadFromStram方法中遇到错误,但对于Delphi 7来说也可以正常工作。 错误: First chance
我正在尝试学习一些新技巧,以便更好地组织我在 Delphi 中的单元中的一些源代码。 我注意到我访问的一些函数或方法似乎是类中的类,但是我还没有成功地在类中创建一个工作类,虽然它编译得很好,但在执行代
我有一个包含许多类的大单元,现在我想通过将某些类分成新的单元来重构该单元。 我不得不承认我缺乏使用Delphi内置IDE功能的经验。利用内置功能“查找|查找对类型的本地引用”并没有多大帮助,因为类方法
我是一名优秀的程序员,十分优秀!