-
Content Count
2297 -
Joined
-
Last visited
-
Days Won
119
Posts posted by Anders Melander
-
-
6 hours ago, Vincent Parrett said:hi color icons were not supported by brcc.
Yes, that's the one.
The Microsoft RC compiler also has some (undocumented) features that enables two-way tooling (e.g. a Resource Editor); It can report on included header files, defined symbols and their values and a few other things.
-
8 hours ago, Remy Lebeau said:Really? About Resource Files, looks pretty formal to me.
Yes. I can see the documentation has definitely improved since I wrote the Resource Editor. File encoding doesn't appear to be mentioned though.
Still the RC compiler supports a lot of undocumented stuff that is only mentioned in the source (which I might or might not have read).
-
Just now, Mark- said:OK, is that a better resource compiler?
It's better maintained and supports more features. The RC format is a proprietary Microsoft format with no formal definition so Microsoft will always be able to support it better.
There are some RC features that are not supported by brcc32 but I can't remember which right now.
brcc32 also has some features that are not supported by the Microsoft compiler, but it would be stupid to use those today. They're from the time when Borland still was contender (i.e. Borland C++ 5 era).
3 minutes ago, Mark- said:It only had the string table as shown above. The file encoding was the issue.
Yes, but if you had included the file then we wouldn't have had to guess.
-
1 hour ago, Mark- said:Regardless of what I put in the RC file I get [on the first line]:
[BRCC32 Error] ResStr.rc(1): Fatal error Expecting resource name or resource type name
Ideas or anyone have a sample RC file that complies without error?
Your file encoding is wrong.
Make sure that it's ANSI or UTF8 without BOM - or even better use the Win SDK RC compiler (set this in the project options).
I've attached one that works.
- 1
-
22 minutes ago, timfrost said:STRINGTABLE BEGIN 1, "Hello" 2, "World" END
Although the RC compiler will accept that, the correct format would be:
STRINGTABLE BEGIN 0 "Hello" 1 "World" END
I.e. no comma between ID and Value.
-
strict
Applies to private and protected scopes.
Works around the fact that private and protected members are visible within the same unit. I.e. it makes the visibility behave like one would expect.- strict private indicates that the members are only visible to the class itself. They are not visible outside the class with no exceptions.
- strict protected indicates that the members are visible to derived classes too.
reintroduce
Used when a class declares a method with the same name as a virtual method in a base class. The only thing it does it to suppress the warning you would otherwise get. Basically you are stating that you are "hiding" a base class virtual method on purpose and not by accident.
class sealed
Prevents inheritance from the class. You will probably only use this if you're creating a class library/framework.
There's no harm not using this if you don't really understand it's purpose.FWIW I would think all this is explained in the help.
-
I have designed and written several systems like that. Some have been for use by the end-user (for those that don't understand SQL or data relationship) and some have been for the internal use of an application (to avoid hard coding queries). My experience is that it never worked like it was supposed to. It might be that my designs was flawed but it's not like I haven't tried everything I could think of.
It is a much more complex problem than what your description suggests. I actually know of a company that was run into the ground trying to solve it (well, there were other factors but this was the one that broke their back).
The last system I implemented consisted of four major components:
- A data dictionary. Contains the meta data: Tables, columns, relationships, etc.
- A graph. Basically a Weighted Undirected Graph using Adjacency List that represents all tables and their relationships.
- A resolver. Given a start and ending node, finds the cheapest path through the graph using Dijkstra's algorithm.
- A query builder. Uses the input criteria (where), the output list (select) and the path through the graph (joins) to generates SQL.
This works great for simple queries, small datasets or simple databases but once you throw a real world, large and complex database at it falls apart for several reasons. Here's just a few of them:
-
It is not enough to find the shortest/cheapest path through the graph.
Given multiple possible paths, the solution should optimally pass through as many of the "where"-tables as possible.
It's not obvious what nodes to chose for the start and end node and the choice will affect the result. -
The criteria often needs to be qualified/scoped or the result will not be what the user expected.
For example if the user asks the car database for "car.name" where "country.name=China" expecting a list of Chinese cars they will not understand that they receive a list of European cars assembled in China because the resolver took an unexpected path through the graph. -
There are many other cases where a choice, that affect the result, has to be made but the user hasn't supplied the information required to do so.
In many situation the desired type of join to use cannot be inferred form the cardinality of a relation.
The users often don't understand cardinality and most often don't even know where they will need to resolve a ambiguity with additional criteria.
The query builder don't know how it should resolve a many-to-many relation or if it should resolve it at all.
My recommendation is that you use a traditional query builder instead and concentrate your efforts on the documentation you mentioned.
- 1
-
2 hours ago, Rollo62 said:wouldn't it be an option to register a custom, "secret" clipboard format
I've already suggested that:
On 1/15/2020 at 10:11 AM, Anders Melander said:It would be easy to use the clipboard with a custom data format, that is only understood by his application
The Windows common controls would not be able to support that format so you'd lose the standard support for copy/paste in all edit controls. There are ways to deal with this but they are not that simple.
-
2 hours ago, Attila Kovacs said:Especially with ctrl-c/ctrl-v. Is that all how clipboard works in your opinion?:)
I don't think anyone has a clue what you are talking about.
- 1
-
16 hours ago, Dany Marmur said:would not https://github.com/DelphiPraxis/The-Drag-and-Drop-Component-Suite-for-Delphi be able to provide some functionality for similar tasks?
It's hard to tell from the "crystal clear" requirements but I don't think so.
I'm guessing that since the OP is asking for clipboard functionality, and have rejected just copying data to and from a string, that he wants the copy/paste features of the standard Windows common controls used in the application to use his own internal clipboard. That isn't possible.
It would be easy to use the clipboard with a custom data format, that is only understood by his application, but the Windows common controls are hardwired to use the standard CF_TEXT data format which is understood by everyone (thus the data can be considered "leaked").
-
52 minutes ago, Attila Kovacs said:I think my description is also crystal clear.
Not really.
-
46 minutes ago, Lars Fosdal said:QP it, perhaps?
Why? It's a programmer error. Not a bug.
-
1 hour ago, Mark Williams said:kill a hung thread
Variations of this question has been asked countless times. Always with the same answer: Don't do it.
Why would you expect a different advice this time?
Move the conversion into a separate process and kill that process instead.
- 2
-
I'm back.
The point of my example was that, provided you use classes, you can generalize the tree structure and the function that traverses the tree. And you can delegate the operation to perform on each node to the caller via the predicate function.
In your example you'd examine the Disabled value of the node and store the node in a list on match. The return value of the predicate specifies if the search should continue or stop. E.g. if you wanted to just test if the tree contains any node that match a certain criteria, the you'd return False on the first match. If Find returns False then you know there was a match.
For each level in the tree you would specialize the generalization for that level to add the necessary data members.
-
If you could drop the records and use classes instead you could do something like this (very incomplete - I'm in a rush):
type TItem = class private type TPredicate = function(AItem: TItem): boolean; private FItems: TList<TItem>; FDisabled: boolean; public function Find(Predicate: TPredicate): boolean; virtual; property Disabled: boolean read FDisabled write FDisabled; end; function TItem.Find(Predicate: TPredicate): boolean; var Child: TItem; begin if (not Predicate(Self)) then Exit(False); for Child in FItems do if (not Child.Find(Predicate)) then Exit(False); Result := True; end; var Item: TItem; Result: TList<TItem>; begin if (Item.Find( function(AItem: TItem): boolean begin if (AItem.Disabled) then Result.Add(AItem); Result := True; end)) then begin ...Result contains list of disabled items... end; end;
-
4 minutes ago, Mike Torrettinni said:this defeats the nested records benefits
You're not nesting records.
TList<T> doesn't contain a list of T. It contains a pointer to a list of T.
-
Why do we need google when we have @David Heffernan?
David, the range and depth of your knowledge never cease to amaze me.
-
3 minutes ago, Clément said:I tried importing some simple TFrames and it was easier to restart those from scratch
That's my experience too.
5 minutes ago, Clément said:the component alignment is perfect
Yup. I'm very satisfied too.
There are some layouts that are hard to get right (layout in columns comes to mind), but generally it has saved me a ton of work.
-
Thanks for the explanation. It seems much more reasonable now.
With regard to validation rules some purists will insist that they belong with the business logic on that tier, and I've seen many examples that implement n-tier that way (post data to the server - get an error message back), but in my experience that result in poor user experience. Much better to validate data as early as possible, on the client, and validate it on the server. If the server can supply the meta data required for the client to build the UI and do validation I see no problem with that.
Just out of curiosity: Have you tried using the DevExpress layout control to handle different font sizes and resolutions? Since I started using it to layout dialogs I've pretty much stopped worrying about what resolution/font/sizes the users are using; The layout control takes care of it.
-
3 hours ago, Uwe Raabe said:First implementing that low priority ticket instead may as well have the opposite effect.
Yes. I'm sure we all experienced that a simple, innocent change ends up leading to much more work later one because we introduced a bug or side effects that we didn't think of.
- 1
-
2 hours ago, dummzeuch said:It's also a question whether the customer is willing to pay for his request to be implemented.
Of course. If the customer can cover the development expenses directly, then that will increase the priority. If the change will benefit other customers, make the product easier to sell or benefit the product in some other way that can also increase the priority and lower the price of the change.
There's still the matter of finite resources to take into account though. Even if the customer pays the expenses up front it still means something else is not getting done.
I used to think I could solve the finite resources problem by implementing stuff in my spare time. Unfortunately that just created another problem as the QA, documentation and marketing departments was completely unable to keep up with the amount of features I could produce that way.
2 hours ago, dummzeuch said:My low priority request might have a much higher priority for the customer
I don't understand. So in the scenario you describe you're not the customer but the developer?
If so, why do you have a request at all?
-
40 minutes ago, Clément said:The server side platform is holding part of the visual definition.
I don't like this part; It sounds like you're polluting your business logic tier with presentation stuff.
Even if you're just using the database and BO tiers for storage of the UI definitions, my guess is that you have created a strong binding between the UI definitions and the presentation tier, so the definitions can only be used by the one presentation tier(s).
I've seen this done several times and it always ends up with half the UI being created the way you describe and the other done the traditional way because of special UI needs that the generic framework can't handle. And then eventually the need arises for a new type of client (e.g. web or mobile) that cannot use the existing UI definitions and slowly the definition framework decays because it turns out that it's faster to just create the whole UI on the client than trying to make the definition framework handle everything for everybody. It's a bit like the write once, run everywhere promise. Sometimes it just faster to write three separate applications than to have one application support three separate platforms.
-
11 minutes ago, Mike Torrettinni said:I can admin I treat low priority changes also based on relationship with the customer.
Sure. Professional relationships, personal preferences and even mood, are just some of the many factors that affect priority. We're humans.
As long as you know why you are making a choice I don't see anything wrong with making it based on "feelings" or intuition. Just don't make all your choices that way 🙂
I regularly make technical decisions based on intuition. I may not be able to rationally explain why I choose one solution over another, except that one "feels" right or the other doesn't "feel" right.
- 1
-
Even trivial changes consume project resources and resources are finite.
Implementing a low priority change takes resources away from higher priority changes and unless there's something wrong with way changes are prioritized I can't really see how one can justify that.
The really hard part is weighing all the different factors when calculating the priority. Giving a ticket priority just because it's old doesn't make much sense. But if the age will cause enough customer dissatisfaction that it ends up having economical consequences then it might make sense. Apart from that I don't think age should be a factor. Each time we go through our ticket list we look at it fresh: At this point in time, what is the most important change for us to focus on.
In my projects it's common for trivial but very low priority changes to be rejected. I think it's better to let the requester know that there's minimal chance their request will ever be granted, given that there will always be more important changes to work on, than to give them false hope.
- 1
This implementation is Thread-safe?
in General Help
Posted
Indeed; Hierarchical lock schemes are notoriously difficult to get right and most people don't even realize that if you have nested locking then you need to have a hierarchy.
... is pretty much a guarantee that one will happen sooner or later.