2012-02-10 2 views
4

쉘 경량 유틸리티 함수 라이브러리의 SHAutoComplete() 함수를 사용하여 모달 대화 상자의 편집 필드에 대한 경로 자동 완성을 사용하도록 설정하고 있습니다.SHAutoComplete() 목록 상자가 현재 표시되어 있는지 어떻게 확인할 수 있습니까?

Esc 키를 누르면 대화 상자가 닫히고 자동 완료가 활성화되지 않은 경우에만 대화 상자가 닫혀 야합니다.

포커스가있는 편집 컨트롤에 대해 완료 목록이 현재 표시되어 있는지 여부를 어떻게 확인할 수 있습니까?

편집 :

나는 윈도우 XP (64)에 나를 위해 작동하지 않습니다

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

데이비드

에 의해 게시 코드 델파이 2009을 사용하고 있습니다 - 대화가 닫혀 도착합니다.

+1

+1, 좋은 질문입니다. 'IAutoComplete'가리스트를 보여주고 있는지 확인하는 것 이외에 수동으로 [invoke it] 할 수 있는지 궁금합니다. (http://stackoverflow.com/q/9077396/960757). – TLama

+0

그래서, 지금 당신의 프로그램에서 Esc 키가 자동 완성 창을 취소하고 * 대화 상자를 닫음을 말하고 있습니까? 그렇다면 autocomplete 객체가 키보드 메시지를 이미 처리했기 때문에 놀랍습니다. 따라서 Esc 키를 가로 채서 전달하지 않는 것이 좋습니다. –

+0

@Rob : 맞습니다. 취소 버튼의'Cancel' 속성을 설정 해제하고 대신'KeyPreview'와'OnKeyDown'을 사용했지만, Esc 키가 완료 목록을 취소 했음에도 불구하고 여전히 호출됩니다. – mghie

답변

1

문제점을 재현 할 수 없습니다. 다음 OnKeyDown 처리기와 KeyPreview := True을 결합하면 원하는 동작이 빈 양식으로 제공됩니다.

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

대화 상자를 닫는 양식에 뭔가가있는 것 같습니다.

내가 이상한 결과, 여러 시스템에 시도
4

:

  • 윈도우 XP 64 목록은 VM웨어 가상 머신에서 프로 Windows XP에서
  • 을 삭제하는 동안 대화 상자가 닫힙니다 내 PC에 대화 상자가 윈도우 7 대화 미상 내 노트북에 너무

하지만

  • 을 닫습니다 이것이 내가 OS가없는 경우에도 올바른 동작을 강제로 작은 구성 요소를 작성하는 선택 너무 불규칙적이기 때문에 대화 상자가

닫히지 않습니다 윈도우 VMware 가상 머신에서 프로 2000

  • 를 닫 아니다 그것을 제공하십시오.

    구성 요소

    는 다음과 같이 사용할 수 있습니다

    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. 
    

    여기에 게시 된 코드

    은 개념 증명하지만 같은 문제로 어려움을 겪고 사람들을 위해 같은 출발점을 제공 할 수있다.

  • 관련 문제