LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Error when discarding duplicated control with tool tip

Hello all,
I have the problem mentionned here:
http://forums.ni.com/ni/board/message?board.id=180&thread.id=21763

But the last message which appears to be a fix doesn't work for me.
Let's see if I got it right:
- have a UIR control
- set a tooltip on it
- duplicate it
- InstallCtrlCallback(,,NULL,0) on the duplicate
- discard the duplicate

I have the error when I try to update the tooltip text with
SetCtrlToolTipAttribute on the original control.

What is the difference between doing
InstallCtrlCallback(panel, Dup, cb_Func, 0)
and
SetCtrlAttribute(panel, Dup, ATTR_CALLBACK_FUNCTION_POINTER, cb_Func)
besides the ability to pass callback data with the former ?

--
Guillaume Dargaud
http://www.gdargaud.net/


0 Kudos
Message 1 of 11
(4,473 Views)
I'm pretty much stuck on this since there seems to be no way to remove a
tooltip once it's set.

Maybe:
- have a UIR control
- set a tooltip on it and use it...
- temporarily remove its callback function so you can
- duplicate it
- put the callback function pointer back in the original ctrl
- use and discard the duplicate, etc...

It seems to work so far, but anyone cares to comment ?
--
Guillaume Dargaud
http://www.gdargaud.net/


0 Kudos
Message 2 of 11
(4,445 Views)
> It seems to work so far, but anyone cares to comment ?

Well, no it doesn't.

The only workaround so far is to use SetBreakOnProtectionErrors(0) before
SetCtrlToolTipAttribute...
--
Guillaume Dargaud
http://www.gdargaud.net/


0 Kudos
Message 3 of 11
(4,420 Views)

The tooltip tool is distributed in source code in the Programmer Toolbox. Looking at its code, I noted that this function uses not to install a callback on the control, but to chain one to it, in order to prevent a possibly existing control callback. That is to say, you may have better results unchaining the control callback (which is installed via "CtrlToolTip" Type Name and can be unchained with the same text passed to UnchainCtrlCallback).

I hadn't time to test it, though...



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 4 of 11
(4,416 Views)

After digging a while on this problem, I have to correct my previous assertion.

Based on my tests it seems that one possible solution to permit duplicating and discarding of duplicated control is this one:

  • When duplicating a control: find if it has an associated tooltip
  • If it has, save and remove it from the control
  • Duplicate the control
  • Reinstall the tooltip


Duplicated controls can then be removed without errors.

I attach a simple project that shows thi method.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 5 of 11
(4,403 Views)
> - When duplicating a control: find if it has an associated tooltip
> - If it has, save and remove it from the control

Remove it with UnchainCtrlCallback, you mean ?

> - Duplicate the control
> - Reinstall the tooltip

OK, will try that, thanks.
I've never used chained callbacks before, so I'm not familiar with them.
--
Guillaume Dargaud
http://www.gdargaud.net/


0 Kudos
Message 6 of 11
(4,366 Views)

Guillaume Dargaud wrote:
> - When duplicating a control: find if it has an associated tooltip
> - If it has, save and remove it from the control

Remove it with UnchainCtrlCallback, you mean ?




No, remove it by passing an empty string to SetCtrlTooltiAttribute. All the matter is realized in the example I attached to my previous post (it lies a bit mimetized among the signature: I need to change it)



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 7 of 11
(4,360 Views)
> No, remove it by passing an empty string to SetCtrlTooltiAttribute.
> All the matter is realized in the example I attached to my previous post

Hmmm, still not working.
I slightly simplified your example:

static char ttStr[255]="";

void ClearFP(int Panel, int Ctrl) {
void* cbkd=NULL;
GetChainedCallbackData (Panel, Ctrl, "CtrlToolTip", &cbkd);
if (cbkd!=NULL) {
GetCtrlToolTipAttribute (Panel, Ctrl, CTRL_TOOLTIP_ATTR_TEXT, ttStr);
SetCtrlToolTipAttribute (Panel, Ctrl, CTRL_TOOLTIP_ATTR_TEXT, "");
}
}

void ReinstateFP(int Panel, int Ctrl) {
if (strlen(ttStr)>0)
SetCtrlToolTipAttribute (Panel, Ctrl, CTRL_TOOLTIP_ATTR_TEXT, ttStr);
ttStr[0]='\0';
}

....

SetCtrlToolTipAttribute(Pnl, SourceCtrl ...);
ClearFP(Pnl, SourceCtrl);
NewCtrl = DuplicateCtrl(Pnl, SourceCtrl, Pnl, "New", Top, Left);
ReinstateFP(Pnl, SourceCtrl);
SetCtrlToolTipAttribute(Pnl, SourceCtrl ...);
DiscardControl(Pnl, NewCtrl);
SetCtrlToolTipAttribute(Pnl, SourceCtrl ...);
// Error happens here randomly

The "if (cbkd!=NULL) {}" is never entered, so this must not be a good way to
know if a tooltip has been set or not...
--
Guillaume Dargaud
http://www.gdargaud.net/


0 Kudos
Message 8 of 11
(4,355 Views)
Are you getting the error on my project too? Which type of controls are you using in your application? If you happen to use some control which has been customised some way (e.g. some toolslib custom control like the password control or radio group control) this can cause some error. As an example, I modified my project adding the possibility to create and duplicate several control types, among which a password control: if you look at the source code you will see the special provisions I had to take on the custom control to prevent runtime errors.


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 9 of 11
(4,324 Views)
I wrote a test program based on the way my main prog works and your
recommendations... but it doesn't exhibit the problem !
So there's either a DuplicateCtrl() that I forgot to wrap rpoperly or
something else...
Here's the code for what it's worth:

#include <ansi_c.h>
#include "toolbox.h"
#include <userint.h>
#include <cvirte.h>

int Pnl, Source, Timer, Dup;
int SourceCount=0, DupCount=0;

//static int CVICALLBACK (*cb)(int, int, int, void *, int, int); // used to
temporarily store the callback before duplication
static char ttStr[255]="";
static int ttPnl, ttCtrl;

void ClearTooltip(int Panel, int Ctrl) {
void* cbkd=NULL;
GetChainedCallbackData (ttPnl=Panel, ttCtrl=Ctrl, "CtrlToolTip", &cbkd);
if (cbkd!=NULL)
GetCtrlToolTipAttribute (Panel, Ctrl, CTRL_TOOLTIP_ATTR_TEXT, ttStr),
SetCtrlToolTipAttribute (Panel, Ctrl, CTRL_TOOLTIP_ATTR_TEXT, "");
}

void ReinstateTooltip(void) {
if (strlen(ttStr)>0)
SetCtrlToolTipAttribute (ttPnl, ttCtrl, CTRL_TOOLTIP_ATTR_TEXT, ttStr);
ttStr[0]='\0';
}

int CVICALLBACK cb_Timer(int panel, int control, int event,
void *callbackData, int eventData1, int eventData2) {
char Str[80];
switch (event) {
case EVENT_TIMER_TICK:
if (rand()&1) { // Sometimes we change the source label
sprintf(Str, "Source Label %d", ++SourceCount);
SetCtrlToolTipAttribute (Pnl, Source, CTRL_TOOLTIP_ATTR_TEXT, Str);
break;
}
if ((rand()&1) && Dup!=0) { // Sometimes we change the duplicate label
sprintf(Str, "Duplicate Label %d", ++DupCount);
SetCtrlToolTipAttribute (Pnl, Dup, CTRL_TOOLTIP_ATTR_TEXT, Str);
break;
}
if (Dup==0) { // Sometimes we create it
ClearTooltip(Pnl, Source);
Dup=DuplicateCtrl (Pnl, Source, Pnl, "Duplicate", 70, 0);
ReinstateTooltip();
DupCount=0;
} else { // And sometimes we discard it
DiscardCtrl (Pnl, Dup);
Dup=0;
}
break;
}
return 0;
}

int CVICALLBACK cb_Num(int panel, int control, int event,
void *callbackData, int eventData1, int eventData2) {
switch (event) {
case EVENT_COMMIT:break; // Do nothing
}
return 0;
}

int main (int argc, char *argv[]) {
if (InitCVIRTE (0, argv, 0) == 0)
return -1; /* out of memory */

// Base elements of the user interface
Pnl = NewPanel(0, "Tooltip test", 10, 10, 200, 200);
Source = NewCtrl (Pnl, CTRL_NUMERIC_LS, "Source", 20, 0);
Timer = NewCtrl (Pnl, CTRL_TIMER, "Timer", 0, 90);
SetCtrlAttribute (Pnl, Source, ATTR_CALLBACK_FUNCTION_POINTER, cb_Num);
SetCtrlAttribute (Pnl, Timer, ATTR_CALLBACK_FUNCTION_POINTER, cb_Timer);
SetCtrlAttribute (Pnl, Timer, ATTR_INTERVAL, 0.);

SetCtrlToolTipAttribute(Pnl, Source, CTRL_TOOLTIP_ATTR_TEXT, "This is the
source tooltip");

DisplayPanel(Pnl);

return RunUserInterface ();
}


I'll keep looking... C:-(
--
Guillaume Dargaud
http://www.gdargaud.net/


0 Kudos
Message 10 of 11
(4,307 Views)