In Windows programming it is often necessary to respond to events, events like the pressing of a button, the creation of a window, resizing of a window, etc. There are many types of events to which can be responded. With callbacks it is possible to respond to a specific event from a specific instance, for instance it is possible to respond to the clicking of a certain button. A callback is a sort of a connection between an event of a window and a method of a destination object.
The predicate add_callback/4 is used to create a callback. For more information about callbacks see callbacks.
The files of this example are located in the folder 'examples\hello\', the file 'hello.txt' contains the code necessary for loading the 'object.txt' and 'win.txt' modules and loading the file 'hello1.txt'. To execute the example load the file 'hello.txt' and enter 'start' as a goal.
To create a more object-oriented application it is possible to derive a class from the class frame and to extend that class, the declaration of this derived class is:
| class worldFrame. inherit frame. public. doOnCreate/1. %Method that will respond to creation of frame doOnSize/1. %Method that responds to resizing of panel endclass worldFrame. |
The class declares two methods and each method will respond to a different event of a different window. While a window is being created the onCreate/1 event is executed. It is also possible that an onSize/2 event is executed just before the onCreate/1 event.
The definition of the doOnCreate/1 method is:
| worldFrame::doOnCreate( _ ) :- this(T), resize(point(150, 120), false), move(point(50, 50), false), createSinglePanel(Panel, Result), add_callback(Panel, onSize, T, doOnSize), L new_obj label, L<-createCenter(Panel, 10, 10, 200, 20, Result), L<-putText('hello world'). |
The method doOnCreate/1 is called for a specific instance, to get access to that instance the built-in-predicate this/1 is used, this predicate assigns the variable T the instance for which the method is being executed.
The next interesting line of code contains add_callback/4, this predicate creates a new callback.
So, if the panel window is resized the doOnSize/1 method of the frame is called. The implementation of the doOnSize/1 is:
| worldFrame::doOnSize( onSize(Sender, point(X,Y)) ) :- NewX is (X-200) // 2, NewY is (Y-20) // 2, label<-move(point(NewX, NewY), true). |
The argument of the event is a structure that contains extra information about the event: the first parameter the sender of the event (which is the panel window), the second parameter is a point/2 structure that contains the new width and height of the panel. The following two lines calculate the new position of the label (the label control is always in the center of the panel window) and the instruction to move the label to the new position.
The last part necessary for everything to work is the code that creates an instance of the class worldFrame and connects the method doOnCreate/1 to the onCreate/1 event.
| start :- X new_obj worldFrame, add_callback(X, onCreate, X, doOnCreate), X<-create(Result), X<-show. |
There are many more Windows programming examples in the examples folder of Trinc-Prolog. All the visual Windows examples can also be tried with the Examples window.
One interesting example is located in the \examples\ctrl\' folder. This example demonstrates many different windows controls. To start the example open the file 'ctrl.txt' and enter 'start.' as goal or use the Examples window.
The complete source of the Hello World example is:
| ensure_loaded('..\\..\\modules\\win.txt'). public. %The frame class for the application, derived from standard class 'frame'. It %extends the standard class with a method that can react to the creation of %the frame window. It then creates a panel window inside itself, and then a label %control is created that displays the text % class helloFrame. inherit frame. public. doOnCreate/1. doOnSize/1. doOnClose/1. endclass helloFrame. helloFrame::doOnCreate( _ ) :- putText('Hello World Example'), this(T), resize(point(150, 120), false), move(point(50, 50), false), createSinglePanel(Panel, Result), add_callback(Panel, onSize, T, doOnSize), add_callback(T, onClose, T, doOnClose), L new_obj label, L<-createCenter(Panel, 10, 10, 200, 20, Result), L<-putText('hello world'), ! . helloFrame::doOnSize( onSize(Sender, point(X,Y)) ) :- NewX is (X-200) // 2, NewY is (Y-20) // 2, label<-move(point(NewX, NewY), true). helloFrame::doOnClose( X ) :- prolog_vm, app<-startQuit. %Start of test program %Stop test program |