📄 0537-0540.html
字号:
<HTML>
<HEAD>
<TITLE>Developer.com - Online Reference Library - 0672311739:RED HAT LINUX 2ND EDITION:Motif Programming</TITLE>
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
<SCRIPT>
<!--
function displayWindow(url, width, height) {
var Win = window.open(url,"displayWindow",'width=' + width +
',height=' + height + ',resizable=1,scrollbars=yes');
}
//-->
</SCRIPT>
</HEAD>
-->
<!-- ISBN=0672311739 //-->
<!-- TITLE=RED HAT LINUX 2ND EDITION //-->
<!-- AUTHOR=DAVID PITTS ET AL //-->
<!-- PUBLISHER=MACMILLAN //-->
<!-- IMPRINT=SAMS PUBLISHING //-->
<!-- PUBLICATION DATE=1998 //-->
<!-- CHAPTER=26 //-->
<!-- PAGES=0529-0544 //-->
<!-- UNASSIGNED1 //-->
<!-- UNASSIGNED2 //-->
<P><CENTER>
<a href="0533-0536.html">Previous</A> | <a href="../ewtoc.html">Table of Contents</A> | <a href="0541-0543.html">Next</A>
</CENTER></P>
<A NAME="PAGENUM-537"><P>Page 537</P></A>
<!-- CODE //-->
<PRE>
/* give the app a name and initial size */
skeleton = XtVaAppInitialize(&skel_app, "Skeleton", NULL, 0, &argc, argv,
NULL, XmNwidth, 320, XmNheight, 240, NULL);
/* create the main window */
skel_window = XtVaCreateManagedWidget("skel", xmMainWindowWidgetClass, skeleton,
XmNscrollingPolicy, XmAUTOMATIC, NULL);
/* build a menu bar across main window */
skel_menubar = XmCreateMenuBar(skel_window, "skel_menubar", NULL, 0);
/* build the File pull-down menu */
skel_filepulldown = XmCreatePulldownMenu (skel_menubar, "File", NULL, 0);
Âskel_string = XmStringCreateLocalized ("File");
/* create the menu, assign ALT+F as mnemonic key */
XtVaCreateManagedWidget ("File", xmCascadeButtonWidgetClass, skel_menubar,
XmNlabelString, skel_string, XmNmnemonic, `F', XmNsubMenuId,
Âskel_filepulldown, NULL);
/* release storage */
XmStringFree(skel_string);
/* now add File pull-down menu elements */
skel_new = XtVaCreateManagedWidget("New", xmPushButtonGadgetClass,
skel_filepulldown, NULL);
skel_open = XtVaCreateManagedWidget("Open", xmPushButtonGadgetClass,
skel_filepulldown, NULL);
XtVaCreateManagedWidget("separator", xmSeparatorGadgetClass, skel_filepulldown,
NULL);
skel_close = XtVaCreateManagedWidget("Close", xmPushButtonGadgetClass,
skel_filepulldown, NULL);
skel_save = XtVaCreateManagedWidget("Save", xmPushButtonGadgetClass,
skel_filepulldown, NULL);
XtVaCreateManagedWidget("separator", xmSeparatorGadgetClass, skel_filepulldown,
NULL);
skel_exit = XtVaCreateManagedWidget("Exit", xmPushButtonGadgetClass,
skel_filepulldown, NULL);
/* add what to do when user selects Exit */
XtAddCallback(skel_exit, XmNactivateCallback, skel_exit_action, NULL);
/* build Edit menu */
skel_editpulldown = XmCreatePulldownMenu(skel_menubar, "Edit", NULL, 0);
skel_string = XmStringCreateLocalized ("Edit");
XtVaCreateManagedWidget ("Edit", xmCascadeButtonWidgetClass, skel_menubar,
XmNlabelString, skel_string, XmNmnemonic, `E', XmNsubMenuId,
Âskel_editpulldown, NULL);
/* release storage */
XmStringFree(skel_string);
/* add Edit pull-down menu elements */
skel_cut = XtVaCreateManagedWidget("Cut", xmPushButtonGadgetClass,
skel_editpulldown, NULL);
skel_copy = XtVaCreateManagedWidget("Copy", xmPushButtonGadgetClass,
skel_editpulldown, NULL);
</PRE>
<!-- END CODE //-->
<PRE>
continues
</PRE>
<A NAME="PAGENUM-538"><P>Page 538</P></A>
<P>Listing 26.1. continued
</P>
<!-- CODE //-->
<PRE>
skel_paste = XtVaCreateManagedWidget("Paste", xmPushButtonGadgetClass,
skel_editpulldown, NULL);
/* build Help menu */
skel_helppulldown = XmCreatePulldownMenu(skel_menubar, "Help", NULL, 0);
Âskel_string = XmStringCreateLocalized ("Help");
XtVaCreateManagedWidget ("Help", xmCascadeButtonWidgetClass, skel_menubar,
XmNlabelString, skel_string, XmNmnemonic, `H', XmNsubMenuId,
Âskel_helppulldown, NULL);
/* release storage */
XmStringFree(skel_string);
/* now move the Help pull-down to right side - thanks, Motif FAQ! */
XtVaSetValues(skel_menubar, XmNmenuHelpWidget, XtNameToWidget(skel_menubar,
"Help"), NULL);
/* now label, create, and assign action to Help menu */
skel_version = XtVaCreateManagedWidget ("Version", xmPushButtonGadgetClass,
skel_helppulldown, NULL);
XtAddCallback(skel_version, XmNactivateCallback, skel_help_action, NULL);
XtManageChild(skel_menubar);
XtRealizeWidget(skeleton);
XtAppMainLoop (skel_app);
return (0);
}
</PRE>
<!-- END CODE //-->
<P>To compile this program, you can use the following command line:
</P>
<!-- CODE SNIP //-->
<PRE># gcc -o skel skeleton.c -L/usr/X11R6/lib -lXm -lXpm -lXt -lXext -lX11
</PRE>
<!-- END CODE SNIP //-->
<P>This line directs the GNU linker to look in the
/usr/X11/lib directories for needed libraries. The program is then linked, using the shared
Xm, Xpm, Xt, Xext, and X11 libraries. The final
size of the program is fewer than 13,000 characters.
</P>
<H4><A NAME="ch26_ 15">
How the Program Works
</A></H4>
<P>When you program in C to build Linux command-line or X programs, you know that if
you use certain routines or functions, you must tell the compiler which
#include files contain definitions needed by the functions in your program. This program starts out by listing the
needed #include files for the different functions used in
skeleton.c.
</P>
<P>Next, the declaration of skeleton as a top-level widget makes information about our
program available outside main(). This is because
skel_help_action(), which creates a Motif dialog, needs to know whom the dialog belongs to. The next two routines,
skel_exit_action() and skel_dialog_handler(), are what as known as callback routines.
</P>
<P>Callback routines make your program work. These routines are called when you push
buttons or select menu items and when your program receives information from other programs or
the operating system. If you look at
skel_dialog_handler(), you'll see the following line:
</P>
<A NAME="PAGENUM-539"><P>Page 539</P></A>
<!-- CODE SNIP //-->
<PRE>XtAddCallback(skel_dialog, XmNokCallback, skel_dialog_handler, NULL);
</PRE>
<!-- END CODE SNIP //-->
<P>This function tells the program what to do after the dialog appears, and when you either
click the OK button, or hit the Enter key—all without a lot of extra code.
</P>
<P>skel_help_action() is also a callback routine, called in response to the
main() program line:
</P>
<!-- CODE SNIP //-->
<PRE>XtAddCallback(skel_version, XmNactivateCallback, skel_help_action, NULL);
</PRE>
<!-- END CODE SNIP //-->
<P>In this instance, skel_help_action() is run when you pull down the menu item Version
from the program's Help menu. The routine
skel_exit_action() is called when you choose Exit from the program's File menu. After creating room for the text string containing the
version information to be displayed, the
skel_help_action() routine then creates the dialog with
</P>
<!-- CODE SNIP //-->
<PRE>skel_dialog = XmCreateMessageDialog (skeleton, "dialog", args, 0);
</PRE>
<!-- END CODE SNIP //-->
<P>and then fills in required information with the routine
</P>
<!-- CODE SNIP //-->
<PRE>XtVaSetValues(skel_dialog, XmNmessageString, skel_string, NULL, NULL);
</PRE>
<!-- END CODE SNIP //-->
<P>followed by the callback routine designation, and finally, displays the dialog with
</P>
<!-- CODE SNIP //-->
<PRE>XtManageChild(skel_dialog);
</PRE>
<!-- END CODE SNIP //-->
<P>The main() routine starts with declarations for different widgets and widget elements. The
call to XtVaAppInitialize() declares the application name, indicates whether or not the
program should read any command-line arguments, and assigns an initial size in pixel width and
height.
</P>
<H4><A NAME="ch26_ 16">
Sample Program Resources
</A></H4>
<P>The initial window size (and many other default actions of all other Motif and many X11
programs) can also be set by using resources. One way to do this is first, open your
.Xdefaults file in your home directory, then type
</P>
<!-- CODE SNIP //-->
<PRE>Skeleton.height: 480
Skeleton.width: 640
</PRE>
<!-- END CODE SNIP //-->
<P>and save the file. Next, replace the line
</P>
<!-- CODE SNIP //-->
<PRE>skeleton = XtVaAppInitialize(&skel_app, "Skeleton", NULL, 0, &argc,
Âargv, NULL, XmNwidth, 320, XmNheight, 240, NULL);
</PRE>
<!-- END CODE SNIP //-->
<P>with
</P>
<!-- CODE SNIP //-->
<PRE>skeleton = XtAppInitialize(&skel_app, "Skeleton",NULL,0, &argc, argv,
NULL, NULL,0);
</PRE>
<!-- END CODE SNIP //-->
<P>Rebuild the program and run it. You should see a much larger window than the earlier
version. Finally, yet another way to feed resources to this program is to create a file called
Skeleton, type in the resource strings for width and height mentioned earlier, and save the file into the
</P>
<P>/usr/X11R6/lib/X11/app-defaults directory. This way, the program will start with a
default window size for everyone on your system.
</P>
<A NAME="PAGENUM-540"><P>Page 540</P></A>
<P>Continuing with the example, the client's main window as a managed widget is created
next with XtVaCreateManagedWidget(); then a menu bar is built across the top of the window
with XmCreateMenubar(). After that, a pull-down menu is created with
XmCreatePulldownMenu(), and then a File button is built on the menu, which will respond not only to a mouse click, but
also to Alt+F.
</P>
<P>Building the rest of the File menu is now easy. Note the callback routine to tell the
program what to do when the Exit menu item is selected. After the File menu, the Edit menu is
created in the same way, along with the Help menu.
</P>
<P>
<CENTER>
<TABLE BGCOLOR="#FFFF99">
<TR><TD><B>
NOTE
</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
Thanks are due to Ken Lee's Motif FAQ for the tip on moving the Help menu string to
the end of the main window's menu bar.
</BLOCKQUOTE></TD></TR>
</TABLE></CENTER>
</P>
<P>Finally, the menu bar is displayed, along with the application, and the program starts
waiting for keystrokes, clicks, and other events in
XtAppMainLoop().
</P>
<P>As you can see, even in a simple Motif program, there's a lot of code devoted to handling
the user interface. Using Motif can save you a lot of time and effort because a lot of the code
required to build, display, and handle the interface is hidden in the Motif routines. This can
free you to concentrate on the internals of what your program does and gives your programs a
consistent look and feel.
</P>
<H3><A NAME="ch26_ 17">
Shared and Static Libraries
</A></H3>
<P>Using shared libraries when you build applications makes sense because program binaries
use a lot less space on your hard drive. But what if you want to compile a program for someone
else who might not have the Motif libraries installed?
</P>
<P>In this case, you might want to build the program using
Motif's static libraries. If you do, be prepared to find that a lot of extra code is linked into your program. How much bigger will
the program be, and how much of a difference using a static build will this make, you might
ask? Let's see! First, you'll build a sample program in two different versions, using the
gcc compiler option -static:
</P>
<!-- CODE //-->
<PRE># gcc -static -o skel.static skeleton.c -L/usr/X11/lib
Â-lXm -lXpm -lXaw -lXt -lXext -lX11
# gcc -o skel.shared skeleton.c -L/usr/X11/lib
Â-lXm -lXpm -lXaw -lXt -lSM -lICE -lXext -lX11
</PRE>
<!-- END CODE //-->
<P>Now let's see the size of the files skel.static and
skel.shared:
</P>
<!-- CODE SNIP //-->
<PRE># ls -l skel.*
-rwxr-xr-x 1 root root 12708 Sep 12 05:12 skel.shared
-rwxr-xr-x 1 root root 1978564 Sep 12 05:11 skel.static
</PRE>
<!-- END CODE SNIP //-->
<P><CENTER>
<a href="0533-0536.html">Previous</A> | <a href="../ewtoc.html">Table of Contents</A> | <a href="0541-0543.html">Next</A>
</CENTER></P>
</td>
</tr>
</table>
<!-- begin footer information -->
</body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -