想实现类似Delphi的代码提示窗口,该怎么做? ( 积分: 100 )

  • 主题发起人 主题发起人 jsyc
  • 开始时间 开始时间
J

jsyc

Unregistered / Unconfirmed
GUEST, unregistred user!
窗口上又一个TEdit,用户在其中输入内容时,弹出该输入提示窗口,用户可从列表中选择文本送到编辑框
 
窗口上又一个TEdit,用户在其中输入内容时,弹出该输入提示窗口,用户可从列表中选择文本送到编辑框
 
简单做法是再搞个窗体,将这个窗体的BorderStyle设为bsNone,需要时显示出来就可以了。
 
放一个listbox把他的BorderStyle设为bsNone

procedure TForm1.Edit1Enter(Sender: TObject);
begin
listbox1.Top:=edit1.Top+edit1.Height;
listbox1.Width:=edit1.ClientWidth;
listbox1.Left:=edit1.Left+2;
if listbox1.Items.Count<=8 then
listbox1.Height:=listbox1.Items.Count*(-listbox1.Font.Height)
else
listbox1.Height:=8*(-listbox1.Font.Height);
listbox1.Visible:=true;
end;

procedure TForm1.ListBox1Click(Sender: TObject);
begin
if listbox1.ItemIndex<>-1 then
begin
edit1.Text:=listbox1.Items.Strings[listbox1.ItemIndex];
listbox1.Visible:=false;
end;
end;
 
如果想选择行跟随鼠标移动
在listbox的mousemove事件里写:
procedure TForm1.ListBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var
p:Tpoint;
i:integer;
begin
p.X:=x;
p.Y:=y;
i:=listbox1.ItemAtPos(p,true);
if i<>-1 then
listbox1.ItemIndex:=i;
end;
 
用数据库.
 
http://www.tommstudio.com/ 上有synEdit控件,可以做到这个.
 
hs-kill的方法可行,但是与Delphi的代码编辑自动提示窗口有差距。有没有更好的方法呢?
 
有差距? 哪部分差距? 视觉效果还是运行感觉?
 
比如说,按上下箭头键,要把消息传给列表框;在form标题、form空白区域或没有焦点的控件(如TSpeedButton)等处上单击,列表框要消失。感觉Delphi的代码自动提示窗口是另一种做法,就是不知道是怎么实现的。
 
汗。。。。我改了改新的,但是焦点有问题。。。还不明白

上下箭头控制:
在keydown事件里写:
procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if listbox1.Visible then
begin
if (key=vk_up) and (listbox1.ItemIndex>0) then
begin
listbox1.ItemIndex:=listbox1.ItemIndex-1;
key:=0;
end;
if (key=vk_down) and (listbox1.ItemIndex<listbox1.Items.Count-1) then
begin
listbox1.ItemIndex:=listbox1.ItemIndex+1;
key:=0;
end;
end;
end;

点击标题栏列表框消失:
放个ApplicationEvents1,在其onmessage事件里写
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
begin
if msg.message=WM_NCLBUTTONDOWN then
listbox1.Visible:=false;
end;
点击其他控件列表框消失:
procedure TForm1.Edit1Exit(Sender: TObject);
begin
listbox1.Visible:=false;
end;

至于空白处。。。。。应该是在form的mousedown事件里写 listbox1.Visible:=false;

如果是speedbutton那些没有焦点的控件。。。。。我还没想到方法,跟踪也没发现事件。。郁闷
 
我看了Delphi处理THintWindow窗口消失的代码,偷取并适当修改了对消息处理的那部分,感觉实现得较好,代码如下,不对处请指正。

处理ApplicationEvents的onmessage事件

procedure Form1.ApplicationEvents1Message(
var Msg: tagMSG; var Handled: Boolean);
begin
if (Msg.hwnd <> Edit1.Handle) and (Msg.hwnd <> ListBox1.Handle) then
begin
if ((Msg.message >= WM_KEYFIRST) and (Msg.message <= WM_KEYLAST)) or
((Msg.message = CM_ACTIVATE) or (Msg.message = CM_DEACTIVATE)) or
(Msg.message = CM_APPKEYDOWN) or (Msg.message = CM_APPSYSCOMMAND) or
(Msg.message = WM_COMMAND) or ((Msg.message > WM_MOUSEMOVE) and
(Msg.message <= WM_MOUSELAST)) or (Msg.message = WM_NCLBUTTONDOWN {WM_NCMOUSEMOVE}) then //
ListBox1.Visible := False;
end;
with Msg do
if (hwnd = Edit1.Handle) and (message = WM_KEYDOWN) then
case wParam of
VK_DOWN:
begin
if ListBox1.Items.Count = 0 then Exit;
ListBox1.ItemIndex := Min(ListBox1.ItemIndex + 1, ListBox1.Items.Count - 1);
Handled := True;
end;
VK_UP:
begin
if ListBox1.Items.Count = 0 then Exit;
ListBox1.ItemIndex := Max(ListBox1.ItemIndex - 1, 0);
Handled := True;
end;
VK_RETURN:
begin
if ListBox1.Items.Count = 0 then Exit;
if (ListBox1.Visible) and (Edit1.Focused) then
Edit1.Text := ListBox1.Items[Max(ListBox1.ItemIndex, 0)];
end;
end;
end;
OnExit里写代码有点问题,单击listbox就已经触发该事件了
 
上面的Msg.message = WM_NCLBUTTONDOWN 应为((Msg.message >= WM_NCLBUTTONDOWN) and (Msg.message <= WM_NCMBUTTONDBLCLK))

另外,listbox要随Edit里的光标走动,处理OnIdle事件:
procedure orm1.ApplicationEvents1Idle(
Sender: TObject; var Done: Boolean);
var
P, P1: TPoint;
begin
if ListBox1.Visible and (Edit1.Focused) then
begin
GetCaretPos(P);
P1.X := Edit1.Left + P.x + 4;
P1.Y := Edit1.Top + P.y + Edit1.Height;
ListBox1.Top := P1.Y;
ListBox1.Left := P1.X;
end;
end;
 
我知道onexit里写有问题。。。一开始就考虑消息了。。可是我这里不知道怎么会事
if (Msg.hwnd <> Edit1.Handle) and (Msg.hwnd <> ListBox1.Handle) then
这句怎么判断都是true

所以我在onexit里加了个判断
procedure TForm1.Edit1Exit(Sender: TObject);
begin
if self.ActiveControl<>listbox1 then
listbox1.Visible:=false;
end

呵呵 后来想用个新form,所以把那句话删了,然后新form有焦点问题,我就改回以前的方法,就忘了把那句加上了

至于THintWindow。。。我还真没看过,回去研究研究

当然用消息是最好的。。。。。。。。
 
后退
顶部