Jump to content
Registration disabled at the moment Read more... ×

PeterPanettone

Members
  • Content Count

    1355
  • Joined

  • Last visited

  • Days Won

    5

PeterPanettone last won the day on August 2 2021

PeterPanettone had the most liked content!

Community Reputation

167 Excellent

Technical Information

  • Delphi-Version
    Delphi 12 Athens

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Moving the current procedure to a new separate unit is a common desire when a unit starts to grow too large, and you realize a specific feature set could be broken out into its own module. It would be fantastic if MMX could have a ONE-STEP refactoring to achieve this. The Cumbersome, Manual, Tool-Assisted Refactoring Process: Let's assume you have UnitA.pas and you want to move ProcedureA and all its helper functions into a new UnitB.pas: Step 1: Create the New Unit First, create your new, empty unit. Go to File > New > Unit - Delphi. Save it as UnitB.pas. Decide on the structure. Will UnitB contain a class (TMyFeatureManager) or will it be a collection of standalone procedures? For this example, let's assume you're creating a new class, as that's the most common and robust approach. // In UnitB.pas: unit UnitB; interface type TMyFeatureManager = class private // Fields that were in UnitA's form will go here public procedure ProcedureA; // ... other public methods will go here end; implementation { TMyFeatureManager } procedure TMyFeatureManager.ProcedureA; begin // Code will go here end; end. Step 2: Use the "Find Usages" and "Go to Definition" Tools In UnitA.pas, right-click on ProcedureA and select Search For Usages. This will show you every place where ProcedureA is called. Inside ProcedureA, right-click on every single procedure it calls (e.g., Helper1, Helper2) and use Go to Definition (Ctrl+Click) to jump to their source. This helps you identify all the "connected procedures" you need to move. Make a list of all the procedures, functions, and private fields/variables that are part of this feature set. Step 3: Use the "Move" Refactoring (Safest Method) The Move refactoring is your best friend here. It will automatically update all references to the moved member. Move the Procedures: In UnitA.pas, right-click on a helper procedure (e.g., Helper1) that you want to move. Select Refactor > Move.... The "Move" dialog will appear. In the "Target Scope" or "Destination" field, select your new TMyFeatureManager class in UnitB. Click OK. What happens: Delphi will physically move the code for Helper1 into UnitB.pas, make it a method of TMyFeatureManager, and automatically add UnitB to the uses clause of UnitA if needed. It will also update any calls inside UnitA to correctly reference the method in the new class. Move the Fields: Do the same for any private fields from UnitA's form that are only used by these procedures. Right-click the field, choose Refactor > Move..., and select TMyFeatureManager as the destination. Repeat this process for every single procedure and field on your list. This is a painstaking but very safe process, as the IDE is managing all the references for you. Step 4: Handle Dependencies After moving the code, you will likely have some compiler errors. These are usually dependency-related. UnitA depends on UnitB: The Move refactoring should have already added UnitB to UnitA's uses clause. UnitB depends on UnitA (or other units): Your new TMyFeatureManager class will likely need to reference components or methods from the original form in UnitA. The Wrong Way (Causes Circular References): Do NOT add UnitA to the uses clause in the interface section of UnitB. This will almost certainly cause a circular unit reference. The Right Way: Add UnitA to the uses clause in the implementation section of UnitB. Pass a reference to the form from UnitA into your new class's constructor. Example of the Correct Dependency Handling: // In UnitB.pas: unit UnitB; interface uses Vcl.Forms; // Or whatever base class your form has type // Forward declare the form class from UnitA TFormA = class; TMyFeatureManager = class private FOwnerForm: TFormA; // A reference to the form that owns this manager public constructor Create(AOwnerForm: TFormA); procedure ProcedureA; end; implementation uses UnitA; // Now we can add the full unit reference here { TMyFeatureManager } constructor TMyFeatureManager.Create(AOwnerForm: TFormA); begin FOwnerForm := AOwnerForm; end; procedure TMyFeatureManager.ProcedureA; begin // Now you can safely access components on the original form FOwnerForm.Button1.Caption := 'Done'; end; end. // In UnitA.pas: procedure TFormA.FormCreate(Sender: TObject); begin // Create an instance of the manager and give it a reference to ourselves FMyFeatureManager := TMyFeatureManager.Create(Self); end; procedure TFormA.Button1Click(Sender: TObject); begin // Call the procedure in the new, separate unit FMyFeatureManager.ProcedureA; end;
  2. PeterPanettone

    Winapi.Windows.PROCESS_QUERY_LIMITED_INFORMATION not found

    This is indeed very strange. I have also discovered that when I use my previous code version: const {$IFNDEF PROCESS_QUERY_LIMITED_INFORMATION} PROCESS_QUERY_LIMITED_INFORMATION = $1000; {$ENDIF} ...then I can compile/build my app, but when I run it from the IDE, I get F2084 Internal Error: AV50A9A35E(509E0000)-R00000000-0 shown in the Structure view (without affecting my app at runtime). So I now simply declare the variable without any compiler conditionals, which resolves all compiler problems.
  3. PeterPanettone

    Winapi.Windows.PROCESS_QUERY_LIMITED_INFORMATION not found

    Delphi 12.2.
  4. PeterPanettone

    Winapi.Windows.PROCESS_QUERY_LIMITED_INFORMATION not found

    Your code creates a compiler error: {$IF NOT DECLARED(PROCESS_QUERY_LIMITED_INFORMATION)}// [dcc32 Error] Common.pas(382): E2070 Unknown directive: '' const PROCESS_QUERY_LIMITED_INFORMATION = $1000; {$IFEND}
  5. PeterPanettone

    Winapi.Windows.PROCESS_QUERY_LIMITED_INFORMATION not found

    Hello Remy Lebeau, Thank you for your answer. However, the Delphi 12.2 compiler seems to accept this as a conditional compilation: The code compiles without errors.
  6. PeterPanettone

    Winapi.Windows.PROCESS_QUERY_LIMITED_INFORMATION not found

    Ah, I've found it here: C:\Users\<username>\Documents\Embarcadero\Studio\23.0\CatalogRepository\WindowsAPIfromWinMD-1.0\Windows.System.Threading.pas Very nice! Unfortunately, the GetIt installer does not add WindowsAPIfromWinMD-1.0 to the Library Path.
  7. PeterPanettone

    Winapi.Windows.PROCESS_QUERY_LIMITED_INFORMATION not found

    Hello DelphiUdIT, Thanks for the hint. How would you reference PROCESS_QUERY_LIMITED_INFORMATION from WinMD? I need to use it in this context: hProcess := Winapi.Windows.OpenProcess( PROCESS_QUERY_LIMITED_INFORMATION, // cannot be retrieved from Winapi.Windows False, ProcessID ); So I implemented it as a local constant: const {$IFNDEF PROCESS_QUERY_LIMITED_INFORMATION} PROCESS_QUERY_LIMITED_INFORMATION = $1000; {$ENDIF}
  8. PeterPanettone

    Winapi.Windows.PROCESS_QUERY_LIMITED_INFORMATION not found

    Doesn't Winapi.Windows pull this constant from Winapi.WinNT.pas? But Winapi.WinNT.pas is also missing.
  9. In my Delphi 12.2 Winapi.Windows.pas unit in Windows 11, the declaration for PROCESS_QUERY_LIMITED_INFORMATION ($1000) constant is missing. Does this mean that my Winapi.Windows.pas unit is potentially corrupted?
  10. PeterPanettone

    Delphi's Project Group problem

    Unfortunately, Delphi does not natively support having separate persistent editor tab sets for each project inside a project group. Delphi’s Project Group (.groupproj) by default shares a single editor tab layout across all projects in the group — which can be frustrating when switching between projects in a Project Group. Is there a custom way to AUTOMATICALLY switch between separate tab sets when switching between projects in a Project Group?
  11. PeterPanettone

    Delphi apps on ARM CPU?

    Have you ever tried GDI+ Win32 apps compiled by Delphi?
  12. PeterPanettone

    Delphi apps on ARM CPU?

    From the Microsoft website (https://learn.microsoft.com/en-us/surface/surface-arm-faq😞 Emulated apps run via the Prism emulation engine, which minimizes performance loss and ensures that most x86/x64 applications operate seamlessly on Arm64 systems. Users shouldn't notice any significant difference between native and emulated apps apart from potential performance variations. Can I run Windows programs that aren't in the Microsoft Store on my Windows 11 Arm-based device? Yes, non-Store Windows apps can be installed and run on Windows 11 Arm-based devices. Most applications run natively or through Prism emulation, providing smooth performance.
  13. PeterPanettone

    Delphi apps on ARM CPU?

    How are Delphi apps performing on your Snapdragon Windows PC? Is the Windows-on-ARM emulation layer slowing Delphi apps down? Does the Delphi IDE run on your Snapdragon Windows PC?
  14. PeterPanettone

    Delphi apps on ARM CPU?

    I'm sorry for that.
  15. PeterPanettone

    Delphi apps on ARM CPU?

    That's my same knowledge. And that's why I asked in the first place.
×