-
Content Count
2771 -
Joined
-
Last visited
-
Days Won
147
Everything posted by Anders Melander
-
ways to organize related code in a form?
Anders Melander replied to David Schwartz's topic in General Help
Rubber Ducking: Monologuing a description of a problem to someone (or something) in order to get a better understanding of it. -
ways to organize related code in a form?
Anders Melander replied to David Schwartz's topic in General Help
Okay, but that didn't really explain anything. Are you just rubber ducking? -
ways to organize related code in a form?
Anders Melander replied to David Schwartz's topic in General Help
So your asking for input on how to organize your big ball of mud while keeping it a big ball of mud? Okay, I've got some of those myself. I don't know why you need to ask for help on this as you seem competent enough to figure this out for yourself by trial and error, but here goes; Generally I organize the functions of a unit as: Global functions. Unit wide (interface section) utility functions. Class constructors/destructor. Class utilities. Class methods ordered by context/task. Disclaimer: Not completely sober -
I'm amazed that people are able to offer architectural and implementation suggestions for "How create a website". Your physic powers must be excellent.
-
DPM Package Manager - presentation
Anders Melander replied to Vincent Parrett's topic in Delphi Third-Party
I think it's pointless trying to comer up with a "cool" abbreviation. Just pick a name that has some good derivative or related words that can be used for the "bundles" and such. "DOPE" fit's that criteria nicely -
Yes. I usually use a simple factory pattern. It briefly goes like this (view = frame): Create a "view registry" class. This class wraps a dictionaly that maps between a view interface and a class type. Move all your stuff into frames. For each frame assign them an interface and register the interface and the view class in the view registry. Create a "view manager" class. This class wraps a TDictionary<TGUID, TView> that contains the currently active view instances and is also responsible for creating new views. So something like: View (i.e. frame) abstract base class and API: unit Foo.Views.API; interface type IView = interface ['{4057A1F4-F22C-4CCF-89DE-9F4AE2E790DE}'] procedure Initialize; end; type // Abstract base class of your views. TView = class abstract(TFrame, IView) protected // IView procedure Initialize; virtual; end; TViewClass = class of TView; type IViewRegistry = interface ['{B4EC0F81-24DF-41D9-BF8A-CE0D9958C9A9}'] procedure RegisterView(const GUID: TGUID; ViewClass: TViewClass); procedure UnregisterView(const GUID: TGUID); function FindView(const GUID: TGUID): TViewClass; end; type IViewManager = interface ['{B4EC0F81-24DF-41D9-BF8A-CE0D9958C9A9}'] function OpenView(const GUID: TGUID): IView; procedure CloseView(const GUID: TGUID); function FindView(const GUID: TGUID): IView; end; implementation ... end. The API of a single view: unit Foo.Views.MyView.API; interface type IMyView = interface ['{063646E3-FB0D-4B8C-984A-A5E54F543651}'] procedure FooBar; end; implementation end. The implementation of a single view: unit Foo.Views.MyView; interface uses Foo.Views.API, Foo.Views.MyView.API; type // Trick to get the IDE to behave without registering the frame in a package TFrame = TView; TMyView = class(TFrame, IMyView) protected // IView procedure Initialize; override; // IMyView procedure FooBar; end; implementation ... intialization // Register our implementation of the IMyView interface ViewRegistry.RegisterView(IMyView, TMyView); end; and then you "just" have to Implement IViewRegistry and IViewManager unit Foo.Views.Manager; interface uses Foo.Views.API; function ViewRegistry: IViewRegistry; function ViewManager: IViewManager; implementation type TViewRegistry = class(TInterfacedObject, IViewRegistry) private FRegistry: TDictionary<TGUID, TViewClass>; protected // IViewRegistry procedure RegisterView(const GUID: TGUID; ViewClass: TViewClass); procedure UnregisterView(const GUID: TGUID); function FindView(const GUID: TGUID): TViewClass; end; var FViewRegistry: TViewRegistry; function ViewRegistry: IViewRegistry; begin if (FViewRegistry = nil) then FViewRegistry := TViewRegistry.Create Result := FViewRegistry; end; procedure TViewRegistry.RegisterView(const GUID: TGUID; ViewClass: TViewClass); begin FRegistry.Add(GUID, ViewClass); end; procedure TViewRegistry.UnregisterView(const GUID: TGUID); begin FRegistry.Remove(GUID, ViewClass); end; function TViewRegistry.FindView(const GUID: TGUID): TViewClass; begin if (not FRegistry.TryGetValue(GUID, Result)) then Result := nil; end; type TViewManager = class(TInterfacedObject, IViewManager) private FViews: TDictionary<TGUID, IView>; protected // IViewManager function OpenView(const GUID: TGUID): IView; procedure CloseView(const GUID: TGUID); function FindView(const GUID: TGUID): IView; end; function TViewManager.OpenView(const GUID: TGUID): IView; begin if (FViews.TryGetValue(GUID, Result) then Exit; var ViewClass := ViewRegistry.FindView(GUID); if (ViewClass = nil) then Boom! Result := ViewClass.Create; FViews.Add(Result); Result.Initialize; end; ...etc. etc... end.
-
Manage overloaded IfThen functions
Anders Melander replied to Mike Torrettinni's topic in General Help
Nice! Didn't know that one. -
Because 7 bits ought to be enough for everything https://en.wikipedia.org/wiki/Digraphs_and_trigraphs#Pascal
-
Micro optimization - effect of defined and not used local variables
Anders Melander replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
You'll get no complaint from me on that. -
Micro optimization - effect of defined and not used local variables
Anders Melander replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Agree. It's a balance, as I'm sure Embarcadero knows and takes into account. Like all evolution, too much change leads to extinction. Too much stability leads to stagnation and obsolescence. -
Micro optimization - effect of defined and not used local variables
Anders Melander replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Easy to say when you have already enjoyed the benefit of that backward compatibility. -
Micro optimization - effect of defined and not used local variables
Anders Melander replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
I'm not sure what it is you disagree with. Optimizing code when there is no need to optimize it is by definition premature optimization. The tool might be able to spot where code can be optimized but it will not be able to spot where that optimization is relevant. For the vast majority of the code I write I make an effort to make the code as readable and verbose as possible, at the cost of performance, because the possible gain of optimization is simply irrelevant. However when I know the code I'm writing is performance critical then I pay attention to what the compiler will do, alignment, loops, implicit finalization, etc., but that's the exception. Of course there are patterns that I have leaned to use regardless of the code being performance sensitive or not (e.g. pass managed types by const). In the cases where I get it wrong, or circumstances changes, then a profiler will tell me exactly where to focus my efforts and, as I said, then it's trivial to correct. I'm not against tools that can spot generic problems but a tool that identifies all cases of function returning managed type, passed as parameter, would be worthless to me. There are better ways of solving that "problem". -
Without knowing anything about your architecture I would say that you need to move the content of each of the tabs into individual frames and then create and destroy these frames on-demand.
-
I don't know but I think in this case it has more to do with limiting the deployment size than with limiting the consumed address space.
-
ANN: Better Translation Manager released
Anders Melander replied to Anders Melander's topic in Delphi Third-Party
I think you'll have to debug a bit then. Set a breakpoint on the call to TextToShortcut and trace into it to see what's going wrong. -
ANN: Better Translation Manager released
Anders Melander replied to Anders Melander's topic in Delphi Third-Party
Thanks. That must be the abbreviation of "Steuerung" I guess. Makes sense. The translated RTL resource strings are also available in the ITE translation memory and that is installed regardless of Delphi's language. -
Manage overloaded IfThen functions
Anders Melander replied to Mike Torrettinni's topic in General Help
I think I'll put that on a t-shirt: "Hope - Helping Delphi survive since 1996" -
ANN: Better Translation Manager released
Anders Melander replied to Anders Melander's topic in Delphi Third-Party
You need to translate the sShortcutCopy text in BTM to German and the translated text should use the German key names. I don't know what those are. The key shortcut names are defined in Vcl.Consts: SmkcBkSp = 'BkSp'; SmkcTab = 'Tab'; SmkcEsc = 'Esc'; SmkcEnter = 'Enter'; SmkcSpace = 'Space'; SmkcPgUp = 'PgUp'; SmkcPgDn = 'PgDn'; SmkcEnd = 'End'; SmkcHome = 'Home'; SmkcLeft = 'Left'; SmkcUp = 'Up'; SmkcRight = 'Right'; SmkcDown = 'Down'; SmkcIns = 'Ins'; SmkcDel = 'Del'; SmkcShift = 'Shift+'; SmkcCtrl = 'Ctrl+'; SmkcAlt = 'Alt+'; I.e. find out what SmkcCtrl is translated to in German. -
ANN: Better Translation Manager released
Anders Melander replied to Anders Melander's topic in Delphi Third-Party
I'm not sure what that is supposed to do (I don't read German that good). If the purpose is to translate the texts returned by TextToShortcut then it is unnecessary since the texts are already resourcestrings. -
ANN: Better Translation Manager released
Anders Melander replied to Anders Melander's topic in Delphi Third-Party
You need to swap the order of FixMenuShortcuts and SwitchSoftwareLanguage... -
Manage overloaded IfThen functions
Anders Melander replied to Mike Torrettinni's topic in General Help
What's the point? The arguments would still be evaluated up front. You need the cooperation of the compiler to avoid that. -
ANN: Better Translation Manager released
Anders Melander replied to Anders Melander's topic in Delphi Third-Party
BTM only translates strings and shortcuts are stored in the DFM as integer values. It's really not good practice to translate the shortcuts anyway. For example the user would expect Copy to be Ctrl+C regardless of the language. Instead you can translate the accelerator keys since these are part of the menu text. E.g. &Copy -> Copy = &Kopieren -> Kopieren If you really want to translate the shortcuts, and have BTM handle translation of them, then I'm afraid you'll have to store them in text format as resourcestrings and then use TextToShortCut to convert the text to a shortcut at run time: resourcestring sShortcutCopy = 'Ctrl+C'; begin MenuCopy.ShortCut := TextToShortCut(sShortcutCopy); end; -
Micro optimization - effect of defined and not used local variables
Anders Melander replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Yes, I understood that. My point is that searching for this pattern, which is a perfectly normal and valid pattern, would be premature optimization. If there is a performance problem in an application then you analyze the application (for example with a profiler) and locate the hot spots. It is then then easy to identify this pattern in those hot spots just by reading the code. You don't need a tool for that. It's like having a tool for identifying loops because loops are slower than no loops. -
"Time limited license"... Thanks, but let's not. Also it seems they've opted to keep the map file info separate from the application. I guess that makes sense on mobile due to the size. Not so much on desktop.
-
Micro optimization - effect of defined and not used local variables
Anders Melander replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
It's not that hard to spot. Why would we need a tool for that?