Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation on 09/09/25 in Posts

  1. Anders Melander

    suggestion for 2 new su forum: AI usage and AI coding

    They will be unemployed because they know how to write code on their own? Yes, that makes perfect sense; Nobody wants to hire that kind of developers.
  2. They will be unemployed because AI will write all the code (or to rephrase: "Computers will program themselves") within a few years, as predicted already 30 years ago and time and time again afterwards. This time for real, we promise!
  3. A simple, cross-platform demo (VCL + FMX) showing how to Super Fast LAN tethering in IPv4 network Automatically discover a server on the same LAN using UDP Broadcast with Indy components. 📌 Overview This project demonstrates a lightweight, zero-configuration **auto-discovery mechanism**: - The **Server** listens on a known UDP port (`3434`) for broadcast packets. - A **Client** (VCL or FMX/Android) sends a broadcast message (`Discovery|Hello...`) on port `3434`. - The **Server replies** directly to the client (on port `22049`) with its LAN IP address. - The **Client receives the reply**, extracts the server’s IP, and can then connect via TCP or continue communication. This makes it possible to build applications that can **find each other on the same LAN instantly** without manual IP setup. 🏗 Components Used - Indy UDP Components - TIdUDPServer. - TIdUDPClient. 2. - Cross-platform IP detection - Windows: `GetAdaptersAddresses` API - Android: `Java.Net.NetworkInterface` enumeration 3. - Thread-safe logging via `TThread.Queue`. 4. - Timer to control discovery message sending Loop All details has been added in my Github Repo here. Mit Licence: Please feel free to fork and improve & use it on your projects... Any remarks or suggestions are very wellcome here. -- thank you All.
  4. Dalija Prasnikar

    suggestion for 2 new su forum: AI usage and AI coding

    I would say that is a good thing. This means in the future Delphi will still have a solid base of developers who know how to write their code.
  5. I have some issues with your implementation: IPv6 networks are not supported. The client request is needlessly wordy. The client broadcasts to 255.255.255.255 instead of to the subnet's actual broadcast IP. Some routers block traffic to 255.255.255.255 by default. In case the client is run on a machine with multiple networks installed (VPN, etc), there is no option to let the user decide which network to broadcast to. The client is using separate UDP sockets to send the request and read replies. You are forcing the client to receive on a specific listening port. The server is not sending its reply back to the real port that actually sent the request. Most routers will block this traffic if port forwarding is used. On the server side, always reply to the sending port. On the client side, either 1) let TIdUDPClient read replies on its sending port, or 2) let TIdUDPServer send the request on its listening binding. Use one or the other, not both. Doesn't use Indy's TIdStack.GetLocalAddressList() method to discover local networks (at least on Windows, as it may have issues on Android). Since your goal is to allow a TCP client to discover a server, I would opt to get rid of the TIdUDPServer on the client side, and just use TIdUDPClient by itself. Send a request, read a response, done. You don't need to make that process asynchronous with TIdUDPServer in most use cases. Using TIdUDPServer on the client side makes more sense if you want to discover multiple servers and then let the user choose between them, or to leave it open so servers can just broadcast their presence over time.
  6. Stefan Glienke

    suggestion for 2 new su forum: AI usage and AI coding

    Wasting terajoules for basic refactorings, welcome to 2025
  7. Renate Schaaf

    How to "dim" a TabSheet?

    This way it works. Don't set the parent, set DimmedControl to self. The sizes and the anchors are set automatically when active is set to true. procedure TForm1.Button1Click(Sender: TObject); begin TransparentPanel := TDimPanel.Create(Self); TransparentPanel.DimmedControl:=self; TransparentPanel.Alpha := 140; TransparentPanel.DimColor := clBlack; TransparentPanel.Active := True; end; Note that once activated, the panel is on top of its dimmedControl, so you would not be able to click on anything on the form. The use of the panel is to temporarily disable input to a part of the application and to give the user visible feedback about it. It acts like a semitransparent glass layer on top of the dimmed window. Looks like you don't want to use it that way.
  8. My experience does indeed not include Claude Code. If you say its awesome, I believe you. I still severely doubt that it could take over my daily work, so I'm not worried. As for the wrong planet: I have had the nagging feeling for years that I am on the wrong planet. Usually when listening to Frankie goes to Hollywood's "Two Tribes"
  9. Renate Schaaf

    How to "dim" a TabSheet?

    Yes, the update on resize should work automatically. For completeness' sake I'm posting the code of the Dimpanel-version which I presently use. I introduced a property Active, which is decoupled from the Visible-property and a propert DimmedControl which is decoupled from the Parent-property. Also, this version should work on Delphi 2006 and up. To dim the whole form this code works: procedure TForm1.Button4Click(Sender: TObject); begin //Dimmer is a TDimpanel created in OnCreate Dimmer.DimColor := clNavy; Dimmer.DimmedControl := self; Dimmer.Alpha := 150; Dimmer.DisableDimmedControlOnActive := true; Dimmer.active := true; end; And here is the code for TDimPanel: Unit uDimPanel; // by aehimself on https://en.delphipraxis.net/topic/4826-how-to-dim-a-tabsheet/ Interface Uses Classes, Windows, ExtCtrls, Graphics, Controls, Messages; Type TDimPanel = Class(TCustomPanel) private _bitmap, _scr: TBitMap; _enabledcontrols: TList; fActive: boolean; fDimmedControl: TWinControl; fDimColor: TColor; fDoDisable: boolean; fAlpha: Byte; Procedure DisableParentControls; Procedure EnableParentControls; Procedure UpdateBitmap(DoRepaint: boolean); procedure SetActive(const Value: boolean); procedure SetDimmedControl(const Value: TWinControl); procedure WMEraseBkgnd(var Msg: TMessage); message WM_EraseBkgnd; protected Procedure Paint; Override; Procedure Resize; Override; Procedure Notification( AComponent: TComponent; Operation: TOperation); override; Procedure Loaded; Override; public Constructor Create(inOwner: TComponent); override; Destructor Destroy; Override; // Set Active = true at runtime to dim the DimmedControl // Set Active = false to re-enable DimmedControl Property Active: boolean read fActive write SetActive; Property Bitmap: TBitMap read _bitmap; // for debug reasons Property Screen: TBitMap read _scr; published Property DimmedControl: TWinControl read fDimmedControl write SetDimmedControl; property DimColor: TColor read fDimColor write fDimColor; property DisableDimmedControlOnActive: boolean read fDoDisable write fDoDisable; property Alpha: Byte read fAlpha write fAlpha; property Align; property OnResize; property StyleElements; //comment for unsuitable Delphi-versions End; procedure Register; Implementation uses SysUtils; Procedure Register; Begin RegisterComponents( 'Custom', [TDimPanel]); End; Constructor TDimPanel.Create(inOwner: TComponent); Begin inherited Create(inOwner); Self.Visible := False; // Self.DoubleBuffered := True; // Might cause flicker if true, plus we are custom drawing Self.ParentBackground := False; Self.BevelOuter := bvNone; Self.Caption := ''; fDimColor := clBlack; fDoDisable := true; fAlpha := 140; if (csDesigning in ComponentState) then exit; _bitmap := TBitMap.Create; _scr := TBitMap.Create; _bitmap.PixelFormat := pf24bit; _bitmap.Transparent := False; _scr.PixelFormat := pf24bit; _scr.Transparent := False; _enabledcontrols := TList.Create; ControlStyle := ControlStyle + [csOpaque]; End; Destructor TDimPanel.Destroy; Begin if fActive and fDoDisable then EnableParentControls; fDimmedControl := nil; _scr.Free; 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; i: Integer; Begin Try For i := 0 to _enabledcontrols.Count - 1 do begin control := TControl(_enabledcontrols[i]); control.Enabled := true; end; Finally _enabledcontrols.Clear; End; End; // Loaded is called, when all properties of all components of the owner // have been read from the .dfm and have called their setters. // Now we can be sure that fDimmedControl has the correct dimensions, // and we just call its setter again. procedure TDimPanel.Loaded; begin inherited; DimmedControl := fDimmedControl; end; procedure TDimPanel.Notification( AComponent: TComponent; Operation: TOperation); begin inherited; if AComponent = fDimmedControl then if Operation = opRemove then fDimmedControl := nil; 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. if (csDesigning in ComponentState) then begin inherited; exit; end; if assigned(_bitmap) then BitBlt( Canvas.Handle, 0, 0, Width, Height, _bitmap.Canvas.Handle, 0, 0, SRCCopy); End; Procedure TDimPanel.Resize; Begin inherited; If Self.Active Then Self.UpdateBitmap(true); End; procedure TDimPanel.SetActive(const Value: boolean); begin // if the parent is not the same as fDimmedControl it doesn't make any sense // for example if fDimmedControl=nil ... if Self.Parent <> fDimmedControl then begin fActive := False; exit; end; fActive := Value; If Self.fActive Then Begin // Make sure nothing can be interacted with while parent is dimmed if fDoDisable then begin Self.DisableParentControls; // Repaint the parent to reflect disabled state of controls Self.Parent.Repaint; end; Self.UpdateBitmap(False); // no need to repaint the parent at this time Self.BringToFront; Self.Visible := true; End Else Begin // Clear bitmaps to free up memory Self.Visible := False; _bitmap.SetSize( 0, 0); _scr.SetSize( 0, 0); if fDoDisable then // Re-enable all controls we disabled earlier Self.EnableParentControls; end; end; procedure TDimPanel.SetDimmedControl(const Value: TWinControl); var save: boolean; begin // Don't check <>, otherwise Loaded won't work! // if fDimmedControl <> Value then // begin fDimmedControl := Value; if (csDesigning in Self.ComponentState) then exit; if assigned(fDimmedControl) then begin save := Self.Active; if fDoDisable then // Re-enable disabled controls from previous parent // and clear DisabledList Self.EnableParentControls; Self.Active := False; Self.Parent := fDimmedControl; Self.Align := alNone; // clear any align set at design time Self.SetBounds( 0, 0, Parent.ClientWidth, Parent.ClientHeight); Self.Anchors := [akLeft, akTop, akRight, akBottom]; // Re-activate if necessary Self.Active := save; end else begin Active := False; Parent := nil; end; end; // Replace shr 8 by div 256, so we don't get a range check error. // Turn optimization on, so div 256 runs as fast as shr 8 // The optimizer sees that 256 is a power of 2. {$IFOPT O- } {$DEFINE O_MINUS } {$O+ } {$ENDIF } {$IFOPT Q+} {$DEFINE Q_PLUS} {$Q-} {$ENDIF} // AlphaBlend Source and Target using alpha/255 on Target, 1-alpha/255 on Source // and store result in target. procedure Alphablend( Source, Target: TBitMap; Alpha: Byte); var stride: Integer; ps, pt: PByte; i: Integer; begin Assert(Source.PixelFormat = pf24bit); Assert(Target.PixelFormat = pf24bit); Assert(Source.Width = Target.Width); Assert(Source.Height = Target.Height); stride := ((Source.Width * 24 + 31) and not 31) div 8; ps := Source.ScanLine[Source.Height - 1]; pt := Target.ScanLine[Target.Height - 1]; for i := 1 to Source.Height * stride do begin pt^ := ps^ + (Alpha * (pt^ - ps^)) div 256; inc(pt); inc(ps); end; end; // Restore optimization to original {$IFDEF O_MINUS} {$O-} {$UNDEF O_MINUS} {$ENDIF} {$IFDEF Q_PLUS} {$Q+} {$UNDEF Q_PLUS} {$ENDIF} Procedure TDimPanel.UpdateBitmap(DoRepaint: boolean); Var dc: HWND; Begin if (csDesigning in ComponentState) then exit; If Self.Active Then Begin if DoRepaint then begin // If the dimpanel is visible, it will be included in the screenshot. So // let's "hide" it... Self.Visible := False; // ...and kindly ask the parent to repaint so new dimensions can be // captured correctly! Self.Parent.Repaint; end; End; Try _bitmap.SetSize( Self.Parent.ClientWidth, Self.Parent.ClientHeight); _scr.SetSize( _bitmap.Width, _bitmap.Height); dc := GetDC(Self.Parent.Handle); Try BitBlt( _scr.Canvas.Handle, 0, 0, _bitmap.Width, _bitmap.Height, dc, 0, 0, SRCCopy); Finally ReleaseDC( Self.Parent.Handle, dc); End; _bitmap.Canvas.Brush.Color := fDimColor; _bitmap.Canvas.FillRect(_bitmap.Canvas.ClipRect); Alphablend( _scr, _bitmap, Alpha); Finally If Self.Active Then if DoRepaint then Self.Visible := true; End; End; procedure TDimPanel.WMEraseBkgnd(var Msg: TMessage); begin Msg.Result := 1; end; End.
  10. IvanilsonR

    Error iOS App Delphi 12.3

    Thank you Dave. I has reinstalled my Mac OS SO and now using SEQUOIA version and last version of XCode and PA Server. The problem was fixed. Thank u very much Ivan
  11. Stefan Glienke

    suggestion for 2 new su forum: AI usage and AI coding

    In my opinion, creating new forums should only be considered if there is sufficient activity around this topic (regardless of whether it's AI or anything else), which I don't currently see.
  12. Anders Melander

    "Pass" parameters to Delphi compiler, from code

    The main question here should be: What problem does this solve? If the answer is "I once lost the options" then there is no problem - because the solution to that problem is "Don't lose the options". I'm afraid I can't see the use case.
  13. Try adding a variable. I included a bunch of screen shots because it's not exactly obvious that you have to create a new Category before you can create a variable. Then add a Category: Select the Category and click Variable and assign it a value: Close Edit Variables. Now you *should* be able to drop that variable into the Rich Edit control.
  14. Renate Schaaf

    How to "dim" a TabSheet?

    Hi, You can use the code in https://www.delphipraxis.net/1486219-post6.html to make a TWincontrol (semi)transparent (not just a stringgrid). Use it for a black panel, set its parentbackground to false and alignClient it on the tabsheet. I tried it with Delphi 10.3.3 CE.
×