2007. október 22., hétfő

Set the level of transparency for a TForm


Problem/Question/Abstract:

I want to create a form that has some degree of transparency. I know that in Windows 2000 SDK there is a very good resource to do that (SetLayeredWindowAttributes), but this one is not implemented in Windows.pas. I tried to import directly from user32.dll, and I even could find the value for some constants (WS_EX_LAYERED) with non documented value (MS C++.net), but at the end, I got some weird messages of "invalid variant type conversion" when trying to use this function. Does somebody have any example written in Delphi using this function?

Answer:

Solve 1:

{ ... }
const
  WS_EX_LAYERED = $80000;
  LWA_COLORKEY = 1;
  LWA_ALPHA = 2;
type
  TSetLayeredWindowAttributes = function(
    hwnd: HWND; {handle to the layered window}
    crKey: TColor; {specifies the color key}
    bAlpha: byte; {value for the blend function}
    dwFlags: DWORD {action}
    ): BOOL; stdcall;

procedure TfBaseSplash.FormCreate(Sender: TObject);
var
  Info: TOSVersionInfo;
  F: TSetLayeredWindowAttributes;
begin
  inherited;
  Info.dwOSVersionInfoSize := SizeOf(Info);
  GetVersionEx(Info);
  if (Info.dwPlatformId = VER_PLATFORM_WIN32_NT) and (Info.dwMajorVersion >= 5) then
  begin
    F := GetProcAddress(GetModulehandle(user32), 'SetLayeredWindowAttributes');
    if Assigned(F) then
    begin
      SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle,
        GWL_EXSTYLE) or WS_EX_LAYERED);
      F(Handle, 0, Round(255 * 80 / 100), LWA_ALPHA);
    end;
  end;
end;


Solve 2:

Make sure you check that the OS supports it. Here's how I do it:

function ALLOWALPHA: Boolean;
type
  TSetLayeredWindowAttributes = function(hwnd: HWND; crKey: LongInt; bAlpha: Byte;
    dwFlags: LongInt): LongInt; stdcall;
var
  FhUser32: THandle;
  SetLayeredWindowAttributes: TSetLayeredWindowAttributes;
begin
  AllowAlpha := False;
  FhUser32 := LoadLibrary('USER32.DLL');
  if FhUser32 <> 0 then
  begin
    @SetLayeredWindowAttributes := GetProcAddress(FhUser32,
      'SetLayeredWindowAttributes');
    if @SetLayeredWindowAttributes <> nil then
    begin
      FreeLibrary(FhUser32);
      Result := TRUE;
    end
    else
    begin
      FreeLibrary(FhUser32);
      Result := False;
    end;
  end;
end;

Nincsenek megjegyzések:

Megjegyzés küldése