Leaderboard
Popular Content
Showing content with the highest reputation on 04/17/20 in all areas
-
The interfaces in Delphi are bad?
David Heffernan replied to Jacek Laskowski's topic in RTL and Delphi Object Pascal
Is it unreasonable to expect that programmers have knowledge and skill? -
The interfaces in Delphi are bad?
David Heffernan replied to Jacek Laskowski's topic in RTL and Delphi Object Pascal
That post is worthless. Best to ignore it. -
The interfaces in Delphi are bad?
A.M. Hoornweg replied to Jacek Laskowski's topic in RTL and Delphi Object Pascal
I use interfaces all the time, and there are simple ways to make existing classes support interfaces with or without reference counting, without having to derive from a common base class like tInterfacedObject. If I want to modify any class in such a way that it supports interfaces without reference counting, I simply add dummy methods _AddRef, _Release, and QueryInterface: Type tNewObject = class(TOldObject, IInterface) protected // IInterface function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall; function _AddRef: Integer; stdcall; function _Release: Integer; stdcall; end; function tNewObject._AddRef: Integer; begin Result := -1; end; function tNewObject._Release: Integer; begin Result := -1; end; function tNewObject.QueryInterface(const IID: TGUID; out Obj): HResult; begin if GetInterface(IID, Obj) then Result := S_OK else Result := E_NOINTERFACE; end; And similarly, it is possible to make any existing class support interfaces with reference counting, it just takes a few more methods: TNewObject = class(TOldObject, IInterface) protected FRefCount: Integer; function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; function _AddRef: Integer; stdcall; function _Release: Integer; stdcall; public procedure AfterConstruction; override; procedure BeforeDestruction; override; class function NewInstance: TObject; override; property RefCount: Integer read FRefCount; end; procedure TNewObject.AfterConstruction; begin // Release the constructor's implicit refcount InterlockedDecrement(FRefCount); Inherited; end; procedure TNewObject.BeforeDestruction; begin if RefCount <> 0 then Error(reInvalidPtr); Inherited; end; // Set an implicit refcount so that refcounting // during construction won't destroy the object. class function TNewObject.NewInstance: TObject; begin Result := inherited NewInstance; TNewObject(Result).FRefCount := 1; end; function TNewObject.QueryInterface(const IID: TGUID; out Obj): HResult; begin if GetInterface(IID, Obj) then Result := 0 else Result := E_NOINTERFACE; end; function TNewObject._AddRef: Integer; begin Result := InterlockedIncrement(FRefCount); end; function TNewObject._Release: Integer; begin Result := InterlockedDecrement(FRefCount); if Result = 0 then Destroy; end; -
Do you name your Threads for debugging?
Darian Miller posted a topic in Tips / Blogs / Tutorials / Videos
I posted a blog article on this topic yesterday: https://www.ideasawakened.com/post/name-your-threads-even-the-ones-auto-created-by-delphi I'm curious how many others do this sort of thing. I think it really comes in handy sometimes. I also went looking for the reasons behind each of the Delphi-created threads, other than the main message loop. Do you have any info on that? I could swear I read an article on it years ago, but couldn't find it. -
A common practice used by lots of web and mobile app devs is to do the basic design work using what's often called a "lo-fi" theme or style. It looks like hand-drawn figures on paper with handwritten lettering. Balsamic is a tool I found that offers this, but there are many others. I like using Delphi for basic prototyping, and I can often build a semi-functional prototype as quickly as graphic artists can build a static wire-frame model in drawing tools. Here's a decent article on the topic that I found with Google's help: https://www.justinmind.com/ui-kits/sketching-web-and-mobile-wireframes-with-justinminds-ui-kit The problem comes when the user sees what appears to be a fully-functional app, and thinks it's nearly finished. Uh, no, it's like a Hollywood sound stage. They can't tell, and I'm hard-pressed to prove it to them. I thought perhaps if there's a lo-fi style for Delphi, I could build something that LOOKS like it's hand-drawn so they don't mistake it for something more complete. Does anybody know of anything like this that's available?
-
Do you name your Threads for debugging?
Jacek Laskowski replied to Darian Miller's topic in Tips / Blogs / Tutorials / Videos
Unfortunatelly I don't. When it comes to the order of starting the "initialization" section it's not always the same, it all depends on the uses section, in my case your code is launched before RTL/VCL threads. I bypassed this problem by adding a anonymous thread with delay: procedure NameDelphiThreads(const pMainThreadId : THandle); begin TThread.CreateAnonymousThread( procedure var vSnapshot:THandle; vProcessId:THandle; vTE32:TThreadEntry32; i:Integer; begin Sleep(100); vProcessId := GetCurrentProcessId(); vSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, vProcessId); if vSnapshot <> INVALID_HANDLE_VALUE then begin [...] end; end ).Start; end; -
Did a real case Benchmark with Windows 2016 and Linux
RDP1974 replied to RDP1974's topic in Network, Cloud and Web
When you have DoS/DDoS protection in apache, for example with the usage of the qos_module, you will see that there will be a lot of failed requests in the output of the command. This happens, because the protection is indeed working and as mentioned, the ab tool basically floods your server with requests, so a lot of requests with the same IP will automatically be blocked by the apache module. Indeed I see that the performance of Delphi apache module or Indy web application, with Firedac and data middleware manipulation, under Linux is brilliant. I wait for the compiler optimization to redo a benchmark. -
Different behavior in Delphi 10.3 and Delphi 2007 version
Uwe Raabe replied to Ramu's topic in Delphi IDE and APIs
The handling of PixelsPerInch has changed in recent Delphi versions with High DPI support. This may be the cause of what you see here. -
Different behavior in Delphi 10.3 and Delphi 2007 version
David Heffernan replied to Ramu's topic in Delphi IDE and APIs
Please provide a minimal project, and describe the display settings on your machine. -
@vfbb @Dave Nottage Thank you very much for both of you for your invaluable help. I was able to successfully make the Universal Links within my application. Indeed I had to change Delphi files but I made a local copy of the files and attached to my application (so FMX and RTL source is not changed) and when compiling, the compiler will use my local copy of the modified files and it works like a charm. Hopefully Embarcadero will implement these classes within the RTL in the future
- 9 replies
-
- ios
- firemonkey
-
(and 6 more)
Tagged with:
-
Because your stylelookup is empty and the default stylelookup of the TPanel is the 'panelstyle', and your new component don't have a default style. Just do this: procedure TForm1.InitSpeedPanel(sp: TSpeedPanelClass); var sb: TSpeedButton; begin sp.StyleLookup := 'panelstyle'; // <<<<<<<<< // ...
-
Using TFileStream to check if file is in use
Anders Melander replied to Patrick Hughes's topic in Algorithms, Data Structures and Class Design
Whatever function you come up with it will be susceptible to race conditions; After you have determined that the file isn't in use, but before you can open and lock it, another process can come in and open it - or vice versa. Working from Remy's example you need to keep the file open after FileCreate. As soon as the file is closed the test result is stale. -
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; -
Responsive UI with heavy background threads running in idle priority
Anders Melander replied to Yaron's topic in General Help
If everything was as you believed then there wouldn't be a problem. The debugger behavior you describe is the same for all versions and is as expected. If you don't want the OS to switch threads during single step then you need to suspend the other threads in the debugger. But you don't really need to single step to locate the problem. Just repeatedly pause the application when it exhibit the behavior you describe and examine the call stacks of the different threads. Sooner or later you will get a snapshop that reveals the cause of the problem. This simple approach almost always work for me.