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 LoadLibrary vs GetModuleHandle, eine Verständisfrage (https://www.delphipraxis.net/207907-loadlibrary-vs-getmodulehandle-eine-verstaendisfrage.html)

KodeZwerg 14. Mai 2021 19:22

LoadLibrary vs GetModuleHandle, eine Verständisfrage
 
Hallo, hier mal ein stück code mit einem Ergebnis was mich etwas verwirrt.

gegeben ist dieser Auszug aus meinem Theming Projekt (der Vollständigkeit halber ist hoffentlich alles nötige mit aufgeführt)

In dieser Variante, funktioniert (auch wenn falsch integriert) bei gesetzten ThemeDarkLight es halbwegs so wie ich es erhoffe.
Delphi-Quellcode:
type
  TkzTheme = (ThemeNone, ThemeDarkLight, ThemeSystem, ThemeWallpaper);

  kzTheme = class(TObject)
    ...
  strict private
    FStyleTheme: TkzTheme;
  strict private
    procedure SetDwmMode(const AMode: ShortInt);
    ...
  end;

  AccentPolicy = packed record
    AccentState: Integer;
    AccentFlags: Integer;
    GradientColor: Integer;
    AnimationId: Integer;
  end;

  TWinCompAttrData = packed record
    attribute: THandle;
    pData: Pointer;
    dataSize: ULONG;
  end;

var
  SetWindowCompositionAttribute: function(Wnd: HWND; const AttrData: TWinCompAttrData): BOOL; stdcall = nil;

implementation

procedure kzTheme.SetDwmMode(const AMode: ShortInt);
const
  WCA_ACCENT_POLICY = 19;
  ACCENT_DISABLE = 0;
  ACCENT_ENABLE_GRADIENT = 1;
  ACCENT_ENABLE_TRANSPARENT = 2;
  ACCENT_ENABLE_BLURBEHIND = 3;
  GRADIENT_COLOR = $01000000;
  DrawLeftBorder = $20;
  DrawTopBorder = $40;
  DrawRightBorder = $80;
  DrawBottomBorder = $100;
var
  dwm10: THandle;
  data: TWinCompAttrData;
  accent: AccentPolicy;
begin
  if (not ((AMode = ACCENT_DISABLE) or (AMode = ACCENT_ENABLE_TRANSPARENT) or (AMode = ACCENT_ENABLE_BLURBEHIND))) then
    Exit;
  dwm10 := LoadLibrary(user32);
  try
    @SetWindowCompositionAttribute := GetProcAddress(dwm10, 'SetWindowCompositionAttribute');
    if @SetWindowCompositionAttribute <> nil then
    begin
      accent.AccentState := AMode;
      accent.AccentFlags := DrawLeftBorder or DrawTopBorder or DrawRightBorder or DrawBottomBorder;
      if ((FStyleTheme = ThemeSystem) or (FStyleTheme = ThemeWallpaper)) then
        accent.GradientColor := FColorBackground;
      data.attribute := WCA_ACCENT_POLICY;
      data.dataSize := SizeOf(accent);
      data.pData := @accent;
      SetWindowCompositionAttribute(FForm.Handle, data);
    end;
  finally
    FreeLibrary(dwm10);
  end;
end;

initialization
  SetWindowCompositionAttribute := GetProcAddress(GetModuleHandle(user32), 'SetWindowCompositionAttribute');
end.
himitsu schrieb ich soll auf LoadLibrary verzichten und direkt per GetModuleHandle zugreifen sowie den Schutzblock entfernen, gesagt getan:
Delphi-Quellcode:
procedure kzTheme.SetDwmMode(const AMode: ShortInt);
const
  WCA_ACCENT_POLICY = 19;
  ACCENT_DISABLE = 0;
  ACCENT_ENABLE_GRADIENT = 1;
  ACCENT_ENABLE_TRANSPARENT = 2;
  ACCENT_ENABLE_BLURBEHIND = 3;
  GRADIENT_COLOR = $01000000;
  DrawLeftBorder = $20;
  DrawTopBorder = $40;
  DrawRightBorder = $80;
  DrawBottomBorder = $100;
var
  data: TWinCompAttrData;
  accent: AccentPolicy;
begin
  if (not ((AMode = ACCENT_DISABLE) or (AMode = ACCENT_ENABLE_TRANSPARENT) or (AMode = ACCENT_ENABLE_BLURBEHIND))) then
    Exit;
  @SetWindowCompositionAttribute := GetProcAddress(GetModuleHandle(user32), 'SetWindowCompositionAttribute');
  if @SetWindowCompositionAttribute <> nil then
  begin
    accent.AccentState := AMode;
    accent.AccentFlags := DrawLeftBorder or DrawTopBorder or DrawRightBorder or DrawBottomBorder;
    if ((FStyleTheme = ThemeSystem) or (FStyleTheme = ThemeWallpaper)) then
      accent.GradientColor := FColorBackground;
    data.attribute := WCA_ACCENT_POLICY;
    data.dataSize := SizeOf(accent);
    data.pData := @accent;
    SetWindowCompositionAttribute(FForm.Handle, data);
  end;
end;
Doch nun funktioniert wenn ThemeDarkLight aktiv ist (Hintergrund ist schwarz) es nicht mehr.

Liegt es daran das mein code generell falsch ist oder gibt es doch unterschiede zwischen LoadLibrary und GetModuleHandle die mir momentan noch verborgen sind?

LG

venice2 14. Mai 2021 19:56

AW: LoadLibrary vs GetModuleHandle, eine Verständisfrage
 
Hmmm..

Delphi-Quellcode:
var
  hUser: HModule;
begin
  hUser := GetModuleHandle('user32.dll');
  @SetWindowCompositionAttribute := GetProcAddress(hUser, 'SetWindowCompositionAttribute');
end;
was sagt hUser ?

GetModuleHandle(user32) <> GetModuleHandle('user32.dll');

KodeZwerg 14. Mai 2021 20:37

AW: LoadLibrary vs GetModuleHandle, eine Verständisfrage
 
Danke Emil für Deine Vorschläge! :thumb:

Ich habe mir alle Varianten mal in einer Box darstellen lassen, alle lieferten die gleiche Nummer.
Der Fehler, bzw das was irgendwie anders arbeitet ist hier verborgen:
Delphi-Quellcode:
    ...
    @SetWindowCompositionAttribute := GetProcAddress(GetModuleHandle(user32), 'SetWindowCompositionAttribute'); // <- so ruf ich es nun auf
    ...
    if ((FStyleTheme = ThemeSystem) or (FStyleTheme = ThemeWallpaper)) then
      accent.GradientColor := FColorBackground
      else
      accent.GradientColor := FColorText; // das hier musste gesetzt werden damit der hintergrund wieder transparent wird...
so funktioniert es momentan, auch wenn nur dürftig (habe immer noch dein video im hinterstübchen^^)

venice2 14. Mai 2021 20:54

AW: LoadLibrary vs GetModuleHandle, eine Verständisfrage
 
Warum du dich weigerst einen String zu übergeben ist mir schleierhaft.
Siehe getmodulehandlea

Code:
HMODULE GetModuleHandleA(
  LPCSTR lpModuleName
);
Es sei denn du hast user32 als const definiert. (vielleicht in irgendeiner Unit in Delphi selbst)
Kann ich jetzt nicht sehen.

Wie dem auch sei. :)

KodeZwerg 14. Mai 2021 21:06

AW: LoadLibrary vs GetModuleHandle, eine Verständisfrage
 
Zitat:

Zitat von venice2 (Beitrag 1489474)
Warum du dich weigerst einen String zu übergeben ist mir schleierhaft.
Es sei denn du hast user32 als const definiert.

Ich weigere mich nicht ein bisschen, wirklich nicht!
Habe es ja mit beide Variationen getestet, als
Delphi-Quellcode:
user32
und auch als
Delphi-Quellcode:
'user32.dll'
, gleiches Resultat erhalten.
Die
Delphi-Quellcode:
uses Winapi.Windows
datei hat es als
Delphi-Quellcode:
const
definiert
Delphi-Quellcode:
 user32    = 'user32.dll';
.

venice2 14. Mai 2021 21:11

AW: LoadLibrary vs GetModuleHandle, eine Verständisfrage
 
Zitat:

uses Winapi.Windows datei hat es als const definiert.
Ok das erklärt alles. Sorry


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