2012-02-10 45 views
4

我使用Shell Lightweight Utility Functions 库中的SHAutoComplete()函数为模态对话框中的编辑字段启用路径自动完成。如何检查当前是否显示SHAutoComplete()列表框?

当按下键时,对话框应关闭,但只有在自动完成未激活时才会关闭。

如何检查当前是否显示针对聚焦编辑控件的完成列表?

编辑:

我使用德尔福2009年在Windows XP 64.大卫

procedure TMyForm.FormKeyDown(Sender: TObject; var Key: Word; 
    Shift: TShiftState); 
begin 
    if Key = VK_ESCAPE then 
    ModalResult := mrCancel; 
end; 

发布对我不起作用的代码 - 对话框被关闭。

+1

+1,好问题;我想知道是否除了检查IAutoComplete是否显示列表也可以手动['调用它'](http://stackoverflow.com/q/9077396/960757)。 – TLama 2012-02-10 08:25:04

+0

那么,你是说现在在你的程序中,Esc键取消了自动填充窗口*并关闭了你的对话框?如果是这样,我很惊讶,因为自动完成对象已经处理了键盘消息,所以它应该知道在拦截它之后不转发Esc键。 – 2012-02-10 08:32:01

+0

@Rob:是的,它确实如此。我取消了取消按钮的取消属性,并使用了表格的“KeyPreview”和“OnKeyDown”,但即使Esc按钮取消了完成列表,它仍然被调用。 – mghie 2012-02-10 08:48:35

回答

1

我无法重现您的问题。以下OnKeyDown处理程序与KeyPreview := True结合使用,以其他空格式给出所需的行为。

procedure TMyForm.FormKeyDown(Sender: TObject; var Key: Word; 
    Shift: TShiftState); 
begin 
    if Key=VK_ESCAPE then 
    ModalResult := mrCancel; 
end; 

我想你的窗体中还有别的东西在关闭对话框。

4

我曾尝试在几个系统上,用奇怪的结果:

  • 我使用Windows XP 64,而名单是在VMware虚拟机上的Windows XP专业版掉了下来
  • 对话框关闭PC上对话框关闭太

  • 我的笔记本电脑与Windows 7的对话框母鹿不是在Windows 2000在VMware虚拟机临关闭
  • 对话框不会关闭

由于这是如此飘忽不定我选择了写迫使即使操作系统不正确的行为一小部分提供它。


该组件可用于这样的:

procedure TForm2.FormCreate(Sender: TObject); 
const 
    SHACF_FILESYS_DIRS = $00000020; 
begin 
    SHAutoComplete(Edit1.Handle, SHACF_FILESYS_DIRS or SHACF_USETAB); 
    fAutoSuggestDropdownChecker := TAutoSuggestDropdownChecker.Create(Self); 
end; 

procedure TForm2.FormKeyDown(Sender: TObject; var Key: Word; 
    Shift: TShiftState); 
begin 
    if Key = VK_ESCAPE then begin 
    if not fAutoSuggestDropdownChecker.DroppedDown then 
     ModalResult := mrCancel; 
    end; 
end; 

,但重要的是,取消按钮不具有Cancel属性集。

组件本身通过挂钩到应用程序消息处理中,并使用当前线程的窗口枚举来检查具有“自动建议下拉菜单”类名称的可见窗口。如果存在并且可见,则自动完成列表被下拉。

unit uAutoSuggestDropdownCheck; 

interface 

uses 
    Windows, Classes, Messages, Forms; 

type 
    TAutoSuggestDropdownChecker = class(TComponent) 
    private 
    fDroppedDown: boolean; 
    fSaveMessageEvent: TMessageEvent; 
    procedure AppOnMessage(var AMsg: TMsg; var AHandled: Boolean); 
    public 
    constructor Create(AOwner: TComponent); override; 
    destructor Destroy; override; 

    property DroppedDown: boolean read fDroppedDown; 
    end; 

implementation 

//////////////////////////////////////////////////////////////////////////////// 

function EnumThreadWindowsProc(AWnd: HWND; AParam: LPARAM): BOOL; stdcall; 
var 
    WndClassName: string; 
    FoundAndVisiblePtr: PInteger; 
begin 
    SetLength(WndClassName, 1024); 
    GetClassName(AWnd, PChar(WndClassName), Length(WndClassName)); 
    WndClassName := PChar(WndClassName); 
    if WndClassName = 'Auto-Suggest Dropdown' then begin 
    FoundAndVisiblePtr := PInteger(AParam); 
    FoundAndVisiblePtr^ := Ord(IsWindowVisible(AWnd)); 
    Result := False; 
    end else 
    Result := True; 
end; 

function IsAutoSuggestDropdownVisible: boolean; 
var 
    FoundAndVisible: integer; 
begin 
    FoundAndVisible := 0; 
    EnumThreadWindows(GetCurrentThreadId, @EnumThreadWindowsProc, 
    LParam(@FoundAndVisible)); 
    Result := FoundAndVisible > 0; 
end; 

//////////////////////////////////////////////////////////////////////////////// 
// TAutoSuggestDropdownChecker 
//////////////////////////////////////////////////////////////////////////////// 

constructor TAutoSuggestDropdownChecker.Create(AOwner: TComponent); 
begin 
    inherited Create(AOwner); 
    fSaveMessageEvent := Application.OnMessage; 
    Application.OnMessage := AppOnMessage; 
end; 

destructor TAutoSuggestDropdownChecker.Destroy; 
begin 
    if (TMethod(fSaveMessageEvent).Code = TMethod(Application.OnMessage).Code) 
    and (TMethod(fSaveMessageEvent).Data = TMethod(Application.OnMessage).Data) 
    then begin 
    Application.OnMessage := fSaveMessageEvent; 
    end; 
    fSaveMessageEvent := nil; 
    inherited; 
end; 

procedure TAutoSuggestDropdownChecker.AppOnMessage(var AMsg: TMsg; 
    var AHandled: Boolean); 
begin 
    if ((AMsg.message >= WM_KEYFIRST) and (AMsg.message <= WM_KEYLAST)) 
    or ((AMsg.message >= WM_MOUSEFIRST) and (AMsg.message <= WM_MOUSELAST)) 
    or (AMsg.message = WM_CANCELMODE) 
    then 
    fDroppedDown := IsAutoSuggestDropdownVisible 
end; 

end. 

这里发布的代码只是概念验证,但可以作为那些与同样问题斗争的起点。

相关问题