Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Non-Vcl -> Bmp SS_NOTIFY dilemma (https://www.delphipraxis.net/205261-non-vcl-bmp-ss_notify-dilemma.html)

KodeZwerg 19. Aug 2020 07:47

Non-Vcl -> Bmp SS_NOTIFY dilemma
 
Guten morgen,
ich habe ein Problem wo ich noch nicht so richtig mit umzugehen weiß.

Ich erstelle ein Bild als Static-Control, weise dem ein OnClick (SS_NOTIFY) zu, aber dann funktioniert mein MouseOver-Event nicht mehr.
Schalte ich OnClick aus, funktioniert MouseOver wieder.
Ich hätte gerne beides auf einmal, was mache ich falsch?

Hier relevante Code teile:
Delphi-Quellcode:
// variablen:
const
  IDC_BMP = 1000;
var
  hWndBmp: HWND;




//hier im Message handler WndProc...

  WM_CREATE:
    begin
      hWndBmp := CreateWindowEx(
                      0,
                      'STATIC', 'VOID',
                      WS_VISIBLE or WS_CHILD
                      SS_NOTIFY or SS_BITMAP,
                      10, 5, 32, 32,
                      hWnd, IDC_BMP, hInstance, nil);
    end;

  WM_COMMAND:
    begin
      if HiWord(wParam) = STN_CLICKED then
        case LoWord(wParam) of
            IDC_BMP:
              begin
                // mach was
              end;
        end;
    end;

  WM_MOUSEMOVE:
    begin
      // get current coordinates
      pt.x := Word(lParam);
      pt.y := Word(lParam shr 16);

      // switch cursor back to normal if outside of image
      if ((ChildWindowFromPoint(hWnd, pt) <> hWndBmp)
          and (GetCursor <> Cardinal(IDC_ARROW))) then
        SetCursor(LoadCursor(0, IDC_ARROW));

      // switch cursor if over image
      if ((ChildWindowFromPoint(hWnd, pt) = hWndBmp)
          and (GetCursor <> Cardinal(IDC_HAND))) then
        SetCursor(LoadCursor(0, IDC_HAND));
    end;


  WM_LBUTTONDOWN:
    begin
      (*
        dirty workaround wenn SS_NOTIFY nicht gesetzt wurde.

        hier code von mouseover reinkopieren
        hier code von onclick reinkopieren
      *)
    end;

himitsu 19. Aug 2020 08:31

AW: Non-Vcl -> Bmp SS_NOTIFY dilemma
 
https://social.msdn.microsoft.com/Fo...forum=vcmfcatl
oder Eines der anderen 4700 Suchergebnisse: Bei Google suchenSS_NOTIFY mouse move

Also SubClassing und damit auch ein eigenes Message-Event für dein STATIC,
oder vielleicht reicht es auch, wenn du dich über SetWindowLongPtr+GWL_WNDPROC ins STATIC rein hängst.

Wenn du in deiner Messagebehandlung auf das HWND achtest, also von wem die Message kommt, dann kannst für Beides auch die selbe Prozedur verwenden
und musst die Positionen eventuell nur noch auf den Parent umrechnen.

KodeZwerg 19. Aug 2020 08:47

AW: Non-Vcl -> Bmp SS_NOTIFY dilemma
 
Danke für Tipp, werde ich abends ausprobieren!

venice2 19. Aug 2020 09:34

AW: Non-Vcl -> Bmp SS_NOTIFY dilemma
 
Zitat:

Bmp SS_NOTIFY dilemma
Es gibt kein dilemma das man nicht lösen könnte selbst ist der Mann\Frau versuche es einfach.
Das Flag SS_NOTIFY benötigt man dafür nicht das überlässt man TTrackMouseEvent!
Zitat:

Zitat von himitsu (Beitrag 1472062)
https://social.msdn.microsoft.com/Fo...forum=vcmfcatl
oder Eines der anderen 4700 Suchergebnisse: Bei Google suchenSS_NOTIFY mouse move

oder vielleicht reicht es auch, wenn du dich über SetWindowLong+GWL_WNDPROC ins STATIC rein hängst.

Schlechte Idee wenn schon SetWindowLongPtr, GetWindowLongPtr
SetWindowLong ist veraltetet und wenn man nachher auf 64 Bit portieren will ist es um so ärgerlicher denn dann muss man alles umschreiben.
Deshalb direkt richtig machen.

siehe.
https://www.delphipraxis.net/83180-m...-ohne-vcl.html

himitsu 19. Aug 2020 09:55

AW: Non-Vcl -> Bmp SS_NOTIFY dilemma
 
upps, ja.

Das Schlimme, ist dass ich die Namen aus der Hilfe kopiert hatte, aber nicht aus dem fetten Hinweistext ganz oben. :oops:
https://docs.microsoft.com/en-us/win...setwindowlonga

KodeZwerg 19. Aug 2020 10:28

AW: Non-Vcl -> Bmp SS_NOTIFY dilemma
 
Zitat:

Zitat von venice2 (Beitrag 1472071)
Zitat:

Bmp SS_NOTIFY dilemma
Es gibt kein dilemma das man nicht lösen könnte selbst ist der Mann\Frau versuche es einfach.

Wie ich es selbst gemacht habe kann man ja oben einsehen. Ich habe bestimmt in meiner WinApi Referenz was überlesen.

Hinauslaufen wird es auf SubClassing, danke für den deprecated Hinweis!

venice2 19. Aug 2020 10:47

AW: Non-Vcl -> Bmp SS_NOTIFY dilemma
 
Beachte aber wenn du das Flag SS_NOTIFY gesetzt hast die Messagen in WM_COMMAND ausgewertet werden über STN_CLICKED, STN_DBLCLK.
WM_LBUTTONDOWN wird durch das setzen dieses Flag gar nicht angesprochen.

Desto trotz kannst du über Postmessage WM_LBUTTONDOWN trotzdem verwenden. Als workaround

Viele Spaß beim ausprobieren.

KodeZwerg 20. Aug 2020 07:56

AW: Non-Vcl -> Bmp SS_NOTIFY dilemma
 
Zitat:

Zitat von venice2 (Beitrag 1472071)
Zitat:

Bmp SS_NOTIFY dilemma
Es gibt kein dilemma das man nicht lösen könnte selbst ist der Mann\Frau versuche es einfach.

Nachwort:

SubClassing hatte auf anhieb funktioniert aber das "versuche es einfach" hatte mir noch keine Ruhe gelassen.
Nachdem ich meine Nase nochmal tiefer in die WinApi Referenz gesteckt habe bin ich auf eine bessere Lösung gekommen.
Delphi-Quellcode:
SetClassLongPtr(Cardinal(hWndArr[1]), Integer(GCL_HCURSOR), Integer(LoadCursor(hWndArr[0], IDC_HAND)));

venice2 20. Aug 2020 16:24

AW: Non-Vcl -> Bmp SS_NOTIFY dilemma
 
Zitat:

Zitat von KodeZwerg (Beitrag 1472136)
Zitat:

Bmp SS_NOTIFY dilemma
Nachdem ich meine Nase nochmal tiefer in die WinApi Referenz gesteckt habe bin ich auf eine bessere Lösung gekommen.
Delphi-Quellcode:
SetClassLongPtr(Cardinal(hWndArr[1]), Integer(GCL_HCURSOR), Integer(LoadCursor(hWndArr[0], IDC_HAND)));

sorry muss da leider noch mal leicht eingreifen.
32 und 64 Bit der zustand ist das SetClassLongPtr je nach verwendeten kompilat zwei werte annehmen kann 4Bit\32Bit 8Bit\64Bit
deshalb ja der umstand das man nicht mehr SetClassLong oder vergleichbares verwenden soll.

Delphi-Quellcode:
SetClassLongPtr(Cardinal(hWndArr[1]), Integer(GCL_HCURSOR), Integer(LoadCursor(hWndArr[0], IDC_HAND)));

zu
Delphi-Quellcode:
SetClassLongPtr(Cardinal(hWndArr[1]), Integer(GCL_HCURSOR), LONG_PTR(LoadCursor(hWndArr[0], IDC_HAND)));

oder
Delphi-Quellcode:
SetClassLongPtr(Cardinal(hWndArr[1]), WParam(GCL_HCURSOR), LParam(LoadCursor(hWndArr[0], IDC_HAND)));


Dann bist du auf den richtigen weg.
Nicht nur die richtige Funktion sondern auch den entsprechenden Daten Typ dazu verwenden sonst macht es keinen sinn.
WParam, LParam sollte die richtige Bit Größe zuweisen je nach dem welche art von Class man verwendet WNDCLASSEX \ WNDCLASS

Siehe dazu nochmal!

Code:
ULONG_PTR SetClassLongPtrA(
  HWND    hWnd,
  int     nIndex,
  LONG_PTR dwNewLong
);
LONG_PTR

Nebenbei kannst du in deiner Class einen Speicher reservieren der für deine Propertys zuständig ist.
Siehe dazu "cbWndExtra"

KodeZwerg 21. Aug 2020 07:27

AW: Non-Vcl -> Bmp SS_NOTIFY dilemma
 
Danke für diesen Hinweis, werde ich auch im nächsten Kompilat berücksichtigen wobei ich momentan noch absolut gar keine Ahnung habe wie ich ein nonVcl project als 64bit kompilieren kann.
Auch Danke für den Speicher-Tipp :thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:40 Uhr.
Seite 1 von 2  1 2      

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