Jump to content

aehimself

Members
  • Content Count

    1090
  • Joined

  • Last visited

  • Days Won

    23

Posts posted by aehimself


  1. Hello,

     

    I have a pagecontrol descendant, where I overridden the DoDrag method to show the picture of the dragged tab:

    Procedure TPageControl.DoStartDrag(Var DragObject: TDragObject);
    Var
     tab: TRect;
     bmp, tabbmp: TBitMap;
    Begin
     inherited;
     If DragObject <> nil Then Exit;
    
     // Create a bitmap of the tab button under cursor
     tab := Self.TabRect(Self.ActivePage.TabIndex);
     bmp := TBitmap.Create;
     bmp.Canvas.Lock;
     tabbmp := TBitmap.Create;
     Try
      bmp.Height := Self.Height;
      bmp.Width := Self.Width;
      tabbmp.Height := tab.Height;
      tabbmp.Width := tab.Width;
      Self.PaintTo(bmp.Canvas.Handle, 0, 0);
      tabbmp.Canvas.CopyRect(tabbmp.Canvas.ClipRect, bmp.Canvas, tab);
      DragObject := TPageControlExtraDragObject.Create(tabbmp);
     Finally
      bmp.Canvas.Unlock;
      FreeAndNil(tabbmp);
      FreeAndNil(bmp);
     End;
    End;

    When the user clicks on one of the tabs I'm manually initiating the dragging process by Self.BeginDrag(False);. When I went into BeginDrag, I saw that if you do not specify a dragging threshold, it takes this value from Mouse.DragThreshold, which is 5 pixels. This - to me - means that the dragging is NOT initiated unless the button is still down, and the cursor went at least 5 pixels away from the initiating position.

    What happens now is that the DoStartDrag event fires immediately, the bitmap is taken and is drawn as a fly-out immediately. Even it I am just switching tabs, which is kind of annoying.

     

    So the question is... if my logic is right (and the DoStartDrag should be fired based on distance) why it is firing immediately? If not, is there a simple setting I forgot to add or I manually have to handle this by MouseMove?

     

    I'm using Delphi 10.4.1, but the "issue" was present in 10.4 and 10.3 as well.


  2. 3 hours ago, Edwin Yip said:

    I think you can also implement the 're-order handles' like that~

    Possible, however there are no requests like that for the time being.

     

    And this is why I hate to implement something new. The next hour when I published the resizable multi-line editor an other request came in, that "it would be nice" if the editor would resize with the form itself, instead of showing a scrollbar 😄


  3. Just a small update, I managed to implement the resizing logic and it was really, really easy. Most of my time went away by drawing the transparent, themed, system default resize gripper...

    ...which almost can not be seen on dark styles, so totally with it! 👍

     

    image.thumb.png.e1cf11f12c0ef3bd1afbd86f396eddc1.png

     

    image.thumb.png.1b948d5a569678917bf3e914e7e6721f.png

     

    Frames above and below are adjusting properly, not changing places or jumping around. Overflow is handled correctly by the alClient scrollbox, if the contents grow too large for the window.

    The only thing is that I did not use splitters, I wrote the resizing logic myself (which is awfully long, like 10 lines of code?)

     

    Procedure TMultiLineParamFrame.ResizeHandleImageMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    Begin
     _resizing := True;
     SetCapture(Self.Handle);
    End;
    
    Procedure TMultiLineParamFrame.ResizeHandleImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    var
     relative: TPoint;
    begin
     If Not _resizing Then Exit;
    
     relative := ScreenToClient(Mouse.CursorPos);
     If relative.Y > 47 Then Height := relative.Y; // Burned in magic number, because we all love them!
    End;
    
    Procedure TMultiLineParamFrame.ResizeHandleImageMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    Begin
     ReleaseCapture;
     _resizing := False;
    End;

     

    Drawing the gripping handle:

    Constructor TMultiLineParamFrame.Create(AOwner: TComponent);
    Var
     bmp: TBitmap;
    Begin
     inherited;
     _resizing := False;
     bmp := TBitmap.Create;
     Try
      bmp.Height := 16;
      bmp.Width := 16;
      bmp.TransparentColor := clYellow;
      bmp.Canvas.Brush.Color := bmp.TransparentColor;
      bmp.Canvas.FillRect(Rect(0, 0, bmp.Width, bmp.Height));
    
      StyleServices.DrawElement(bmp.Canvas.Handle, StyleServices.GetElementDetails(tsGripper), Rect(0, 0, bmp.Width, bmp.Height));
      ResizeHandleImage.Picture.Assign(bmp);
     Finally
      FreeAndNil(bmp);
     End;
    End;

     

    • Like 2

  4. I just found this awesome thing of @RRUZ, called TSMBIOS. Unfortunately though it seems to be abandoned now, and the only result I get on an Ubuntu 18.04 server is a nullpointer exception; even if I execute it via sudo (or su).

    Does anyone know about an updated fork of this component or something similar; which can gather hardware information on Windows and Linux?


  5. 7 minutes ago, dummzeuch said:

    Got it to work. Now the GExperts PEInfo tool also shows all strings in all languages stored in the version info resource which includes the non-standard once like BuildDateTime:

    Nice job. I think soon I'll need something like this in one of my applications - at least I'll know where to look 🙂


  6. With all respect, I don't think Git structure is the root cause here; refactoring the 850 EXEs to one single application plus modules (not necessarily .DLLs) would worth more on the long run in my opinion.

    Most of us, Delphi developers were hired to maintain old, large (and often poorly written) legacy applications; I know how likely the management approves 1-2 devs to "break free" and start re-designing everything.

    But, with properly structured and divided code, you'll quickly see that there will be no need of mapping one git repository to a number of drives.

     

    Thus, achieving your current goal to reduce merge conflicts.


  7. I'm using String for string everywhere with no noticeable performance penalty (although, I never had to write performance-critical programs so far). If I know that encoding is in the game (e.g.: receiving data from a web browser) or I'm working with binary data I'm using TBytes.

    Pretty happy until now.

    • Like 1

  8. 1 minute ago, Anders Melander said:

    I'm doing incremental backup and I rotate media every one or two weeks so it's not that bad. The "other house" is right next to the main building and the cabinet is in my workshop, right next to where I keep the beer, so it's nice to have an excuse to "go file the backup".

    Damn it. First of all, have the highest possible levels of my admiration.

    As for the location... damn it again. I should re-structure my IT equipment at home.


  9. Just now, Anders Melander said:

    At home I'm doing rotating backups to disk. The disks are stored in a non-fireproof cabinet in another building.

    If you mean you physically remove and transport disks between houses on a regular basis for years, you have my highest possible admiration. I'm just too lazy to do that, I give up after a month or two.

    I still have so much to learn 😞


  10. First things first, I am horrible in UI design. With that said...

     

    Considering the fact that one main step can not change without all the sub-steps complete, my main UI would only show the currently active step.

     

    "Project XY is in Pending Signoff state"

    list of substeps below, with a fancy green checkmark right next to the substeps already accomplished. Don't make a dfference between optional and required ones - the main step will change anyway if all required ones are completed.

     

    This applies to the user and admin interface too. I don't really care when the previous main step's substeps were completed if my only purpose is to approve something / check how my thing is progressing. Have a history, as a side menu option.

     

    But then again, I am really, really bad in UI design. It's just how I would do it.

     

    Edit:

     

    image.thumb.png.6ae4eaaa856209f56ae7d4b11a76645c.png

    • Thanks 1

  11. 15 minutes ago, Anders Melander said:

    No. You want your media isolated from anything that can damage it.

    That is a really valid point. So you need 2 fireproof safes. 1 for the library, 1 for the server 🙂

    15 minutes ago, Anders Melander said:

    That includes the backup device.

    That is not possible. How are you writing data on a media, which is not physically in a drive?

    Again, I am strictly talking about home-use "hacky" but safe-enough solutions.

    17 minutes ago, Anders Melander said:

    400 EUD will get you started and I'm sure they can be had for a fraction of that second hand.

    I have trust issues. I'll not buy critical equipment (like a fire extinguisher or car tires) second hand. If I want my data safe - brand new safe. If not - no safe at all.

    400 EUR is a bit off the hobby limit in my opinion. But then again - how much one is willing to and how much one can spend on their hobby is a subjective factor.


  12. 1 minute ago, David Schwartz said:

    You don't have to keep telling us here that you're allergic to anything but mag tapes

    I'm not. I'm not even using mag tapes, they (and the drives + libraries) are too expensive for a hobby. I'm just accepting the opinion of smarter people than me, who still describe the ONLY valid (local) backup medium as tapes. I'm not that good in physics, but the industry standard have its tests.

    I'm only strictly against calling flash-based devices as backup. They are not that reliable. End of story.

    6 minutes ago, David Schwartz said:

    But replacing it with cloud storage kind of negates the whole idea, so don't bother to go there.

    Never said that. Cloud backup is a valid option. I never did - and will never - discourage people of Cloud-based backup. I just have trust issues, but that's my own business.

    8 minutes ago, David Schwartz said:

    BTW, why is it that so many people who are allergic to paying anything for software seem to have no problem paying for cloud storage when they can roll their own using an old computer, whatever storage medium they prefer, and free software?

    I mean, that's basically what I'm suggesting here -- save yourself $100/yr in cloud storage fees by using free stuff and things you're already paying for.

    I'll bet almost anything that at least half of the people here (and majority of IT geeks around the globe) do this. We are happy to spend the price of a house on a backup server for our company but private life is different - if it is still a hobby.

    People usually pay because they need GUARANTEE. What happens if your house and your friends house catches fire at the same time?


  13. Yes, it does (but I don't know since when):

     

    Type
     TMyClass = Class
     public
      Class Var Counter: Integer;
      Constructor Create; ReIntroduce;
     End;
    
    Constructor TMyClass.Create;
    Begin
     Inc(Self.Counter);
    End;
    
    Procedure TForm1.Button1Click(Sender: TObject);
    Var
     v1, v2: TMyClass;
    Begin
     v1 := TMyClass.Create;
     v2 := TMyClass.Create;
     ShowMessage(IntToStr(TMyClass.Counter)); // Will show 2
    End;


     


  14. 11 hours ago, Angus Robertson said:

    Change to using the TIcsMailQueue component, you prepare email using THtmlSmptCli after which you forget about it while a thread tries to send the mail using several mail servers over several days, all queued.

    That's actually quite impressive, I didn't know ICS has these functions built-in! Simple question - does it (or offers a way to) handle backlogs? What happens if an E-mail could not be sent because no connection could be made and the application shuts down?


  15. 6 hours ago, dummzeuch said:

    I'm not sure whether I'd care much about Delphi projects when my house burns down.

    Well said. That would be my last concern too, especially since I have offsite replication of my upstream git repositories 🙂

    7 hours ago, dummzeuch said:

    I don't have a house, I live in a rented flat, so maybe I would care.

    <OFFTOPIC>

    If there are no swarm of mosquitos, it's quite pleasant to have your morning coffee / lunch / dinner outside. On the downside - a house will ALWAYS keep you busy. There is no such thing as "I'm bored" it's only "I'm lazy to do this and this" 😄

     

    <EVENMOREOFFTOPIC>

    I had a landlord once. She was a living creature from hell. Even though I had good relations with the neighbors and paid on time, after a couple of months I was already afraid she is going to poison my dog so I decided to cancel our contract and move out to nowhere. That was the last nail in the coffin - I do not trust people ever since and I do everything in my power not to depend on anyone.

    </EVENMOREOFFTOPIC>

    </OFFTOPIC>


  16. 8 minutes ago, FPiette said:

    It is possible to have some kind of fireproof safe. In a company I worked for, they have such a safe.

    My wife already looks suspicious when I tell her we take the car to the mechanic and it's going to be expensive. I don't even want to imagine convincing her why I need a fireproof safe, which costs triple the amount than our car.

    At home you'll quickly get bored of rotating backup mediums and locking them away. You'll want your backup equipment INSIDE the safe so it can do everything automated. As safes SHOULD act as a perfect Faraday-cage, unless they include a fireproof RJ45 socket wired from the outside in...

    I'm not saying anything more. I'll trademark this stuff 😄

    • Haha 1

  17. 17 hours ago, Edwin Yip said:

    BTW, what do you mean by "burnt myself" in this context?

    It was outside of the IT area, a real-world thing. Unfortunately I can not remember (happened a long-long time ago) but for example:

    - I have a personal problem with John Doe, and he writes an application

    - Since I don't like him, I start to talk sh*t and discourage people from using his product

    - Everyone is still using it. Then, it turns out it has a bridge to some inconvenience I faced for years

    - I start to use it because of that minor thing and it turns out the application is pretty good

    - Now, try to explain to everyone you discouraged why exactly you are now a user too

    - ???

    - Profit

     

    Fortunately, the only thing I achieved is my own humiliation, no legal stuff. It was still a remarkable experience.

    • Haha 2

  18. 9 hours ago, haentschman said:

    ...yes.

    What if your house burns down? All data that cannot be restored, especially the Delphi projects, must be transferred to the data center outside the house. (Webspace/Webserver) :classic_cool:

    Proper backup solutions require the backup area (including servers and libraries) to be physically separated to different buildings. Thus, production center burns - you still have backups and vice versa.

    I also run a machine with extremely low power consumption kilometers away from my house. It's only job is to replicate the data from my prod server, when network is up.

×