function GetMouseHook(Code, wParam, lParam: Integer): Integer; stdcall;
var
M: ^MOUSEHOOKSTRUCT;
Msg: Integer;
x,y:integer;
begin
Result:= 0;
if TheForm=nil then exit;
// check for appropriate code
if (Code >= 0)
// and for active application
and Assigned(Application)
and Application.Active
and (not IsIconic(GetActiveWindow))
then begin
msg:=wparam;
// check for mouse messages
if ((Msg >= wm_LButtonDblClk) and (Msg <= wm_MButtonDblClk))
or ((Msg >= wm_NCRButtonDblClk) and (Msg <= wm_NCMButtonDblClk))
or (Msg = wm_LButtonDown)
or (Msg = wm_NCLButtonDown)
or (Msg = wm_NCRButtonDown)
then begin
// here you should check for clicks outside of active form
// and take an appropriate action
// because actial message is packed into the TMsg structure, we should unpack it
M:= pointer(lParam);
x:=m.pt.x;
y:=m.pt.y;
with TheForm do begin
if (x<left) or (y<top) or (x>=left+width) or
(y>=top+height)
then ModalResult:=mrCancel;
end;
Exit;
end;
end;
// in Win32 api stated that this call is optional but I think this statement
// should be always included
Result:= CallNextHookEx(HGetMouseHook, Code, wParam, lParam);
end;
procedure SetMouseHook(Fm:TForm);
begin
if (HGetMouseHook = 0) and (Fm<>nil)
then begin
TheForm:=Fm;
HGetMouseHook:= SetWindowsHookEx(WH_MOUSE, @GetMouseHook,
0,GetCurrentThreadID);
end;
end;
procedure FreeMouseHook;
begin
if HGetMouseHook <> 0
then begin
UnhookWindowsHookEx(HGetMouseHook);
HGetMouseHook:= 0;
TheForm:=nil;
end;
end;
所以最好使用Form1的OnMouseMove事件来判断当前鼠标是不是在Edit1上,如下:
procedure TMainForm.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if WindowFromPoint(Mouse.CursorPos)<>Edit1.Handle then
if ListBox1.Visible then
ListBox1.Visible:=False;
end;
这样,每次当鼠标不在Edit1上时,ListBox1都会自动消失,而当鼠标放到Edit1上时,你可以自己编程实现是否是直接出现ListBox1还是点了鼠标以后才出现ListBox1!
procedure Register;
begin
RegisterComponents('MyCtrl', [TListEdit]);
end;
procedure TListEdit.DefaDlg;
begin
if(FHelpQuery=nil) or
(FResultFieldName='') or
(Not sChanged and Not ExeByBtn
and (FParamName<>'')
and (Trim(text)<>'') )
then
Exit
else
GetData(FResultFieldName, Text);
end;
procedure TListEdit.DoBtnClick(sender:Tobject);
begin
ExeByBtn := True;
Exefun(self);
end;
procedure TListEdit.Exefun(Sender:Tobject);
begin
if ReadOnly then
exit;
if Assigned(FonBtnClick) then
FonBtnClick(Self)
else
DefaDlg;
end;
procedure TListEdit.OnDlgDestroy(sender:TObject);
begin
if Not FhelpQuery.IsEmpty and (HelpQuery.Tag=1) then
begin
DoAfterGetData;
// Setfocus;
end;
ListShowed:=False;
if FGridResize then
begin
FGridWidth := Tform(Sender).Width;
FGridHeight := Tform(Sender).Height; //记录下栅格的大小
end;
end;