从Delphi

时间:2018-04-10 17:27:41

标签: delphi devexpress external sendmessage

我需要从外部应用程序获取TcxTreeList(自定义Devexpress控件)中的所有数据。我知道如何从外部应用程序(即树视图,列表框,备忘录,列表视图等)中的标准控件获取数据,发送正确的Windows消息,但我不知道如何为这种情况做到这一点自定义控件。 从Devexpress读取文档我可以看到以下类层次结构:TcxTreeList - > TcxCustomTreeList - > TcxExtEditingControl - > TcxEditingControl - > TcxControl - > TCustomControl,但不幸的是我不知道要发送什么样的Windows消息才能获取数据。

例如:为了获取标准树视图的数据,我以正确的顺序发送带有TVGN_CHILD,TVGN_NEXT,TVM_GETITEM等参数的消息。

有人可以建议我如何获取TcxTreeList控件的数据吗?

我当然要问这个问题,因为完全无法修改外部应用程序的源代码(我没有)或者重写它。

提前谢谢

1 个答案:

答案 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库(附带完整资源)可能是一项不错的投资。

祝你好运!