我需要从外部应用程序获取TcxTreeList(自定义Devexpress控件)中的所有数据。我知道如何从外部应用程序(即树视图,列表框,备忘录,列表视图等)中的标准控件获取数据,发送正确的Windows消息,但我不知道如何为这种情况做到这一点自定义控件。 从Devexpress读取文档我可以看到以下类层次结构:TcxTreeList - > TcxCustomTreeList - > TcxExtEditingControl - > TcxEditingControl - > TcxControl - > TCustomControl,但不幸的是我不知道要发送什么样的Windows消息才能获取数据。
例如:为了获取标准树视图的数据,我以正确的顺序发送带有TVGN_CHILD,TVGN_NEXT,TVM_GETITEM等参数的消息。
有人可以建议我如何获取TcxTreeList控件的数据吗?
我当然要问这个问题,因为完全无法修改外部应用程序的源代码(我没有)或者重写它。
提前谢谢
答案 0 :(得分:2)
我认为你可能会对此采取一些艰难的斗争。请尝试以下方法:
下载&安装Devex VCL试用版
创建一个新的Delphi项目,在其主窗体中添加一个TcxTreelist,在其中添加两列 树,并使用树的项目编辑器,向它添加两个顶级项目节点和一个子项目 这些中的每一个。
编译&运行该项目,然后使用类似的WinSpy ++检查其行为。
请注意,在您单击任何树节点之前,cxTreelist没有内部窗口(我的意思是 来自OS pov的窗口。)
在编辑树中的一个数据节点时,会创建一个类TcxCustomInnerTextEdit的窗口。 TcxCustomInnerTextEdit在单元cxTextEdit.Pas中的Devex VCL源中声明,并且是后代 TCustomEdit。它具有如下消息处理程序(除了TCustomEdit')
{ private }
procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
procedure EMReplaceSel(var Message: TMessage); message EM_REPLACESEL;
procedure EMSetSel(var Message: TMessage); message EM_SETSEL;
procedure WMChar(var Message: TWMChar); message WM_CHAR;
procedure WMClear(var Message: TMessage); message WM_CLEAR;
procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
procedure WMIMEChar(var Message: TMessage); message WM_IME_CHAR;
procedure WMIMEComposition(var Message: TMessage); message WM_IME_COMPOSITION;
procedure WMKeyDown(var Message: TWMKeyDown); message WM_KEYDOWN;
procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
procedure WMNCPaint(var Message: TWMNCPaint); message WM_NCPAINT;
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
procedure WMSetFont(var Message: TWMSetFont); message WM_SETFONT;
procedure WMSize(var Message: TWMSize); message WM_SIZE;
procedure WMUndo(var Message: TWMSize); message WM_UNDO;
protected
procedure MouseEnter(AControl: TControl); dynamic;
procedure MouseLeave(AControl: TControl); dynamic;
正如您所说,如何从标准Windows控件获取数据,这些处理程序声明可能足以让您了解自己是否可以执行所需操作。
如果您可以通过向应用程序发送消息来选择所需的节点,具体取决于 在您想要做的事情上,您可以使用这些处理程序的消息来完成它。
您是否可以使用UI自动化进行类似操作,我不确定。生成导入单元 从UIAutomationCore.dll开始,按照示例进行实验,然后尝试使用它 在How get current url address on mains browsers using UIAutomation?。
您会注意到导入单元中的一个枚举常量是
TreeScope_Children
但是,如果您能使用它,我会感到惊讶
cxTreeList的各个数据节点,但你永远不知道。
顺便说一下,TcxCustomInnerEdit实现了几个接口
IcxCustomInnerEdit = interface(IcxContainerInnerControl)
['{468D21B5-48AA-4077-8ED5-4C6112D460B1}']
function CallDefWndProc(AMsg: UINT; WParam: WPARAM; LParam: LPARAM): LRESULT;
function CanProcessClipboardMessages: Boolean;
function GetEditValue: TcxEditValue;
function GetOnChange: TNotifyEvent;
function GetReadOnly: Boolean;
procedure LockBounds(ALock: Boolean);
procedure SafelySetFocus;
procedure SetEditValue(const Value: TcxEditValue);
procedure SetParent(Value: TWinControl);
procedure SetOnChange(Value: TNotifyEvent);
procedure SetReadOnly(Value: Boolean);
property EditValue: TcxEditValue read GetEditValue write SetEditValue;
property Parent: TWinControl write SetParent;
property ReadOnly: Boolean read GetReadOnly write SetReadOnly;
property OnChange: TNotifyEvent read GetOnChange write SetOnChange;
end;
{ IcxInnerEditHelper }
IcxInnerEditHelper = interface
['{35667555-6DC8-40D5-B705-B08D5697C621}']
function GetHelper: IcxCustomInnerEdit;
end;
和IcxContainerInnerControl声明为
IcxContainerInnerControl = interface
['{1B111318-D9C9-4C35-9EFF-5D95793C0106}']
function GetControl: TWinControl;
function GetControlContainer: TcxContainer;
property Control: TWinControl read GetControl;
property ControlContainer: TcxContainer read GetControlContainer;
end;
但我不知道你是否可以从一个单独的Delphi应用程序中调用这些接口,即使它们对你所处的内容有任何用处。
我还没有研究过整个TcxTreeList的代码,但我想象的是图像 对每个数据节点进行绘制"虚拟"作为一个整体的树形图,除了当前关注的节点(如果有的话)。所以,我不希望找到 每个数据节点和树状记录的其他内部共存的子控件。
支出或预算,购买Devex VCL库(附带完整资源)可能是一项不错的投资。
祝你好运!