-
Content Count
2297 -
Joined
-
Last visited
-
Days Won
119
Posts posted by Anders Melander
-
-
55 minutes ago, Uwe Raabe said:Don't you think you've gone a bit overboard with the amount of font properties that can be handled?
I mean: Both Size and Height? One is derived from the other.
And in 25 years I don't think I've ever had to customize Quality or Pitch in the GUI...
Charset, AFAIK, isn't needed with unicode.
-
3 hours ago, Sherlock said:MDI is said to be an interface type, Microsoft wants to get rid of.
"is said to" = rumor
The SO thread is just a lot of different opinions on MDI. Like this thread will probably become.
1 hour ago, Lars Fosdal said:MDI has been deprecated for years
Do you have any proof for that claim?
I've seen it many, many times but never with any reliable sources. Also one would think that MS would document that fact, in the relevant API and concept documentation, like they usually do...
I have several MDI applications that runs just fine on Windows 10. They're all based on DevExpress though and I don't know if they have done anything special to handle Win10 but I doubt it.
-
1 hour ago, Vandrovnik said:isn't it better to use sizeof(pointer) instead
Yes.
I've only used this on 32-bit and I don't know if the structures are the same for 64-bit.
-
1 hour ago, Der schöne Günther said:It seems to do some magic to swap out the method for resolving resource strings from System.pas with something else.
That's fairly easy and you don't need to hack the system unit. You just need to patch the LoadStringW import.
For example the following patches FindResourceW and a few others to implement a DFM fallback mechanism that loads from the main module in case the resource module doesn't contain a given DFM resource.
It can easily be modified to patch LoadStringW to load resourcestrings from a dictionary or whatever.
unit amLocalization.FindResourceFallback; interface function EnableResourceLoadingFallback: Boolean; implementation uses Windows; function HookAPI(const Name, Module: string; Hook: pointer): pointer; var ImageBase, Old: Cardinal; PEHeader: PImageNtHeaders; PImport: PImageImportDescriptor; PRVA_Import: LPDWORD; ProcAddress: Pointer; begin Result := nil; ImageBase := GetModuleHandle(NIL); PEHeader := Pointer(Int64(ImageBase) + PImageDosHeader(ImageBase)._lfanew); // pointer to the imports table of the main process: PImport := Pointer(PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + ImageBase); // pointer to the WinAPI function we want to hook: ProcAddress := GetProcAddress(GetModuleHandle(PChar(Module)), PChar(Name)); if ProcAddress = NIL then Exit; while PImport.Name <> 0 do begin PRVA_Import := LPDWORD(pImport.FirstThunk + ImageBase); while PRVA_Import^ <> 0 do begin if PPointer(PRVA_Import)^ = ProcAddress then begin // initially imports table is in read-only segment: if not VirtualProtect(PPointer(PRVA_Import), 4, PAGE_READWRITE, Old) then Exit; Result := PPointer(PRVA_Import)^; // replacing import address with our own: PPointer(PRVA_Import)^ := Hook; // restoring old memory protection mode: if not VirtualProtect(PPointer(PRVA_Import), 4, Old, Old) then begin Result := nil; Exit; end; end; Inc(PRVA_Import); end; Inc(PImport); end; end; type TFindResourceW = function(hModule: HMODULE; lpName, lpType: PWideChar): HRSRC; stdcall; var FindResourceW: TFindResourceW = nil; function HookedFindResourceW(hModule: HMODULE; lpName, lpType: PWideChar): HRSRC; stdcall; begin Result := FindResourceW(hModule, lpName, lpType); if (Result = 0) and (hModule <> hInstance) then Result := FindResourceW(hInstance, lpName, lpType); end; type TLoadResource = function(hModule: HINST; hResInfo: HRSRC): HGLOBAL; stdcall; var LoadResource: TLoadResource = nil; function HookedLoadResource(hModule: HINST; hResInfo: HRSRC): HGLOBAL; stdcall; begin Result := LoadResource(hModule, hResInfo); if (Result = 0) and (hModule <> hInstance) then Result := LoadResource(hInstance, hResInfo); end; type TSizeofResource = function(hModule: HINST; hResInfo: HRSRC): DWORD; stdcall; var SizeofResource: TSizeofResource = nil; function HookedSizeofResource(hModule: HINST; hResInfo: HRSRC): DWORD; stdcall; begin Result := SizeofResource(hModule, hResInfo); if (Result = 0) and (hModule <> hInstance) then Result := SizeofResource(hInstance, hResInfo); end; function EnableResourceLoadingFallback: Boolean; begin FindResourceW := HookAPI('FindResourceW', kernel32, @HookedFindResourceW); Result := Assigned(FindResourceW); if (Result) then begin LoadResource := HookAPI('LoadResource', kernel32, @HookedLoadResource); Result := Assigned(LoadResource); end; if (Result) then begin SizeofResource := HookAPI('SizeofResource', kernel32, @HookedSizeofResource); Result := Assigned(SizeofResource); end; end; initialization EnableResourceLoadingFallback; finalization end.
-
Constant resourcestring references are resolved during initialization by System._InitResStrings.
If you change the application language after that, e.g. by calling LoadResourceModule, then these references will not be updated.
In the example below the first ShowMessage in unaffected by the change of language while the second one isn't.
resourcestring sFoo = 'Foo'; sBar = 'Bar'; const sFooBar: array[boolean] of string = (sFoo, sBar); sBetterFooBar: array[boolean] of PResStringRec = (@sFoo, @sBar); begin LoadResourceModule('foofoo.bar'); ShowMessage(sFooBar[True]); ShowMessage(LoadResString(sBetterFooBar[True])); end;
Apart from that I suspect the RTL/VCL uses PResStringRec for C++ compatibility.
- 1
-
For inspiration DevExpress controls have the standard ParentFont and individual properties to override font color and style (among other things) for Normal, Disabled, Focused and Hot state.
There's also a style controller component so different styles can be configured centrally instead of on the individual controls.
-
3 hours ago, Mike Torrettinni said:Saw and interesting example where the Form was dimmed, but the notification message was not - very noticeable and no modal windows.
Sounds like an example of doing something just because you can.
-
-
Are you asking if there's a way to have the Getter and Setter methods declared automatically from the property declaration in the interface declaration?
E.g. you have:
type
IMyInterface = interface
property Foo: string read GetFoo write SetFoo;
end;
and you want to end up with:
type
IMyInterface = interface
function GetFoo: string;
procedure SetFoo(const Value: string);property Foo: string read GetFoo write SetFoo;
end;
AFAIK there's no standard way to have the getters and setter automatically declared 😞
What I usually do, if there's a lot of them, is to just copy the property declaration to an implementing class, use class completion on that to generate the getters and setters and then copy the declaration of those back to the interface declaration.
-
2 minutes ago, aehimself said:Hard drives as you might think - not necessarily
Okay. Now the use of W2K makes much better sense. Interesting constraints.
Anyway, back to the problem. If you can observe that virtual and physical memory consumption increases during execution, but all resources are released before the process is terminated (thus no leaks detected), then you can force the allocated memory to be reported as leaks by terminating the application prematurely with a call to Halt.
-
8 minutes ago, aehimself said:Yes. Considering built-in devices (robotic arms, controllers, etc.) where you can not upgrade the hardware and/or the software, I like to experiment with the absolute minimum
That makes good sense, but why limit virtual memory? Doesn't the devices have hard disks?
-
12 hours ago, TomDevOps said:Manual memory management is pain and only slows you down.
You should probably rephrase that "and only slows me down".
In my experience laziness always comes at a price. Not bothering to use descriptive identifiers saves a few keystrokes at the price of readability. ARC and GC relieves the developer of having to deal with some of the complexities of resource management, at the price of performance. Etc.
I would honestly rather have good performance and full control of what's going on with the resources.
12 hours ago, TomDevOps said:They should remove that sort of things too.
Yes. Let's break COM support so we can save some keystrokes.
- 6
-
15 hours ago, Kryvich said:I would like to see in some future version of Delphi
How is that relevant to the topic?
-
FWIW, Windows 2000 isn't supported by the version of Delphi you're using.
Also, please read the event log message again. It has all the clues:
- It isn't your application that is experiencing an "out of memory" error.
- It's Windows that is experiencing an "out of virtual memory" error.
- To fix it: Increase the size of the page file.
My guess is that the W2K system has a fixed size page file - or no page file at all. Otherwise it would just increase the size automatically - or maybe that feature was added later. I forget. and who cares anymore.
If you're really interested in why you get a windows error and not an application error, read some books on Windows internals and the virtual memory manager, or just google it.
- 2
-
2 hours ago, dkprojektai said:function ReadFromMemFile(hEngine: TENGINE; pBuffer: Pointer; bufferSize: Integer): TRESULT;
You're not giving us much to work with here.
Do you have any documentation about what kind of data ReadFromMemFile expect the input buffer to hold?
-
3 hours ago, dkprojektai said:pBuffer - Pointer to memory buffer which contain image file data
You didn't really answer @Vandrovnik's question.
For Windows bitmaps the bitmap file image (i.e. bitmap header and pixel data) isn't stored in memory.
When TBitmap loads a bmp file it reads the header information then the pixel data. From this it stores the relevant meta data (width/height, color depth, palette, etc) and pixel data in memory.
Of these you only have direct access to the raw pixel data.
If you need the file bitmap image in memory then you will either have to save the bitmap to a memory stream or construct the image yourself in memory.
btw, when I write "image" I don't mean in the picture/graphic/bitmap sense.
Maybe you should try to explain what problem you are trying to solve.
- 1
-
1 hour ago, David Heffernan said:That memory will be backed by the swap file.
Technically it's the page file.
The terms page file and swap file have their roots in VMS. Both Windows NT and VMS were designed by his holiness, Dave Cutler.
The swap file doesn't exist anymore in Windows (I believe it was there in early versions) but was used when a process working set was completely removed from physical memory. E.g. in low memory situations or if the process went into extended hibernation.
-
Just now, Mike Torrettinni said:Yes, probably I will get to the similar limit even in 64bit code, if customer has 4GB memory.
No.
You still don't understand the difference between physical and virtual memory.
- 1
-
3 minutes ago, Fr0sT.Brutal said:Even virtual memory could be insufficient if an app requests to expand a 1G array
Please google "64-bit"
- 1
-
10 minutes ago, Stefan Glienke said:Unfortunately what was great in 2003 might not be anymore because hardware evolved.
True, but even in 2003 it was a 16-bit leftover from the DOS days.
-
1 hour ago, Mike Torrettinni said:I was thinking for may years that 64bit will solve my memory issues... then I realized that many customers don't have 32GB, some are OK with just 4GB of memory.
Please google "virtual memory".
- 2
-
It supports both XMLDOC (which I agree makes the source unreadable) and external documentation files:
I've been using it to generate library help files (in CHM-format) but it can also display the help as tooltips in the Delphi editor.
- 1
-
1 hour ago, Lars Fosdal said:From my experience, the complexity of dealing with multiple generations of breaking changes has been far more expensive in man-hours than the cost of keeping current.
What breaking changes are those?
At one of my clients we upgraded all projects (many millions LOC) directly from Delphi XE & XE2 (for 64-bit) to Delphi 10.2 with no significant effort. The worst part was the tasks you'll have to do anyway every time you migrate a project from one version of Delphi to another.
If they had kept up to date all the way through, they would have had to pay maintenance on 20+ licenses to get the occasional new feature they didn't really need and they would have had to fix and work around all the new bugs they got as well.
- 1
-
2 hours ago, Uwe Raabe said:You might be forced to reconsider this statement when your customers are more and more using high dpi configurations and criticize the visual quality of your application.
Windows does a better job of making old applications behave well under high DPI than the VCL has so far managed.
I would prefer to have the UI consistently scaled than having some parts support high DPI, some parts scaled and some messed up.
Rio and MDI Applications
in VCL
Posted
Thanks.
It's still a secondary source but I guess that if Embarcadero believes it to be canon then we have to work from that.