我看了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就已经触发该事件了