2009-03-31 5 views
19

포커스를 잃지 않고 메인 폼 위에 두 번째 폼을 표시하기 위해 고심합니다.델파이 : 활성화하지 않고 윈도우 보이기

나는 ShowWindow(second.handle, SW_SHOWNOACTIVATE)을 시도했지만 메인 폼은 초점을 잃습니다.

사람이에 대한 좋은 조리법이 있는가 ... 내가 두 번째 창에서 Visible := false을 설정 한 경우, ShowWindow에 대한 호출이 두 번째 양식을 활성화하지 않지만, 표시 할 때 창문이 비어?

업데이트 : 주어진 일에 알림 창을 표시하려고합니다. 기본 양식이 언제든지 초점을 잃지 않는 것이 중요합니다.

+0

흠 ... 내 편집 중 하나가 사라졌습니다. 이전에 몇 가지 문제가있었습니다 ...? – Vegar

답변

24

코드에 문제가있을 수 있습니다.

가이 코드를 테스트, 그것은 작동 :

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    ShowWindow(Form2.Handle, SW_SHOWNOACTIVATE); 
    Form2.Visible := True; 
end; 

Visible하지 Show 사용에주의! 그렇지 않으면 SW_SHOWNOACTIVATE이 무시됩니다.

+0

미안하지만 여전히 활성화되어 있습니다 :-( – Vegar

+0

내 대답을 수정하고 테스트했습니다 :) –

+0

와우, 정말 대단합니다 :-) 트릭은 디자인 타임에 표시가 틀리게 보이도록 설정 한 것 같습니다. showwindow()에 대한 호출. 감사! – Vegar

2

창을 표시하고 (모달 아님) 주 창으로 초점을 재설정 할 수 있습니다.

procedure TMainForm.ButtonClick(Sender: TObject); 
begin 
    OtherForm.Show; 
    SetFocus; 
end; 

은 상단에있는 다른 형태를 표시하지 않습니다 2006 년

이에서 테스트. 그러나 초점이 맞지 않는 창문을 가지고있는 것은 직관적이지 못합니다.

+0

하지만 이것은 이벤트와 데이터 저장 등을 트리거하기에 충분할 것이고 나는 그것을 원하지 않을 것입니다 ... – Vegar

+0

메인 폼의 하위 폼에서 작업하는 경우 (예 : 편집 텍스트) 다양한 상황에서이 작업이 이루어지지 않습니다. 주 양식은 알림을 팝업해야합니다. 당신이 타이핑하는 과정에서 문자를 잃어 버리고 포커스를 메인 양식으로 되돌려 놓았을 때 편집중인 원래의 자식 형태로 되돌아 가지 않습니다. DR의 단순한 것을 발견 할 때까지이 문제는 저를 괴롭혔습니다. 나는 그것을 고쳐야했다) 고침. – DeveloperChris

1

가능하다면 ... 그래도 난 델파이의 최신 버전이 테스트하지했습니다 과거

SetWindowPos(WindowHandle, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE or SWP_NOSIZE or SWP_NOMOVE); 

이을해야 사용했던 공구 팁의 일종을 사용하여 고려 창에서 알림 정보를 표시합니다. 도구 설명이 표시되거나 사용자가 클릭 할 때 기본 창에서 포커스를 훔치지 않습니다. 일반 양식은 기본적으로 테두리를 가지며 사용자가 테두리를 클릭하면 기본 양식의 초점이 느슨해집니다.

여기에 몇 가지 기본 코드가 있습니다. 자유가 불릴 때 끝은 사라진다; 그러나 수면을 사용하는 것보다 타이머를 설정하는 것이 좋습니다. 여기

with THintWindow.Create(nil) do 
    try 
    ActivateHint(MyRect, 'My Notification'); 
    Sleep(DisplayTime); 
    finally 
    Free; 
    end 
+0

아마도 이것이 가장 쉬운 방법 일 것입니다 만, hintwindow를 단순한 텍스트 이상을 표시하도록 사용자 정의해야합니다. – Vegar

1

당신은 다음과 같습니다

// you have set your 2nd form as non resizable, without border nor title etc... 
    Form2.Enabled := False; // prevent the 2nd form to grab focus even when clicked 
    SetWindowPos(Form2.Handle, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW or SWP_NOACTIVATE or SWP_NOSIZE or SWP_NOMOVE); 
    // be sure to hide it automatically when done as it is disabled... 
+0

그러면 양식이 보이지 않고 실제로 표시됩니다. –

1

나는 과거에 이런 짓을하지만 (죄송합니다) 마지막 작업의 propietary 때문에 나는 코드가 없습니다.

내가 잘 기억한다면

는, 내가 한 일은이었다 : 클라이언트 클래스 A에서

  1. 프로 시저 (또는 함수)를 호출하는 클래스 (전통적인 파스칼 방법)에 속하는하지 않습니다.
  2. 그 메소드에서 TForm을 상속하지 않는 클래스 B에서 어떤 메소드를 호출하십시오.
  3. B의 메소드에서 부모 또는 소유자가없는 팝업 양식 P의 인스턴스를 작성하십시오. 인스턴스의 메소드를 호출합니다.
  4. 인스턴스에서 호출 된 메서드에서 show 자체. (3 단계)

코드는 다음과 같이 갈 수 :

var p: TPopupForm; 
begin 
    p := TPopupForm.Create(nil); 
    p.ShowWindow; 
    p.Release; 
end; 

이 작동하지 않는 경우, 미안 해요, 내가 너무 델파이이 없습니다. 두 번째 형태는 동적으로을 만들어 까지

ShowWindow(Form2.Handle, SW_SHOWNOACTIVATE); 
Form2.Visible := True; 

...까지

0

다니엘스 코드가 작동합니다. 그런 다음 두 번째 양식은 기본 너비와 높이로 0,0 위치에 있습니다.

잠시 동안 ShowWindow이 실행되면 화면에 두 번째 양식이 표시되며 다음 줄이 실행될 때 사라집니다.

나는 역동적으로 만들어진 투명 오버레이 양식에 대한 코드를 사용하고 있습니다. 다음 코드는 주어진 답을 조합 한 것으로, 부모 양식을 통해 활성화하지 않고 두 번째 양식을 배치합니다.

SetWindowPos(Form2.Handle, HWND_TOP, Left, Top, Width, Height, SWP_NOACTIVATE); 
Form2.Visible := True;