LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

InstallWinMsgCallback changes the panel's ATTR_CALLBACK_DATA?

Solved!
Go to solution

Why does calling InstallWinMsgCallback change the callback data of my panel?  This does not seem like proper behavior?  Based on the documentation, I don't get the impression that my panel's ATTR_CALLBACK_DATA and the callbackdata pointer passed to InstallWinMsgCallback have to be the same... but they do.

 

This problem can be reproduced easily.  Set the a panel's ATTR_CALLBACK_DATA, call InstallWinMsgCallback with something different and they then look at/try to use what you get back from GetPanelAttribute( ...,ATTR_CALLBACK_DATA ..);

 

 

If this is intended behavior it makes InstallWinMsgCallback quite limited.  We currently have some libraries that add things like StatusBars, Docking, etc to UI and these libraries use InstallWinMsgCallback.  I can't use them in apps that need to use a panel's ATTR_CALLBACK_DATA.

 

(I'm using CVI 9.0.0)


Greg 

0 Kudos
Message 1 of 9
(4,861 Views)

Hey Greg,

 

You've run into an unfortunate consequence of the way that we chain callbacks for the implementation of  InstallWinMsgCallback, as well as other toolbox functions such as ChainPanelCallback.  The solution for your situation is to use the functions SetChainedPanelCallbackData and GetChainedPanelCallbackData.  This will allow you to be able to set and get the callback data associated with both callback routines.

 

Feel free to let me know if you have any further questions about this.

 

NickB

National Instruments 

0 Kudos
Message 2 of 9
(4,849 Views)

Quite unfortunate and should be explicitly indicated in the InstallWinMsgCallback documentation.

 

Using ChainPanelCallback would imply that I know/assume my panel may get 'chained' at some point, but this not the case.   Consider that fact the most applications I develop make heavy use of libraries built to enhance and add functionality to CVI UI controls.   In order to use a panel's ATTR_CALLBACK_DATA, (which I do in almost every application/library I write to eliminate the need for global panel variables (and other things),  I have to know that none of the libraries/helper code, I use calls 'InstallWinMsgCallback'.... or assume they do and work around it.

 

Without knowing how you've Implemented InstallWinMsgCallback, it doesn't seem like a difficult task to leave the panel's callback data alone. It is a poor design that the callback data gets altered by what should a 'hidden' feature to the standard callback implementation.

 

Are there plans to fix/improve this behavior in the CVI 2009? 

 

Greg 

 

 

0 Kudos
Message 3 of 9
(4,845 Views)
Hey Greg - 
 
Let me clarify what I said a little bit.  I ran into a similar issue to yours a couple days ago, and assumed you were running into the same issue without reading your post carefully enough. 
 
If you specify a panel's callback data and then call InstallWinMsgCallback, our implementation ensures that the right callback gets called with the right callback data - meaning your panel callback will receive the data you set with SetPanelAttribute, and the WinMsgCallback will receive the data you passed into the InstallWinMsgCallback function.   This is the intended behavior, and if you are seeing something different than this, we would like to know. 
 
However, because the implementation of InstallWinMsgCallback chains an additional callback to your panel, you will not be able to call GetCtrlAttribute to get your original callback data.  A new link has been inserted into the callback chain, and as such, the original callback data is no longer immediately accessible.  To get the original callback data programmatically, you will need to call GetChainedPanelCallbackData and pass "" as the type name.  You would do the same (SetChainedPanelCallbackData) to set the original callback data.
 
There are no plans to change this implementation for CVI 2009, but when you are making use of these extended libraries, there is no harm in calling Get/SetChainedPanelCallbackData with an empty string for the type name instead of Get/SetPanelAttribute.  I do agree with you that the documentation for some of these toolbox features is lacking, and we will be working to address that in future releases.
 
If you have any further questions, please let me know
 
NickB
National Instruments 
 
0 Kudos
Message 4 of 9
(4,829 Views)

Here is how I run into this problem..

 

In many of my applications I set the Panel ATTR_CALLBACK_DATA to a reference to a structure of "application settings".  In all my CTRL callbacks I call "GetPanelAttribute.. ATTR_CALLBACK_DATA to get this reference.  I often use multiple 'instances" of the same code/objects/(dlls) and this method is an easy way to eliminate all global variables (such as the default-to-global panel handle).  

 

This I can't do after InstallWinMsgCallback is called and I couldn't find any reason in the docs as to why/how my panel callback data was changed.  I consider this a pretty normal thing to do which is why I'm making a case for it to be 'fixed'.  Essentially what this means is that GetPanelAttribute(...ATTR_CALLBACK_DATA..) is completely unreliable in applications that depend on other code/libraries or in which I don't have 100% control over all of the code, since I cannot be certain that the included code doesn't InstallWinMsgCallback.  The only way to reliably get a panel's callback data is with the Get/SetChainedPanelCallbackData


Greg 

0 Kudos
Message 5 of 9
(4,808 Views)

Hey Greg,

 

Thanks for that explanation.  It makes sense, and I can certainly understand how this would be a major headache to you.  Just curious - is there a reason you don't set the control's callback data to be a reference to the same application settings structure?  I assume you are probably using it for something else?

 

As far as you second point is concerned, I definitely agree that the documentation needs work in this area, and I will be getting this pushed through in coming versions.  I'm thankful for you pointing out this deficiency in our documentation.  

 

Finally, if you are using some other code / libraries that you suspect might be chaining callbacks or using functions like InstallWinMsgCallback, I would recommend using Get/SetChainedPanelCallbackData.  There is very little overhead involved in making these calls (It basically loops backwards through the callback chain to find the original callback function and data - so the overhead is proportional to the number of callbacks that have been chained.  From what I can tell, in your case, this should just be one extra loop iteration), and  it is guaranteed to give you the original callback data associated with the panel.

 

NickB

National Instruments 

0 Kudos
Message 6 of 9
(4,803 Views)

Nick, 

 

You are correct in that some cases I am using the Ctrl's callback data for something else and also, I am too lazy to want to have to set the callback data for each of the dozens of controls on some panels. I agree that there are several ways to work around this problem.  I guess my point is that they should not be necessary.  My original question stands as to way this must be so since it doesn't seem like a difficult fix and when fixed would make a more logical and clean solution i.e. ChainCallbacks do their own thing without messing with the default behavior / normal callback functions/data.

 

I have this particular application working fine with the Chained callbacks. (another minor annoyance.. I didn't have a panel callback function to chain.. so had to make an empty one)

Thanks for the help/info. 

 

Greg 

0 Kudos
Message 7 of 9
(4,800 Views)
Solution
Accepted by gvan

Hey Greg,

 

It sounds like you've gotten things working, so I apologize about dragging this out, but I wanted to make sure I understand your mentioned minor annoyance.  You said that you had to create an empty callback function to chain - you should not have to do this.  If you are referring to using the GetChainedPanelCallbackData to get the original callback data, you just need to pass an empty string to the "type name" parameter.  This is another thing that isn't documented very well - and one that I will be specifically working to address.  I most likely muddied the waters by including SetChainedPanelCallbackData in the converstation.  You would only need to use this function if you needed to set new callback data after the call to InstallWinMsgCallback, or a call to one of the other callback chaining functions.  If you ever run into this case (needing to change the original callback data after you fear the callback data may have been altered by a callback chaining function), you would call SetChainedPanelCallbackData with an empty string as the "type name" parameter.

 

I will do my best to answer your question regarding why the behavior is the way it is as well.  The main problem is that the Get/SetPanelAttribute functions are part of our UI library, and the InstallWinMsgCallback / callback chaining functions are part of our toolbox code.  Initially, the toolbox code was developed more as an example of some of the things you could do with CVI, but as it has grown, more and more dependence on it has been established, and the line between example code (that was never necessarily intended to be as robust as our libraries) and library code has been blurred.  

 

This means that the callback chaining functions are in no way integrated with our UI Library code.  In fact, if you open up toolbox.c, you can find all the implementation for these functions.  Basically, what happens is when these functions are called, we get the current callback data and callback function (using GetPanelAttribute), store these items in a list, and then set the new callback function and data with the UI Library SetPanelAttribute function.  When events need to be sent to your panel, we traverse this list, calling each callback with the appropriate data.  This is why your original callback data gets 'blapped', and why you must be careful about using some specific toolbox functions intermingled with the UI Library functions.  (it is this interaction that you have noted is not documented as well as it should be, and what we will be working on addressing)

 

NickB

National Instruments 

Message 8 of 9
(4,794 Views)

Nick,


Passing "" is originally how I understood your explanation, and also works fine.  I got off track there.

 

Thanks for detail on implementation.  I can see how the toolbox has become a bit of a tangle as more functionality is added there.  There are several other posts here and workarounds I've used to avoid some of the other pitfalls with the toolbox.  I'm not used to making the distinction between it and the UI. 


Greg 

0 Kudos
Message 9 of 9
(4,786 Views)