-
Content Count
2914 -
Joined
-
Last visited
-
Days Won
130
Everything posted by Remy Lebeau
-
If you are going to do that, it would be simpler to use SetString() instead: SetString(AMsg, PChar(stat), Length(stat)); Or Copy(): AMsg := Copy(stat, 1, MaxInt); Especially since both of these approaches handle empty strings, whereas accessing index 1 of an empty string is technically undefined behavior, even though Move() won't do actually anything when the Length is 0.
-
The correct way to use UniqueString() in this example would be like this: procedure StatusOut(const stat: string); var AMsg: string; begin AMsg := stat; UniqueString(AMsg); // use AMsg as needed... end;
-
Indy question readbytes VS readstring
Remy Lebeau replied to alnickels's topic in Network, Cloud and Web
There are no real "advantages" per-se, they are just different methods meant for reading different kinds of data. Use whatever method is appropriate for whatever kind of data you are trying to read. If you are reading textual data, then ReadLn(), ReadString(s)(), Capture(), etc are all suitable, depending on the formatting of the text. If you are reading binary data, then ReadBytes() or ReadStream() are suitable. -
[WebBrowser] how to get url on click a href in TWebbrowser
Remy Lebeau replied to Juan Young's topic in Cross-platform
VCL's TWebBrowser has an OnBeforeNavigate2 event. FMX's TWebBrowser has OnShouldStartLoadWithRequest and OnDidStartLoad events. -
Variant to generic T, how?
Remy Lebeau replied to Jacek Laskowski's topic in RTL and Delphi Object Pascal
Can't you just assign the Variant to the field directly and let the Variant handle the conversion? Why do you need to go through TValue at all? procedure ToField<T>.SetFromVariant(const aValue : Variant); begin fData := aValue; end; Internally, when TValue is holding a Variant, TValue.AsType<T>() will look at the Variant's VType, copy the appropriate TVarData field to a temp TValue, and then assign that temp to the Result variable via TValue.Get<T>(). So just take out the middle man (TValue), Variant already knows how to do that same conversion directly. -
The Platform/Feature Manager does not exist when using the Offline (ISO-based) installer, only when using the Online (GetIt-based) installer. This is stated as much in the Installation documentation:
-
Yes, because it CAN'T switch to PostMessage(). That would grant the caller permission to free the string data before it has actually been used to update the Memo. The Add() must be synchronous, regardless of its implementation, blocking the caller until the update is complete to ensure the integrity of the string data.
-
You mean WM_COPYDATA, not WM_COPY.
-
How do you deal with deprecated symbols in backwards compatible code?
Remy Lebeau replied to dummzeuch's topic in RTL and Delphi Object Pascal
I would rewrite that to something more like this instead. Don't duplicate code that doesn't need to be duplicated: var LCount: Integer; LCount := o.{$IFDEF JSONOBJ_HAS_COUNT}Count{$ELSE}Size{$ENDIF}; if LCount <> 3 then raise Exception.CreateFmt(_('Parsing error on JSON answer: Root object size is %d not 3.'), [LCount]); I would just write a class helper or separate function, and IFDEF the code inside of it. Class helpers were first introduced in Delphi 2005, but were buggy and not officially supported until Delphi 2006. JSON was first introduced in Delphi 2010. -
SuperObject is open-source. Just diff the two versions to see what is different between them. Or, just update the D2007 code to use the same version that the XE7 code is using. Or update both codes to the latest version. So pick ONE and stick with it for both codes. I don't do JSON processing in my code.
-
Responsive UI with heavy background threads running in idle priority
Remy Lebeau replied to Yaron's topic in General Help
Agreed. If IsSuspended were a manual-reset Event or ConditionalVariable, the main thread could sleep on it more efficiently. Or, on Windows 8+, you can use WaitOnAddress() to make the main thread sleep while it waits for the boolean to change value. -
Using TFileStream to check if file is in use
Remy Lebeau replied to Patrick Hughes's topic in Algorithms, Data Structures and Class Design
Rather than polling, you might consider letting the OS notify you when the file is being used. There is no guarantee that other apps will actually keep the file open while they are working on the data. In fact, it is not unusual for an app to open a file, load the data, and then close the file, and then reopen the file later only if new data is being saved. -
Using TFileStream to check if file is in use
Remy Lebeau replied to Patrick Hughes's topic in Algorithms, Data Structures and Class Design
To use a TFileStream just to check if the file is in use, you need to use fmOpenRead instead of fmCreate, and you definitely need to use fmShareExclusive instead of fmShareDenyNone, and note that the file could fail to open for any number of reasons, not all of which are related to the file being in use, so you have to check for that, eg: function FileReallyIsInUse(fName: string): boolean; begin Result := False; try TFileStream.Create(fName, fmOpenRead or fmShareExclusive).Free; except on E: EFOpenError do Result := GetLastError() in [ERROR_SHARING_VIOLATION, ERROR_LOCK_VIOLATION]; end; end; However, the exception doesn't carry the error code, and using GetLastError() after the exception is raised does not guarantee the original error code is preserved. You are better off simply calling the Win32 CreateFile() function directly instead (which avoids the need to allocate an object in memory, or invoke the overhead of exception handling): function FileReallyIsInUse(fName: string): boolean; var hFile: THandle; begin hFile := CreateFile(PChar(fName), GENERIC_READ, 0, nil, OPEN_EXISTING, 0, 0); if hFile <> INVALID_HANDLE_VALUE then begin CloseHandle(hFile); Result := False; end else Result := GetLastError() in [ERROR_SHARING_VIOLATION, ERROR_LOCK_VIOLATION]; end; Or, the RTL's FileOpen() function: function FileReallyIsInUse(fName: string): boolean; var hFile: THandle; begin hFile := FileOpen(fName, fmOpenRead or fmShareExclusive); if hFile <> INVALID_HANDLE_VALUE then begin FileClose(hFile); Result := False; end else Result := GetLastError() in [ERROR_SHARING_VIOLATION, ERROR_LOCK_VIOLATION]; end; -
Why is ShowMesssage blocking all visible forms?
Remy Lebeau replied to Mike Torrettinni's topic in VCL
That is exactly what a TForm's PopupParent property is meant for. A TForm stays on top of its PopupParent Form, it can never go behind the PopupParent. Like I described earlier in this same discussion. Otherwise, just use a TFrame instead. Put it on top of the TForm that needs to be "blocked", and disable access to the TForm's controls until the TFrame is dismissed. -
Only windowed controls (TWinControl descendants) can receive input focus, and thus be assigned as an ActiveControl. TLabel is a graphical control (TGraphicControl descendant), not a windowed control. If you need a windowed text label, use TStaticText instead of TLabel. TBitBtn is a windowed control. All windowed controls support that. All components, visual and non-visual, support that. The reason that doesn't work for you is most likely due to OS theming. So turn off theming on the button. Or, use a 3rd party button that allowed custom coloring. Or, just owner-draw the button yourself manually. I don't think any standard controls support vertical alignment, only custom-drawn controls can do that. All controls support that. For controls that are just wrappers for standard OS controls (like TButton), that behavior is controlled by the user's system settings, not by the framework. Most controls support that. Even if the event is not exposes, it still exists in all controls. Why are you posting this in a Delphi forum and not in the Lazarus forums? https://forum.lazarus.freepascal.org
-
Then why is this being posted in a Delphi forum and not in the Lazarus forums? https://forum.lazarus.freepascal.org
-
Problems downloading files from a FTP server using the ICS FTP Client. The DIR command has no carriage return or line feeds
Remy Lebeau replied to M-Brig's topic in VCL
RFC 3659 Well, not just undocumented, but implementation-defined. Servers can (and do) use whatever format they want for LIST. -
Common code base for VCL and FMX control code
Remy Lebeau replied to Girish Patil's topic in Cross-platform
Is your component visual (derived from TControl)? Or is it non-visual (derived from TComponent)? Non-visual components can be used in both VCL and FMX without splitting up the implementation (just IFDEF the pieces you need). But visual controls take more work to design for separate frameworks. Then those lines should be in separate units. The rest of your code should be in a common unit(s) that the framework-specific units can then use. This is where Unit Scope Names come into play. Create separate VCL-specific and FMX-specific projects with appropriate Unit Scope Names specified in the Project Options, and then don't use any Unit Scope names in your code. That way, you have less IFDEF'ing to do. Your common gtDocumentPrinter code should be in its own separate unit, not in an include file. All the more reason not to use an include file. -
Smaller custom component between design & Running mode
Remy Lebeau replied to Damien Leveugle's topic in VCL
Probably because the IDE is not HighDPI-aware, so it gets stretched by the OS. It wasn't necessary to show EVERYTHING, most of that code is not related to painting. -
Smaller custom component between design & Running mode
Remy Lebeau replied to Damien Leveugle's topic in VCL
You are going to have to show your actual painting code. The fundamentals of painting controls haven't changed over the years (certainly newer APIs - ie theming - have been added, but that is secondary). Your old painting code should still be functioning the same way it always did. -
Read in multiple lines and display them in a TMemo object
Remy Lebeau replied to stephanos's topic in General Help
Setting the Text property replaces the ENTIRE contents of the Memo. If you want to APPEND a line to the EXISTING text, use the Lines.Add() method instead, eg: Memo1.Lines.Add(lineoftext); In which case, your entire loop can be replaced with a single LoadFromFile() instruction, eg: procedure TForm1.Button4Click(Sender: TObject); begin Memo1.Lines.LoadFromFile('Test.txt'); end; Or, if you want to append the entire file to the end of the EXISTING text, do what Lars Fosdal showed you - load the file into a TStringList first, then you can AddStrings() that into the TMemo. If you really want to manually loop through a text file line-by-line, consider using the TStreamReader class instead of old-style Pascal file I/O. TStreamReader has a ReadLine() method (and in Delphi, it supports Unicode text encodings), eg: procedure TForm1.Button4Click(Sender: TObject); var FS: TFileStream; Reader: TStreamReader; begin FS := TFileStream.Create('Test.txt', fmOpenRead or fmShareDenyWrite); try Reader := TStreamReader.Create(FS); try while not Reader.Eof do begin lineoftext := Reader.ReadLine(myFile); Memo1.Lines.Add(lineoftext); end; finally Reader.Free; end; finally FS.Free; end; end; -
Automatically make your PC wake up at a given time
Remy Lebeau replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
Both of my PCs at home are old Dells, running XP and Win7, and they both have BIOSes that support scheduling power events on weekdays only. So they both power up before I start a work day, and as long as I shut them down cleanly (ie, not by holding down the power button, which I do have to do sometimes) then they power up correctly on the next weekday. No weekend runs, unless I leave them powered on Friday night (for backups, etc). -
Use an Xcode Storyboard to Provide the App’s Launch Screen
Remy Lebeau replied to MikeMon's topic in Cross-platform
Here is a response I saw on another forum with a similar question: -
Responsive UI with heavy background threads running in idle priority
Remy Lebeau replied to Yaron's topic in General Help
The only way your worker threads could be causing the UI to lag is if they are making the UI thread wait for lengthy periods of time, such as by synchronizing with the UI thread, submitting large amounts of asynchronous notifications to the UI thread, not yielding to the CPU so the UI thread gets starved for CPU time, etc. But without seeing your actual code, it is hard to say for sure why your UI is lagging. That is what the debugger is meant for. -
FastMM4 and option "AlwaysClearFreedMemory"
Remy Lebeau replied to A.M. Hoornweg's topic in General Help
No, it is not, because AlwaysClearFreedMemory is a compile-time {$define}, not a runtime variable (like ReportMemoryLeaksOnShutdown is, for instance). It is processed only when FastMM4.pas is being compiled. There was a feature request made 2 years ago asking for AlwaysClearFreedMemory to be configurable at runtime. It is still open: #51 Feature request regarding option "AlwaysClearFreedMemory" Then don't do such things on strings/interfaces containing sensitive data. And do use things like the CryptProtectMemory(), CryptUnprotectData(), and SecureZeroMemory() functions to secure the sensitive data in memory while you are not actively using it.- 5 replies
-
- fastmm4
- alwaysclearfreedmemory
-
(and 3 more)
Tagged with: