Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi API-Funktion SetWindowPos (https://www.delphipraxis.net/100247-api-funktion-setwindowpos.html)

juezi 25. Sep 2007 06:21


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

pstruh 25. Sep 2007 07:26

Re: API-Funktion SetWindowPos
 
Moin, Moin,

versuche es doch mal mit
Delphi-Quellcode:
SetForegroundWindow(Self.Handle);

juezi 25. Sep 2007 07:41

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

s-off 25. Sep 2007 07:55

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;

juezi 25. Sep 2007 07:58

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

s-off 25. Sep 2007 08:05

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:
PostMessage(Self.Handle, WM_SYSCOMMAND, SC_RESTORE, 0);
SetForegroundWindow(Self.Handle);
Edit1.SetFocus;
Edit 2:
Um nochmal auf eine Deiner letzteren Fragen zurück zu kommen; mit
Delphi-Quellcode:
PostMessage(Self.Handle, WM_SYSCOMMAND, SC_MINIMIZE, 0);
könntest Du Deine Form natürlich vorher minimieren.

juezi 25. Sep 2007 13:00

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

s-off 25. Sep 2007 13:19

Re: API-Funktion SetWindowPos
 
Zitat:

Zitat von juezi
kann es daran liegen das ich meine Abfrage zum Einblenden und Ausblenden in einem Timer laufen habe?

Bzgl. der Kernaussage: Nein. Meine Tests basierten ebefalls auf einem Timer.

Deinen Code habe ich mir nicht durchgelesen; formatier ihn bitte.

juezi 25. Sep 2007 15:06

Re: API-Funktion SetWindowPos
 
Hallo,

ich habe meinen Code einfach aus Delphi hierein kopiert,
kann ich den Code hier formatieren lassen?
Danke

Apollonius 25. Sep 2007 15:10

Re: API-Funktion SetWindowPos
 
Die Delphi-Tags im Schreibfenster drumherumlegen.
Delphi-Quellcode:
 Code

juezi 25. Sep 2007 15:19

Re: API-Funktion SetWindowPos
 
Hallo,

hier nochmal der formatierte Code

Delphi-Quellcode:
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;
Danke

s-off 25. Sep 2007 15:24

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:
if (eStatus = 9) and not Fl_SetSerial then
begin
[...]
end
else if (eStatus <> 9) then begin
[...]
end;
Edit: Bevor jemand meckert:
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.

juezi 26. Sep 2007 05:38

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

juezi 26. Sep 2007 10:13

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

s-off 26. Sep 2007 10:23

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.?

juezi 27. Sep 2007 07:07

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

RWarnecke 27. Sep 2007 07:33

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.

s-off 27. Sep 2007 07:43

Re: API-Funktion SetWindowPos
 
Zitat:

Zitat von juezi
Meine Aufgabe ist es den Bediener der Presse aufmerksam zu machen einen Barcode einzulesen[...]

Stell Dich doch einfach daneben und hau ihm auf die Finger, wenn er dran ist :mrgreen:
Sorry, aber das konnte ich mir nicht verkneifen :zwinker:

Zitat:

Zitat von juezi
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.

Tastatureingaben werden an die aktive Anwendung geschickt.
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.

juezi 27. Sep 2007 07:45

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

juezi 27. Sep 2007 07:55

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

s-off 27. Sep 2007 08:08

Re: API-Funktion SetWindowPos
 
Zitat:

Zitat von juezi
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

Tschuldigung, meinte auch Press, nicht Down... Also bekommt Deine Anwendung keine Infos.
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.

juezi 27. Sep 2007 08:25

Re: API-Funktion SetWindowPos
 
Hallo,

wo sollte ich Deiner Meinung nach den (WM_KILLFOCUS) abfragen, durch den Timer der läuft?

Danke

s-off 27. Sep 2007 09:08

Re: API-Funktion SetWindowPos
 
Zitat:

Zitat von juezi
Hallo,

wo sollte ich Deiner Meinung nach den (WM_KILLFOCUS) abfragen, durch den Timer der läuft?

Danke

Nee,

Du deklarierst Dir eine Prozedur im Private-Abschnitt Deiner Klasse:
Delphi-Quellcode:
Type
   TForm1 = Class(TForm)
   private
      Procedure KillFocus(Var Message: TMessage); message WM_KILLFOCUS;
   End;
Mit STRG+SHIFT+C erzeugst Du dann den Methodenrumpf und schaust mal, was Du da drin anstellen kannst.

juezi 27. Sep 2007 09:29

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

s-off 27. Sep 2007 09:52

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.

juezi 27. Sep 2007 11:10

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:
procedure TForm1.KillFocus(var Message: TMessage);
begin
  Label2.Caption := 'Fokus gekilled';
end;
wenn ich aber auf andere Anwendungen klicke läuft meine Anwendung nicht in diese procedure rein,
muss ich noch irgendwelche uses angeben oder mache ich grundsätzlich etwas falsch.

Danke

s-off 27. Sep 2007 12:23

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.

juezi 27. Sep 2007 14:02

Re: API-Funktion SetWindowPos
 
Hallo,
muss ich noch irgendeine Abfrage in einem Timer machen oder reicht wirklich nur das Einfügen der procedure.

Danke

s-off 27. Sep 2007 14:06

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

juezi 22. Okt 2007 13:40

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