-
Content Count
2896 -
Joined
-
Last visited
-
Days Won
160
Everything posted by Anders Melander
-
Polywick Studio - Delphi and C++ Builder developer.
Anders Melander replied to PolywickStudio's topic in Job Opportunities / Coder for Hire
-
...unless you also monitor the parent directory. Maybe make the polling optional?
-
VPN is just transport layer encryption and is not relevant. The documentation for ReadDirectoryChangesW answers your other question:
-
It sounds as if you've given up before the fight's begun - and a fight there will be. On many different fronts. So far I've read and heard endless tales of the efforts wasted on "ai". I'm sure it will eventually settle into something actually usable - if we can survive that long, but until then I'm running circles around the people that try to get ahead of the game "ai". The cake is a lie.
-
Bad case of astigmatism? 🙂
-
I doubt that you will find anything that implements everything since there's really no need or practical use for that. You can have a look at the PNG implementation in Graphics32: https://github.com/graphics32/graphics32/blob/master/Source/GR32_PortableNetworkGraphic.pas I don't know if it covers more or less of the specs than TPNGImage but at least it's fully extensible so you can add anything that it's missing if you want to.
-
Not my users - but of course that's not really relevant to you. "The program" isn't shown on a monitor; A window is and a program can have several windows, each positioned independently. You can use TForm.Monitor to determine what monitor a form is currently positioned on. Anyway, here's some reading material: https://learn.microsoft.com/en-us/windows/win32/gdi/the-virtual-screen https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemmetrics#SM_CXVIRTUALSCREEN https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemmetrics#SM_XVIRTUALSCREEN https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createdcw
-
This might be because the Desktop Window Manager (DWM) ghosts your application and synthesizes an image of it. The same thing happens if your application isn't reading from the message queue (e.g. it's running in a tight loop, doing stuff); The application can't repaint itself so DWM takes over and displays an image of what it looked like the last time it was repainted. I think that what we get when copying from the desktop DC isn't necessarily what is actually displayed on the screen. I think the DWM has an internal buffer that composes the image we see based on the desktop DC and whatever other things it thinks should be shown (e.g. ghosted windows). There's probably an API somewhere that provides access to DWM.
-
I second that. I wouldn't dream of using my own code for something like this when we have madExcept. It even allows the user to annotate the screenshot AFAIR.
-
I think you need to work with monitors instead of "the screen". Different monitors can have different DPI, and they might not align. Here's some random code: procedure TBitmapEditorToolScreenShot.TSnapShotList.Capture; var i: integer; DesktopDC: HDC; Canvas: TCanvas; begin if (FItems = nil) then FItems := TObjectList<TSnapShot>.Create else FItems.Clear; for i := 0 to Screen.MonitorCount-1 do FItems.Add(TSnapshot.Create(Screen.Monitors[i])); // Capture desktop DesktopDC := GetDC(HWND_DESKTOP); if (DesktopDC = 0) then RaiseLastOSError; try Canvas := TCanvas.Create; try Canvas.Handle := DesktopDC; for i := 0 to FItems.Count-1 do FItems[i].Capture(Canvas); // See TSnapShot class below finally Canvas.Free; end; finally ReleaseDC(HWND_DESKTOP, DesktopDC); end; end; All it does it to create a list of monitors and then it does a capture of each monitor into separate bitmaps. Here's the class that represents a monitor and its bitmap and which does the actual capture: type TBitmapEditorToolScreenShot = class(TCustomBitmapEditorTool, ICaptureController) strict private type TSnapShot = class private FMonitor: Forms.TMonitor; FBitmap: TBitmap; public constructor Create(AMonitor: Forms.TMonitor); destructor Destroy; override; procedure Capture(DesktopCanvas: TCanvas); property Monitor: Forms.TMonitor read FMonitor; property Bitmap: TBitmap read FBitmap; end; ...more stuff... end; procedure TBitmapEditorToolScreenShot.TSnapShot.Capture(DesktopCanvas: TCanvas); begin if (FBitmap = nil) then FBitmap := TBitmap.Create; FBitmap.SetSize(FMonitor.BoundsRect.Width, FMonitor.BoundsRect.Height); FBitmap.PixelFormat := pf24bit; FBitmap.Canvas.CopyRect(FBitmap.Canvas.ClipRect, DesktopCanvas, FMonitor.BoundsRect); end; constructor TBitmapEditorToolScreenShot.TSnapShot.Create(AMonitor: Forms.TMonitor); begin inherited Create; FMonitor := AMonitor; end; destructor TBitmapEditorToolScreenShot.TSnapShot.Destroy; begin FBitmap.Free; inherited; end;
-
Yup. I started with Turbo Pascal's ancestor PolyPascal, which used WordStar key bindings, and I have used that ever since (that's the Classic IDE binding in Delphi). Unfortunately many of Delphi's newer editor functions aren't available with the Classic IDE key bindings. That said, I seem to remember that Classic had a key binding for column mode but I can't remember what it was. ^KN or something like that. No, it shouldn't. The compiler will use the project options by default.
-
I'm not sure I understand your question. You can get the editor to insert the current compiler options into the source with Ctrl+O+O (default and classic keyboard binding), if that's what you're asking.
-
Compiler options: {$ALIGN 8} {$ASSERTIONS ON} {$BOOLEVAL OFF} {$DEBUGINFO OFF} {$EXTENDEDSYNTAX ON} {$IMPORTEDDATA ON} {$IOCHECKS ON} {$LOCALSYMBOLS ON} ...etc... Compile-time feature flags & compiler version, and platform detection (these were snipped from the Graphics32 library): (* Symbol: NO_GENERIC_METACLASS_LISTS ------------------------------- The C++ Builder linker has problems resolving ambiguities caused by metaclass types because they all get mangled as TClass. As a result of this the compiled object files end up containing duplicate symbols, which in turn causes a LIB266 linker error. Specifically we get into problems with TCustomClassList<T> where "T" is a metaclass. To work around the problem we define the NO_GENERIC_METACLASS_LISTS for C++ Builder which causes us to use TClassList for all class types. *) {$if defined(BCB)} {$define NO_GENERIC_METACLASS_LISTS} {$ifend} (* Symbol: GENERIC_POINTERS ------------------------------- Typed pointers to generic types are supported. Older Delphi versions cannot resolve a pointer to a generic type correctly and therefore must use plan untyped pointers instead. Exact Delphi version is unknown but XE4 doesn't work and Delphi 10 does. The symbol is defined for XE5 and later, and for FPC. The exact version of Delphi that supports the feature is unknown at this time. *) {$if defined(FPC)} {$define GENERIC_POINTERS} {$elseif (CompilerVersion > 25.0)} {$define GENERIC_POINTERS} {$ifend}
-
Sure, I use them myself. But not for code and declarations.
-
Include files works just the same in Delphi as they did in TP. It's just that we don't use them as you describe anymore. Not because it isn't possible but because there are better ways of doing things now. Memory size? Do you think an application uses more memory because it uses units instead of include files? Well, it doesn't. And, if anything, using units will generally produce smaller exe files compared to include files. You really should read the documentation I linked to - and more. So far most of what you have written are caused by not understanding the basics of Delphi.
-
Yes, that's what you would use units for if you programmed in Delphi - but of course you can pretend that it's still 1985 and continue using include files, if you prefer that.
-
The functionality you describe is provided by units in Delphi. Please read: https://docwiki.embarcadero.com/RADStudio/Sydney/en/Programs_and_Units_(Delphi) While Delphi does support include files (.INC) you generally only use them for declaring symbols or constant values used as feature switches or, in rare cases, for cross platform support.
-
Component installation and paths
Anders Melander replied to Dmitry Onoshko's topic in Delphi IDE and APIs
There isn't. You can do one of either: Add the path of the component source to the global library search path: Tools->Options->Language->Delphi->Library path Add the path of the component source to the project library search path: Project->Options->Building->Delphi compiler->Search path In general I would recommend #2 and, if possible, try to keep the path relative to the project. -
TBitmap.AlphaFormat is broken beyond repair - literally. See: https://quality.embarcadero.com/browse/RSP-26621 If you need to handle 32-bit RGBA bitmaps, use something that was designed for it.
-
...depending on your definition of "soon" 🙂
-
A Conditional Ternary Operator for the Delphi
Anders Melander replied to EugeneK's topic in RTL and Delphi Object Pascal
FPC seems to have accepted (or rather resigned to) the Delphi syntax: https://gitlab.com/freepascal.org/fpc/source/-/merge_requests/1037 ...which is a present surprise, given their usual attitude towards all things Delphi (see the inline vars discussions, for example). -
A Conditional Ternary Operator for the Delphi
Anders Melander replied to EugeneK's topic in RTL and Delphi Object Pascal
Perhaps, but I seriously doubt that it's a representative metric with regard to the needs of the current Delphi users. In all of the Delphi shops that I've ever worked in, I think I was the only one who ever posted something there and even I gave up on that in the end. -
A Conditional Ternary Operator for the Delphi
Anders Melander replied to EugeneK's topic in RTL and Delphi Object Pascal
Yeah, right 🤦♂️ More syntactic sugar, the compiler codegen is still a joke, and we still haven't got SIMD intrinsics. The only time I've ever wished for a ternary operator was when porting C code and being in a rush. But I wouldn't mind all this fluff (since I don't have to use it) - if they would also throw an occasional bone to those of us that need low level performance. Yes, but you don't have to use it. -
if Obj <> nil then Obj.Free
Anders Melander replied to EugeneK's topic in ICS - Internet Component Suite
Delphi 1 ; procedure TObject.Free ObjectFree: MOV BX,SP LES DI,SS:[BX+4] MOV AX,ES OR AX,DI JE @@1 MOV AL,1 PUSH AX PUSH ES PUSH DI LES DI,ES:[DI] CALL ES:[DI].vtDestroy @@1: RETF 4 Delphi 2 procedure TObject.Free; asm TEST EAX,EAX JE @@exit MOV ECX,[EAX] MOV DL,1 CALL dword ptr [ECX].vtDestroy @@exit: end; -
Are TInterlocked.Exchange and CompareExchange implementation really Atomic with class types??
Anders Melander replied to @AT's topic in RTL and Delphi Object Pascal
Again: There is no type conversion. A hard type-cast is not a type conversion. It's just telling the compiler to treat a variable as a specific type even though it actually is another type. The compiler allows this because the types are of the same binary size.