Abstracting ID on message map based on class hierarchy - oop

I have a hierarchy of classes one base B, several derived D from B.
There is a protected member m_treeID, which is the ID of each tree inside.
I want at the base class to fill the message map like
ON_NOTIFY(NM_CLICK, m_treeID, OnNMClickTree)
instead of going for each D to do
ON_NOTIFY(NM_CLICK, TREE_A, OnNMClickTree)
ON_NOTIFY(NM_CLICK, TREE_B, OnNMClickTree)
... and so on.
Is it possible?

If I understand you right, have you looked at using ON_NOTIFY_RANGE?
If you need to process the same WM_NOTIFY message for a set of controls, you can use ON_NOTIFY_RANGE rather than ON_NOTIFY. For instance, you may have a set of buttons for which you want to perform the same action for a certain notification message.
When you use ON_NOTIFY_RANGE, you specify a contiguous range of child identifiers for which to handle the notification message by specifying the beginning and ending child identifiers of the range.
ClassWizard does not handle ON_NOTIFY_RANGE; to use it, you need to edit your message map yourself.
It explains how to use it in the article. As long as TREE_A, TREE_B etc. are sequentially numbered then you can have one message handler for all of them.

Related

Is it possible to test if two types are of the same unknown inheritance in VB.net?

Is it possible to dynamically identify the closest common hierarchy or inheritance of two or more unknown typed objects? In other words, I'd like to test if, say, Integer and String have a common hierarchy, without knowing the objects I'm testing are going to be an Integer and String due to user selection. I found a C++ question posted that seems similar to my issue here: Check if two types are of the same template
However, I'm not familiar with any VB.net equivalents of the answers posted there, and online translators simply provide an error when I attempt to translate them. So is this even possible in VB.net in the first place?
The closest to this action that I know of is the .IsAssignableFrom() function, but in my case I don't know what the parent class/interface/whatever is to test against in the first place. the above function is the only thing even remotely related to this issue that pops up on any search I do.
The context I need this is in the Revit API; I'm trying to see if user selected elements have a similar hierarchy/inheritance that is not the Object Type, and if so to allow an action, otherwise, give a warning dialog box.
EDIT: Due to the nature of the Revit API and the desired effects of my command, the users of my plugin could select anything in the model, and I'm not able to determine which of the MANY common ancestors I could be looking for to compare using IsAssignableFrom. I could test for the (I think universal) common ancestor of Element type, but I don't want to allow users to run the command if you select a wall and an element tag. I need to find the common ancestors of the user-selected elements and confirm that the closest common ancestor is below Element type in hierarchy.
For example, the room tag element in the API has a hierarchy sort of like this:
Object -> Element -> SpatialElementTag -> RoomTag
There may be more intermediate inheritances, but I'm not going to track them down in the API documentation. And then each element may have a slightly different ancestry. IsAssignableFrom would be great if I knew the base ancestry I wanted to test for.
TnTinMn's answer gives me the type of solution I'm looking for.
The Type.BaseType Property returns:
The Type from which the current Type directly inherits, or null if the current Type represents the Object class or an interface.
Using this information, it is possible to define an iterator to enumerate the inheritance tree.
Private Iterator Function SelfAndAncestors(srcType As Type) As IEnumerable(Of Type)
Do Until srcType Is Nothing
Yield srcType
srcType = srcType.BaseType
Loop
End Function
Now you can use the Enumerable.Intersect Method to find all common types in the inheritance between two ancestry enumerations and return the first common ancestry type.
Dim t1 As Type = GetType(Form)
Dim t2 As Type = GetType(UserControl)
Dim highestCommonAncestor As Type = Enumerable.Intersect(SelfAndAncestors(t1), SelfAndAncestors(t2)).First()
For this case, the highest common ancestor is ContainerControl.

How to get order of intersection points that create and remove after moving an object in arrangement?

I want to get the sequence of events or intersection points that created and removed in the arrangement after moving a circular object form one position to another and I don't know how to do this using CGAL lib.
Use, what we refer to as, observers; see the example program examples/Arrangement_on_surface_2/observer.cpp and the doc. at https://doc.cgal.org/latest/Arrangement_on_surface_2/classCGAL_1_1Arr__observer.html
In particular, populate the following observer member functions
after_create_vertex (Vertex_handle v)
after_remove_vertex ()

RavenDb GenerateDocumentKey

I need to generate Id for child object of my document. What is the current syntax for generating document key?
session.Advanced.Conventions.GenerateDocumentKey(document) is not there anymore. I've found _documentSession.Advanced.DocumentStore.Conventions.GenerateDocumentKey method but its' signature is weird: I am okay with default key generation algorithm I just want to pass an object and receive an Id.
The default implementation of GenerateDocumentKey is to get the "dynamic tag name" for the class, and append a slash. For example, class Foo would turn into Foos/ which then goes through the HiLoKeyGenerator so that ids can be assigned on the client-side without having to consult the server each time.
If you really want this behavior, you could try to use the HiLoKeyGenerator on your own, but have you considered something simpler? I don't know what your model is, but if the child thing is fully owned by the containing document (which it should be, to be in the same document) have you have several much easier options:
Just use the index within the collection
Keep a int NextChildThingId property on the document and increment that every time you add a ChildThing
Just use a Guid, although those are no fun to read, type, look at, compare, or speak to someone over the phone.

ABAP Objects - access message class of a class?

In the header information of an ABAP Objects class, I can enter a message class to use with the MESSAGE statement. This works like the MESSAGE-ID statement of a report or a function pool. Since I can't find the message class I entered in the header data anywhere in the generated sections, I assume that it's generated into the top-level CLASS-POOL statement somewhere.
For some libraries (for examples, the BAL application logging), it's necessary to specify the message class using a variable or a method parameter. Up to now, I've defined a constant that specified the message class and used that constant. I'm wondering if it's possible to access the message class specified in the header data in some other way so that I can get rid of that redundant variable.
Has anyone found a way to do so?
EDIT: The new way should be easier than the old one - I'm not crazy enough to add a CLASS-CONSTRUCTOR and perform some database access or SEO_* function calls just to get rid of that constant.
I think you need a CLASS-CONSTRUCTOR to set a class attribute with the message class.
The MESSAGE statement with INTO clause has the side effect of setting the SY- system variables. So you could put into your CLASS-CONSTRUCTOR something like:
DATA: lf_dummy TYPE string.
MESSAGE s999 INTO lf_dummy.
af_msgid = sy-msgid.
You could use the class builder API:
data the_class type ref to cl_oo_class.
create object the_class
exporting
clsname = `ZCL_SOMECLASS`.
data message_class type arbgb.
message_class = the_class->class-msg_id.
I haven't come across any syntax to do what you ask. For the reasons I outline below, I could believe that SAP never saw a need to include such functionality.
In my experience, the message class is an attribute of the message, not of the object that raises it, so it should be kept together with the type, number, and variables of the message. For example if my object is returning the number of an error, it should be returning the id (class) as well.
In this light I cannot see a reason why you would ever need to know the message-class assigned to an ABAP-OO class, you would only ever need to know the message-class of the messages returned by the ABAP-OO class.
The way I usually manage this is to raise my messages into a dummy field, and then use a subroutine to populate the contents of the sy-msg* fields into a BAPIRETURN structure. Then I return this BAPIRETURN structure to the caller. This way the type, id, number, and variables of the message are all kept together.

what is the best design pattern for this problem?

I have a class that has several properties. Some properties can be changed by other classes but some properties are dependent on other properties. For example assume that my class has three properties: A, B and C. A and B can be changed by other classes in system and C is equal to A + B. The class generate property change notification So I want when A or B changed, a notification generate for both the changed property (A or B) and a notification is generated for C too.
I have three options (any other?)
1- Create a normal C property (with backing field) and add code in setter of A and B to change C.
2- Create a normal C property and listen to property change notification of my class inside of my class and change C when A or B changes.
3- Create a calculating property for C no setter but getter is A+B, in setter of A (and B), I fire property change for both A (or B) and C.
Which one is a better design pattern (in C#)? I personally like design number 2.
Sounds like an Observer pattern might be useful here. See for example http://www.oodesign.com/observer-pattern.html. Although a search for Observer pattern will yield many results and other examples, some much simpler, and language specific.
I would probably go with a variation on 2 and 3.
You could have a calculated property (getter only) for C so that the C = A + B calculation is only in one place.
Then, as per your option 2, you could listen to property changed events within the same class... but instead of updating C when you detect a PropertyChanged event for A and B, you only need to raise a PropertyChanged event for C at that time.
2 is the purest since it keeps A,B and C separate, but it does involve a bit of overhead qith the string parsing in the property notification.
If it was a simple set of properties I'd be tempted with 1, since they are still reasonably separate but the update is much simpler. 3 is the worst IMO, since A+B are replicating code which should be separate anyway (C notifications).
The problem here is that you are trying to mix the way that things should be done with the way Microsoft forces you to do things... :)
But my rantings aside it think that option 3 sounds cleanest. Certainly not 1, that is the worst by far, and I think that subscribing to your own property change events could lead to some funky problems that would be hard to debug when some poor sap tries to maintain the code in the future...
If you think about it at a high level, what you are suggesting in 3 perfectly describes what is happening in the class:
Any time that property A is changed observers of the class should be notified that property C has also changed (because it has).