[Search for users]
[Overall Top Noters]
[List of all Conferences]
[Download this site]
Title: | DECWINDOWS 26-JAN-89 to 29-NOV-90 |
Notice: | See 1639.0 for VMS V5.3 kit; 2043.0 for 5.4 IFT kit |
Moderator: | STAR::VATNE |
|
Created: | Mon Oct 30 1989 |
Last Modified: | Mon Dec 31 1990 |
Last Successful Update: | Fri Jun 06 1997 |
Number of topics: | 3726 |
Total number of notes: | 19516 |
2410.0. "PLI list box problem, need help!!!" by CSC32::B_BRADACH () Thu Mar 08 1990 14:10
I have a customer who is writing an application in pli and decwtoolkit
routines, specifically a list box.
Please don't tell me "write it in C", the customer has the code
already written in C. He MUST USE PLI for this application.
He is having a problem setting up
the activate callback in order to create the list box.
I know absolutly nothing about pli. If anyone out there knows pli and
decwindows, can you give me some ideas of things to try. the listing
file follows this.
Thanks in advance for ANY IDEAS AT ALL!!!
bernie
csc/cs
============================cut here================================
MENU_INITIALIZE 8-MAR-1990 08:54:01 VAX PL/I V3.3-065 Page 1
01 8-MAR-1990 08:51:46 [B_BRADACH.DECWINDOWS]HONG_PUN_2.PLI;65 (1)
1 menu_initialize: procedure options (main);
2 1
3 1 %include 'sys$library:decw$xlibdef.pli';
7996 1 %include 'sys$library:decw$dwtwidgetdef.pli';
18328 1
18329 1 %REPLACE TRUE BY '1'B;
18330 1 %REPLACE FALSE BY '0'B;
18331 1
18332 1 list_exit: procedure (widget,tag,reason);
18333 2 dcl widget fixed bin(31),
18334 2 tag fixed bin(31),
18335 2 1 reason like dwt$any_cb_st;
18336 2
18337 2 return;
18338 2 end list_exit;
18339 1
18340 1 dcl dpy fixed bin(31),
18341 1 les_display fixed bin(31),
18342 1 id_of_screen fixed bin(31),
18343 1 1 args(0:2) like dwt$arg,
18344 1 application_context pointer,
18345 1 null builtin,
18346 1 urlist pointer static init (NULL),
18347 1 num_urs fixed bin(31),
18348 1 argc fixed bin(31),
18349 1 argv (10) pointer static init ((10) null),
18350 1 width fixed bin(31),
18351 1 height fixed bin(31),
18352 1 n fixed bin(31),
18353 1 x fixed bin(31),
18354 1 y fixed bin(31),
18355 1 menu_x_pos fixed bin(31),
18356 1 menu_y_pos fixed bin(31),
18357 1 main_window pointer,
18358 1 top_level pointer;
18359 1
18360 1 dcl compound_items(2) pointer,
18361 1 list_widget pointer,
18362 1 status fixed bin(31),
18363 1 widget_window_id fixed bin(31),
18364 1 1 activate_callback(0:1) like dwt$callback,
18365 1 1 help_callback (0:0) like dwt$callback;
18366 1 top_level = xt$initialize ('lesmenu', 'graphicsmenu', urlist,
18367 1 num_urs, argc, argv);
18368 1 argc = 0;
18369 1 call dwt$vms_set_arg (40, args, argc, dwt$c_nx);
18370 1 argc = 1;
18371 1 call dwt$vms_set_arg (40, args, argc, dwt$c_ny);
18372 1 argc = 2;
18373 1 call xt$set_values (top_level, args, n);
18374 1 call dwt$vms_free_argnames (args, n);
18375 1
18376 1 x, y = 0;
18377 1 width, height = 200;
18378 1 main_window = dwt$main_window (top_level, 'mywin', x, y, width, height);
MENU_INITIALIZE 8-MAR-1990 08:54:01 VAX PL/I V3.3-065 Page 2
01 8-MAR-1990 08:51:46 [B_BRADACH.DECWINDOWS]HONG_PUN_2.PLI;65 (1)
18379 1
18380 1 call xt$manage_child (main_window);
18381 1 allocate dwt$comp_string set (compound_items (1));
18382 1 allocate dwt$comp_string set (compound_items (2));
18383 1
18384 1 allocate dwt$widget set (list_widget);
18385 1
18386 1 status = dwt$latin1_string ('Menu Item 1', compound_items(1)->dwt$comp_string);
18387 1 status = dwt$latin1_string ('Menu Item 2', compound_items(2)->dwt$comp_string);
18388 1
18389 | 1 /* how do you declare a call back procedure??????
18390 | 1 *
18391 | 1 * This is where the error ocurs
18392 | 1 */
18393 1 activate_callback(0).dwt$a_callback_proc = list_exit;
%PLIG-E-BADASSIGN, The source operand, LIST_EXIT, of an
assignment is invalid for conversion to the
POINTER target.
18394 1 activate_callback(0).dwt$l_callback_tag = 0;
18395 1
18396 1 activate_callback(1).dwt$a_callback_proc = null();
18397 1 activate_callback(1).dwt$l_callback_tag = 0;
18398 1
18399 1 help_callback(0).dwt$a_callback_proc = null();
18400 1 help_callback(0).dwt$l_callback_tag = 0;
18401 1 list_widget->dwt$widget = dwt$list_box (main_window, 'listbox',0,0,
18402 1 compound_items,
18403 1 2,
18404 1 2,
18405 1 ref(activate_callback),
18406 1 ref(help_callback),
18407 1 dwt$c_resize_fixed,
18408 1 dwt$c_true);
18409 1
18410 1 call xt$manage_child (list_widget->dwt$widget);
18411 1
18412 1 call xt$realize_widget (top_level);
18413 1 call xt$main_loop ();
18414 1
18415 1
18416 1
18417 1
18418 1 end menu_initialize;
%PLIG-I-NOBJECT, No object file produced.
18419
18420
COMMAND LINE
------- ----
PLI/LIST HONG_PUN_2
T.R | Title | User | Personal Name | Date | Lines |
---|
2410.1 | | PSW::WINALSKI | Careful with that VAX, Eugene | Fri Mar 09 1990 19:25 | 55 |
| The problem is that LIST_EXIT is a procedure name, and DWT$A_CALLBACK_PROC is
a POINTER variable. The two are not compatible data types. What you have to
do is cause PL/I to give you the address of LIST_EXIT's entry mask as a
POINTER value. You can do this by assigning LIST_EXIT to an ENTRY variable.
ENTRY variables are VMS bound procedure value data types. The first longword
of an ENTRY variable is the address of the procedure's entry mask. The second
longword is the frame pointer value for the bound procedure. You can use
overlay defining of a UNION structure to "launder" the entry mask address into
a pointer value, as follows:
DECLARE
1 bound_proc_value UNION,
2 e ENTRY VARIABLE,
2 p POINTER;
...
/* establish LIST_EXIT as the activate callback */
bound_proc_value.e = list_exit;
activate_callback(0).dwt$a_callback_proc = bound_proc_value.p;
In your example program, LIST_EXIT is a nested procedure. You therefore must
be careful that it doesn't do any up-level addressing of automatic variables
in outer scopes. The handle that LIST_EXIT has for up-level addressing is
the frame pointer of the outer scope, passed in R1 when the procedure is
called. However, DECwindows is not going to fill this in properly. Here's
an example of the kind of up-level addressing that won't work:
FOO: PROCEDURE OPTIONS(MAIN);
DECLARE x FIXED BINARY(31);
LIST_EXIT: PROCEDURE(widget, tag, reason);
DECLARE widget FIXED BINARY(31),
tag FIXED BINARY(31),
1 reason LIKE dwt$any_cb_st;
x = widget;
RETURN;
END list_exit;
...
END foo;
In this example, LIST_EXIT references the automatic variable X declared in the
outer scope FOO. If you were to CALL LIST_EXIT from FOO, this would work
because PL/I will put the frame information for FOO in R1 before doing the call.
Howver, if LIST_EXIT is called from DECwindows (or as a VMS AST, in a lot of
other situations), DECwindows is not going to do anything special before the
call, R1 will contain garbage, and the assignment to X will fail.
Note that this applies only to AUTOMATIC variables (the default). Referencing
STATIC variables in outer scopes is OK.
--PSW
|
2410.2 | any ideas why the items don't appear?? | CSC32::B_BRADACH | | Tue Mar 13 1990 17:06 | 8 |
| Paul:
Thanks for the response on this and the explanation for what is
happening. The list box is appearing on the display, but the item list
is not coming up. Any ideas on this??
bernie
csc/cs
|
2410.3 | | PSW::WINALSKI | Careful with that VAX, Eugene | Wed Mar 14 1990 18:30 | 37 |
| RE: .2
The following bit of code is wrong:
>allocate dwt$comp_string set (compound_items (1));
>allocate dwt$comp_string set (compound_items (2));
>status = dwt$latin1_string ('Menu Item 1', compound_items(1)->dwt$comp_string);
>status = dwt$latin1_string ('Menu Item 2', compound_items(2)->dwt$comp_string);
DWT$LATIN1_STRING allocates space for the Latin1 string for you. The ALLOCATE
statements aren't necessary, and in fact they cause memory to be dropped on
the floor.
You don't see the list box entries because you have told DWT$LATIN1_STRING to
fill in the longword pointed to by COMPOUND_ITEMS(n) with a pointer to the
compound string. In fact what you want is for DWT$LATIN1_STRING to fill in
COMPOUND_ITEMS(n) itself (not what it points to) with the pointer. After the
above code is executed, you have the following situation:
COMPOUND_STRING(n) ----> a longword ----> compound string
what you want is:
COMPOUND_STRING(n) ----> compound string
when the list box widget create routine tries to interpret the longword pointer
as a compound string, it get garbage and hence you don't see your list box item.
Unfortunately, the toolkit fails silently in these situations.
What you want to do is get rid of the ALLOCATE statements entirely and do the
following for the DWT$LATIN1_STRING calls:
status = dwt$latin1_string ('Menu Item 1', compound_items(1));
status = dwt$latin1_string ('Menu Item 2', compound_items(2));
--PSW
|
2410.4 | It works!!! -- thanks for all the help | CSC32::B_BRADACH | | Fri Mar 16 1990 16:38 | 10 |
| Paul:
Thanks for you all of the help. Your explanations on what was
happening really helped!!!!
I now have it working with both low level and
high level routines. Thanks again.
bernie
csc/cs
|