Jump to content

Anders Melander

Members
  • Content Count

    2854
  • Joined

  • Last visited

  • Days Won

    156

Posts posted by Anders Melander


  1. 2 hours ago, A.M. Hoornweg said:

    I had to cope with deployment over slow connections paid by data volume until quite recently. 

    So use an installer or zip the files.

    I'm not buying the argument that users can't figure out how to unzip a file or run an installer. IME, they can if they have to.


  2. 3 hours ago, David Heffernan said:

    I mean, the memory can get paged out again so it's not that terrible. 

    Yes it is because it trashes the page cache.

    If memory is low then something else has to be paged out before the exe can be extracted to memory - and then paged out.


  3. 47 minutes ago, ErikT said:

    Now, in the code example above, I would have expected to type CommPortDriver1.OnReceiveData := @CommPortReceiveData; , to set the address of the procedure in CommPortDriver1.OnReceiveData. But then I get the error "Incompatible types: 'TReceiveDataEvent' and 'Pointer'"

    CommPortReceiveData is a method pointer. @CommPortReceiveData is a pointer to a method pointer.

     

    You have declared TCommPortReceiveData as a "procedure of object". That makes it a method pointer so this:

    procedure CommPortReceiveData(Sender: TObject; DataPtr: Pointer; DataSize: Cardinal);

    is wrong (it's not a method; It's a procedure) while this:

    procedure TUploadThread.CommPortReceiveData(Sender: TObject; DataPtr: Pointer; DataSize: Cardinal);

    is correct.

     

    52 minutes ago, ErikT said:

    When I do that, I get the error "Declaration of 'CommPortReceiveData' differs from previous declaration". I guess that this has something to do with the way the procedure has been declared in the TUploadThread type. 

    You haven't declared the method. You have declared a pointer to a method.

    Your declaration in TUploadThread should look like this instead:

    TUploadThread = class(TThread)
    private
      ...other stuff...
      procedure CommPortReceiveData(Sender: TObject; DataPtr: Pointer; DataSize: Cardinal);
    ...more stuff...
    end;

     

    • Like 1

  4. 39 minutes ago, Brandon Staggs said:

    Where is the confusion?

    I wouldn't know; I'm not confused - but that shouldn't stop people from explaining if they find joy in that.

     

    It should have been obvious that I know recent Delphi versions doesn't support being installed on Windows 7, given that I've installed and run several versions on Windows 7 and of course got told by the installer that it wasn't supported. I also stated that I hadn't encountered any problem with Delphi applications running on Windows 7.


  5. 5 hours ago, 357mag said:

    Just step over and trace into.

    Trace Into = Step Into

     

    But you don't need to trace into. You can just place a breakpoint inside your square function.

     

    This is a very simple problem so I suggest you try to single-step through it "in your head" first; What happens when you call square(0), square(1), etc.


  6. 5 hours ago, Cristian Peța said:

    I don't think that list is up to date given that Delphi has complained when you tried to install it on Windows 7 since 10.3 (AFAIR).

     

    That said, I upgraded my main system from Windows 7 to 10 last year but before then I didn't have any problems with the IDE or applications not working on Win7.


  7. Btw, you should let the TSizeableLabel own the HostedLabel so this:

    HostedLabel := TLabel.Create(AOwner);

    should be:

    HostedLabel := TLabel.Create(Self);

    - And there you have an example of when to use Self.

     

    Now since the HostedLabel is owned by the control, it will be destroyed automatically when the control is destroyed (the base class TComponent takes care of that), so you can must get rid of the HostedLabel.Free.


  8. Just now, Paul Dardeau said:

    I will make all the stylistic and quick/easy changes you suggested.

    If you search here for "Style guide" I think you can find some good ones.
    Be aware though that most of them will pretend to teach the One True Style and that is obviously false because I haven't published it yet 😉 

     

    4 minutes ago, Paul Dardeau said:

    What type of control would you suggest for the handles?

    TCustomControl is probably the easiest to work with. You'll be using a window handle per handle so it's not super optimal, but I wouldn't worry about it unless you'll be using hundreds of these at the same time.

    With the handles as separate controls you should also be able to generalize your control so it can attach itself to any TControl instead of embedding it (like I what I thought you were doing - good thing I didn't delete the comment 🙂 ).


  9. Very nice!

     

    Here's some suggestions from looking through the code:

    • The default scope is published so you'll probably want to start your class declaration with private scope:
    TSizeableLabel = class(TCustomControl)
    private
      ...
    • By convention member variables are prefixed with F (for field).
      private
        FInSizingHandle: boolean;
        FResizeInProgress: boolean;
        FMoveInProgress: boolean;
        ...
    • The HostedLabel should be a property, with a setter, not a variable (reason comes below):
      private
        FHostedLabel: TLabel;
        procedure SetHostedLabel(Value: TLabel);
      public    
        property HostedLabel: TLabel read FHostedLabel write SetHostedLabel;
        ...
        
    procedure TSizeableLabel.SetHostedLabel(Value: TLabel);
    begin
      if (Value = FHostedLabel) then
        exit;
      FHostedLabel := Value;
    end;
    • When a component links to another component, it should be able to handle that the other component is deleted.
      You do this by asking to be notified when the other component is deleted.
      protected
        procedure Notification(AComponent: TComponent; Operation: TOperation); override;
        ...
    
    procedure TSizeableLabel.Notification(AComponent: TComponent; Operation: TOperation);
    begin
      inherited;
      if (Operation = opRemove) and (AComponent = FHostedLabel) then
        HostedLabel := nil;
    end;
    
    procedure TSizeableLabel.SetHostedLabel(Value: TLabel);
    begin
      if (Value = FHostedLabel) then
        exit;
    
      if (FHostedLabel <> nil) then
        FHostedLabel.RemoveFreeNotification(Self);
    
      FHostedLabel := Value;
    
      if (FHostedLabel <> nil) then
        FHostedLabel.FreeNotification(Self);
    end;
    • Forget the above 🙂 
      I commented while I read the code and only now see that the label is owned by
      TSizeableLabel.
      In that case, the property should not have a setter.
    • You don't need to initialize your booleans class vars to False.
      They have already been initialized.
    • You don't need to test for nil before calling Free.
      Free already does that.
    • You don't need to reference Self unless you need to pass a reference. The scope is Self by default.
    • Use Pascal case: Result, False, etc.

    Otherwise very clean and readable code. I wish my team mates wrote code that pretty 🙂 

     

    Did you consider using 8 small controls for the handles instead? It would have made painting and the mouse and cursor handling much easier, I think.

     

     

    • Like 2
    • Thanks 1

  10. Just now, Paul Dardeau said:

    Part of the reason I was drawn to Delphi is the 'Rapid' part of application development. If I have to spent a lot of time figuring out old code to do something that seems relatively common, that goes against the grain of rapid development (in my opinion).

    It's not "relatively common". In my 30 years with Delphi I think I've only had a need to do it (resize a control with the mouse) once and that was for a run-time form designer.
    Moving a control can be done with something like 10 lines of code. Resize is harder.

     

    The Raize controls are owned by Embarcadero now and can probably be installed via GetIt.
    https://blogs.embarcadero.com/konopka-signature-vcl-controls-version-7/

     

    9 minutes ago, Paul Dardeau said:

    That's not how I would do it but it's certainly a possibility. Why not try it instead of just giving up?

     

    10 minutes ago, Paul Dardeau said:

    One of the things I was hoping to hear from others in this forum post are things like "I've used 3rd party component X and it worked great" or "I built my own by subclassing Y and adding functionality Z".

    Okay then: I googled the problem, read a lot of examples, tried some different solutions and then wrote some code based on the experience I just acquired. Worked great!

    Better?

     

    15 minutes ago, Paul Dardeau said:

    I find comments like "Let me teach you a trick: <google search links>" to be condescending. I introduced myself by saying that I'm new to Delphi.

    Fair enough. Sorry about that.

    I guess I just don't understand that approach to problem solving.


  11. Just now, Paul Dardeau said:

    I did many searches and did not find any good answers, hence my post here. Sorry if I offended your superior intellect.

    As far as I can see both of the searches above returns a plethora of relevant answers to your question, which you are not exactly the first to ask.

    So what's preventing you from using any of them?


  12. 2 hours ago, Ian Branch said:

    My experience is that it appears to be hung and non-responsive but if I look in the Task Manager I can still see it doing something.  No idea what.

    Use process explorer instead and look at the threads. It will show you the call stack which might get you some hint about what it's doing.

     

    image.thumb.png.de9e3201f8ec337713782f64a63d7581.png

    9 out of 10 times when the IDE hangs for me it's caused by the Structure View when the form editor is active (see above) - and the IDE never recovers. Specifically it appears to be a problem with the VirtualTreeView used by the Structure View.


  13. 1 hour ago, 357mag said:

    What does that mean? The next integer? What next integer?

    I don't know where you are reading this but the sentence is assuming that the pointer points to an element in an array of integers. So incrementing the pointer will make it point to the next integer in the array.

     

    Maybe you should stay away from pointers until you figure this out 🙂 

    • Like 1

  14. 2 hours ago, Dave Nottage said:

    What would you discuss?

    Not everything is an issue or an enhancement request. It's common to have discussions enabled so a topic can be debated before it becomes a task - if ever.

    It's a question of how you manage a project but if Remy prefers everything in one place then it should stay that way since the issue list is primarily a tool for the maintainers, not for the users.

    Personally I prefer questions and other chit-chat in the discussions. I manage a lot of different projects and I need the issue lists to only show me work items.


  15. It seems the ZZZ locales are "supplemental" or "custom" locales and that the information Windows returns about them (such as their abbreviated name (ZZZ)) depends on whether they are used by the current user or not. Wonderful!

     

    I've now added a checkbox to the Languages dialog to hide these misfits by default.
    image.thumb.png.1b3f73347bc00edfb00b70af658971ac.png

    There are still a few remaining ZZZ locales though that I can't explain. Hmmm. It seems LOCALE_SABBREVLANGNAME has been deprecated. It would have been nice if they had updated the documentation to reflect that little detail.

    https://github.com/tpn/winsdk-10/blob/master/Include/10.0.16299.0/um/WinNls.h#L750


  16. 47 minutes ago, Anders Melander said:

    If the filename of the generated language module is *.ZZZ then something is wrong.

    Ah! I see what the problem is; Microsoft has changed their locale database again. They've added a bunch of weird language variants that return ZZZ as their "abbreviated language name" - among them a lot of English variants. For example, what the hell is "English (Finland)" or "English (World)" ?
    image.png.2d6f99d6050beb15785be96448bca2f6.png

     

    What exact target language did you specify?

     

    I think that if you change the target language to just "English" with no variant then the filetype should become ENU (which is actually English (United States)).

    You can also go into the settings and change the File naming scheme to RFC 4646.


  17. 1 hour ago, Robert_RR said:

    My language is Portuguese, and I generated an English translation (word) .ZZZ file and placed it in the folders as you said, but I had no success.
    Could you help me? (Rad Studio 12)

    If the filename of the generated language module is *.ZZZ then something is wrong. It should be *.EN*

    The precise filetype depends on what English variant you chose.

    Does it work if you change the filetype to just .EN ?


  18. 1 hour ago, JohnLM said:

    if I change something in the main Memo at design-time, I may not remember to update that to the dynamic ones.

    So don't set them at design-time; Set them at run-time in a function that will then also be used setup the other memos.

     

    There aren't that many properties on a TMemo so I really don't think it's worth it to try and be clever here but if you really want to you can either use RTTI or streaming (see TStream.WriteComponent/ReadComponent). If your memo use event handlers you will get into trouble with the stream method.

×