LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Why does a DIsplayPanel call work differently for different types of widgets?

I have two widgets on the same panel.  The first widget is an "EDIT_NUMERIC" type.  For this widget, when I call DisplayPanel to popup a panel, the panel is raised to the top when it is displayed.  The second widget is an "EDIT_RING" type.  For this widget, when I make the same DisplayPanel call to popuo the same panel, the panel is not raised to the top and is displayed underneath the panel.  The LoadPanel call is the same no matter which widget is selected and has already occurred.   The parentPanelHandle is 0 in both cases.  The only difference that I can see is that these two widgets use different Events to call the DisplayPanel.  For the EDIT_NUMERIC widget type, I use the EVENT_GOT_FOCUS event and for the EDIT_RING, I use an EVENT_LEFT_CLICKED. 
 
Does anyone know how I can have the DisplayPanel have the panel that is displayed be raised to the top for an EDIT_RING type widget?  I cannot specify different parentPanelHandles because I am using the exact same code for all of my widgets regardless of their type.
 
Thanks,
Donna
0 Kudos
Message 1 of 15
(4,082 Views)
For EVENT_LEFT_CLICK then the event is also sent to the panel callback, not just the control callback.  I don't think the same is true for EVENT_GOT_FOCUS.  Have you tried a call to ProcessDrawEvents() as part of your control callback?
0 Kudos
Message 2 of 15
(4,080 Views)
I am not sure what you mean by "control callback"? 
I thought that the only callback that is called is the one that I specify when creating the widget.  I will try what you have suggested but I am not sure where to put the call to ProcessDrawEvents().
Thanks,
Donna
0 Kudos
Message 3 of 15
(4,083 Views)

The panel the control is on also gets some of the events that a control gets.  I am assuming that when the panel gets the EVENT_LEFT_CLICK it causes the panel to redraw as the active panel. 

ProcessDrawEvents() would be placed right at the end of your control callback.  

 

 
0 Kudos
Message 4 of 15
(4,075 Views)
You may also be able to use SetActivePanel(panel) to make your panel the current active panel (has focus for keyboard/mouse events) when you call display panel. 
0 Kudos
Message 5 of 15
(4,072 Views)

As far as I can imagine, your problems probably lies in how the ring control manages the EVENT_LEFT_CLICK event. In my opinion this event is processed BEFORE the user interface pops up the list of possible choices the ring includes, and this is to permit to the program to discard this event (swallow it) if for some reasons the programmer wants so. What may be happening is this:

1, The user clicks on the ring: a LEFT_CLICK events is fired and the callback is executed
2. In the callback the new panel is loaded and displayed. The event is not swallowed
3. The list of choices of the ring is showed in the panel that holds the ring: this implicitly sets this panel as the topmost one, thus hiding the second panel loaded

Since it is the normal behaviour that a ring shows the list of choices when clicked on, you will need to find a different moment for displaying the second panel.



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 6 of 15
(4,059 Views)

Roberto,

  Thanks for your response and for your explanation.  I actually cannot find a different moment for displaying the second panel because I am password protecting my widget.  So before a user can select a value from the edit ring, they need to enter in a password. 

I tried the suggestions of adding in a SetActivePanel and a ProcessDrawEvents call before the DisplayPanel call.  Now the panel shows up on top for a split second, then moves to the back.

I may have to change the type of widget but I sure hate to because I have screen shots made in a User's manual and it is a lot of work.

Thanks,

Donna

0 Kudos
Message 7 of 15
(4,051 Views)
Maybe you could setup your widgets as indicators and provide a separate button for password request: after a satisfactory password is entered you can set your control as hot and process their update, could you?
 
Or you can arrange a more complicated structure as follows:
1. The user clicks on the ring: EVENT_LEFT_CLICK is fired
2. Inside the ring callback process the event swallowing it (return 1) and launching the password panel
3. When entered a password, fire again the ring callback with EVENT_LEFT_CLICK passing a value in CallbackData to skip processing step 2
 
I cannot test here but more or less your control callback should like this:
 
int CVICALLBACK theRingCallback int panel, int event, void *callbackData,
  int eventData1, int eventData2)
{
   switch (event) {
      case EVENT_LEFT_CLICK:
         if (!callbackData) {
            PostDeferredCall (thePwdRequestCallback, NULL);    // Call a separate function for displaying the second panel
            return 1;             // Swallow mouse event
         }
         break;
   }
   return 0;
}
 
The deferred function will have this structure
 
void CVICALLBACK thePwdRequestCallback (void *callbackData)
{
   // Load and display the panel
   if (passwordOk) theRingCallback (panelHandle, PANEL_RING, EVENT_LEFT_CLICK, (void *1), 0, 0);
 
   return;
}
 
It may need some trimming but it should work.
Roberto


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 8 of 15
(4,045 Views)
Donna,
please forget about my last post and its complicated solution: it simply cannot work since there is no way to show the list of choices of the ring after password request neither directly calling its callback nor queuing a message to the control.
Instead, I found that the simplest solution at all is to handle the password request directly inside the EVENT_LEFT_CLICK callback, as in the sample I am attaching: tha "Cancel" button swallows mouse event so that the control does not show the popup list.
 
BTW, I don't know why you are not processing the LEFT_CLICK event on the numeric too, but please note that in this case if you want to add a "Cancel" functionality to your password request you will need to restore the focus on the prevoius control (received by the callback in eventData1 parameter), otherwise the focus remains on the numeric itself and the operator is permitted to change it withount any further control, since the GOT_FOCUS event is not fired any more. Again, take a look at the sample attached.
 
Roberto

Message Edited by Roberto Bozzolo on 02-14-2006 09:15 AM



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 15
(4,040 Views)
Roberto,

Actually, there is a fairly simple way of programmatically displaying the choices of a ring. You can do so using the following code:

    SetActiveCtrl (panelHandle, PANEL_RING);
    FakeKeystroke (' ');

That should result in the ring's menu being displayed.

I ran your example and it also works pretty well, but it's not always a good idea to do a lot of involved work (such as displaying other panels, etc) in very low level events, such as as mouse clicks and keypresses, depending on what the rest of the UI is doing. It's probably best to just swallow the left-click event right away, and later on to fake the left click using the code above.

Luis
Message 10 of 15
(4,023 Views)