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 WMNCHitTest ist tot seit Vcl.Styles benutzt wird (https://www.delphipraxis.net/202586-wmnchittest-ist-tot-seit-vcl-styles-benutzt-wird.html)

KodeZwerg 20. Nov 2019 11:59

WMNCHitTest ist tot seit Vcl.Styles benutzt wird
 
Delphi Rio 10.3.2

Hallo, seitdem ich auf Rio umgesattelt habe und Vcl.Styles benutze ist der HitTest komplett tot, kann mir jemand helfen das wieder in Gang zu bekommen?

Delphi-Quellcode:
private
  procedure WMNCHitTest(var msg: TWMNCHitTest); message WM_NCHITTEST;
end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.WMNCHitTest(var msg: TWMNCHitTest);
begin
  inherited;
  if msg.Result = htClient then
    msg.Result := htCaption;
end;
Ich wollte erreichen das sich mein Formular per Maus bewegen läßt auch innerhalb der Form und nicht nur über deren Titelleiste.

Bin über jeden Hinweis dankbar, nehme auch gerne workarounds an!

Grüße!

Michael II 20. Nov 2019 13:10

AW: WMNCHitTest ist tot seit Vcl.Styles benutzt wird
 
Ich habe 10.3 U2 (inkl. Patches) und auf meinem NB (Windows 10, Build 19013) klappt es.

hoika 20. Nov 2019 13:19

AW: WMNCHitTest ist tot seit Vcl.Styles benutzt wird
 
Hallo,
klappt es auch mit Vcl.Styles?

KodeZwerg 20. Nov 2019 13:27

AW: WMNCHitTest ist tot seit Vcl.Styles benutzt wird
 
Zitat:

Zitat von Frühlingsrolle (Beitrag 1451620)
Guten Tag KodeZwerg,

das Fenster bekommst du z.B. mit den Funktionen SetWindowPos() und MoveWindow() bewegt.
Für den Ablauf an sich benötigst du die Ereignisse OnMouseMove, OnMouseEnter, OnMouseLeave oder die entsprechenden Windows-Nachrichten dazu.
Es könnte auch einfacher gehen.

Ich beginne zu verstehen und probier es heut abend aus, Danke schonmal für den Tipp!
Zitat:

Zitat von Michael II (Beitrag 1451624)
Ich habe 10.3 U2 (inkl. Patches) und auf meinem NB (Windows 10, Build 19013) klappt es.

Zitat:

Zitat von hoika (Beitrag 1451625)
Hallo,
klappt es auch mit Vcl.Styles?

Ich lade morgen ein Dummyprojekt hoch, das Problem ist, das Vcl.Styles etwas unsichbares über mein eigenes Fenster legt, das habe ich zumindest mit einem WinSpy erfahren.
Ich setze den Style in der .dpr Datei global für alle Formulare, Formulare selbst haben keine seperaten Styles gesetzt. (Ich nutze "Jet" falls das weiterhilft)
Der HitTest kommt gar nicht mehr an...

KodeZwerg 20. Nov 2019 13:54

AW: WMNCHitTest ist tot seit Vcl.Styles benutzt wird
 
Zitat:

Zitat von Frühlingsrolle (Beitrag 1451627)
Laut der Seite thoughtco.com - Drag a Delphi Form Without the Caption Bar funktioniert das Beispiel über den HitTest nur bedingt, sofern keine weiteren Steuerelemente / Fenster auf der Form gegeben sind, die die Oberfläche überdecken.
Ansonsten soll man beim Mausklick / OnMouseDown folgendes ausführen:
Delphi-Quellcode:
// OnMouseDown
ReleaseCapture;
SendMessage(Form1.Handle, WM_SYSCOMMAND, 61458, 0) ;

// bzw.
ReleaseCapture;
(Sender as TControl).Perform(WM_SYSCOMMAND, SC_MOVE or HTCAPTION, 0);
Die MouseDown-Methode kann man den anderen Steuerelementen ebenso zuweisen und das Programm-Fenster lässt sich im gesamten Bereich per LMB/LMT verschieben.

P.S.: Beim TLabel u.ä. funktioniert es nicht, da hier kein Fenster gegeben.

Frühlingsrolle, ich habe mir gerade den Link durchgelesen, gute Resource -> guter Fund dazu!
Hab's verstanden wie ich es umzusetzen habe und gehe mal von einem Erfolg aus, werde dennoch morgen ein buggy dummy hochladen :-)

Michael II 21. Nov 2019 07:09

AW: WMNCHitTest ist tot seit Vcl.Styles benutzt wird
 
Zitat:

Zitat von hoika (Beitrag 1451625)
Hallo,
klappt es auch mit Vcl.Styles?

Ja es funktioniert auch mit VCL Styles:

Wie KodeZwerg schreibt wird WM_NCHITTEST via die beteiligten VCL Units nicht ans Form weitergeleitet. => WMNCHitTest wird nie aufgerufen.

Lösung: Entweder passt du den VCL Code an oder aber (hier wohl besser/einfacher) du überschreibst WndProc des Formulars.

Getestet mit D10.3.2 und Win10 19013.

KodeZwerg 21. Nov 2019 10:25

AW: WMNCHitTest ist tot seit Vcl.Styles benutzt wird
 
Da ich nicht genau weiß, wegen copyright von style "Jet", lade ich nicht das project hoch sondern zeige hier nur den code.

Vielen Dank an Frühlingsrolle, Du hast mir den Weg gezeigt wie man es lösen könnte!

Delphi-Quellcode:
program Project1;

{$IFNDEF MSWindows}
  {$MESSAGE ERROR 'This application is made for Windows only!'}
{$ENDIF MSWindows}

uses
  Vcl.Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Vcl.Themes,
  Vcl.Styles;

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  TStyleManager.TrySetStyle('Jet');
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.
Delphi-Quellcode:
unit Unit1;

{$IFNDEF MSWindows}
  {$MESSAGE ERROR 'This unit is made for Windows only!'}
{$ENDIF MSWindows}

interface

uses
  Winapi.Windows, Winapi.Messages, System.Classes,
  Vcl.Forms, Vcl.Controls, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    CheckBox1: TCheckBox;
    procedure CheckBox1Click(Sender: TObject);
  private
    procedure WMNCHitTest(var Msg: TWMNCHitTest) ; message WM_NCHitTest;
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.WMNCHitTest(var Msg: TWMNCHitTest);
begin
  inherited;
  Self.Caption := 'WMNCHitTest aktiv!'; // diese Zeile dient nur zum Beweis ob man sich in dieser prozedur befindet.
  Panel1.Visible := False;              // dies kann man testen indem man die Zeile "TStyleManager.TrySetStyle('Jet');" aus der Project1.dpr auskommentiert.
  if ((ControlAtPos(ScreenToClient(Msg.Pos), True, True, True) = nil) and (Msg.Result = htClient))
    then
      Msg.Result := htCaption;
end;

procedure TForm1.CheckBox1Click(Sender: TObject);
begin
  if (Sender as TCheckBox).Checked
    then
      Self.OnMouseDown := FormMouseDown
    else
      Self.OnMouseDown := nil;
  Panel1.SetFocus; // damit die CheckBox-Caption-Umrahmung verschwindet wenn man Vcl.Style aktiviert hat.
end;

// fix von Zarko Gajic mit Verbesserung von Frühlingsrolle
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  ReleaseCapture;
//  SendMessage(Self.Handle, WM_SYSCOMMAND, SC_MOVE or HTCAPTION, 0); // original von Herrn Gajic
//  (Sender as TControl).Perform(WM_SYSCOMMAND, SC_MOVE or HTCAPTION, 0); // original von Frühlingsrolle
  Self.Perform(WM_SYSCOMMAND, SC_MOVE or HTCAPTION, 0); // so würde ich es nun nutzen, da ein TControl.Perform wahrscheinlich die komponente anstelle des formulars verschiebt.
//  SetCapture(Self.Handle); // ich bin mir nicht sicher ob man es setzen sollte/muss...?
end;

end.
Thema für mich erfolgreich abgeschlossen, Danke allen!


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