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

📄 ch34.htm

📁 linux-unix130.linux.and.unix.ebooks130 linux and unix ebookslinuxLearning Linux - Collection of 12 E
💻 HTM
📖 第 1 页 / 共 5 页
字号:


directory for the following libraries: <TT>libXm.a</TT>, <TT>libXt.a</TT>, and <TT>libX11.a</TT>.



If possible, use the shared library versions of these libraries with <TT>.so</TT>



extensions followed by some numbers. The advantage of using shared libraries is a



smaller Motif application; a typical application like the one you've been working



on can be up to 1MB in size because of Motif's overhead.</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. Also, shipping a shared library



with your application may cause 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 it. Check



your compiler documentation. 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.</P>



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



<PRE><FONT COLOR="#0066FF">gcc l34_1.c -o list1 -lXm -lXt -lX11



</FONT></PRE>



<P>The program can be run from a command line if you create a script file:</P>



<PRE><FONT COLOR="#0066FF">$ cat mk



gcc $1.c -o $1 -lXm -lXt -lX11



</FONT></PRE>



<P>and pass it just the filename without the extension. The best way is to create



a <TT>makefile</TT>, but this script file will work with the examples in this text.



So, to compile <TT>l34_1.c</TT>, you would use the script as follows:</P>



<PRE><FONT COLOR="#0066FF">$ mk l34_1



</FONT></PRE>



<P>You should see the output shown in Figure 34.2 on your screen. Your application



is the one with <TT>l34_1</TT> in its frame.



<H3 ALIGN="CENTER"><A NAME="Heading12<FONT COLOR="#000077">The Widget Hierarchy</FONT></H3>



<P>The Motif Widget set is a hierarchy of Widget types. (See Figure 34.3.) Any resources



provided by a Widget are inherited by all its derived classes. Consider the three



most important base classes: <TT>Core</TT>, <TT>XmPrimitive</TT>, and <TT>XmManager</TT>.



<BR>



<BR>



<A HREF="../art/34/34lnx03.jpg"><B>Figure 34.3.</B></A> <I>The partial Motif hierarchy.</I>



<H4 ALIGN="CENTER"><A NAME="Heading13<FONT COLOR="#000077">Core</FONT></H4>



<P>The <TT>Core</TT> Widget class provides the basis for all classes. It provides



at least the following resources for all Widgets: <TT>XmNx,XmNy</TT>: A Widget's



position on the display.</P>



<P><TT>XmNheight, XmNwidth</TT>: A Widget's size.</P>



<P><TT>XmNborderWidth</TT>: Set to 1 by default.</P>



<P><TT>XmNsensitive</TT>: A Boolean resource that specifies whether this Widget can



receive input.</P>



<P><TT>XmNcolorMap</TT>: The default color map.<BR>



<BR>



<TT>XmNbackground</TT>: The background color.<BR>



<BR>



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



<H4 ALIGN="CENTER"><A NAME="Heading14<FONT COLOR="#000077">XmPrimitive</FONT></H4>



<P>The <TT>XmPrimitive</TT> Widget class inherits all the resources from <TT>Core</TT>



and adds more functionality. <TT>XmNforeground</TT>: The foreground color.</P>



<P><TT>XmNhighlightOnEnter</TT>: Changes color when the pointer is within a displayed



area of Widget.</P>



<P><TT>XmNhighlightThickness</TT>: If <TT>XmNhighlightOnEnter</TT> is TRUE, changes



the border to this thickness.</P>



<P><TT>XmNhighlightColor</TT>: The color a Widget changes to when highlighted.</P>



<P><TT>XmNshadowThickness</TT>: This is the thickness to show the pseudo-three-dimensional



look for which Motif is famous. The default value is 2.</P>



<P><TT>XmNtopShadowColor</TT> and <TT>XmNbottomShadowColor</TT>: Sets the color for



top and bottom lines around a Widget.<BR>



<BR>



<TT>XmNuserData</TT>: A pointer available for the programmer's use.<BR>



<BR>



The <TT>XmPrimitive</TT> Widget also provides the <TT>XmNdestroyCallback</TT> resource.



This can be set to a function that would do clean-up when a Widget is destroyed.



In Motif 1.2.x or later, the <TT>XmPrimitive</TT> class also provides a <TT>XmNhelpCallback</TT>



that is called when the F1 key is pressed in the Widget's window. This is to allow



specific help information for a button, for example.



<H4 ALIGN="CENTER"><A NAME="Heading15<FONT COLOR="#000077">XmManager</FONT></H4>



<P>The <TT>XmManager</TT> class provides support for all Motif Widgets that contain



other Widgets. This is never used directly in an application, and it works in a manner



similar to the <TT>XmPrimitive</TT> class. It provides the following resources: <TT>XmNforeground</TT>:



The color of the pixels in the foreground.</P>



<P><TT>XmNshadowThickness</TT>: For the three-dimensional effect.</P>



<P><TT>XmNtopShadowColor</TT>: For the three-dimensional effect. This is automatically



defaulted to a color derived from the background color. This color is used on the



left and top borders of a Widget.</P>



<P><TT>XmNbottomShadowColor</TT>: For the three-dimensional effect. This is automatically



defaulted to a color derived from the background color. This color is used on the



right and bottom borders of a Widget.<BR>



<BR>



<TT>XmNuserData</TT>: For storing user data. Could be used as a <TT>void</TT> pointer.



<H3 ALIGN="CENTER"><A NAME="Heading16<FONT COLOR="#000077">The Label Widget</FONT></H3>



<P>The Label Widget is used to display strings or pixmaps. Include the <TT>Xm/Label.h</TT>



file in your source file before using this Widget. Some of the resources for this



Widget include these: <TT>XmNalignment</TT>: Determines the alignment of the text



in this Widget. The acceptable values are <TT>XmALIGNNMENT_END</TT>, <TT>XmALIGNMENT_CENTER</TT>,



and <TT>XmALIGNEMENT_BEGIN</TT> for right, center, and left justification, respectively.</P>



<P><TT>XmNrecomputeSize</TT>: A Boolean resource. If set to TRUE, the Widget will



resize should the size of the string or pixmap change dynamically. This is the default.



If set to FALSE, the Widget will not attempt to resize itself.</P>



<P><TT>XmNlabelType</TT>: The default value of this type is <TT>XmSTRING</TT> to



show strings. However, it can also be set to <TT>XmPIXMAP</TT> when displaying a



pixmap specified in the <TT>XmNpixmap</TT> resource.</P>



<P><TT>XmNlabelPixmap</TT>: This is used to specify which pixmap to use when the



<TT>XmNlabelType</TT> is set to <TT>XmPIXMAP</TT>.<BR>



<BR>



<TT>XmNlabelString</TT>: This is used to specify which <TT>XmString</TT> 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;<BR>



<BR>



To get acquainted with left and right justification on a label, see Listing 34.2.



The listing also shows how the resources can be set to change Widget parameters programmatically



and via the <TT>.Xresource</TT> files.



<H3 ALIGN="CENTER"><A NAME="Heading17<FONT COLOR="#000077">Listing <A NAME="Heading1834.2.



How to use a Label Widget.</FONT></H3>



<PRE><FONT COLOR="#0066FF">/*



** This application shows how to use a Label Widget.



*/







#include &lt;X11/Intrinsic.h&gt;



#include &lt;Xm/Xm.h&gt;



#include &lt;Xm/Form.h&gt;



#include &lt;Xm/PushB.h&gt;



#include &lt;Xm/Label.h&gt;   /** &lt;---- for the label **/











void  bye(Widget w, XtPointer clientdata, XtPointer calldata);







int main(int  argc, char **argv)



{



Widget top;



XtAppContext app;



Widget aForm;



Widget aLabel;          /** &lt;---- for the label ***/



Widget aButton;



Arg   args[5];







/**



*** Initialize the toolkit.



**/



top = XtAppInitialize(&amp;app, &quot;KBH&quot;, NULL, 0, (Cardinal *)&amp;argc,



            argv, NULL, args, 0);







/**



*** Create a Form on this top-level Widget. This is a nice Widget



*** to place other Widgets on top of.



**/



aForm = XtVaCreateManagedWidget(&quot;Form1&quot;,



      xmFormWidgetClass, top,



      XmNheight,90,



      XmNwidth,200,



      NULL);







/**



*** Add a button on the form you just created. Note how this Button



*** Widget is connected to the form that it resides on. Only



*** left, right, and bottom edges are attached to the form. The



*** top edge of the button is not connected to the form.



**/



aButton = XtVaCreateManagedWidget(&quot;Push to Exit&quot;,



      xmPushButtonWidgetClass, aForm,



      XmNheight,20,



      XmNleftAttachment,XmATTACH_FORM,



      XmNrightAttachment,XmATTACH_FORM,



      XmNbottomAttachment,XmATTACH_FORM,



      NULL);







/**



*** Now let's create the label for us.



*** The alignment is set to right-justify the label.



*** Note how the label is attached to the parent form.



**/







aLabel = XtVaCreateManagedWidget(&quot;This is a right justified Label&quot;,



      xmLabelWidgetClass, aForm,



      XmNalignment, XmALIGNMENT_END,



      XmNleftAttachment,XmATTACH_FORM,



      XmNrightAttachment,XmATTACH_FORM,



      XmNtopAttachment,XmATTACH_FORM,



      NULL);







/**



*** Call the function &quot;bye&quot; when the PushButton receives



*** an activate message; i.e. when the pointer is moved to



*** the button and Button1 is pressed and released.



**/



XtAddCallback( aButton, XmNactivateCallback, bye, (XtPointer) NULL);



XtRealizeWidget(top);



XtAppMainLoop(app);



return(0);



}







void  bye(Widget w, XtPointer clientdata, XtPointer calldata)



{



exit(0);



}



</FONT></PRE>



<P>Output is shown in Figure 34.4. <BR>



<BR>



<A HREF="../art/34/34lnx04.jpg"><B>Figure 34.4.</B></A> <I>Using the Label Widget.</I></P>



<P>Avoid using the <TT>\n</TT> in the label name. If you have to create a multistring



Widget, use the <TT>XmStringCreate</TT> calls to create a compound string (see the



next section). Another way to set the string is by specifying it in the resource



file and then merging the resources.</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<TT> XmALIGNMENT_BEGINNING</TT>



for a left-justified label.



<H3 ALIGN="CENTER"><A NAME="Heading19<FONT COLOR="#000077">Strings in Motif:



Compound Strings</FONT></H3>



<P>A compound string is Motif's way of representing a string. In 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 <TT>XmString</TT>.</P>



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



<PRE><FONT COLOR="#0066FF">XmString XmStringCreate( char *text, char *tag);



</FONT></PRE>



<P>This function will return an equivalent compound string given a pointer to a NULL-



terminated C string and a tag. The tag specifies which fontlist to use and is defaulted



to <TT>XmFONTLIST_DEFAULT_TAG</TT>.</P>



<P>New lines in C strings have to be handled by special separators in Motif. So to



create a string and preserve the newlines, use the call</P>



<PRE><FONT COLOR="#0066FF">XmString XmStringCreateLtoR( char *text, char *tag);



</FONT></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 <TT>XmString</TT>s in a function before returning,



or else all references to the strings will be lost. The definition of a call to free



<TT>XmString</TT> resources is</P>



<PRE><FONT COLOR="#0066FF">XmStringFree( XmString s);



</FONT></PRE>



<P>You can run similar operations on strings as you would in a C program, except



that these string operations are called by different names. Use the function</P>



<PRE><FONT COLOR="#0066FF">Boolean XmStringByteCompare( XmString s1, XmString s2);



</FONT></PRE>



<P>for a strict byte-for-byte comparison, and for just the text comparison, use</P>



<PRE><FONT COLOR="#0066FF">Boolean XmStringCompare( XmString s1, XmString s2);



</FONT></PRE>



<P>To check if a string is empty, use</P>



<PRE><FONT COLOR="#0066FF">Boolean XmStringEmpty( XmString s1);



</FONT></PRE>



<P>To string two strings together, use</P>



<PRE><FONT COLOR="#0066FF">XmString XmStringConcat( XmString s1, XmString s2);



</FONT></PRE>



<P><TT>XmString Concat() </TT>creates a new string by concatenating <TT>s2</TT> to



<TT>s1</TT> and returns it. This returned string has to be freed just like <TT>s1</TT>



and <TT>s2</TT>.</P>



<P>If you want to use <TT>sprintf</TT>, use it on a temporary buffer and then create



a new string. For example:</P>



<PRE><FONT COLOR="#0066FF">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);



</FONT></PRE>



<P>If a string value becomes corrupted without your performing any direct actions



on it, check to see whether the Widget is not making a copy for its use of the passed



<TT>XmString</TT>. Sometimes a Widget might be keeping only a pointer to the <TT>XmString</TT>.



If that string were freed, the Widget might wind up pointing to bad data.</P>



<P>One good way to check is to set an <TT>XmString</TT> resource, then use the <TT>XtGetValues</TT>



function to get the same resource from the Widget. If the values of the <TT>XmString</TT>s



are the same, the Widget is not making a copy for itself. If they are not the same,



it is 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 a copy of such resources for itself.</P>



<P>A similar test could be used to determine whether a Widget returns a copy of its



resource or a pointer to it. Use the same listing shown two paragraphs ago, but this



time use a <TT>getValue</TT> to get the same resource twice. Then do the comparison



to see whether the address for the original string matches the address of the returned



value from <TT>getValue()</TT>: If the values match, the Widget keeps a pointer.



If the values do not match, the Widget keeps an internal copy.</P>



⌨️ 快捷键说明

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