⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unx47.htm

📁 Linux Unix揭密.高质量电子书籍.对学习Linux有大帮助,欢迎下载学习.
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<BR></P>

<P>In the past, the way to create and manage a widget was to call XtCreate and XtManageChild in two separate calls. However, this text will use a single call to create and manage a widget: XtVaCreateManagedWidget.

<BR></P>

<P>Note the parameters to this call to create the Form widget:

<BR></P>

<PRE>aForm = XtVaCreateManagedWidget(&quot;Form1&quot;, xmFormWidgetClass, top, XmNheight,90, XmNwidth,200,

NULL);</PRE>

<P>The first parameter is the name of the new widget. The second parameter describes the class of the widget being created. Recall that this is simply the widget name sandwiched between xm and WidgetClass. In this case it's xmFormWidgetClass. Note the 
lowercase x for the class pointer. This class pointer is declared in the header files included at the beginning of the file, Form.h.

<BR></P>

<HR ALIGN=CENTER>

<NOTE>

<IMG SRC="imp.gif" WIDTH = 68 HEIGHT = 35><B>TIP:</B> As another example, a label's class pointer would be called xmLabelWidgetClass and would require the Label.h file. Motif programmers have to be especially wary of the case-sensitivity of all variables.

<BR></NOTE>

<HR ALIGN=CENTER>

<P>The next argument is the parent widget of this new widget. In this case top is the parent of Form1. The top widget was returned from the call to XtAppInitialize.

<BR></P>

<P>The remaining arguments specify the parameters of this widget. In this case you are setting the width and height of this widget. This list is terminated by a NULL parameter.

<BR></P>

<P>After the form is created, a button is placed on top of it. A Form widget facilitates placement of other widgets on top of it. In this application you will cause the button to &quot;attach&quot; itself to the bottom of the form. The three lines attach 
themselves to the form.

<BR></P>

<PRE>XmNleftAttachment,XmATTACH_FORM,

XmNrightAttachment,XmATTACH_FORM, XmNbottomAttachment,XmATTACH_FORM,</PRE>

<P>The class of this button is included in the PushB.h file and is called xmPushButtonWidgetClass. The name of this widget is also the string that is displayed on the face of the button. Note that the parent of this button is the aForm widget. Thus the 
hierarchy is: top  is the parent of aForm  is the parent of aButton.

<BR></P>

<P>The next step is to add a callback function when the button is pressed. This is done with the following call:

<BR></P>

<PRE>XtAddCallback( aButton, XmNactivateCallback, bye, (XtPointer) NULL);</PRE>

<P>In this call:

<BR></P>

<UL>

<LI>aButton is the pushbutton widget.

<BR>

<BR></LI>

<LI>XmNactivateCallback is the action that will trigger this function.

<BR>

<BR></LI>

<LI>bye is the name of the function called. You should declare this function before making this function call.

<BR>

<BR></LI>

<LI>NULL is a pointer. This pointer could point to some structure meaningful to function bye.

<BR>

<BR></LI></UL>

<P>This will register the callback function bye for the widget. Now the topmost widget, top, is realized. This causes all managed widgets below top to be realized. The application then goes into a forever loop while waiting for events.

<BR></P>

<P>The bye function of this program simply exits the application.

<BR></P>

<H3 ALIGN="CENTER">

<CENTER><A ID="I6" NAME="I6">

<FONT SIZE=4><B>Compiling This Application</B>

<BR></FONT></A></CENTER></H3>

<P>Read the compiler documentation for your machine. Almost all vendor supplied compilers now conform to the ANSI C standard. If your compiler is not ANSI compatible, get an upgrade&#151;you'll need it.

<BR></P>

<P>Next, check the location of the libraries in your system. Check the /usr/lib/X11 directory for the following libraries: libXm.a, libXt.a, and libX11.a. If possible, use the shared library versions of these libraries with .so extensions followed by some 

numbers. The advantage of using shared libraries is that it results in a smaller Motif application. A typical application like the preceding one can be up to 1M in size because of the overhead of Motif.

<BR></P>

<P>The disadvantage of shared libraries is that your end user may not have the correct version of the library in his path. This does annoy some end users, especially if no fast method of acquiring this resource is available to them. Also, shipping a shared 

library with your application may require you to pay some licensing fees to the original library vendor. From a programmer's perspective, shared libraries are sometimes impossible to use with your debugger. Of course, if your debugger supports them, use 
them. Check your compiler documentation.

<BR></P>

<P>In most cases, if you intend to use shared libraries, use the static versions to do your debugging and testing and then compile the shared version. Always check your vendor's licensing agreement for details on how to ship shared libraries.

<BR></P>

<P>The application can be compiled with this command:

<BR></P>

<PRE>CC list1.c -o list1 -lXm -lXt -lX11</PRE>

<P>CC is your version of the ANSI compiler: gcc, acc, cc, or whatever. The program can be run from a command line; create a script file:

<BR></P>

<PRE>CC $1.c -o $1 -lXm -lXt -lX11</PRE>

<P>Now pass this script file; just the filename without the extension. The best way is to create a makefile, although this command will work with the examples in this text.

<BR></P>

<H3 ALIGN="CENTER">

<CENTER><A ID="I7" NAME="I7">

<FONT SIZE=4><B>The Widget Hierarchy</B>

<BR></FONT></A></CENTER></H3>

<P>The Motif widget set is a hierarchy of widget types. (See Figure 47.1.) Any resources provided by a widget are inherited by all its derived classes. Consider the three most important base classes: Core, XmPrimitive, and XmManager.

<BR></P>

<P>

<BR><B><A HREF="47unx01.gif">Figure 47.1.  The widget hierarchy.</A></B>

<BR></P>

<H4 ALIGN="CENTER">

<CENTER><A ID="I8" NAME="I8">

<FONT SIZE=3><B>Core</B>

<BR></FONT></A></CENTER></H4>

<P>The Core widget class provides the basis for all classes. It provides at least the following variables:

<BR></P>

<UL>

<LI>XmNx, XmNy: This is a widget's position on the display.

<BR>

<BR></LI>

<LI>XmNheight, XmNwidth: This is a widget's size.

<BR>

<BR></LI>

<LI>XmNborderWidth: This is set to 1 by default.

<BR>

<BR></LI>

<LI>XmNsensitive: A Boolean resource that specifies whether this widget can receive input.

<BR>

<BR></LI>

<LI>XmNcolorMap: The default colormap.

<BR>

<BR></LI>

<LI>XmNbackground: The background color.

<BR>

<BR></LI></UL>

<P>Check the Motif Programmer's reference manual for a complete listing.

<BR></P>

<H4 ALIGN="CENTER">

<CENTER><A ID="I9" NAME="I9">

<FONT SIZE=3><B>XmPrimitive</B>

<BR></FONT></A></CENTER></H4>

<P>The XmPrimitive widget class inherits all the resources from Core and adds more functionality.

<BR></P>

<UL>

<LI>XmNforeground: The foreground color.

<BR>

<BR></LI>

<LI>XmNhighlightOnEnter: Changes color when the pointer is within the window of the widget.

<BR>

<BR></LI>

<LI>XmNhighlightThickness: If XmNhighlightOnEnter is True, changes the border to this thickness.

<BR>

<BR></LI>

<LI>XmNhighlightColor: The color to use when drawing the highlighted border.

<BR>

<BR></LI>

<LI>XmNshadowThickness: The number of pixels used to draw the psuedo-3D look that Motif is famous for. This is defaulted to 2.

<BR>

<BR></LI>

<LI>XmNtopShadowColor and XmNbottomShadowColor: Sets the color for top and bottom lines around a widget.

<BR>

<BR></LI>

<LI>XmNuserData: A pointer available for use to the programmer.

<BR>

<BR></LI></UL>

<P>The XmPrimitive widget also provides the XmNdestroyCallback resource. This can be set to a function that does clean-up when a widget is destroyed. In Motif 1.2 or later, the XmPrimitive class also provides a XmNhelpCallback resource that is called when 

the F1 key is pressed in the widget's window. This is to allow specific help information for a widget.

<BR></P>

<H4 ALIGN="CENTER">

<CENTER><A ID="I10" NAME="I10">

<FONT SIZE=3><B>XmManager</B>

<BR></FONT></A></CENTER></H4>

<P>The XmManager class provides support for all Motif widgets that contain other widgets. This is never used directly in an application and works in a similar manner to the XmPrimitive class.

<BR></P>

<H3 ALIGN="CENTER">

<CENTER><A ID="I11" NAME="I11">

<FONT SIZE=4><B>The Label Widget</B>

<BR></FONT></A></CENTER></H3>

<P>The Label widget is used to display strings or pixmaps. Include the Xm/Label.h file in your source file before you use this widget.

<BR></P>

<P>Some of the resources for this widget include:

<BR></P>

<UL>

<LI>XmNalignment: This resource determines the alignment of the text in this widget. The allowed values are XmALIGNNMENT_END, XmALIGNMENT_CENTER, and XmALIGNMENT_BEGIN, for right-, center-, and left- justification, respectively.

<BR>

<BR></LI>

<LI>XmNrecomputeSize: A Boolean resource. If set to TRUE, the widget will be resized when the size of the string or pixmap changes dynamically. This is the default. If set to FALSE, the widget will not attempt to resize itself.

<BR>

<BR></LI>

<LI>XmNlabelType: The default value of this type is XmSTRING to show strings. However, it can also be set to XmPIXMAP when displaying a pixmap specified in the XmNpixmap resource.

<BR>

<BR></LI>

<LI>XmNlabelPixmap: This is used to specify which pixmap to use when the XmNlabelType is set to XmPIXMAP.

<BR>

<BR></LI>

<LI>XmNlabelString: This is used to specify which XmString compound string to use for the label. This defaults to the name of the label. See the section &quot;Strings in Motif: Compound Strings&quot; later in this chapter.

<BR>

<BR></LI></UL>

<P>To get acquainted with left- and right-justification on a label, see file 47_2 on the CD-ROM. This listing also shows how the resources can be set to change widget parameters, programmatically and through the .Xresource files.

<BR></P>

<P>Avoid using the \n in the label name. If you have to create a multi-string widget, use the XmStringCreate call to create a compound string. (See the next section, &quot;Strings in Motif: Compound Strings.&quot;) Another way to set the string is to 
specify it in the resource file and then merge the resources.

<BR></P>

<P>The listing shows the label to be right-justified. You could easily center the string horizontally by not specifying the alignment at all and letting it default to the center value. Alternatively, try setting the alignment parameter to 
XmALIGNMENT_BEGINNING for a left-justified label.

<BR></P>

<H3 ALIGN="CENTER">

<CENTER><A ID="I12" NAME="I12">

<FONT SIZE=4><B>Strings in Motif Compound Strings</B>

<BR></FONT></A></CENTER></H3>

<P>A compound string is Motif's way of representing a string. For a typical C program, a null-terminated string is enough to specify a string. In Motif, a string is also defined by the character set it uses. Strings in Motif are referred to as compound 
strings and are kept in opaque data structures called XmString.

<BR></P>

<P>In order to get a compound string from a regular C string, use this function call:

<BR></P>

<PRE>XmString XmStringCreate( char *text, char *tag);</PRE>

<P>This returns an equivalent compound string, given a pointer to a null-terminated C string and a tag. The tag specifies which font list to use and is defaulted to XmFONTLIST_DEFAULT_TAG.

<BR></P>

<P>New lines in C strings have to be handled by special separators in Motif. To create a string and preserve the new lines, use this call:

<BR></P>

<PRE>XmString XmStringCreateLtoR( char *text, char *tag);</PRE>

<P>The compound strings have to be created and destroyed just like any other object. They persist long after the function call that created them returns. Therefore, it's a good idea to free all locally used XmStrings in a function before returning, or else 

all references to the strings will be lost.

<BR></P>

<P>Here's the definition of a call to free XmString resources:

<BR></P>

<PRE>XmStringFree( XmString s);</PRE>

<P>You can run operations on strings similar to those you would under ASCII programming, except that they are called by different names. Use Boolean XmStringByteCompare( XmString s1, XmString s2); for a strict byte-for-byte comparison. For just the text 
comparison, use XmStringCompare( XmString s1, XmString s2);.

<BR></P>

<P>To check if a string is empty, use the following:

<BR></P>

<PRE>Boolean XmStringEmpty( XmString s1);</PRE>

<P>To concatenate two strings together, use the following:

<BR></P>

<PRE>XmString XmStringConcat( XmString s1, XmString s2);</PRE>

<P>It creates a new string by concatenating s2 to s1. This new resource has to be freed just like s1 and s2.

<BR></P>

<P>If you want to use sprintf, use it on a temporary buffer and then create a new string. For example:

<BR></P>

<PRE>char str[32];

XmString xms;

......

sprintf(str,&quot; pi = %lf, Area = %lf&quot;, PI, TWOPI*r);

xms =  XmStringCreateLtoR( str,  XmFONTLIST_DEFAULT_TAG); ......

n = 0;

XtSetArg(arg[n],XmNlabelString,xms); n++; XtSetValues(someLabel, arg, n); XmStringFree(xms);</PRE>

<P>If a string value is corrupted by itself over time, check to see if the widget is not making a copy of the passed XmString for its own use. Sometimes a widget may only be keeping a pointer to the XmString. If that string was &quot;freed,&quot; the 
widget may wind up pointing to bad data.

<BR></P>

<P>One good way to check is to set an XmString resource. Then use the XtGetValues function to get the same resource from the widget. If the values of the XmStrings are the same, the widget is not making a copy for itself. If they aren't the same, it's safe 

to free the original because the widget is making a local copy. The default course of action is to assume that a widget makes copies of such resources for itself.

<BR></P>

<P>A similar test could be used to determine if a widget returns a copy of its resource to a pointer to it. Use the preceding listing, but this time use XTgetValues to get the same resource twice. Then do the comparison.

<BR></P>

<PRE>/**

*** This is a sample partial listing of how to check if the

*** data returned on an XtGetValues and an XtSetValues

*** call is a copy or a reference.

***/

#include &quot;Xm/Text.h&quot;

..

Widget w;

XmString x1, x2, x3;

x3 = XmStringCreateLtoR(&quot;test&quot;, XmFONTLIST_DEFAULT_TAG); XmTextSetString(w,x3);

...

x1 = XmTextGetString(w);

x2 = XmTextGetString(w);

XtWarning(&quot; Checking SetValues&quot;);

if (x1 != x3)

     XtWarning(&quot;Widget keeps a copy ! Free original!&quot;);

else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -