Callbacks for arguments in Scilab - user-interface

I'm writing a GUI in Scilab and assigning callbacks to pushbutton controls. When a button is pressed, another control is affected, e.g. text inside a textbox changes. This whole routine itself (creation and initialization of the GUI) lives inside a function, that is I have to call my create_my_gui() to run it.
My problem lies in variable scope and callback usage. Several of my buttons affect several other controls in exactly the same way, so I would like to use the same callback function and pass a handle to the control I'm trying to affect into the callback.
For example when I press the N-th button, I'd like to pass the handle N-th control into the callback:
function buttonPressCallback ( controlHandle )
controlHandle.string = 'Button pressed!';
endfunction
The problem is that callbacks are defined as strings:
myButton3.callback = 'buttonPressCallback ( myTextBox3 )'
And after I've run my create_my_gui() function, all variables go out of scope and are destroyed, including handles to all controls. When I press the button, Scilab tries to run whatever string was specified as the callback and complains about the variable, myTextBox3 for example, not existing.
Is there a way I can refer to uicontrols in Scilab after the function that created them exited? I understand that Scilab has very peculiar ways of addressing things and perhaps I'm just not thinking in correct Scilab programming patters just yet. Is there the "right way" of doing this?

Found a decent solution. Each uicontrol can be tagged by setting myUicontrol.tag = 'my_tag';. This uicontrol can then be found globally using my_handle = findobj('tag','my_tag');.

You can acccess the calling uicontrol object via gcbo, like:
get(gcbo,"value");

Related

What is the equivalent of python's "window.get_property("visible") in GTK+ (C)?

In order to show some window upon a clicking a button in the main window, i have to use "on_delete_event" signal to show or hide the appropriate windows. I know the pygtk "window.get_property("visible")". I searched the documentation there is no such thing as gtk.get
_property all i found was "gtk.mnemonics.get_visible or something like this.
I'm pretty sure somebody has used show and hide stuff in GTK+(C)
The functions you want are g_object_get() and g_object_set(). These apply to all GObjects, not just GtkWidget.
In the case of GtkWidget's "visible" property there is also a gtk_widget_get_visible() function (and a gtk_widget_is_viisble() function that also checks all parents of a GtkWidget) and an equivalent gtk_widget_set_visible().
Remember that GtkWindow is derived from GtkWidget; the former will use the latter's methods and properties where appropriate.

How do I test if my custom callback is set as the current procedure for a given window?

We have a kiosk mode application for Windows Mobile 5 that was going strong for a year at least in production. It uses window subclassing through the SetWindowLong windows API function to override the behavior of the taskbar to prevent users from ever leaving our application or other explicitly allowed applications.
My callback overrides the handling of a few window messages and calls the default handler for other messages. This is done by storing the previous function pointer returned by SetWindowLong, and using it inside of the new function by calling CallWindowProc on it.
Then we had to update the application to be compatible with Windows Mobile 6.5.3, and started having a bunch of problems. I followed this article to disable the bottom menu buttons which are new on 6.5. On a single application, it works fine and the menu respects my callback. As soon as the user opens up another application through ours, that window seems to be recreated, and I had to devise a mechanism to detect foreground window changes and then "resubclass" the window again.
In my code, I don't have control of when exactly this window is recreated, so my first attempt was to use the GetWindowLong function to obtain the current callback address and test it against my own function address. I learned the hard way that I can't just compare the values like that, since it does not always return the function pointer.
Because I'm not able to test if my method is the current handler that way, I end up sometimes setting my method as the handler, and the previous handler is also my own method (in this case, the window was not recreated and thus already had my method set). This results in an infinite loop, since my callback ends up calling itself indefinitely.
How can I know if my custom function is the one being used by a certain window, so that I can avoid this infinite recursion?
Don't use SetWindowLong(GWL_WNDPROC) to subclass a window. Use SetWindowSubClass() instead (like Raymond Chen said):
Subclassing Controls
Safer subclassing
Amongst providing safer subclassing semantics (such as allowing multiple subclasses at a time), it also allows you to associate user-defined data with each subclass. So you could use GetWindowSubclass() to check if you have already subclassed the window or not.
Or, you could simply keep track of whether or not you have already subclassed the window. A simple boolean variable will suffice. Once your subclass is in place, you MUST remove the subclass before the window is fully destroyed. So, for instance, when the subclass receives the WM_NCDESTROY message, you can remove the subclass and clear your boolean at the same time, and then the next time you see the window again your boolean will tell you that you need to subclass the window.
Send the custom message to window. Handle this message in your custom function to return some value that will indicate that it was your custom handler.. and so on.
if(SendMessage(hwnd, mymsg, 0, 0) != myvalue)
;// It's not your handler

Access Windows Controls from another class or window

In an MFC program I am trying to access controls that are in one window (class) from another (sibling or daughter) window with code in a different .cpp file. Typically you access a control with a DDX_Control variable defined in the class .cpp file.
DDX_Control(pDX, IDC_STATUS, m_Status);
The code for the other window is in a different file, so I don’t have access to the control variable (m_Status). What I have done is used FindWindow to find the main window, then GetDlgItem to find the control I am interested in:
CWnd * tmpWnd = CWnd::FindWindow(NULL,"MainWindow"); // find the main dialog box
CStatic * tmpStatus = (CStatic*) tmpWnd->GetDlgItem(IDC_Status);
tmpStatus->SetWindowText(“Status Report);
This works fine in the debugger, but fails when executed outside the debugger. FindWindow gets the window ID correctly, but GetDlgItem returns null.
Ideally I’d like to access the control variable (m_Status) from the other window, but I don’ know how to do so. I understand the GetDlgItem is less than ideal under any circumstance.
One solution would be to send a message to the main window class and tell it what to do, but I’d have to have a routine to handle each control and know how to handle whatever kind of data I am sending.
Is there a “right” way to do this?
Thank you
The ultimate answer is to cast to the original class:
((CspDlg *)AfxGetMainWnd())->m_Status.SetWindowText("Report");
Since you created the "main" window you have an object or pointer for it. Or, you can call AfxGetMainWnd() to get a pointer to it. Then you can use that to access a public member such as m_Status. All of your windows are interconnected and it should not be necessary to use FindWindow to find any window in your own program.
The fact that some variables may be defined in another file is not relevant. That can be handled with suitable use of #include "theotherfile.h" and object pointers/references.

Is there any way to activate the Apply button from a print propery page with PrintDlgEx?

I have custom print property sheets/pages that have been added to the dialog displayed by PrintDlgEx. These property sheets are, of course, used to change additional options. The issue is that there does not appear to be any documented way to activate the Apply button from the property sheet's dialog function, or anywhere for that matter. This seems to be a huge omission on Microsoft's part.
Is there any "official" way to change the Apply button's state? If not, are there any possible workarounds?
Is there any "official" way to change the Apply button's state? If not, are there any possible workarounds?
Not directly, no. You would have to retrieve the button's HWND manually an then manipulate it as needed.
use SetWindowHookEx() to install a local WH_CBT hook for the thread that is calling PrintDlgEx(). The dialog's HWND will be available as a parameter of the callback function when it receives a HCBT_ACTIVATE notification. Then you can locate the Apply button's HWND within the dialog (use Spy++ or similar tool to get details about the button, then have your code use GetDlgItem() or FindWindowEx() to get the button's HWND). Be sure to call UnhookWindowsHookEx() after PrintDlgEx() exits (or at least after you are done using the button HWND).
use SetWinEventHook() to register for EVENT_OBJECT_CREATE, EVENT_OBJECT_SHOW, and/or EVENT_SYSTEM_DIALOGSTART notification(s) for the thread that is calling PrintDlgEx(). The dialog and button HWNDs will be available as a parameter of the callback function. Be sure to call UnhookWinEvent() after PrintDlgEx() exits (or at least after you are done using the button HWND).
Once you have the button's HWND, you can do whatever you want with it. It is a standard button control, so any standard button message/function can be used with it.
A more close to "official" way is to call PropSheet_Changed().
The way I get the property sheet dialog is to look at the source of PSN_ notifications sent to IPrintDialogCallback::HandleMessage(). Or you can use GetParent(GetParent(generalDialog)).
Once you call PropSheet_Changed() the Apply button will activate.
You're right, it seems to be a huge omission on Microsoft's part, as it's not a simple thing to code, but it's something that most people adding property sheets would need.
I can put some code up if anyone needs it.

In MATLAB, how can you have a callback execute while a slider is being dragged?

I have created a MATLAB GUI using GUIDE. I have a slider with a callback function. I have noticed that this callback, which is supposed to execute 'on slider movement', in fact only runs once the slider has been moved and the mouse released.
Is there a way to get a script to run as the slider is being dragged, for live updating of a plot? There would I presume need to be something to stop the script being run too many times.
Even though the callback of the slider isn't being called as the mouse is moved, the 'Value' property of the slider uicontrol is being updated. Therefore, you could create a listener using addlistener that will execute a given callback when the 'Value' property changes. Here's an example:
hSlider = uicontrol('Style', 'slider', 'Callback', #(s, e) disp('hello'));
hListener = addlistener(hSlider, 'Value', 'PostSet', #(s, e) disp('hi'));
As you move the slider you should see 'hi' being printed to the screen (the listener callback), and when you release the mouse you will see 'hello' printed (the uicontrol callback).
Just for the record, this subject is discussed in detail here: http://UndocumentedMatlab.com/blog/continuous-slider-callback/ - several alternative solutions are presented there. gnovice's solution using addlistener is equivalent to the handle.listener alternative, since addlistener is basically just a wrapper for the latter.
If you want to execute the same original callback you passed to uicontrol you can add this generic listener which bootstraps the existing callback:
sld.addlistener('Value','PostSet',#(src,data) data.AffectedObject.Callback(data.AffectedObject,struct('Source',data.AffectedObject,'EventName','Action')));
Related blog post

Resources