API-Funktion SetWindowPos
Hallo Zusammen
ich habe folgendes Problem, wenn ich //Formular in den Vordergrund bringen SetWindowPos(handle,HWND_TOPMOST,Left,Top,Width,He ight,SWP_SHOWWINDOW); form1.Activate; edit1.SetFocus; ausführe, wird mir das Fenster in den Vordergrund geholt ist aber nicht aktiv, ich muss es dann anklicken um es zu aktivieren. Vielen Dank für Eure Hilfe |
Re: API-Funktion SetWindowPos
Moin, Moin,
versuche es doch mal mit
Delphi-Quellcode:
SetForegroundWindow(Self.Handle);
|
Re: API-Funktion SetWindowPos
Hallo,
vielen Dank für die schnelle Antwort, leider hab ich das gleiche Problem. (Vielleicht eine kurze Erklärung zu meiner Anwendung, ich muss ein Formular anzeigen um einen Barcode der über die Tastatureingabe eingelesen wird an eine andere Fremde Applikation via dll übergeben, dafür habe ich gedacht das ich das Formular einblende, der Barcode wird dann über ein edit Feld eingelesen.) Danke |
Re: API-Funktion SetWindowPos
Hallo,
bei mir funktioniert es so, wie von pstruh beschrieben. Der Focus ist auf dem Edit und ich kann sofort losschreiben, ohne irgendetwas anklicken zu müssen (allerdings nur, wenn meine Form vorher nur im Hintergrund war - sollte sie minimiert sein, funktioniert es nicht).
Delphi-Quellcode:
SetForegroundWindow(Self.Handle);
Edit1.SetFocus; |
Re: API-Funktion SetWindowPos
Hallo,
nochmals danke, Du hast gesagt Du legst Deine Anwendung nur in den Hintergrund, welchen Befehlt verwendest Du hierfür, ich verwende zum Ausblenden den Befehl SetWindowPos(handle,HWND_BOTTOM,Left,Top,Width,Hei ght,SWP_SHOWWINDOW); Danke |
Re: API-Funktion SetWindowPos
Keinen Befehl; habe es manuell in den Hintergrund gelegt, indem ich ein anderes Fenster nach vorn geholt habe.
Edit: Wenn Du es so machst, dann funktioniert es auch, sollte Deine Form, oder die ganze Application minimiert sein:
Delphi-Quellcode:
Edit 2:
PostMessage(Self.Handle, WM_SYSCOMMAND, SC_RESTORE, 0);
SetForegroundWindow(Self.Handle); Edit1.SetFocus; Um nochmal auf eine Deiner letzteren Fragen zurück zu kommen; mit
Delphi-Quellcode:
könntest Du Deine Form natürlich vorher minimieren.
PostMessage(Self.Handle, WM_SYSCOMMAND, SC_MINIMIZE, 0);
|
Re: API-Funktion SetWindowPos
Hallo,
vielen Dank, leider habe ich immer noch das Problem mit dem anklicken, kann es daran liegen das ich meine Abfrage zum Einblenden und Ausblenden in einem Timer laufen habe? Hier der Quellcode meines Timers procedure TForm1.Timer1Timer(Sender: TObject); begin //Dll-Funktion um Maschinenstatus abzufragen MepRemote_ReadMachineState(eStatus); //Wenn der Status 9 ist muss das Formular eingeblendet werden um den Barcode abzufragen if (eStatus = 9) and not Fl_SetSerial then begin //Barcode-Formular in den Vordergrund bringen PostMessage(Self.Handle, WM_SYSCOMMAND, SC_RESTORE, 0); SetForegroundWindow(Self.Handle); Edit1.SetFocus end; //Wenn der Status ungleich 9 ist muss das Formular wieder in den Hintergrund gehen if (eStatus <> 9) then begin Fl_SetSerial := false; edit1.Text := ''; //Barcode-Formular in den Hintergrund bringen SetWindowPos(handle,HWND_BOTTOM,Left,Top,Width,Hei ght,SWP_SHOWWINDOW); end; end; Danke |
Re: API-Funktion SetWindowPos
Zitat:
Deinen Code habe ich mir nicht durchgelesen; formatier ihn bitte. |
Re: API-Funktion SetWindowPos
Hallo,
ich habe meinen Code einfach aus Delphi hierein kopiert, kann ich den Code hier formatieren lassen? Danke |
Re: API-Funktion SetWindowPos
Die Delphi-Tags im Schreibfenster drumherumlegen.
Delphi-Quellcode:
Code
|
Re: API-Funktion SetWindowPos
Hallo,
hier nochmal der formatierte Code
Delphi-Quellcode:
Danke
procedure TForm1.Timer1Timer(Sender: TObject);
begin //Dll-Funktion um Maschinenstatus abzufragen MepRemote_ReadMachineState(eStatus); //Wenn der Status 9 ist muss das Formular eingeblendet werden um den Barcode abzufragen if (eStatus = 9) and not Fl_SetSerial then begin //Barcode-Formular in den Vordergrund bringen PostMessage(Self.Handle, WM_SYSCOMMAND, SC_RESTORE, 0); SetForegroundWindow(Self.Handle); Edit1.SetFocus end; //Wenn der Status ungleich 9 ist muss das Formular wieder in den Hintergrund gehen if (eStatus <> 9) then begin Fl_SetSerial := false; edit1.Text := ''; //Barcode-Formular in den Hintergrund bringen SetWindowPos(handle,HWND_BOTTOM,Left,Top,Width,Height,SWP_SHOWWINDOW); end; end; |
Re: API-Funktion SetWindowPos
Und Dein 'Barcode-Formular' ist Form1, ja?
Ansonsten würde 'Self' nicht passen. Desweiteren würde ich bedingt auf den Status reagieren, also das Ganze mit 'Else' abwickeln:
Delphi-Quellcode:
Edit: Bevor jemand meckert:
if (eStatus = 9) and not Fl_SetSerial then
begin [...] end else if (eStatus <> 9) then begin [...] end; das hat zwar nichts mit Deinem aktuellen Problem zu tun, verhindert aber, dass gar nicht erst auf 'Status <> 9' geprüft wird, sollte '(eStatus = 9) and not Fl_SetSerial' bereits zutreffen. In diesem Beispiel Kinkerlitzchen, aber da können ggf. auch dickere Dinger dahinter stecken, die man sich so sparen und die Performance optimal halten kann. |
Re: API-Funktion SetWindowPos
Hallo,
danke habe das else .. if eingebaut, gibt es die Möglichkeit ein Formular speziell mit einem Befehl zu aktivieren, ich vermute das die andere Anwendung mit der ich über dll kommuniziere sich einmal den Fokus zurückholt. Vielen Dank |
Re: API-Funktion SetWindowPos
Hallo,
ich habe noch eine andere Frage, gibt es die Möglichkeit eine Tastatureingabe abzufragen wenn mein Formular im Vordergrund ist aber nicht aktiv ist, wäre eine Lösung für mein Problem, denn ich benötige eigentlich nur den String vom Barcodescanner, ich dachte der Weg über das edit-Feld wäre gut geht aber bei mir irgendwie nicht. Vielleicht gibt es ja die Möglichkeit das man grundsätzlich die Tastatureingabe abfragen kann. Vielen Dank |
Re: API-Funktion SetWindowPos
Sicherlich kann man da etwas machen - aber ich weiss leider noch nicht, was Du erreichen möchtest, und wie das Ganze von statten gehen soll.
Wie viele Anwendungen hast Du, was machen die, was meinst Du mit Tastatureingabe etc.? |
Re: API-Funktion SetWindowPos
Hallo,
es laufen auf dem PC folgende Anwendungen, 1. Anwendung ist eine Automatisierungsanwendung die über eine PCI-Karte eine Presse steuert 2. es läuft ein RPC-Server der für die Kommunikation der 1. Anwendung über eine dll zuständig ist 3. eine Anwendung läuft zur Kommunikation einer SPS mit der Automatisierungssoftware der Presse 4. Meine Anwendung soll auf dem PC laufen um einen Barcode einlesen zu können, dieser eingelesene Barcode kann dann auch über eine dll-Funktion an den RPC-Server übergeben werden, anhand dieses Barecodes speichert Automatisierungssoftware der Presse Daten mit ab, Dateiname = Barcodenummer. Meine Aufgabe ist es den Bediener der Presse aufmerksam zu machen einen Barcode einzulesen, hierfür dachte ich das ich ein Formular einblende um den Barcode über ein edit-Feld einzulesen, da der Barcodescanner über die Tastatur eingeschleift ist. Jetzt habe ich aber das Problem das nach dem Einblenden meines Formulars die Automatisierungssoftware den Fokus zurückholt, mein Formular ist sichtbar aber ist noch nicht aktiv, dazu muss ich das Formular erst anklicken. Ich habe nur die Möglichkeit die 4. Anwendung zu bearbeiten, wenn es die Möglichkeit gibt die Tastatureingabe abzufragen ohne das mein Formular aktiv ist, wäre mein Problem gelöst. Mein Formular könnte ich sichtbar machen wenn auch nicht aktiv, der Bediener würde den Barcode scannen und ich würde anhand der Tastatureingabe meinen Barcode an die Automatisierungssoftware senden. Ich bin für jeden Tip dankbar Vielen Dank |
Re: API-Funktion SetWindowPos
Hallo,
muss der Barcode der eingscannt wird vorher überprüft werden ? Wenn nein, würde ich das ganze über ein Programm laufen lassen, was im Hintergrund läuft. Bei vielen Barcode-Scannern, kann man ja noch irgendwelche Steurungszeichen mitsenden. Das Hintergrundprogramm überprüft die Tastatureingaben, wenn nun das Steuerungszeichen eingegeben wird, werden die Daten an Deine Anwendung übergeben. |
Re: API-Funktion SetWindowPos
Zitat:
Sorry, aber das konnte ich mir nicht verkneifen :zwinker: Zitat:
Beschäftige Dich doch mal mit Hooks. Mit einem globalen Keyboardhook kannst Du die Tastatureingabe abfangen/-fragen, unabhängig davon, welche Anwendung gerade aktiv ist. Vorher könntest Du allerdings noch mit Form.OnKeyDown prüfen, ob Deine Form nicht vielleicht doch Input bekommt, der nur nicht da landet, wo er hin soll. |
Re: API-Funktion SetWindowPos
Hallo
zuerst vielen Dank für Deine Hilfe, der Barcode muss noch überprüft werden, es müssen die ersten 8 Zeichen einer Nummer (96619889) entsprechen, aber die Überprüfung kann auch im Hintergrund gemacht werden, falls der Barcode nicht die Nummer hat muss nur eine Meldung ausgegeben werden (Messagebox). Könnte man die Eingaben der Tastatur nicht gleichzeitig in meinem Formular laufen lassen, ohne das mein Formular aktiv ist, ich bekomme anhand des eStatus 9 über die dll-Funktion mitgeteilt das die Presse einen Barcode erwartet, jetzt könnte ich mein Formular einblenden (wenn es aktiv wäre könnte ich gleich weiter machen), ich würde abwarten was für Zeichen vom Scanner kommen und dann über meine Anwendung den Barcode über eine weitere dll-Funktion wieder an die Presse geben. Hast Du schon eine Idee? Vielen Dank |
Re: API-Funktion SetWindowPos
Hallo,
ich habe folgende Ereignisse probiert OnKeyDown und OnKeyPress, hier habe ich breakpoints gesetzt, wenn mein Formular aktiv ist komme ich in OnKeyPress bei einer Eingabe rein, wenn mein Formular nicht aktiv ist komme ich nicht zum breakpoint, OnKeyDown reagiert überhaupt nicht, (aktiv oder nicht aktiv) Danke |
Re: API-Funktion SetWindowPos
Zitat:
Dann wirst Du wohl entweder das probieren müssen, was Rolf Warnecke beschrieben hat, oder Dich wirklich mit Tastaturhooks beschäftigen müssen. Vielleicht ist es auch möglich, irgendwie auf die Windowsmessage (WM_KILLFOCUS) zu reagieren, sobald Dein Fenster den Fokus verlieren soll. Kannst ja mal rumtesten. |
Re: API-Funktion SetWindowPos
Hallo,
wo sollte ich Deiner Meinung nach den (WM_KILLFOCUS) abfragen, durch den Timer der läuft? Danke |
Re: API-Funktion SetWindowPos
Zitat:
Du deklarierst Dir eine Prozedur im Private-Abschnitt Deiner Klasse:
Delphi-Quellcode:
Mit STRG+SHIFT+C erzeugst Du dann den Methodenrumpf und schaust mal, was Du da drin anstellen kannst.
Type
TForm1 = Class(TForm) private Procedure KillFocus(Var Message: TMessage); message WM_KILLFOCUS; End; |
Re: API-Funktion SetWindowPos
Hallo,
danke, wird diese Methode nur ausgeführt wenn der Fokus von einer anderen Anwendung gekillt wird? Ich kann im Moment nicht so richtig folgen was Du meinst. Danke |
Re: API-Funktion SetWindowPos
Dein Fenster erhält die Message 'WM_KILLFOCUS', sobald es den Fokus verlieren soll, unabhängig davon, ob das von einer anderen Anwendung ausgeht, oder nicht.
|
Re: API-Funktion SetWindowPos
Hallo,
sorry für meine Unwissenheit, aber ich weiß nicht wo ich diese WM_KILLFOCUS bekommen soll ich habe es wie folgt probiert
Delphi-Quellcode:
wenn ich aber auf andere Anwendungen klicke läuft meine Anwendung nicht in diese procedure rein,
procedure TForm1.KillFocus(var Message: TMessage);
begin Label2.Caption := 'Fokus gekilled'; end; muss ich noch irgendwelche uses angeben oder mache ich grundsätzlich etwas falsch. Danke |
Re: API-Funktion SetWindowPos
Hmm, alles sehr mysteriös.
Bei mir springt er in die Prozedur, bevor meine Form den Fokus verliert; egal auf welche Art und Weise. |
Re: API-Funktion SetWindowPos
Hallo,
muss ich noch irgendeine Abfrage in einem Timer machen oder reicht wirklich nur das Einfügen der procedure. Danke |
Re: API-Funktion SetWindowPos
Nein, keine Abfrage im Timer.
Prozedur wie gezeigt deklarieren und implementieren. Dann den Rumpf mit Daten füllen. Was da rein kann, um Dein Problem musst Du selber testen. Evtl. kannst Du Durch Antwort auf die Nachricht verhindern. Probier's halt aus. Sobald Deinem Formular dann der Verlust des Fokus droht (WM_KILLFOCUS), wird die Prozedur angesprungen. Vielleicht gibt es noch eine Message, die das Formular erhält nachdem es den Fokus verloren hat. Da könntest Du dann wieder mit SetWindowPos agieren... |
Re: API-Funktion SetWindowPos
Hallo,
ich habe jetzt eine Lösung gefunden die vielleicht nicht die beste ist aber in meinem Fall kann ich meine Barcodeanwendung aktivieren, ich habe folgendes gemacht Ich setze meinen Cursor mit SetCursorPos(x,y) auf mein Formular und löse mit mouse_event einen Click aus, wie gesagt nicht die feine Art aber wirkungsvoll. Vielen Dank für Eure Hilfe |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:22 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz