2009-03-31 14 views
19

Ich habe Mühe, eine zweite Form über der Hauptform zu zeigen, ohne Fokus zu verlieren.Delphi: Zeige Fenster ohne Aktivierung

Ich habe versucht ShowWindow(second.handle, SW_SHOWNOACTIVATE), aber die mainform verliert den Fokus. Wenn ich Visible := false auf dem zweiten Fenster setzen, wird der Anruf an ShowWindow nicht das zweite Formular aktivieren, aber die Fenster ist leer, wenn gezeigt ...

Hat jemand dafür ein gutes Rezept haben?

UPDATE: Was ich versuche zu tun, zeigt ein Benachrichtigungsfenster bei einem bestimmten Ereignis. Es ist wichtig, dass die Hauptform zu keiner Zeit den Fokus verliert.

+0

Hum ... Eine meiner Bearbeitungen ist weg ... Ich denke, SO hatte einige Probleme früher ...? – Vegar

Antwort

24

Es muss etwas mit Ihrem Code nicht stimmen.

ich diesen Code getestet, es funktioniert:

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

Vorsicht Visible, nicht Show nutzen zu können! Andernfalls überschreibt es die SW_SHOWNOACTIVATE.

+0

Es tut mir leid, aber es ist immer noch aktiviert :-( – Vegar

+0

Ich änderte meine Antwort und testete es :) –

+0

Wow, es ist erstaunlich :-) Die Tricks scheint zu sein, sichtbar zur Entwurfszeit falsch zu sein, und setzen Sie es auf wahr nach der Aufruf von showwindow(). Vielen Dank! – Vegar

2

Sie können das Fenster anzeigen (nicht modal) und den Fokus auf das Hauptfenster zurücksetzen. Dies schließt nicht die andere Form über zeigen

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

Getestet auf 2006

. Aber es ist sehr gegensätzlich, ein Fenster oben zu haben, das nicht den Fokus hat.

+0

Aber das würde ausreichen, Ereignisse und Datenspeicher usw. auszulösen, und ich will das nicht ... – Vegar

+0

dies funktioniert nicht unter verschiedenen Umständen, zum Beispiel, wenn Sie arbeiten (sagen Sie, Text zu bearbeiten) in einer untergeordneten Form des Hauptformulars und das Hauptformular muss eine Benachrichtigung anzeigen. Sie verlieren alle Zeichen, die Sie gerade eingeben, und setzen den Fokus zurück auf das Hauptformular. Der Fokus wird nicht auf das ursprüngliche untergeordnete Formular zurückgesetzt, das Sie bearbeitet haben. Dieses Problem verfolgte mich lange, bis ich DRs einfach fand (Ich hätte daran denken müssen). – DeveloperChris

1

ich verwendet habe dies in der Vergangenheit

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

Ich habe dies mit obwohl neueren Versionen von Delphi nicht getestet ...

1

Wenn möglich, sollten Sie als eine Art Werkzeugspitze mit Fenster zum Anzeigen der Benachrichtigungsinformationen. Ein Tooltip wird den Fokus nicht aus Ihrem Hauptfenster stehlen, wenn er angezeigt wird oder wenn ein Benutzer darauf klickt. Ein reguläres Formular hat standardmäßig einen Rahmen und wenn der Benutzer auf diesen Rahmen klickt, wird das Hauptformular den Fokus verlieren.

Hier ist ein paar grundlegende Code, um dies zu tun. Die Spitze verschwindet, wenn frei gerufen wird; Allerdings wäre es besser, wenn Sie einen Timer als den Schlaf einstellen würden.

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

Vielleicht ist dies der einfachste Weg zu gehen, aber ich würde das Hinweisfenster anpassen müssen, um mehr als nur einfachen Text zu zeigen ... – Vegar

1

Sie sind hier:

// 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

Dies macht es tatsächlich sichtbar, ohne die Form sichtbar zu setzen? –

1

Ich tat dies in der Vergangenheit, aber ich habe nicht den Code, weil es propietary in letzten Job (sorry) war.

Wenn ich mich gut erinnern, was ich tat, war:

  1. Von Client-Klasse A eine Prozedur aufrufe (oder Funktion), die nicht zu einer Klasse nicht gehört (eine traditionelle Pascal-Methode).
  2. Rufen Sie von dieser Methode eine Methode in einer Klasse B auf, die nicht von TForm erbt
  3. Erstellen Sie aus der Methode in B eine Instanz von Popup-Formular P, aber ohne Eltern oder Besitzer; und rufe eine Methode in der Instanz auf.
  4. Von der in der Instanz aufgerufenen Methode, selbst anzeigen.

Der Code (aus Schritt 3) könnte etwa so lauten:

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

Es tut mir leid, wenn dies nicht funktioniert, ich weiß nicht Delphi haben.

0

Daniels Code funktioniert bis ...

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

Bis Ihr zweites Formular dynamisch erstellt wird. Dann befindet sich Ihr zweites Formular an der Position 0,0 mit Standardbreite und -höhe.

Für einen kurzen Moment, wenn ShowWindow ausgeführt wird, werden Sie das zweite Formular auf dem Bildschirm sehen, verschwinden, wenn die nächste Zeile ausgeführt wird.

Ich verwende den Code für ein transparentes Overlay-Formular, das dyamisch erstellt wird. Der folgende Code ist eine Kombination der gegebenen Antworten und platziert das zweite Formular ohne Aktivierung über das übergeordnete Formular.

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