-
Content Count
1102 -
Joined
-
Last visited
-
Days Won
24
Everything posted by aehimself
-
Messed up text in components. This is why I explicitly mentioned that it's not a display issue, data in the dataset is garbage too. I guess this never worked on my side, for a long time I simply got a "Fetched value truncated" error from Oracle until I found out changing a property gets rid of that (see the prev, thread mentioned in the linked one). Data is still corrupted, though. I don't know, but based on the initial Oracle error I guess it is going to be a memory corruption. I already checked MadExcept's buffer under / overrun protection, did not fire off. After increasing the initial_buffer_size, Oracle doesn't throw an error anymore. Yes, I did that, but it's not consistent. I have a feeling that it is going to be a sweetspot, when a specific amount of character data was returned the error appeared. Simply removing 3 random text columns already returned all data, formatted correctly afaik. Failed to mention this, thanks! Yes, we are connecting to the exact same DB. This is something I can not tell. I don't have access to the DB create scripts, PL/SQL says all the textual fields are VARCHARs only. Unfortunately my knowledge in private life of RDBMSs is very limited, I consider myself a user only, so I don't know what is (should be) the difference between normal varchar and nvarchar.
-
Pascal syntax highlighter treats backslash as escape character
aehimself replied to Remy Lebeau's topic in Community Management
That's a strange way to write sLineBreak 🙂 -
Problems with installing RAD Studio 11 in Wine
aehimself replied to AntiClasxson1958's topic in Delphi IDE and APIs
I experimented with Delphi (I think 10.2) and Wine but never got it to work completely. Everything more complex than a single form caused AVs and other funky things. Maybe things already changed at Wine, but my latest experience is that it won't fully work, ever. -
Windows desktop client for verification of EU Covid-19 health certificates
aehimself replied to Daniel's topic in I made this
Oooooh, how many of sleepless nights I caused myself when due to encoding issues I changed some string routines to TBytes... I can feel the satisfaction of your "oh, damn it" moment when you realized what went wrong 🙂 -
best way to structure an application
aehimself replied to al17nichols's topic in RTL and Delphi Object Pascal
No need for a launcher, a single .EXE can do it - at least on Windows. Windows allows to rename the executable even if your application is running. So the steps are... - Download the updated .exe, and save it e.g. .exe.new - Rename the current application (Application.ExeName) to .exe.old - Rename the updated file .exe.new -> .exe - Launch the .exe and immediately quit - It's a good practice to wait for the previous process to actually die before doing any actual work, like reading settings up, etc. - Upon startup check and delete any .exe.old files I'm using this method and it works like a charm. -
Using uninitialized object works on Win32, throws AV on Win64
aehimself posted a topic in General Help
Hello, Not that long ago we managed to fix up the codebase enough so our large legacy application could be compiled to Win64. Since then this is the second time when something causes an AV on Win64 which worked for 15+ years on Win32. Pseudocode: Procedure TForm1.Button1Click(Sender: TObject); Procedure DoStuff(Var sl: TStringList); Begin If Not Assigned(sl) Then sl := TStringList.Create; sl.Text := 'Just add' + sLineBreak + 'some data'; End; Var sl: TStringList; Begin Try If condition Then Exit; DoStuff(sl); [...] Finally sl.Free; End; End; There are two points where said code can fail: - sl wasn't initialized to nil before passing it to DoStuff. Win32 happily created the TStringList, Win64 didn't and therefore the next method doing anything with it threw an AV - Before even having a chance to initialize sl, we might break out of the method, but sl.Free is called anyway. On Win32 this was fine, Win64 threw an AV first chance As far as I'm aware Delphi is not initializing local variables and I also don't think we were that lucky for 15+ years that these variables were always reserved on a previously cleared memory area (therefore, pointing to nil). Before you say anything, I know that this is a coding issue and was corrected quickly, I'm interested why it behaves differently; maybe some compiler differences...? What can be the explanation? Cheers! -
Using uninitialized object works on Win32, throws AV on Win64
aehimself replied to aehimself's topic in General Help
Based on what I know about local variable initialization, luck was the only logical explanation. But considering the amount of chances it could have broken (15+ years, ~100 clients, software is running on 10 machines at each, minimum, in daily use) I started to have doubts. If this is pure luck, I'll advise our CEO to start to play the lottery 🙂 -
Class properties: Wins prettyness over functionality ?
aehimself replied to Rollo62's topic in Algorithms, Data Structures and Class Design
However I disagree with the opinion that properties are useless, but the above is driving me nuts, too. To be able to achieve this, I have a public, readonly ex. Status property, and a protected writeable InternalStatus property, which point to the same variable. It works, but I hate even to look at it. Maybe this could be solved if internally we refer to Self as an interface... idk. -
Delphi 7 is a lot slower on Windows 10 (compared to Win7)
aehimself replied to Yaron's topic in Delphi IDE and APIs
Security patches WOULD be important, if there's no firewall whatsoever between the machine and the Internet (WinXP 30 sec countdown, anyone?) OR if you are visiting shady websites OR if any machine on the network is already infected. I have an ESXi at home with VMs of all Windows Server versions from Win2k up so I can test the product compatibility. For none of these I have blocked Internet access and with only a router inbetween I had no issues (that I know of, anyway :)). in the past years. I'd say it's safe to have EOL OSes connected to the Internet if you know exactly what you are doing. -
As far as I am aware, SQLite was designed to be a small, "engineless", flatfile data storage which can be queried just like any RDBMS. It never meant to have all the functionality of those, it simply provided an alternate, standardized way to store, and quickly access information. Therefore, limitations. Quite few, and easily workaround-able, imo, though.
-
I started to use databases after the 32bit UNIX timestamp panic was already all over the Internet. Therefore I quickly learned to define all UNIX timestamps as UInt64s 🙂 Nonetheless very true. From Wiki if someone is interested:
-
Updating a JSON file with THTTPClient
aehimself replied to Bob Baudewyns's topic in Network, Cloud and Web
Maybe you think of FTP, but HTTP does not work this way. You need a receiver script / application on your web server which will receive and save that file. -
Use UNIX timestamp and convert in the application. SQLite will be more than happy to store that number for you. Lately I'm even storing dates as UNIX timestamps in local settings files too. It's really convenient.
-
Posting large binary files with Indy using IdMultipartFormData, Do I need wait?
aehimself replied to DavidJr.'s topic in Indy
I wanted to save time before to convert blocking methods to background threads but still blocking the calling method while it runs... used a cycle like this. Once issues started to appear I spent months getting rid of this "shortcut". It became way more messy and way more complicated. Even if you don't have issues at the moment... remember, this cycle is the devil reincarnated. -
My comment was meant to be ironic. Sounded more ironic before I pressed send anyway. I'd rephrase "nothing" to "nothing in this matter". There has been a significant improvement in speed and accuracy of error insight, suggestions - at least in small to midsize projects. The IDE got more stable (once you disable LiveBindings and the welcome screen) and some convenience features were introduced (e.g. Ctrl+click on inherited). Hell, my IDE did not crash by itself since D10.1, not even at work with an endless amount of (even custom) components installed. Delphi is getting better in lots of ways. Alas, this still doesn't mean that the speed / willingness of Emba fixing bugs is not tragicomic.
-
Good news then! This is not an issue brought by the new version!
-
Individual settings will overwrite the one set on the parent. What I really don’t like from this perspective is that there is no “force inheritance”. You change a setting topmost, but if the same setting has a different value somewhere, it’s not going to be changed.
-
I can not imagine myself sitting down, debugging in head instead of news with my morning coffee. Respect for you there.
-
As far as I know you might be able to copy the relevant lines from within the .dproj file but there's no way I'm familiar with to push the "child" settings up. This is why I'm always setting all information at the topmost level (All configuration) even if it's a Win32 build only.
-
While I agree this is a really annoying issue... may I ask why you decided to print a unit...?
-
Interface question
aehimself replied to David Schwartz's topic in Algorithms, Data Structures and Class Design
Yes, but it's not pinpointing the line in the source code where the leaked object was created like as DeLeaker / FastMM full does. My main application which is about 1M LOC, you tell me a class name and I can tell where and why it was created. In older, legacy applications this can be a nightmare, especially if - like at work - everyone uses a TStringList instance for text manipulation, data storage or even as a parameter for a function call. I guess this is what @David Schwartz meant. In these occasions, having the complete callstack of a leaked object is a life saver. -
Interface question
aehimself replied to David Schwartz's topic in Algorithms, Data Structures and Class Design
To be honest I don't see the reason why interfaces are required here. If the objects are freed up multiple times that clearly indicates a coding issue; using interfaces for lifecycle management in this case seems a bit like duct tape on a totaled car. I am also storing objects in .Data properties, using the OnDelete handler to manually free these up and set the .Data to nil. Never had a single issue with multiple release attempts or leaks (except if VCL styles are active but that's a different topic). Out of curiosity you can add a FreeNotification handler and put a breakpoint in that. That way you could examine what is freeing your objects up when you don't want them to, yet. -
@clarke Since the D7 era I was using Delphi's own TClientSocket - TServerSocket. Had some quirks but it worked perfectly. Due to a bug in my receiver code (which originally I thought is in the component) I migrated to ICS about a year ago. A bit more complicated, but works perfectly as well. Depending on your needs you can check these out. ICS works fine on D11 (I'm unsure if TClientSocket - TServerSocket is still shipped, though), both has decent documentation.
- 17 replies
-
- chat.
- client .server
-
(and 1 more)
Tagged with:
-
Hello, I found and modified a code to highlight matching brackets in SynEdit in a Delphi IDE style (no color highlights, but a square around the characters. All is working fine except this one scenario: Enter this pattern and place the cursor in the middle of the inner brackets: Now, press backspace: And now, enter an opening bracket again: The rectangle around the first bracket doesn't get cleared and I can not figure out why. What is even more strange, if you put all in one line all works just fine: This image was taken after deleting and reentering the inner starting bracket. The code I have at the moment is the following: // This whole method was copied from https://stackoverflow.com/questions/18487553/synedit-onpainttransientdemo and modified // to draw rectangles instead of coloring. Procedure TEditorFrame.SynEdit1PaintTransient(Sender: TObject; Canvas: TCanvas; TransientType: TTransientType); Procedure PaintText(Const inPoint: TPoint; Const inText: String); Begin Case TransientType Of ttAfter: Begin // Clear brush and pen has font color: rectangle will be drawn SynEdit1.Canvas.Brush.Style := bsClear; SynEdit1.Canvas.Pen.Color := SynEdit1.Font.Color; End; ttBefore: Begin // Solid brush and pen has background color: Rectangle will be cleared SynEdit1.Canvas.Brush.Style := bsSolid; SynEdit1.Canvas.Pen.Color := SynEdit1.Color; End; End; SynEdit1.Canvas.Rectangle(inPoint.X, inPoint.Y, inPoint.X + SynEdit1.Canvas.TextWidth(inText), inPoint.Y + SynEdit1.Canvas.TextHeight(inText)); SynEdit1.Canvas.TextOut(inPoint.X, inPoint.Y, inText); End; Const OCSYMBOLS: Array[0..7] Of Char = ('(', ')', '{', '}', '[', ']', '<', '>'); Var bufcoord: TBufferCoord; tp: TPoint; a: Integer; c: Char; Begin bufcoord := SynEdit1.CaretXY; a := SynEdit1.RowColToCharIndex(bufcoord); If (a > 0) And (a <= SynEdit1.Text.Length) Then Begin // First, take the character BEHIND the cursor and check if it's an opener or a closer c := SynEdit1.Text[a]; If Not TArray.BinarySearch<Char>(OCSYMBOLS, c, a) Then c := #0; End Else c := #0; If c = #0 Then Begin // Variable a might have been overwritten by TArray.BinarySearch so let's initialize it again a := SynEdit1.RowColToCharIndex(bufcoord); If (a < SynEdit1.Text.Length) Then Begin // If the character behind the cursor wasn't an opener or a closer, // take the character AFTER the cursor and check the same c := SynEdit1.Text[a + 1]; If Not TArray.BinarySearch<Char>(OCSYMBOLS, c, a) Then c := #0; End; If c = #0 Then Exit; End Else bufcoord.Char := bufcoord.Char - 1; // Originally this was a FOR cycle but it's a waste to go through all if only one iteration actually performs something. // During the binary search we already got the index and if it's an opener or a closer. Simply use those previously saved // values SynEdit1.Canvas.Font.Assign(SynEdit1.Font); tp := SynEdit1.RowColumnToPixels(SynEdit1.BufferToDisplayPos(bufcoord)); PaintText(tp, c); bufcoord := SynEdit1.GetMatchingBracketEx(bufcoord); If (bufcoord.Char = 0) Or (bufcoord.Line = 0) Then Exit; tp := SynEdit1.RowColumnToPixels(SynEdit1.BufferToDisplayPos(bufcoord)); If tp.X <= SynEdit1.GutterWidth Then Exit; // We need to paint the opposite symbol now: if first one was an opener then a closer and vice versa. // Instead of an If statement we can simply use a XOr 1, as it will turn 1 -> 2 and 2 -> 1, 3 -> 4 and // 4 -> 3... giving the exact opposite symbol in the pair that we need PaintText(tp, OCSYMBOLS[a XOr 1]); End; I'm using TurboPack SynEdit on D10.4.2. If the code doesn't compile just use SynEdit1.Gutter.Width instead, I think nothing else had to be changed. Can someone please check and give some hints on why things go south? 🙂 Thanks!