Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Rechtsklick in minimierter Caption abfangen (https://www.delphipraxis.net/200788-rechtsklick-minimierter-caption-abfangen.html)

Amateurprofi 24. Mai 2019 17:43


Rechtsklick in minimierter Caption abfangen
 
Wenn ein Programm minimiert ist, wird beim Klicken in die minimierte Caption in der Taskleiste
1) Bei Linksklick das Programmfenster "geöffnet"
2) Bei Rechtsklick ein Menu geöffnet, in dem verschiedene Optionen angeboten werden.

Ich möchte, dass mein Programm einen Rechtsklick in die minimierte Caption abfängt und darauf reagiert.

Hintergrund:
Das Programm spielt den ganzen Tag Musikstücke ab.
Wenn ich einen Anruf erhalte will ich die Wiedergabe anhalten und wieder starten können, OHNE dafür das Programmfenster "offnen" zu müssen.

Ich habe bei den Schweizern folgendes gefunden, was aber nur funktioniert, wenn das Programmfenster geöffnet es.
Wenn es minimiert in der Tastleiste liegt, funktioniert das nicht.
" funktioniert das nicht" heißt, die Prozedur "TForm1.WMNCRBUTTONDOWN" wird nicht aufgerufen.

Weiß jemand eine Lösung für das Problem?

In der Deklaration der Form
Delphi-Quellcode:
private
   procedure WMNCRBUTTONDOWN(var msg: TMessage); message WM_NCRBUTTONDOWN;
end;
Im Implementation Abschnitt
Delphi-Quellcode:
Procedure TForm1.WMNCRBUTTONDOWN(var msg: TMessage);
begin
   if msg.wParam = HTCAPTION then Caption := 'Right Click!';
   // Message.Result := 0; {to ignore the message}
   inherited;
end;

DieDolly 24. Mai 2019 17:56

AW: Rechtsklick in minimiete Caption abfangen
 
Zitat:

Ich habe bei den Schweizern folgendes gefunden, was aber nur funktioniert, wenn das Programmfenster geöffnet es.
Dafür bieten sich doch perfekt Task-Buttons an oder wie die heißen. Diese Buttons im Taskicon die auch VLC hat.

Aviator 26. Mai 2019 15:11

AW: Rechtsklick in minimierter Caption abfangen
 
Seit XE6 oder XE7 gibt es die bereits angesprochenen TTaskBarButtons. Die sind genau dafür gedacht. Es gibt sogar eine Demo dafür im Demo Verzeichnis. Schau dir mal an was mit der TaskBar alles gemacht werden kann.

Hier noch ein etwas ausführlicherer Blogeintrag von Marco Cantu der das Thema behandelt. Ist aber im Prinzip nix anderes, als das er die Demo durchkaut.

EDIT: In deinem Profil steht XE2. Keine Ahnung ob das noch stimmt. Falls ja, dann müsstest du das entsprechende Interface von Microsoft manuell implementieren. Ist halt etwas mehr Aufwand, funktioniert aber genau so.

DieDolly 26. Mai 2019 15:18

AW: Rechtsklick in minimierter Caption abfangen
 
Zitat:

Zitat von Aviator (Beitrag 1433170)
EDIT: In deinem Profil steht XE2. Keine Ahnung ob das noch stimmt. Falls ja, dann müsstest du das entsprechende Interface von Microsoft manuell implementieren. Ist halt etwas mehr Aufwand, funktioniert aber genau so.

Oder einfach Windows7TaskbarComponents nehmen. Ich habe 10.3 und benutze trotzdem Windows7TaskbarComponents.
https://delphi.fsprolabs.com/

Aviator 26. Mai 2019 16:03

AW: Rechtsklick in minimierter Caption abfangen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Also wenn ich das als BuiltIn Funktion hätte, dann würde ich die auch benutzen. Zumal die von dir verlinkte Komponente offiziell nur bis XE2 unterstützt wird.

Anhang 51155

DieDolly 26. Mai 2019 16:10

AW: Rechtsklick in minimierter Caption abfangen
 
Funktioniert wie gesagt einwandfrei mit 10.3.

Amateurprofi 27. Mai 2019 02:10

AW: Rechtsklick in minimierter Caption abfangen
 
Zitat:

Zitat von DieDolly (Beitrag 1433173)
Funktioniert wie gesagt einwandfrei mit 10.3.

Danke für den Tipp.
Leider für mich nicht tauglich (XE 2).

DeddyH 27. Mai 2019 06:30

AW: Rechtsklick in minimierter Caption abfangen
 
Zitat:

Zitat von Aviator (Beitrag 1433172)
Zumal die von dir verlinkte Komponente offiziell nur bis XE2 unterstützt wird.

Zitat:

Zitat von Amateurprofi (Beitrag 1433179)
Leider für mich nicht tauglich (XE 2).

:roll:

DieDolly 27. Mai 2019 11:09

AW: Rechtsklick in minimierter Caption abfangen
 
Abgesehen davon läuft die Komponente bis 10.3 problemlos.

Amateurprofi 27. Mai 2021 11:17

AW: Rechtsklick in minimierter Caption abfangen
 
Falls jemand ähnliches vorhat:
Ich habe mein Problem jetzt so gelöst:

1) Ein kurzes Programm geschrieben.
2) Eine Verknüpfung auf den Desktop gelegt.
3) Dieser einen Shortcut zugewiesen (Alt-Ctrl- .) (war erstaunt, dass " . " als Shortcut funktioniert.)

Wenn ich jetzt Alt-Ctrl-. drücke, wird
A) wenn das Musik.Programm geöffnet ist, diesem eine Message geschickt, die von dem Musik-Programm entsprechend verarbeitet wird.
B) wenn das Musik.Programm nicht geöffnet ist, wird es mit ShellExecute geöffnet.
Das funktioniert prächtig und gefällt mir noch besser als meine ursprüngliche Idee mit Rechtsklick auf die minimierte Caption in der TaskBar.
Was mir nicht gefällt: Das Programm "blitzt" kurz auf; hab noch keine Lösung gefunden, das zu verhindern.
Vielleicht weiß ja jemand auch dafür eine Lösung.

Delphi-Quellcode:
program ToggleMusic;

{$APPTYPE CONSOLE}

{$R *.res}

uses
   WinApi.Windows, WinApi.ShellApi,
   System.SysUtils;

const MusicPath='E:\Daten\Delphi XE2\Music\Win32\Debug\Music.exe';
var Win:HWND; StartUpInfo:TStartUpInfo; Dsn:String;
begin
   StartupInfo.cb:=SizeOf(StartUpInfo);
   StartupInfo.dwFlags:=STARTF_USESHOWWINDOW;
   StartupInfo.wShowWindow:=SW_HIDE;
   Win:=FindWindow(Nil,'Music Player');
   if Win<>0 then begin
      PostMessage(Win,$7FFF,0,0);
   end else begin
      Dsn:=MusicPath;
      if FileExists(Dsn) then
         ShellExecute(0,'open',PWideChar(Dsn),nil,nil,SW_SHOWNORMAL);
   end;
end.

himitsu 27. Mai 2021 11:57

AW: Rechtsklick in minimierter Caption abfangen
 
Zitat:

Delphi-Quellcode:
PostMessage(Win,$7FFF,0,0);

$7FFF: Nein!

A) Man verwendet niemals nichtssagende Werte (MagicValue), vor allem nicht, wenn es entsprechende Konstanten gibt. (WM_USER+X)
B) Außerdem liegt dieser Wert auch noch im falschen Bereich. (MSDN-Library durchsuchenWM_APP+X)
C) Man sollte muß für sowas prozessübergreifendes MSDN-Library durchsuchenRegisterWindowMessage verwenden.

Amateurprofi 27. Mai 2021 23:34

AW: Rechtsklick in minimierter Caption abfangen
 
Zitat:

Zitat von himitsu (Beitrag 1490249)
Zitat:

Delphi-Quellcode:
PostMessage(Win,$7FFF,0,0);

$7FFF: Nein!

A) Man verwendet niemals nichtssagende Werte (MagicValue), vor allem nicht, wenn es entsprechende Konstanten gibt. (WM_USER+X)
B) Außerdem liegt dieser Wert auch noch im falschen Bereich. (MSDN-Library durchsuchenWM_APP+X)
C) Man sollte muß für sowas prozessübergreifendes MSDN-Library durchsuchenRegisterWindowMessage verwenden.

$7FFF: Doch!

Aus "About Messages and Message Queues" Kapitel "Application-Defined Messages"

Zitat:

Values in the range 0x0400 (the value of WM_USER) through 0x7FFF are available for message identifiers for private window classes.
Aber vielleicht hab ich das falsch verstanden.
Wie auch immer, so wie ich es gemacht habe funktioniert es.

Wo siehst du den Unterschied zwischen $7FFF und WM_USER+X wo bei letzterem das X auch ein willkürlich festgelegter Wert ist.

In dem Musik-Programm, das der Empfänger der Message ist, sind diverse Users-Messages definiert

Code:
   UM_GetInfo=WM_User;
   UM_SettingsChanged=UM_GetInfo+1;
   UM_OverWrite=UM_SettingsChanged+1;
   UM_RichEditVScroll=UM_OverWrite+1;
   UM_DurationCount=UM_RichEditVScroll+1;
   UM_DurationDone=UM_DurationCount+1;
   UM_RepaintListBoxes=UM_DurationDone+1;
   UM_SetInfo=UM_RepaintListBoxes+1;
   ...
   UM_ToggleMusic=$7FFF;
und, wie du sehen kannst, ist die letzte "UM_ToggleMusic=$7FFF".
Was für einen Sinn macht es, diese auch in meinem kleinen Progrämmchen mit einem Namen zu versehen?
Ich würde das einsehen wenn wie z.B. in der Vcl diese Konstante "Global" verfügbar wäre (Wobei das wahrscheinlich irgendwie machbar wäre).
Da das hier aber nicht der Fall ist, bringt es aus meiner Sicht keinen Vorteil, auch in dem sendenden Programm die Konstante "UM_ToggleMusic=$7FFF" zu definieren.

Trotzdem: Danke für den Hinweis.

himitsu 27. Mai 2021 23:39

AW: Rechtsklick in minimierter Caption abfangen
 
Unterschied?

Man sieht was das zu bedeuten hat!



Außerdem geh immer davon aus, dass deine Message mal ausversehn an ein falsches Programm geht, und wenn es "zufällig" auch auf diese Message-ID reagiert, dann kann sonstwas passieren.
(immerhin gibt es gefühlt 2 Milliarden Music Player, wovon bestimmt irgendwo mal Einer genau die selbe nichtssagende Caption besitzt)

WM_USER und WM_APP am Besten nur programmintern verwenden,
und wenn es zu "anderen" Programmen geht, dann RegisterWindowMessage und schon kann es keine Konflikte geben. (außer jemand hat den selben "Namen" für eine andere Funktion, aber dann war eben der Name einfach nicht eindeutig/gut genug)

Amateurprofi 29. Mai 2021 02:52

AW: Rechtsklick in minimierter Caption abfangen
 
Zitat:

Zitat von himitsu (Beitrag 1490298)
Unterschied?

Man sieht was das zu bedeuten hat!



Außerdem geh immer davon aus, dass deine Message mal ausversehn an ein falsches Programm geht, und wenn es "zufällig" auch auf diese Message-ID reagiert, dann kann sonstwas passieren.
(immerhin gibt es gefühlt 2 Milliarden Music Player, wovon bestimmt irgendwo mal Einer genau die selbe nichtssagende Caption besitzt)

WM_USER und WM_APP am Besten nur programmintern verwenden,
und wenn es zu "anderen" Programmen geht, dann RegisterWindowMessage und schon kann es keine Konflikte geben. (außer jemand hat den selben "Namen" für eine andere Funktion, aber dann war eben der Name einfach nicht eindeutig/gut genug)

Das sehe ich doch: Es wird $7FFF gesendet.
Nee, die Message wird nicht "aus versehen" an irgendein anderes Programm gesendet.
Warum nicht?!
Weil nur ich diese Routine verwende, und auf meinem Rechner eben kein anderes Programm läuft, das diese Caption hat.
Deine Einwände sind völlig in Ordnung, wenn es sich um kommerzielle Programme handelt, die dann eventuell auf Rechnern laufen, auf denen andere Bedingungen herrschen.
Das ist aber nicht der Fall, weil, wie gesagt: Meine Programme und ausschließlich mein Rechner.
RegisterWindowMessage hatte ich mir auch angeschaut, aber anfangs nicht verstanden, weil man da nur einen String als Parameter übergeben kann, aber keinen Wert.
Jetzt, nach Lesen deines Beitrags, hab ich mir das noch mal angeschaut und mir ist klar geworden, dass der Wert von Windows festgelegt wird. Deswegen also Danke!
Was ich dabei aber immer noch nicht richtig verstehe:
Wenn ich das empfangende Programm kompiliere steht ja noch kein numerischer Wert für die Message fest.
Ich schließe daraus, dass beide, das sendende Programm und das empfangende Programm, die Message "registern" müssen.
Ist das richtig?

Amateurprofi 21. Jun 2021 12:03

AW: Rechtsklick in minimierter Caption abfangen
 
Das in #10 gezeigte Programm macht, wenn ich AltGr+. drücke, folgendes:
A) Wenn das Programm "Music.exe" läuft: Sendet eine Message an "Music.exe", die dort verarbeitet wird und das Abspielen von MP3s startet oder stoppt.
B) sonst: Öffnet Music.exe.

Die Code-Sequenz in den ersten 3 Zeilen nach "begin" soll bewirken, dass das Programm nicht angezeigt wird (hab ich im INet gefunden).
Leider funktioniert das nicht.
Frage:
Wie kann ich verhindern, dass das Programm angezeigt wird, auch nicht kurz "aufblitzt"?


Delphi-Quellcode:
program ToggleMusic;

{$APPTYPE CONSOLE}

{$R *.res}

uses
   WinApi.Windows, WinApi.ShellApi,
   System.SysUtils;

const MusicPath='E:\Daten\Delphi XE2\Music\Win32\Debug\Music.exe';
var Win:HWND; StartUpInfo:TStartUpInfo; Dsn:String;
begin
   StartupInfo.cb:=SizeOf(StartUpInfo);
   StartupInfo.dwFlags:=STARTF_USESHOWWINDOW;
   StartupInfo.wShowWindow:=SW_HIDE;
   Win:=FindWindow(Nil,'Music Player');
   if Win<>0 then begin
      PostMessage(Win,$7FFF,0,0);
   end else begin
      Dsn:=MusicPath;
      if FileExists(Dsn) then
         ShellExecute(0,'open',PWideChar(Dsn),nil,nil,SW_SHOWNORMAL);
   end;
end.

DeddyH 21. Jun 2021 12:42

AW: Rechtsklick in minimierter Caption abfangen
 
Wenn Du eine TStartupInfo konfigurierst, solltest Du sie zweckmäßigerweise auch nutzen. Oder Du lässt sie ganz weg und änderst im ShellExecute-Befehl SW_SHOWNORMAL in SW_HIDE.

Amateurprofi 21. Jun 2021 15:18

AW: Rechtsklick in minimierter Caption abfangen
 
Zitat:

Zitat von DeddyH (Beitrag 1491297)
Wenn Du eine TStartupInfo konfigurierst, solltest Du sie zweckmäßigerweise auch nutzen. Oder Du lässt sie ganz weg und änderst im ShellExecute-Befehl SW_SHOWNORMAL in SW_HIDE.

Danke DeddyH,
aber hilft leider nicht.

Zu "Wenn Du eine TStartupInfo konfigurierst, solltest Du sie zweckmäßigerweise auch nutzen."
Ja, täte ich gern, wenn ich nur wüsste, wie.
Kannst du mir bitte kurz erklären, wie ich die TStartupInfo nutze.

Zu "Oder Du lässt sie ganz weg und änderst im ShellExecute-Befehl SW_SHOWNORMAL in SW_HIDE."
Da hast du etwas falsch verstanden.
Mich stört nicht, dass das ggfs. mit ShellExecute geöffnete Programm sichtbar ist - im Gegenteil, dass soll sichtbar sein.
Aber das Programm, das das ShellExecute ausführt, soll nicht sichtbar sein.

DeddyH 21. Jun 2021 15:40

AW: Rechtsklick in minimierter Caption abfangen
 
Achso, dann lass doch einfach die Zeile {$APPTYPE CONSOLE} weg.

KodeZwerg 21. Jun 2021 15:59

AW: Rechtsklick in minimierter Caption abfangen
 
Zitat:

Zitat von Amateurprofi (Beitrag 1491306)
Zu "Wenn Du eine TStartupInfo konfigurierst, solltest Du sie zweckmäßigerweise auch nutzen."
Ja, täte ich gern, wenn ich nur wüsste, wie.
Kannst du mir bitte kurz erklären, wie ich die TStartupInfo nutze.

Das ein ein Teil von der CreateProcess() Api. Da findest Du schnell Beispiele.

Als Alternative mag ich noch ShellExecuteEx() hier vorschlagen:
Delphi-Quellcode:

var
  shi: TShellExecuteInfo;
  commandLine: string;
begin
  commandLine := '"A:\Path\a FileName.exe"';
  shi := Default(TShellExecuteInfo);
  shi.cbSize := SizeOf(TShellExecuteInfo);
  shi.lpFile := PChar(commandLine);
  shi.nShow := SW_HIDE;
  ShellExecuteEx(@shi);

Amateurprofi 21. Jun 2021 21:24

AW: Rechtsklick in minimierter Caption abfangen
 
Zitat:

Zitat von DeddyH (Beitrag 1491309)
Achso, dann lass doch einfach die Zeile {$APPTYPE CONSOLE} weg.

Vielen Dank, DeddyH,
funktioniert.

Amateurprofi 21. Jun 2021 21:38

AW: Rechtsklick in minimierter Caption abfangen
 
Zitat:

Zitat von KodeZwerg (Beitrag 1491311)
Zitat:

Zitat von Amateurprofi (Beitrag 1491306)
Zu "Wenn Du eine TStartupInfo konfigurierst, solltest Du sie zweckmäßigerweise auch nutzen."
Ja, täte ich gern, wenn ich nur wüsste, wie.
Kannst du mir bitte kurz erklären, wie ich die TStartupInfo nutze.

Das ein ein Teil von der CreateProcess() Api. Da findest Du schnell Beispiele.

Als Alternative mag ich noch ShellExecuteEx() hier vorschlagen:
Delphi-Quellcode:

var
  shi: TShellExecuteInfo;
  commandLine: string;
begin
  commandLine := '"A:\Path\a FileName.exe"';
  shi := Default(TShellExecuteInfo);
  shi.cbSize := SizeOf(TShellExecuteInfo);
  shi.lpFile := PChar(commandLine);
  shi.nShow := SW_HIDE;
  ShellExecuteEx(@shi);

Danke,
ist aber am Thema vorbei.
Da ist ein kleines Programm, das zunächst prüft, ob ein bestimmtes anderes Programm läuft.
Wenn dieses andere Programm läuft, wird diesem eine Message geschickt.
Wenn nicht, wird es (das ander Programm) mit ShellExecute geöffnet.

Mein Problem war das das Programm (das, das entweder die Message schickt oder ...) nicht angezeigt werden sollte.
Dein Vorschlag ändert nichts am Problem, schafft aber ein neues.
Dann wird das Programm, das mit ShellExcute geöffnet wird, nicht angezeigt, aber das soll, wie ich in #17 schrieb, sehr wohl angezeigt werden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:02 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