-
Content Count
2771 -
Joined
-
Last visited
-
Days Won
147
Everything posted by Anders Melander
-
How to creating an image preview in the background?
Anders Melander replied to Steve Maughan's topic in Algorithms, Data Structures and Class Design
That doesn't really address the problem. -
Difference between Pred and -1
Anders Melander replied to John Kouraklis's topic in RTL and Delphi Object Pascal
It depends. Sometimes indexed access is faster. -
How to creating an image preview in the background?
Anders Melander replied to Steve Maughan's topic in Algorithms, Data Structures and Class Design
You could just create a new task and ignore the old one (including its output). If the rendering can't be interrupted then there isn't much else you can do. The actual implementation is trivial and will depend on the surrounding code so there's not much point in giving examples. -
Looking for a grid that adds columns as it's widened
Anders Melander replied to Tom F's topic in VCL
The standard windows List-View control, wrapped by the Delphi TListView component does this. The Tile View style is probably what fits your requirements best but unfortunately that isn't directly supported by TListView. Google Delphi LV_VIEW_TILE to find solutions around that. -
Difference between Pred and -1
Anders Melander replied to John Kouraklis's topic in RTL and Delphi Object Pascal
I notice you didn't answer the question, but no; It makes the code harder to read as you have to think about what Pred does. With "Count-1" there's no doubt. Don't use a feature just because it's new or you've just discovered it. -
Difference between Pred and -1
Anders Melander replied to John Kouraklis's topic in RTL and Delphi Object Pascal
Why is that "cool"? -
Welcome to software development. You may find that things become easier (or even clear) for you if you: Read the help. Learn about classes and inheritance. Specifically the VCL class hierarchy is important. Examine the VCL source code. See what others do. See what works and what doesn't and learn from your experience.. Good luck.
-
It sounds like you really just need protection against casual discovery of the information. In that case just obfuscate it. E.g. with a simple ROT13 or even base64 encode. If someone already has access to the physical machine, and is willing to do the work required, the battle is lost any way. There are a million ways to circumvent any local encryption scheme so forget about that.
-
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. -
Responsive UI with heavy background threads running in idle priority
Anders Melander replied to Yaron's topic in General Help
Did you really mean logical core? That would completely defeat the purpose of logical cores. Anyhow, TThread.Create calls BeginThread which calls the CreateThread API function. Nothing special there. The system scheduler will in the majority of cases take care of running the thread on the most suitable core. LOL I doubt it. That would require a call to SetThreadAffinityMask or SetProcessAffinityMask. -
Sounds like docking is the better choice then.
-
Anyhoo, to actually address then issue, if the OP wants to maintain MDI and support High-DPI then I would recommend having a look at DevExpress' Tabbed MDI: https://community.devexpress.com/blogs/thinking/archive/2010/08/16/vcl-tabbed-mdi-multiple-document-interface.aspx Another alternative is to use docking. Just don't use the VCL docking. It sucks.
-
Yes I know about all the different opinions against MDI and while I agree with some of them that's not the topic of this thread. Also I think quoting Joel went out of vogue some 15 years ago
-
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.
-
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.
-
"is said to" = rumor The SO thread is just a lot of different opinions on MDI. Like this thread will probably become. 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.
-
Exception.CreateFmt vs. CreateResFmt
Anders Melander replied to dummzeuch's topic in RTL and Delphi Object Pascal
Yes. I've only used this on 32-bit and I don't know if the structures are the same for 64-bit. -
Exception.CreateFmt vs. CreateResFmt
Anders Melander replied to dummzeuch's topic in RTL and Delphi Object Pascal
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. -
Exception.CreateFmt vs. CreateResFmt
Anders Melander replied to dummzeuch's topic in RTL and Delphi Object Pascal
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. -
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.
-
Why is ShowMesssage blocking all visible forms?
Anders Melander replied to Mike Torrettinni's topic in VCL
Sounds like an example of doing something just because you can. -
Why is ShowMesssage blocking all visible forms?
Anders Melander replied to Mike Torrettinni's topic in VCL
Um... Because it's a modal dialog. If it didn't block it wouldn't be modal. -
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.
-
Generics and Classes on Windows 2000 = OOM
Anders Melander replied to aehimself's topic in General Help
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. -
Generics and Classes on Windows 2000 = OOM
Anders Melander replied to aehimself's topic in General Help
That makes good sense, but why limit virtual memory? Doesn't the devices have hard disks?