入题,在richedit编辑框中如何象delphi代码编辑器般出现代码提示框供选择
解决方案 »
- Xp下不能使用日志钩子
- 2000server共享了一个文件夹,并创建了一个用户名和密码,用于其他机器访问该文件夹。问题是有没有办法编程实现,用户在自己机器上直接修
- 终于开张了!:~~)
- 现在做一个程序,要将原有手工填写的表格做成电子版的,并且在输入的地方嵌入EDIT或COMBOX?用什么方法实现啊?急急急!!
- 请问谁有RAVE的技术资料!总共100分,我肯定结贴的!
- 如何获取网页返回的状态,也就是,如何判断 一个网页能否打开?
- 能不能用delphi做一个程序,把网站上的新闻标题拖到程序里,程序能显示新闻标题的内容和url链接!!! 谢谢。。大侠们 !!!
- 看了我的程序,他们哭了!
- 请问如何从EMAIL地址中解析到SMTP服务器的地址??
- tp中怎样生成在一定范围里的随机数
- 公式分析,救急!!
- 问,怎样加载TDataModule呀,
up
后者的话要看你具体处理怎样的数据了,如果是代码的提示,可是要进行代码分析,看编译原理去,我也不会,呵呵。。
关键有两点,首先是如何把richedit中的光标位置转化为窗体弹出的位置,这里涉及了插入点如何定位的问题
其次,窗体弹出时是处于一个什么状态。从delphi的效果看,窗体中的大概是个listbox之类的东西,在弹出时获取了focus;但是此时主窗体也同样没有失去focus,怎么实现的呢
{ TPopupListbox }
TPopupListbox = class(TCustomListbox)
private
FSearchText: String;
FSearchTickCount: Longint;
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure CreateWnd; override;
procedure KeyPress(var Key: Char); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
end;procedure TPopupListBox.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do
begin
Style := Style or WS_BORDER;
ExStyle := WS_EX_TOOLWINDOW or WS_EX_TOPMOST;
AddBiDiModeExStyle(ExStyle);
WindowClass.Style := CS_SAVEBITS;
end;
end;procedure TPopupListbox.CreateWnd;
begin
inherited CreateWnd;
Windows.SetParent(Handle, 0);
CallWindowProc(DefWndProc, Handle, wm_SetFocus, 0, 0);
end;procedure TPopupListbox.Keypress(var Key: Char);
var
TickCount: Integer;
begin
case Key of
#8, #27: FSearchText := '';
#32..#255:
begin
TickCount := GetTickCount;
if TickCount - FSearchTickCount > 2000 then FSearchText := '';
FSearchTickCount := TickCount;
if Length(FSearchText) < 32 then FSearchText := FSearchText + Key;
SendMessage(Handle, LB_SelectString, WORD(-1), Longint(PChar(FSearchText)));
Key := #0;
end;
end;
inherited Keypress(Key);
end;procedure TPopupListbox.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
inherited MouseUp(Button, Shift, X, Y);
TInplaceEditList(Owner).CloseUp((X >= 0) and (Y >= 0) and
(X < Width) and (Y < Height));
end;
TPopupWindow = class(TCustomControl)
private
FEditor: TWinControl;
FCloseUp: TCloseUpEvent;
procedure WMMouseActivate(var Message: TMessage); message WM_MOUSEACTIVATE;
protected
procedure CreateParams(var Params: TCreateParams); override;
{$IFDEF WIN32}
function Getvalue: Variant; virtual; abstract;
procedure Setvalue(const value: Variant); virtual; abstract;
{$ELSE}
procedure CreateWnd; override;
function Getvalue: string; virtual; abstract;
procedure Setvalue(const value: string); virtual; abstract;
{$ENDIF}
procedure InvalidateEditor;
procedure PopupMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure CloseUp(Accept: Boolean); virtual;
public
constructor Create(AOwner: TComponent); override;
function GetPopupText: string; virtual;
procedure Hide;
procedure Show(Origin: TPoint);
property OnCloseUp: TCloseUpEvent read FCloseUp write FCloseUp;
end;{ TPopupWindow }constructor TPopupWindow.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FEditor := TWinControl(AOwner);
{$IFDEF WIN32}
ControlStyle := ControlStyle + [csNoDesignVisible, csReplicatable,
csAcceptsControls];
{$ELSE}
ControlStyle := ControlStyle + [csAcceptsControls];
{$ENDIF}
Ctl3D := False;
ParentCtl3D := False;
Visible := False;
Parent := FEditor;
onMouseUp := PopupMouseUp;
end;procedure TPopupWindow.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do begin
Style := WS_POPUP or WS_BORDER or WS_CLIPCHILDREN;
{$IFDEF WIN32}
ExStyle := WS_EX_TOOLWINDOW;
{$ENDIF}
WindowClass.Style := WindowClass.Style or CS_SAVEBITS;
end;
end;{$IFNDEF WIN32}
procedure TPopupWindow.CreateWnd;
begin
inherited CreateWnd;
if (csDesigning in ComponentState) then SetParent(nil);
end;
{$ENDIF}procedure TPopupWindow.WMMouseActivate(var Message: TMessage);
begin
Message.Result := MA_NOACTIVATE;
end;function TPopupWindow.GetPopupText: string;
begin
Result := '';
end;procedure TPopupWindow.InvalidateEditor;
var
R: TRect;
begin
if (FEditor is TCustomComboEdit) then begin
with TCustomComboEdit(FEditor) do
SetRect(R, 0, 0, ClientWidth - FBtnControl.Width - 2, ClientHeight + 1);
end
else R := FEditor.ClientRect;
InvalidateRect(FEditor.Handle, @R, False);
UpdateWindow(FEditor.Handle);
end;procedure TPopupWindow.PopupMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then CloseUp(PtInRect(Self.ClientRect, Point(X, Y)));
end;procedure TPopupWindow.CloseUp(Accept: Boolean);
begin
if Assigned(FCloseUp) then FCloseUp(Self, Accept);
end;procedure TPopupWindow.Hide;
begin
SetWindowPos(Handle, 0, 0, 0, 0, 0, SWP_NOZORDER or
SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_HIDEWINDOW);
Visible := False;
end;procedure TPopupWindow.Show(Origin: TPoint);
begin
SetWindowPos(Handle, HWND_TOP, Origin.X, Origin.Y, 0, 0,
SWP_NOACTIVATE or SWP_SHOWWINDOW or SWP_NOSIZE);
Visible := True;
end;
现在主要还是光标的位置难以确定
用GetCaretPos()配合clienttoscreen确定光标位置是有偏差的
我这里测试X坐标还不算很明显,但是Y坐标就差的比较远啦
希望可以有更好的解决办法
从单步执行的效果看,Y方向的差距是很大的,而且那个值也不知是怎么算出来的
procedure TForm1.RichEdit1SelectionChange(Sender: TObject);
var
vPoint: TPoint;
begin
GetCaretPos(vPoint);
vPoint := TRichEdit(Sender).ClientToScreen(vPoint); Form2.Left := vPoint.X;
Form2.Top := vPoint.Y + Trunc(TRichEdit(Sender).SelAttributes.Height * 1.3);
SetFocus;
end;procedure TForm1.FormShow(Sender: TObject);
begin
Form2.Show;
end;
误差个几个像素用户不会说啥的~~
值得参考呀
2、直接在richedit上显示一个listbox不久行了?