Xref: utzoo comp.windows.x:25931 comp.windows.x.motif:488 Path: utzoo!attcan!utgpu!news-server.csri.toronto.edu!mailrus!uwm.edu!lll-winken!sun-barr!newstop!sun!argv From: argv@turnpike.Eng.Sun.COM (Dan Heller) Newsgroups: comp.windows.x,comp.windows.x.motif Subject: Re: Creating a Message Box Message-ID: <140925@sun.Eng.Sun.COM> Date: 18 Aug 90 18:41:33 GMT References: <1990Aug16.025738.13408@media.uucp> <140782@sun.Eng.Sun.COM> <1511@s5.Morgan.COM> Sender: news@sun.Eng.Sun.COM Organization: O'Reilly && Associates Lines: 72 In article <1511@s5.Morgan.COM> jordan@Morgan.COM (Jordan Hayes) writes: > Actually, although Dan's suggestion is decent, i'd rather do it with > the callback taking the action directly, rather than setting a local > variable and doing your own main loop (what if you also have other > input sources? why block them?). When the callback gets called, go > open the file. I can't see the "blocking of other input sources" as being a problem or having any negative effect here. If you post a dialog box and return, your input sources are not blocked because the XtMainLoop() routine will continue to get events and read input, etc. Writing your own XtMainLoop in the middle of another routine (a callback) has no affect on that at all -- those other input sources remain unblocked. Furthermore, since the dialog box is *modal* the user has no ability to interact with the application anyway. In fact, your own XtMainLoop() has no real negative side effects here. Once you understand that your own XtMainLoop() is no different from returning to the first (original) XtMainLoop() called in the program, you begin to understand how this feature can be xploited to solve many logistical problems within an application design. For example, consider is a button in the main application labled "save" that when the user selects it, its corresponding callback routine saves the current data to a file specified in some text widget or file selection box somewhere. if (file_exists(filename) == False) { /* ask user to he wants to create it */ answer = AskUser("File does not exist, create it?"); if (answer != YES) return; } else { answer = AskUser("File Exists, Overwrite?"); if (answer == CANCEL) return; mode = (answer == YES)? "w" : "a"; } if (!(fp = fopen(filename, mode))) { post_error("Can't open filename for %s", *mode == 'w'? "writing" : "appending"); return; } In the above scenario, it is clear that the flow of control is much easier to understand (as a reader) and easier to control (for the programmer). Maintenance is also easier because if had we used the design of return-to-main-loop-after-each-dialog-is-popped-up, then you would have to write a large amount of callback routines for each dialog box and each question answered. If we used your suggestion of "open the file within the 'answer' callback routine", then you must write a specialized routine for each scenario that may come up. Code size and complexity is substantially reduced by _generalizing_ the problem into one or two small routines that can be used in an arbitrary way. The only routines required are the AskUser() routine and the response() routine I outlined in my previous posting. AskUser() is the "public" function that takes a string as a "question" and puts it into an InformationDialog (if you're using Motif) and sets the okCallback and cancelCallback to be response(). That is the "static" function used only by AskUser() that sets the "answer" variable which is ultimately returned to AskUser(), which is ultimately returned to the code displayed above). [note: post_error() above just needs to post a dialog and return; it does not need to simulate XtMainLoop() like AskUser does.] -- dan ---------------------------------------------------- O'Reilly && Associates argv@sun.com / argv@ora.com Opinions expressed reflect those of the author only.