Jump to content

aehimself

Members
  • Content Count

    1030
  • Joined

  • Last visited

  • Days Won

    22

Posts posted by aehimself


  1. 17 hours ago, Anders Melander said:

    One thing to be aware of with EurekaLog is that it, in my experience, makes the link stage unbearable slow for large projects.

    My main home project atm is ~500k LOC if I'm not mistaken. Linking speed won't be an issue I presume.

     

    If I'd be able to encrypt and patch the executable with the .MAP file I think it would be possible to disable all hooks and magic of MadExcept and use it only to fill the .StackTrace of exceptions (unit can be seen here). That'd be an acceptable solution too.


  2. http://forum.madshi.net/viewtopic.php?f=4&t=28723

     

    I have the same symptoms. This simple code:

    procedure TForm1.FormCreate(Sender: TObject);
    
     Function RecExDump(E:Exception): String;
     Begin
      If Not Assigned(E) Then Exit('');
    
      Result := E.ClassName + ' - ' + E.Message + sLineBreak + E.StackTrace + sLineBreak + sLineBreak + RecExDump(E.InnerException);
     End;
    
    begin
     Try
      Try
       Raise Exception.Create('Original');
      Except
       Exception.RaiseOuterException(EListError.Create('Outer'));
      End;
     Except
      On E:Exception Do ShowMessage(RecExDump(E));
     End;
    End;

    Shows both exceptions without MadExcept enabled and with EurekaLog. If MadExcept is enabled, EecExDump only sees the outer exception,


  3. Hello,

     

    I was using MadExcept until now but it's limitations are growing on me slowly. First that it simply swallows TThread.FatalException which is an easy fix honestly, but still.

    But yesterday when I started to experiment with nested exceptions and realized that MadExcept simply doesn't support this I started to look for alternatives.

     

    I downloaded a trial of EurekaLog and while the settings look intimidating at a first glance, it seems to work as I expect.

    Before I'm reaching out to their official support I would like to know if anyone managed to achieve is a bare-minimum Eurekalog functionality: no bug reports, no custom forms; ONLY stack traces for exceptions?

    I'll continue to play around with the settings (Threads show no stack traces for now) but if someone knows what should I check and uncheck for the above I'd be able to experiment and decide if I'll switch a lot faster.

     

    Thank you!


  4. 17 minutes ago, Fr0sT.Brutal said:

    Well, it's not the App.PM's fault, it's the misuse. You just run a continuous loop which could iterate millions times per second if there's no messages in the queue. Surely it eats up CPU time and other operations get slower. What happens if you uncomment that Sleep?

    BTW, each additional connect you run adds one more nested loop with App.PM=>Button.OnClick=>Connect thus the call stack grows.

    I never said it was the fault of Application.ProcessMessages; it was mine for using it 🙂

     

    Tbh I don't see a difference between running in a cycle of While thread.Terminated Do and dataset.Next millions of iterations. It just depends how much data you have.

     

    Sleep was originally uncommented, I think I could go down to 5 ms sleep before starting to eat up the CPU.

     

    But since I took a deep breath and started to get rid of this - I don't want to experiment to try to patch-the-patch to make it look better. This time I want to do it right 🙂

    • Like 1

  5. On 3/25/2021 at 8:56 PM, Dalija Prasnikar said:

    Also, this is not just the problem with reacting to input, but all the calls to Application.ProcessMessages will make that long operation running even longer.

    This is the exact thing I experienced. I took the shortcut when I converted my app to use background threads for operations. Instead of

    Connection.Connect;
    DoSomeStuff;

    I started a thread and did...

    StartConnectionInBackgroundThread;
    While Not thread.Finished Do
    Begin
    //  Sleep(10);
      Application.ProcessMessages;
    End;
    DoSomeStuff;

    All was fine until only one code like this ran. In the moment two tried to connect simultaneously (not mentioning a couple of occasional deadlocks) connections took 5-10 times more than they normally would, if they connect by themselves. Also, UI was responsive, but sluggish.

     

    For 20+ builds now I'm in the process to get rid of this shortcut I thought was a good idea before. And while it did what I wanted to achieve on the surface - it did backfire on the long run. For 2+ weeks I'm making changes what the end user might not even realize, and these changes affect 20-30 source files per piece.

     

    I completely agree with @Dalija Prasnikar and some others on this matter - I wish I didn't know Application.ProcessMessages exists in the first place 🙂 

    • Like 1

  6. I think that whenever you change the datasource / dataset on the DBGrid it reinitializes everything, including the column captions you set in design time.

    To change the column caption, you can change the field's DisplayLabel property:

     

    dataset.FieldByName('FNAME').DisplayLabel := 'Medlemsnr';

     

    This will cause the DBGrid to display that as a caption automatically when it creates the column.

    You'll still have to manually change the caption to bold every time, that is.

    • Thanks 1

  7. On a memo it indeed has the rectangle. I guess it'll have to do with TLabel being a TGraphicControl instead of a TWinControl.

    I don't know how to fix it but I can offer an alternative. I have similar loading indicators but just dropping it in front of everything will not catch the user's attention immediately. You can try to put it on a DimPanel, that way the background "issue" will disappear too:

     

     


  8. 7 hours ago, Renate Schaaf said:

    I would remove the Register-procedure for the time being, it needs a quite a few changes to make it play nicely in the IDE, one sore point is e.g. the re-introduced constructor.

    To be completely honest I did not try to install it in the IDE as I prefer to create most of my custom components runtime (in my local unit the Register procedure does not exist at all because of this). The constructor can be the standard, just throw an AV if the specified owner is not a TWinControl.

    What else is problematic?


  9. Unfortunately I cannot go back to delete the previous unit implementations so they have to stay. Anyway I added enabling/disabling parent controls AND the register procedure. Thank you all who helped to make this happen! 🙂

    Unit uDimPanel;
    
    Interface
    
    Uses Vcl.ExtCtrls, Vcl.Graphics, Vcl.Controls, System.Generics.Collections;
    
    Type
     TDimPanel = Class(TPanel)
     strict private
      _bitmap: TBitMap;
      _enabledcontrols: TList<TControl>;
      Procedure DisableParentControls;
      Procedure EnableParentControls;
      Procedure UpdateBitmap;
     strict protected
      Procedure InternalThemeChanged(Const inSystemTheme: Boolean); Virtual;
     protected
      Procedure Paint; Override;
      Procedure Resize; Override;
      Procedure VisibleChanging; Override;
     public
      Constructor Create(inOwner: TWinControl); ReIntroduce; Virtual;
      Destructor Destroy; Override;
      Procedure ThemeChanged(Const inSystemTheme: Boolean);
     End;
    
    Procedure Register;
    
    Implementation
    
    Uses System.SysUtils, System.Classes, WinApi.Windows;
    
    Procedure Register;
    Begin
     RegisterComponents('Additional', [TDimPanel]);
    End;
    
    //Procedure TDimPanel.SetTransparent(Const inWinControl: TWinControl; Const inTransparent: Boolean);
    //Var
    // exStyle: DWORD;
    //Begin
    // exStyle := GetWindowLongPtr(inWinControl.Handle, GWL_EXSTYLE);
    // If exStyle = 0 Then RaiseLastOSError;
    //
    // If inTransparent Then
    // Begin
    //   exStyle := exStyle Or WS_EX_LAYERED;
    //   If SetWindowLongPtr(inWinControl.Handle, GWL_EXSTYLE, exStyle) = 0 Then
    //     RaiseLastOSError;
    //   If Not SetLayeredWindowAttributes(inWinControl.Handle, 0, 127, LWA_ALPHA) Then
    //     RaiseLastOSError;
    // End
    // Else
    // Begin
    //   exStyle := exStyle XOr WS_EX_LAYERED;
    //   SetWindowLong(inWinControl.Handle, GWL_EXSTYLE, exStyle);
    // End;
    //End;
    
    Constructor TDimPanel.Create(inOwner: TWinControl);
    Begin
     inherited Create(nil); // Change to inOwner if you don't want to free it up by yourself...
    
     _bitmap := Vcl.Graphics.TBitMap.Create;
     // Drawing with opacity might alphablend seemingly random parts with
     // pfDevice (default) or pf32bit. Enforce a 24 bit pixel format to ensure
     // what is on the owner is what gets painted.
     _bitmap.PixelFormat := pf24bit;
    
     _enabledcontrols := TList<TControl>.Create;
    
     Self.Visible := False;
     Self.DoubleBuffered := True;
     Self.Parent := inOwner;
     Self.ParentBackground := False; // Might cause flicker if true, plus we are custom drawing
     Self.Left := 0;
     Self.Top := 0;
     Self.Width := Self.Parent.ClientWidth;
     Self.Height := Self.Parent.ClientHeight;
     Self.Anchors := [akLeft, akTop, akRight, akBottom];
     Self.BevelOuter := bvNone;
    End;
    
    Destructor TDimPanel.Destroy;
    Begin
     FreeAndNil(_bitmap);
     FreeAndNil(_enabledcontrols);
    
     inherited;
    End;
    
    Procedure TDimPanel.DisableParentControls;
    Var
     a: Integer;
    Begin
     // Should be empty every time, but to be sure...
     _enabledcontrols.Clear;
    
     For a := 0 To Self.Parent.ControlCount - 1 Do
       If (Self.Parent.Controls[a] <> Self) And
          Self.Parent.Controls[a].Enabled Then
       Begin
         _enabledcontrols.Add(Self.Parent.Controls[a]);
         Self.Parent.Controls[a].Enabled := False;
       End;
    End;
    
    Procedure TDimPanel.EnableParentControls;
    Var
     control: TControl;
    Begin
     Try
       For control In _enabledcontrols Do
         control.Enabled := True;
     Finally
       _enabledcontrols.Clear;
     End;
    End;
    
    Procedure TDimPanel.InternalThemeChanged(Const inSystemTheme: Boolean);
    Begin
     // Dummy
    End;
    
    Procedure TDimPanel.Paint;
    Begin
     // Omit the call to inherited in general. We only need a black background
     // and the opaque bitmap we captured earlier.
    
     Self.Canvas.Brush.Color := clBlack;
     Self.Canvas.FillRect(Rect(0, 0, Self.Width, Self.Height));
    
     Self.Canvas.Draw(0, 0, _bitmap, 125);
    End;
    
    Procedure TDimPanel.Resize;
    Begin
     inherited;
    
     If Self.Visible Then
       Self.UpdateBitmap;
    End;
    
    Procedure TDimPanel.ThemeChanged(Const inSystemTheme: Boolean);
    Begin
     Self.InternalThemeChanged(inSystemTheme);
    End;
    
    Procedure TDimPanel.UpdateBitmap;
    Var
     dc: HWND;
    Begin
     If Self.Visible Then
     Begin
       // If the dimpanel is visible, it will be included in the screenshot. So
       // let's "hide" it...
       Self.SendToBack;
       // ...and kindly ask the parent to repaint so new dimensions can be
       // captured correctly!
       Self.Parent.Repaint;
     End;
     Try
       _bitmap.SetSize(Self.Parent.Width, Self.Parent.Height);
       dc := GetDC(Self.Parent.Handle);
       Try
         BitBlt(_bitmap.Canvas.Handle, 0, 0, _bitmap.Width, _bitmap.Height, dc, 0, 0, SRCCOPY);
       Finally
         ReleaseDC(Self.Parent.Handle, dc);
       End;
     Finally
       If Self.Visible Then
         Self.BringToFront;
     End;
    End;
    
    Procedure TDimPanel.VisibleChanging;
    Begin
     inherited;
    
     If Not Self.Visible Then
     Begin
       // Force owned controls to resize before showing the panel
       Self.Resize;
       // Make sure nothing can be interacted with while parent is dimmed
       Self.DisableParentControls;
       // UpdateBitmap is not called if Self.Visible is false...
       Self.UpdateBitmap;
       // Neither does BringToFront
       Self.BringToFront;
     End
     Else
     Begin
       // Clear bitmap to free up memory
       _bitmap.SetSize(0, 0);
       // Re-enable all controls we disabled earlier
       Self.EnableParentControls;
     End;
    End;
    
    End.
    • Like 1

  10. 4 hours ago, Renate Schaaf said:

     

    
    Procedure TDimPanel.VisibleChanging;
    Begin
     inherited;
    
     If Not Self.Visible Then
     Begin
       Self.Resize;
       Self.UpdateBitmap; // UpdateBitmap is not called if Self.Visible is false...
       //********
       Self.BringToFront;  //BringToFront isn't called either, necessary for parent is TPageControl
     End
     Else
       _bitmap.SetSize(0, 0); // clear bitmap to free up memory
    End;

     

    True that! In my code I have a child inherited from this and I'm calling BringToFront there... but yes, it makes a lot more sense here!

     

    4 hours ago, Renate Schaaf said:

     

    Now it would be really nice if one could use it as a component so one can design the controls on it...

    Feel free to add the Register procedure 🙂 I like to keep my IDE as clean as possible... too many components might make it sluggist / unstable.


  11. This is the final unit I created and which works as I expected to. Feel free to suggest improvements and use if you see fit! I'm not sure if selecting areas to capture / paint would speed up the process but that is a plausible choke point.

    Unit uDimPanel;
    
    Interface
    
    Uses Vcl.ExtCtrls, Vcl.Graphics, Vcl.Controls;
    
    Type
     TDimPanel = Class(TPanel)
     strict private
       _bitmap: TBitMap;
       Procedure UpdateBitmap;
     protected
       Procedure Paint; Override;
       Procedure Resize; Override;
       Procedure VisibleChanging; Override;
     public
       Constructor Create(inOwner: TWinControl); ReIntroduce;
       Destructor Destroy; Override;
     End;
    
    Implementation
    
    Uses System.SysUtils, System.Classes, WinApi.Windows;
    
    //Procedure TDimPanel.SetTransparent(Const inWinControl: TWinControl; Const inTransparent: Boolean);
    //Var
    // exStyle: DWORD;
    //Begin
    // exStyle := GetWindowLongPtr(inWinControl.Handle, GWL_EXSTYLE);
    // If exStyle = 0 Then RaiseLastOSError;
    //
    // If inTransparent Then
    // Begin
    //   exStyle := exStyle Or WS_EX_LAYERED;
    //   If SetWindowLongPtr(inWinControl.Handle, GWL_EXSTYLE, exStyle) = 0 Then
    //     RaiseLastOSError;
    //   If Not SetLayeredWindowAttributes(inWinControl.Handle, 0, 127, LWA_ALPHA) Then
    //     RaiseLastOSError;
    //   End
    //   Else
    //   Begin
    //     exStyle := exStyle XOr WS_EX_LAYERED;
    //     SetWindowLong(inWinControl.Handle, GWL_EXSTYLE, exStyle);
    //   End;
    //End;
    
    Constructor TDimPanel.Create(inOwner: TWinControl);
    Begin
     inherited Create(nil); // Change to inOwner if you don't want to free it up by yourself...
    
     _bitmap := Vcl.Graphics.TBitMap.Create;
     // Drawing with opacity might alphablend seemingly random parts with
     // pfDevice (default) or pf32bit. Enforce a 24 bit pixel format to ensure
     // what is on the owner is what gets painted.
     _bitmap.PixelFormat := pf24bit;
    
     Self.Visible := False;
     Self.DoubleBuffered := True;
     Self.Parent := inOwner;
     Self.ParentBackground := False; // Might cause flicker if true, plus we are custom drawing
     Self.Left := 0;
     Self.Top := 0;
     Self.Width := Self.Parent.ClientWidth;
     Self.Height := Self.Parent.ClientHeight;
     Self.Anchors := [akLeft, akTop, akRight, akBottom];
     Self.BevelOuter := bvNone;
    End;
    
    Destructor TDimPanel.Destroy;
    Begin
     FreeAndNil(_bitmap);
    
     inherited;
    End;
    
    Procedure TDimPanel.Paint;
    Begin
     // Omit the call to inherited in general. We only need a black background
     // and the opaque bitmap we captured earlier.
    
     Self.Canvas.Brush.Color := clBlack;
     Self.Canvas.FillRect(Rect(0, 0, Self.Width, Self.Height));
    
     Self.Canvas.Draw(0, 0, _bitmap, 125);
    End;
    
    Procedure TDimPanel.Resize;
    Begin
     inherited;
    
     If Self.Visible Then
       Self.UpdateBitmap;
    End;
    
    Procedure TDimPanel.UpdateBitmap;
    Var
     dc: HWND;
    Begin
     If Self.Visible Then
     Begin
       // If the dimpanel is visible, it will be included in the screenshot. So
       // let's "hide" it...
       Self.SendToBack;
       // ...and kindly ask the parent to repaint so new dimensions can be
       // captured correctly!
      Self.Parent.Repaint;
     End;
     Try
       _bitmap.SetSize(Self.Parent.Width, Self.Parent.Height);
       dc := GetDC(Self.Parent.Handle);
       Try
         BitBlt(_bitmap.Canvas.Handle, 0, 0, _bitmap.Width, _bitmap.Height, dc, 0, 0, SRCCOPY);
       Finally
         ReleaseDC(Self.Parent.Handle, dc);
       End;
     Finally
       If Self.Visible Then
         Self.BringToFront;
     End;
    End;
    
    Procedure TDimPanel.VisibleChanging;
    Begin
     inherited;
    
     If Not Self.Visible Then
     Begin
       Self.Resize;
       Self.UpdateBitmap; // UpdateBitmap is not called if Self.Visible is false...
     End
     Else
       _bitmap.SetSize(0, 0); // clear bitmap to free up memory
    End;
    
    End.

    Edit: I might also want to disable controls on the parent in VisibleChanging to ensure nothing can be focused by pressing tab as @Attila Kovacs suggested earlier.


  12. 1 minute ago, Attila Kovacs said:

    I can't see ReleaseDC.

    Also, instead of DC you could pass Canvas.Handle.

    Also, you could tune if with only repainting clipping area's.

    Btw, for me it works with pf32bit.

    I never really worked with imaging, I had no idea that there is such a thing as ReleaseDC 🙂 I am relying on errors by ReportMemoryLeaksOnShutdown which missed this.

     

    btw, if you meant to change it like this:

      BitBlt(_bitmap.Canvas.Handle, 0, 0, _bitmap.Width, _bitmap.Height, THackWinControl(Self.Parent).Canvas.Handle, 0, 0, SRCCOPY);

    It does not work, throws an AV. Canvas seems to be nil?
     


  13. 55 minutes ago, Renate Schaaf said:

    You can send the panel to back, redraw its parent, capture the parent's bitmap, send the panel back to front. Surprisingly, there's hardly any flicker when doing this.

    It works and surely the flicker is neglectable...unless you have VCL Styles active. Then it flickers like madness 🙂 Guess I'll just have to live with it 😄

     

    For anyone interested, this is how the relevant code looks like:

     TDimPanel = Class(TPanel)
     strict private
      _bitmap: TBitMap;
     protected
      Procedure Paint; Override;
      Procedure Resize; Override;
      Procedure VisibleChanging; Override;
     End;
    
    Procedure TDimPanel.Paint;
    Begin
     Self.Canvas.Draw(0, 0, _bitmap, 80);
    End;
    
    Procedure TDimPanel.Resize;
    Begin
     inherited;
    
     If Self.Visible Then
       Self.UpdateBitmap;
    End;
    
    Procedure TDimPanel.UpdateBitmap;
    Var
     dc: HWND;
    Begin
     If Self.Visible Then
     Begin
       Self.SendToBack;
       Self.Parent.Repaint;
     End;
     Try
       _bitmap.SetSize(Self.Parent.Width, Self.Parent.Height);
       dc := GetDC(Self.Parent.Handle);
       BitBlt(_bitmap.Canvas.Handle, 0, 0, _bitmap.Width, _bitmap.Height, dc, 0, 0, SRCCOPY);
     Finally
       If Self.Visible Then
         Self.BringToFront;
     End;
    End;
    
    Procedure TDimPanel.VisibleChanging;
    Begin
     inherited;
    
     If Not Self.Visible Then
     Begin
       Self.UpdateBitmap;
       Self.Repaint;
     End
     Else
       _bitmap.SetSize(0, 0); // clear bitmap to free up memory
    End;

    ...just make sure you change _bitmap.PixelFormat to pf24bit in the constructor 🙂

     

    • Like 1

  14. 29 minutes ago, Renate Schaaf said:

    Maybe the bottom half gets alphablended away?  I noticed that black vanishes, which I don't understand. Everything is fine, when drawing a colored background first.

    Progress. If I open the saved bitmap with Irfanview and re-save it, drawing it with opacity works. Size drops from 1,9 to 1,4 MB, bit depth drops from 32 to 24 bit. So yes, something is wrong with the bitmap format 🙂

     

    Edit: damn it. Creating the bitmap like

     _bitmap := Vcl.Graphics.TBitMap.Create;
    // _bitmap.Transparent := False;
     _bitmap.PixelFormat := pf24bit;
    // _bitmap.AlphaFormat := afDefined;

    repainting with opacity works like a charm. It does not work with pfDevice or pf32bit.

     

    Time to put my components back on it 🙂


  15. 47 minutes ago, Attila Kovacs said:

    @aehimself I see. I'd add a client aligned panel on the top of it, drawing a dimmed/blurred image from the things below and adding some controls to this panel to interact with.

    That is exactly what I am trying to achieve now. The problem I'm getting is why the TPanel's Self.Canvas.Draw(0, 0, _bitmap); works while Self.Canvas.Draw(0, 0, _bitmap, 128); draws only the top half of the panel... see 

    50 minutes ago, Attila Kovacs said:

    You just have to make sure that the underlying controls can't be triggered/selected with pressing tab. Perhaps you need an intermediate container tab on each sheet to be able to disable the whole sheet but not the dimmed/blurred one.

    Good point, thank you! Did not think about this!

     


  16. 7 hours ago, Attila Kovacs said:

    Could you define the symmetric difference of the sets "Everything" and "important stuff" ?

    We have no idea what else could be on the page which would make sense to dim but not the "important stuff".

    Are you putting unimportant stuff onto the forms? 🙂 Enemy deception? 🙂 

    I don't see why it is that important, but let's say you have a connection to a server on each tab. It can be a web page, RDP, or simply some data aware controls. Once the connection is broken, the tabsheed would go dimmed, with a clear message "Reconnecting" (and an abort button) would be shown. This is just one example.

    Or let's say each tab allows you to manipulate data like... financial records. One tab = one person. There is a button which calculates some averages but since it takes so long, it is being done in a background thread. Until the thread is running no data must be modified as it can cause incorrect results. So, the tab sheet goes dimmed, with a marquee progress bar and a "Please wait" text.

    Or, you have a chat application, like IRC. One tab = one channel. If you are kicked from a channel, the tab goes dimmed, saying "You have been kicked from the channel" and a button to close the tabsheet.

     

    The things dimmed are not important at that stage because they can not be used; let them be a MsTSCAX control, TWebBrowser, TDBEdit or just a TButton - this is "everything". Important stuff means everything that the tab wants you to know at this point, a message maybe with some controls to interact with.

     

    Hope this helps to clear the desired outcome 🙂


  17. One more thing, this is not really going to work when resizing, as the parent of my dimmed control is the tabsheet (which I need the image of). When I take an image of the tabsheet while the dimmed panel is visible, it's image will be seen on the picture, slowly fading out everything in the process.

     

    I need to think think through.


  18. 3 minutes ago, FredS said:

    I'm confused, what's the reason for wanting your controls to look Un-Dimmed?

     

    ..and if that is the case why not custom draw just your Tabsheet/Panel background dimmed?

    I want to display a progress / warning indicator on a tabsheet which will block all actions to the components on the tabsheet... imagine like the UAC "popup".

    Everything in the background is dimmed as they are unavailable at the moment, only the important stuff (buttons, labels, etc) are shown with full visibility.


  19. So, the "screenshot" and repaint dimmed works... almost.

    The bitmap is captured correctly (saved to a file, shows perfectly) but drawing it back causes some issues...

     

    I have a TPanel descendant, like...

     TDimPanel= Class(TPanel)
     protected
      Procedure Paint; Override;
      Procedure Resize; Override;
     End;
     
    Procedure TDimPanel.Resize;
    Var
     dc: HWND;
    Begin
     inherited;
    
     _bitmap.SetSize(0, 0); // Clear the bitmap
     _bitmap.SetSize(Self.Parent.Width, Self.Parent.Height);
    // Self.Parent.PaintTo(_bitmap.Canvas.Handle, 0, 0); // Does not capture everything, leaves some components out...
     dc := GetDC(Self.Parent.Handle);
     BitBlt(_bitmap.Canvas.Handle, 0, 0, _bitmap.Width, _bitmap.Height, dc, 0, 0, SRCCOPY);
     _bitmap.SaveToFile('C:\shot.bmp');
    End;
    
    Procedure TDimPanel.Paint;
    Begin
     inherited;
    
     Self.Canvas.Draw(0, 0, _bitmap, 128);
    // Self.Canvas.Ellipse(0, Self.Height - 20, 20, Self.Height);
    End;

    But only the upper half of the bitmap is drawn on the panel, bottom half is empty. If ellipse drawing is uncommented, it shows up properly. The funny thing is that if I use

     Self.Canvas.Draw(0, 0, _bitmap);

    all is drawn perfectly, but I loose opacity... I guess it will have something to do in how the bitmap is set up...? At the moment I have the following in the constructor:

     _bitmap := Vcl.Graphics.TBitMap.Create;
     _bitmap.Transparent := False;
     _bitmap.PixelFormat := pf32bit;

    Moving the code out of my project to a TForm and using it's canvas to paint the bitmap to has the same behaviour.

     

    Any help is greatly appreciated, these imaging-things are way out of my league.


  20. 9 hours ago, Renate Schaaf said:

    When one tries to remove the layered style from the child controls of the panel they either get invisible or one gets a Win-Error.

    I was afraid so. I got WinErrors when I tried to do so.

    9 hours ago, Renate Schaaf said:

    For the long answer I guess you have to go back to your bitmap-idea.

    This: https://www.codeguru.com/csharp/csharp/cs_controls/tutorials/article.php/c12323/Creating-NonTransparent-Controls-on-a-SemiTransparent-Window.htm is old, but looks good.

    While the bitmap screenshot idea will work, it feels really hacky. Makes me a bit more comfortable that others got to the same idea to this problem, though.

    It's just a little bit strange that "dimming" is this complicated to achieve.

     

    Thanks anyway, I'll start with the bitmap idea 🙂

×