Q&A

  • SetActiveWindow가 안먹혀요...
질문은 다름아닌 SetActiveWindow에 대한 질문입니다.

델파이1에서

SetActiveWindow(Self.Handle);

하게되면 내폼이 뒤에 가려져있어도 화면 맨 위로 올라와서 활성화 됩니다.

그런데, 32Bit(델파이2,3,4:모두 테스트해봄)에서는 올라오지 않습니다...

그져 버튼에 포커스가 가는 정도...



제가 원하는 기능은 다음과 같습니다.



그런데, 32Bit(델파이2,3,4:모두 테스트해봄)에서는 올라오지 않습니다...

그져 버튼에 포커스가 가는 정도...

제가 원하는 기능은 다음과 같습니다.

타이머 이벤트에서 이벤트가 걸리면 자신의 폼이 화면 맨위로 올라와 키보드로 버튼을

누를 수 있게 폼이 활성화되는 것입니다.

제가 테스트하는 예는 다음과 같습니다.



먼저 화면에 버튼과 타이머 컴포넌트를 올립니다.

타이머에 Enabled를 False로 주고, Interval을 2000으로 설정합니다.

그런다음 아래와 같이 코딩을 합니다..



procedure TForm1.Timer1Timer(Sender: TObject);

begin

SetActiveWindow(Self.Handle); //이부분이 중요하겠죠?

Timer1.Enabled := False;

end;

procedure TForm1.Button1Click(Sender: TObject);

begin

Timer1.Enabled := True;

end;



실행시킨 뒤 버튼을 누른 후 2초후에 화면이 활성화되는 것이죠...

물론 버튼을 누른후 2초내에 다른 폼을 활성화 시켜놔야 합니다...

그래야 테스트가 될테니까요 ^^;

여기서 제가 말하는 활성화라 함은 폼의 캡션(타이틀)바가 파란색으로

나타나며 폼에있는 버튼을 키보드로 클릭할 수 있어야합니다.



예전에 수많은 델파이전문가(?)들이 수많은 종류의 API를 동원해서

테스트했지만 헛수고였습니다...



암튼, 염치없는 부탁이지만... 말로만 답변하시지 마시고,

테스트를 꼭 해보시고 답변을 해 주셨으면 좋겠습니다.

굳이 테스트 할 시간이 없으면 제가 하겠으니 많은 답변 부탁드립니다...

3  COMMENTS
  • Profile
    이정욱 1999.07.10 02:53
    SetForegroundWindow 함수를 사용해 보세요.



    OHJANG 께서 말씀하시기를...

    > 질문은 다름아닌 SetActiveWindow에 대한 질문입니다.

    > 델파이1에서

    > SetActiveWindow(Self.Handle);

    > 하게되면 내폼이 뒤에 가려져있어도 화면 맨 위로 올라와서 활성화 됩니다.

    > 그런데, 32Bit(델파이2,3,4:모두 테스트해봄)에서는 올라오지 않습니다...

    > 그져 버튼에 포커스가 가는 정도...

    >

    > 제가 원하는 기능은 다음과 같습니다.

    >

    > 그런데, 32Bit(델파이2,3,4:모두 테스트해봄)에서는 올라오지 않습니다...

    > 그져 버튼에 포커스가 가는 정도...

    > 제가 원하는 기능은 다음과 같습니다.

    > 타이머 이벤트에서 이벤트가 걸리면 자신의 폼이 화면 맨위로 올라와 키보드로 버튼을

    > 누를 수 있게 폼이 활성화되는 것입니다.

    > 제가 테스트하는 예는 다음과 같습니다.

    >

    > 먼저 화면에 버튼과 타이머 컴포넌트를 올립니다.

    > 타이머에 Enabled를 False로 주고, Interval을 2000으로 설정합니다.

    > 그런다음 아래와 같이 코딩을 합니다..

    >

    > procedure TForm1.Timer1Timer(Sender: TObject);

    > begin

    > SetActiveWindow(Self.Handle); //이부분이 중요하겠죠?

    > Timer1.Enabled := False;

    > end;

    > procedure TForm1.Button1Click(Sender: TObject);

    > begin

    > Timer1.Enabled := True;

    > end;

    >

    > 실행시킨 뒤 버튼을 누른 후 2초후에 화면이 활성화되는 것이죠...

    > 물론 버튼을 누른후 2초내에 다른 폼을 활성화 시켜놔야 합니다...

    > 그래야 테스트가 될테니까요 ^^;

    > 여기서 제가 말하는 활성화라 함은 폼의 캡션(타이틀)바가 파란색으로

    > 나타나며 폼에있는 버튼을 키보드로 클릭할 수 있어야합니다.

    >

    > 예전에 수많은 델파이전문가(?)들이 수많은 종류의 API를 동원해서

    > 테스트했지만 헛수고였습니다...

    >

    > 암튼, 염치없는 부탁이지만... 말로만 답변하시지 마시고,

    > 테스트를 꼭 해보시고 답변을 해 주셨으면 좋겠습니다.

    > 굳이 테스트 할 시간이 없으면 제가 하겠으니 많은 답변 부탁드립니다...





  • Profile
    OHJANG 1999.07.10 04:30
    제가 글에서 분명히 아래와 같이 밝혔거늘... 쩝...



    > 예전에 수많은 델파이전문가(?)들이 수많은 종류의 API를 동원해서

    > 테스트했지만 헛수고였습니다...



    우선 귀하의 빠른 답변에 감사드립니다...

    그러나 그 함수는 예전에 이미 테스트를 한 함수이며, 제가 말씀드린데로 동작하지 않습니다.



    실행해 보시면 아시겠지만 실행결과는 테스크바가 빰빡거리며, 화면의 버튼이 포커스를 가질뿐 화면 맨 앞으로도, 활성화도 되지 않습니다.



    이정욱 께서 말씀하시기를...

    > SetForegroundWindow 함수를 사용해 보세요.

    >

    > OHJANG 께서 말씀하시기를...

    > > 질문은 다름아닌 SetActiveWindow에 대한 질문입니다.

    > > 델파이1에서

    > > SetActiveWindow(Self.Handle);

    > > 하게되면 내폼이 뒤에 가려져있어도 화면 맨 위로 올라와서 활성화 됩니다.

    > > 그런데, 32Bit(델파이2,3,4:모두 테스트해봄)에서는 올라오지 않습니다...

    > > 그져 버튼에 포커스가 가는 정도...

    > >

    > > 제가 원하는 기능은 다음과 같습니다.

    > >

    > > 그런데, 32Bit(델파이2,3,4:모두 테스트해봄)에서는 올라오지 않습니다...

    > > 그져 버튼에 포커스가 가는 정도...

    > > 제가 원하는 기능은 다음과 같습니다.

    > > 타이머 이벤트에서 이벤트가 걸리면 자신의 폼이 화면 맨위로 올라와 키보드로 버튼을

    > > 누를 수 있게 폼이 활성화되는 것입니다.

    > > 제가 테스트하는 예는 다음과 같습니다.

    > >

    > > 먼저 화면에 버튼과 타이머 컴포넌트를 올립니다.

    > > 타이머에 Enabled를 False로 주고, Interval을 2000으로 설정합니다.

    > > 그런다음 아래와 같이 코딩을 합니다..

    > >

    > > procedure TForm1.Timer1Timer(Sender: TObject);

    > > begin

    > > SetActiveWindow(Self.Handle); //이부분이 중요하겠죠?

    > > Timer1.Enabled := False;

    > > end;

    > > procedure TForm1.Button1Click(Sender: TObject);

    > > begin

    > > Timer1.Enabled := True;

    > > end;

    > >

    > > 실행시킨 뒤 버튼을 누른 후 2초후에 화면이 활성화되는 것이죠...

    > > 물론 버튼을 누른후 2초내에 다른 폼을 활성화 시켜놔야 합니다...

    > > 그래야 테스트가 될테니까요 ^^;

    > > 여기서 제가 말하는 활성화라 함은 폼의 캡션(타이틀)바가 파란색으로

    > > 나타나며 폼에있는 버튼을 키보드로 클릭할 수 있어야합니다.

    > >

    > > 예전에 수많은 델파이전문가(?)들이 수많은 종류의 API를 동원해서

    > > 테스트했지만 헛수고였습니다...

    > >

    > > 암튼, 염치없는 부탁이지만... 말로만 답변하시지 마시고,

    > > 테스트를 꼭 해보시고 답변을 해 주셨으면 좋겠습니다.

    > > 굳이 테스트 할 시간이 없으면 제가 하겠으니 많은 답변 부탁드립니다...

    >

    >





  • Profile
    구창민 1999.07.10 11:53
    OHJANG 께서 말씀하시기를...

    > 제가 글에서 분명히 아래와 같이 밝혔거늘... 쩝...

    > 예전에 수많은 델파이전문가(?)들이 수많은 종류의 API를 동원해서

    > 테스트했지만 헛수고였습니다...



    OHJANG 님 안녕하세요?

    말씀하신 수많은 전문가들의 수많은 테스트 내용들은 어떤것들이었는지

    혹시 올려주실순 없는지요?

    수많은 전문가 님들이 테스트 했다는 내용을 참조하고 싶습니다.

    저는 지식이 짧아 아래와 같이 무식하게 프로그램 해 보니까

    기냐~~아앙 되네요..

    아래에 소스 올립니다.

    보시면 금방 이해되실 거구요.. 원하시는 대로 동작할겁니다.

    그럼..



    unit Unit1;



    interface



    uses

    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

    StdCtrls, ExtCtrls;



    type

    TForm1 = class(TForm)

    Button1: TButton;

    Timer1: TTimer;

    procedure Button1Click(Sender: TObject);

    procedure Timer1Timer(Sender: TObject);

    private

    { Private declarations }

    public

    { Public declarations }

    end;



    var

    Form1: TForm1;



    implementation



    {$R *.DFM}



    procedure TForm1.Button1Click(Sender: TObject);

    begin

    WinExec('notepad', SW_SHOWNORMAL);

    Timer1.Enabled := True;

    end;



    procedure TForm1.Timer1Timer(Sender: TObject);

    var Pt, OldPt : TPoint;

    begin

    GetCursorPos(OldPt);

    SetWindowPos(Handle, HWND_TOPMOST,

    Left, Top, Width, Height,

    SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);

    Application.ProcessMessages;

    Pt.x := (Button1.Left-10);

    Pt.y := (Button1.Top-10);

    Pt := ClientToScreen(Pt);

    Pt.x := Round(Pt.x * (65535 / Screen.Width));

    Pt.y := Round(Pt.y * (65535 / Screen.Height));

    Mouse_Event(MOUSEEVENTF_ABSOLUTE or

    MOUSEEVENTF_MOVE,

    Pt.x,

    Pt.y,

    0,

    0);

    Mouse_Event(MOUSEEVENTF_ABSOLUTE or

    MOUSEEVENTF_LEFTDOWN,

    Pt.x,

    Pt.y,

    0,

    0);;

    Mouse_Event(MOUSEEVENTF_ABSOLUTE or

    MOUSEEVENTF_LEFTUP,

    Pt.x,

    Pt.y,

    0,

    0);

    SetWindowPos(Form1.Handle, HWND_NOTOPMOST,

    Left, Top, Width, Height,

    0);

    SetCursorPos(OldPt.x, OldPt.y);

    Timer1.Enabled:=False;

    end;



    end.