Jump to content

aehimself

Members
  • Content Count

    1089
  • Joined

  • Last visited

  • Days Won

    23

Posts posted by aehimself


  1. 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

  2. 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 🙂


  3. 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!

     


  4. 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 🙂


  5. 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.


  6. 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.


  7. 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.


  8. 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 🙂


  9. Hello,

     

    I am trying to "dim" a whole tabsheet so a notification can be clearly shown - blocking the sheet itself, but not blocking the main form. I guess I'd need an alpha blended panel or a semi-transparent bitmap drawn on a TImage... never really worked with imaging until now so I'm not sure about the terms. Other than the standard components I have Graphics32 installed; can this be achieved with a custom TPanel descendant or with Graphics32 somehow? I would like not to install any 3rd party component just for this if not needed.

     

    Worst case scenario I'll capture the tabsheet as a bitmap and draw it on a alClient panel with Canvas.Draw - which supports opacity.

     

    Using Delphi 10.4.2 if it matters.


  10. There is no portable version of Delphi available afaik, however I suppose if you copy all necessary files from a PC where you installed Delphi to an other, it might work.

    But, you have to read the EULA carefully though; I'm not sure if this kind of deployment is allowed.

     

    Why installing it is not an option? In my personal opinion a fresh reinstall is always cleaner, guaranteed to work than attempting to "force it to life".


  11. When I saw the release notes on 10.4.2 and read that TEdgeBrowser now works with the GA Edge, I got excited. I thought it means you have Windows 10 installed with Edge and it works. Well, unfortunately it's not the case, What it means is that you no longer need the Canary edition, you simply can download the runtime from Microsoft's website.

     

    In all cases, you need WebView2.dll. It can come from GetIt, or you can download and extract the .NuGet package from Microsoft. You'll find the DLL under build\native folder.

     

    Next, download the WebView2 Runtime. Evergreen is the easiest, it downloads and keeps a system wide runtime up-to-date. If you choose this, you are set and ready, everything should work.

     

    If you choose the fixed version, things will be a bit different, as you have to tell TEdgeBrowser where to look for the files. Extract the fixed version, and simply add

     

    EdgeBrowser1.BrowserExecutableFolder := 'C:\Users\user\Downloads\Microsoft.WebView2.FixedVersionRuntime.89.0.774.54.x86';

     

    before the .Navigate. All set, right?

     

    Nah. Embarcadero simply forgot about the TWebBrowser component, which can use Edge mode, but it does not publish this property - so normally it can only be used with Evergreen editions.

    Fortunately though, this can be fixed with the usual dirty hack:

    Type
     THackBrowser = Class(TWebBrowser);
    
    procedure TForm2.FormCreate(Sender: TObject);
    begin
    // EdgeBrowser1.BrowserExecutableFolder := 'C:\Users\user\Downloads\Microsoft.WebView2.FixedVersionRuntime.89.0.774.54.x86';
     THackBrowser(WebBrowser1).GetEdgeInterface.BrowserExecutableFolder := 'C:\Users\user\Downloads\Microsoft.WebView2.FixedVersionRuntime.89.0.774.54.x86';
     WebBrowser1.Navigate('https://www.whatismybrowser.com/');
    end;

    Now, you can give your users the freedom. If they decide to download the Edge Runtime, your application will use Edge engine. If not, it still works in IE11 mode. Just don't forget to set FEATURE_BROWSER_EMULATION in the registry 🙂

     

    Hope it helps others!

    • Like 2

  12. 3 hours ago, Fr0sT.Brutal said:

    Why do you think so?

     

    1 hour ago, Lars Fosdal said:

    Pretty simple but effective. Hasn't failed me yet. 

    I tried creating a batch file from within the service. It slept 5 seconds (so I can see the process start) called NET STOP, slept 5 seconds (giving time for the service to stop) and NET START. When I called this batch from within the service I remember seeing the process starting and ending when the service terminated. This is why I never used this method.

    As it works for others I am sure I did something wrong; unfortunately I don't have the code snipplet to debug now.

     

    @Lars Fosdal this looks promising, I'll make a dummy service app to test it 🙂


  13. 8 hours ago, amit said:

    Is there any other way to check whether there is no problem at all on the server side?     Please suggest.   Thank you.

    Well, I have 2 ideas. 1 - use the HTTP status codes. 200 means all fine, it was inserted. 500 means an error happened, transaction was rolled back, resend is needed from the client.

    If you can not control the status codes, you can add a "status check API". After a 200 OK for inserting the record, the client can query the inserted IDs for verification.

    If I understand the question completely, that is.

     

    But, I never really worked with stuff like this so take this with a grain of salt. I always liked to control everything, so when it was needed I launched my own webserver via ICS. That way I could set return codes, headers, session cookies, and even send detailed answers in any format whenever I wanted to.


  14. Thank you all for the replies guys but I don't want to hijack OP's topic. The methods here seem to be "hacky" (to crash the service and let Windows to restart it - it's a tricky approach I have to admit, though!) or already tried (creating a batch file to sleep for 5 seconds, and issue the NET TOP/START commands. Issue is, as parent program stops, it stops the child processes and therefore the batch file execution too).

     

    I was curious if there is a trick to restart a service from within the service itself without the need of a loader, maintenance service - an other executable in general. As it is not that important for me at the moment I'll just keep my eyes open to see if such method was unearthed already.


  15. On 2/23/2021 at 1:06 PM, Lars Fosdal said:

    Our services runs on domain controlled servers and are descendents from TService, but they must be configured to run with a specific AD user (i.e. not the default system user) that has the necessary rights to access it's own file, and to start and stop services to be able to upgrade themselves. 

    It's not related to the topic, but may I ask how you implemented the update mechanism? Without a "loader" (e.g. actual code is in a DLL, service only loads and executes the DLL,) I never managed to achieve this. I never figured out how to restart the service from within the service.


  16. On 2/27/2021 at 12:59 PM, amit said:

    I want to use them to construct the SQL to update record flag in SQL table.   The Bracket in the RetIDList will be romoved and finally the RetIDList will be '1,2,3,4,5'.   Then I will create Update SQL as 
     

    
      qry.SQL.clear;
      qry.SQL.add('Update Table1 Set Flag=0 where ID in ('+RetIDList+');'); 
      qry.ExecSql;

     

    Just two notices. If you will ever use Oracle and RetIDList will contain more than 1000 elements, the code will fail. I don't know if any other RDBMS has this limitation though.

    How trusted is the file? Taking a string value from somewhere and putting it in a SQL command exposes your application to injection attacks.

    • Like 2

  17. Can anyone who has 10.4.2 confirm (or just explain if I misundrestood) but TEdgeBrowser now works without the +200 MB download requirements if Windows has the Chromium-based Edge installed?

    New TEdgeBrowser Extensions

    The TEdgeBrowser VCL component introduced in 10.4 (a wrapper around the Windows 10 Chromium-based Edge WebView2 control) has been updated with support for the GA version of Microsoft's WebView2 control and its SDK. Besides better compatibility, the component now offers enhanced support for files cache management and the use of custom WebView2 versions.


  18. 1 minute ago, pyscripter said:

    In the SvgIconImageList demo case, the application was compiled with the Windows default style and the error occurs when you change the style at runtime.   I think that may be significant because it causes the controls to be recreated.

    This is interesting. I am also changing the style runtime, when the application starts. However at this stage the frame including the TreeView does not exist yet in my case so I'd say it's irrelevant.


  19. 2 minutes ago, balabuev said:

    I was not able to reproduce the issue. Tried with Form>PageControl>TabSheet>Frame>PageControl>TabSheet>TreeView.

    Can you upload simplified demo project?

    My issue is that I have 5-6 TreeViews in my application in different locations and only one seems to be affected. I don't know what is the difference, this is what I was attempting to debug in the first place. If I know more, I will be able to make a small test case.


  20. 2 minutes ago, pyscripter said:

    The bug is not related to frames.

    I had a guess about it, but since at me it is on a frame... but you are right, let me rephrase it to "moving Items.Clear to the owning component's BeforeDestruction event" to be more inclusive 🙂

×