The main problem is that InstallPopup doesn't cause your code to wait: it just installs and displays a modal dialog box. Normally, when a modal dialog box is active, you can't operate controls on any other panel. However, in your program, you install the popup while you're still operating a control on panel1. In that case, the popup panel doesn't take charge until you release the Number Control on panel1. If you continue to operate Number Control on panel1, you generate another EVENT_VAL_CHANGED. The popup panel is already installed, but, because InstallPopup doesn't cause your code to wait, you try to install the popup again. You can only have one instance of a popup installed at a time. (You can have more than one popup installed, but you can't install the same popup twice without first removing it).
The simple solution is to use GetUserEvent() to force your code to wait after you call InstallPopup. Look at the help in the function panel for GetUserEvent and try the following.
int nWaited4Control;
int nWaited4Panel;
int nWaited4Event;
SetCtrlVal (panelHandle, PANEL_WARNINGLED, 1);
InstallPopup (panelHandle2);
nWaited4Event = GetUserEvent (1, &nWaited4Panel, &nWaited4Control);
Here's a couple of other thing you may want to think about.
1. You can get into trouble using callbacks on a popup panel. In your simple example with a single popup, a callback is OK, but when you have a popup on a popup, events can be missed. To avoid using a callback on your popup, you can check the event in your code immediately after GetUserEvent, like this.
InstallPopup (panelHandle2);
nWaited4Event = GetUserEvent (1, &nWaited4Panel, &nWaited4Control);
if (nWaited4Event == EVENT_COMMIT && nWaited4Panel == panelHandle2 && nWaited4Control == WARN_OKBUTTON)
RemovePopup(0);
2. You might want to think about using EVENT_COMMIT instead of EVENT_VAL_CHANGED. EVENT_VAL_CHANGED occurs before EVENT_COMMIT. As you grab the knob of Number Control on panel1, and start to turn it, multiple EVENT_VAL_CHANGED's will occur. EVENT_COMMIT only occurs when you let go of the knob. Using EVENT_VAL_CHANGED can make it harder to adjust Number Control back below the limit because the popup panel keps popping up.
3. Do you want to allow the user to set Number Control above the limit? If not, you could use SetCtrlVal to set Number Control to the limit if the user tries to go over the limit. In your popup panel, you could also give the user options to override the limit or to increase the limit to the new setting. But the usability of these options gets back to whether you're using EVENT_VAL_CHANGED or EVENT_COMMIT.