Chapter IV Forms Programming In this chapter, I will continue to show the reader's simple and effective program style by adding an About dialog to the Contacts program for the previous chapter. You will learn how to create a form with bitmap, text, and buttons. You can join menu and code in the Contacts program allow you to access the About dialog and return to the Contacts main form. In this process, we will first understand the basic settings of the application, create a large and small application icon for the Contacts program. Program Settings We will change some settings that have affected throughout the program. It will also create icons for Contacts. First, make a backup for your program: 1. Open a Windows file browser; 2. Find the Contacts folder; 3. Copy and paste Contacts; 4. Named new folder is Contacts Ch.3. This is your backup folder. Create a size application icon first review the project settings of the resource constructor. Note: The constructor version of Code Warrior6 has a bug-- does not allow you to create and edit multiple (multibit) icons. We found a solution that found file icon.txt in the CD included with this book, and wrote how to solve this problem. 1. Run the resource constructor, open contacts.rsrc; 2. Find the project setting icon at the bottom of the Contacts.RSRC window. If there is only one pointing arrow at the bottom of the window, click the project settings will pop up. In engineering settings, there is generally changed: the name, version string, and application icon of the application icon. In the previous chapter, you have changed the name of the application icon. Table 4-1 lists all sets of extreme functions: Name Description Generate App Resources generates version and icon names for the application, I suggest that you are in most cases the sub-check box. Application Icon Name Application Version String Application Version Number. When you make a meaningful modification for your application, you should improve the version number to represent a different version. Application icon defines a black and white program large icon, which is prepared for Palm OS 2.0 and earlier, not available here. Auto Generate Header File resource constructor automatically generates header files. Select. The include Details In Header resource constructor adds content to the header file. Select. Keep IDS in Sync automatically changes the ID when the resource constructor changes when the control ID changes. If you don't change the ID in the program, you can don't choose; but in general, you will be better. Table 4-1: Options for the project settings in the resource constructor. 3. Create an application big icon. Select Multibit Icon from the resource list and press CTRL-K. Be sure to ensure that the resource ID is 1000. Also note that if you press the Create button on the edge of the application icon properties, the standard icon is generated instead of multiple icons. Although it can also generate large icons, it is not ideal. 4. Double-click the new icon, pop up a editing window, you can draw it in it now. By selecting two icons on the right end of the editing window, determine the color of the black and white or 2 bits. The editing controls in the edit window are similar to the drawing (Paint) and other charts under Windows. When the completion is completed, the window can be turned off by X on the top of the window. Figure 4-1 is the large icon drawn by the person; Figure 4-1 Large icon 5 in a Contacts program. Next, create an application small icon.
It can only be displayed in Palm OS 3.0 or later. Open the Contacts.RSRC window, select Multibit Icons; 6 on the Resource Type and Name panel. Press CTRL-K to create a new icon; 7. Click ID and change it to 1001, this step is important; Click on the new icon. The icon editing window is popped, because the Palm OS only displays the upper 9 pixels and the leftmost 15 pixels, pay attention to when design. The small icon drawn, as shown in Figure 4-2; Figure 4-2 Small icon CodeWarrior in a Contacts program How to use the project settings in this section How to use the application: 1. The CodeWarrior integrates the development environment and opens the Contacts project; 2. Select Edit | Stater Settings. The reason for the program setting is also called Stater Settings is that it has not changed it since we have established a Starter project. At Stater Settings will find a large number of setup options, don't mix them; 3. The left side of the Stater Setting dialog is set to set the tree. Select Target Setting under Target Switch, change the name in Target Name by Starter to Contacts; save, the CodeWarrior integration development environment will call the project Contacts; 4. Check 68k Target under the Target subtree, change the file name from starter.tmp to Contacts.tmp; 5. Palmrez Post Linker under the Linker subtree. Change the Mac Resource Files to Contacts.tmp; Turn Output Files Set by Starter.prc to Contacts.prc, add contacts-PPGU to the blank; Note: As mentioned, in Palm Equipment All things are saved in the form of a database, and the application is no exception. Each database must have a unique name, otherwise there will be a problem. Contacts-PPGU is the file name associated with its unique original ID, so naming ensures uniqueness. For more primitive ID, please refer to the next chapter. There are still many other setting properties under the Contact Settings sub-tree, but there is no need to set them at this time. If you are interested, you can refer to the contents of the CodeWarrior Integration Development Environment Guide (Guide). Multi-window interface we will add a form to the Contacts program: ABOUT form. We will also modify the code in Contacts.c to switch between the forms. Add that the contents of the contents.rsrc file We will add an About Form for the resource file: 1. Open the resource constructor, open the file contacts.rsrc; 2. Built a About form. Select Forms from the list of resource files and press CTRL-K; 3. Name form. Click the name Untitled to About; 4. Hit the About Form; 5. Find the form properties on the left of the Form dialog panel. Table 4-2 Lists the various properties of the form extremely use; 6. Modify the form properties. Check Save Behind, write About Contacts.
Table 4-2 Forms The number of pixels of the left position of the LEFT ORIGIN form, the entire screen is 160 pixels. The number of pixels of the top position of the top origin form is 160 pixels from top to bottom. The width of the Width form does not necessarily spend a full screen. Height form height. Usable determines if the form is visible, if the object is not identified as usable, it is invisible. The form is usually identified as usable. Modal If the form is a working form and selects Modal, the strike event outside the window is not worthy of any effect. The name of the MODAL form is in the center of the top of the form. The Modal form is not interrupted by a system dialog such as a warning, so it should be cautious when used. Save Behind If selected, after the form is closed, the contents of the form on the screen before the form will be saved. The ID number of the form ID form, ID unique identifier form. Help ID If the form is modal, you can fill in the ID string representing the help information resource file, and an "I" icon appears in the upper right corner of the form. If you press it, the help information will be called. The Details form in the Date Book application has one such example available for reference. The ID number of the Menu Bar ID Form Menu bar, in the last chapter, we will use this property to add a menu. DEFAULT Button ID If this ID number is provided, when the user switches other applications, the Palm OS will automatically press this button before exiting. This is especially convenient for MODAL forms, often used by the default button for Cancel. Form Title If a title is provided for the form, Palm OS will create a title bar that is written with you setting the title. Add a bitmap to the About Form Add a bitmap, steps as follows: 1. Select the Bitmaps under the Resource Type and name list; 2. Create a new bitmap by ctrl-k; 3. In the constructor, select Options | SET Image Size. Allows you to adjust the size of the bitmap; 4. Adjust the bitmap size is 42x42; 5. Draw a bitmap. The picture I made is shown in Figure 4-3. It is difficult to make such a large picture with the editor of the constructor. I first use the brush (Paint) painted and cut it; 6. After the painting. Click the X-closed bitmap editor in the upper right corner; 7. Add the bitmap to the Contacts form. Select Window | Catalog to open the Catalog window. Drag one bit map to the About form; 8. Change the properties of the bitmap. The properties of the bitmap are very intuitive. Please refer to Table 4-3; 9. Set the BitMap Resource ID to the resource ID number of the bitmap created in front. Its ID number should be 1000. At this point, you should see your bitmap in the general location that appears in the bitmap; 10. Set the location map in the form of Left Origin and Top Origin. Set the left position of 59 (let it in the middle) top position is 20 (let it under the title bar). The Object ID identifies the unique ID number in the list. This number cannot be the same as any other ID number in the application. The name of the Object Identifier bitmap. The number of pixels left on the left position of the Left Origin bitmap, the full screen is 160 pixels. The number of pixels on top of the top of the top origin bit is 160 pixels up and down the full screen. Bitmap resource ID determines the ID number of the resource file of the bitmap. USABLE determines the visible or not of the bit map. Bitchart can only be seen when it is marked as usable. Add Tags Now create a label that contains Contacts information. You can drag a label onto the form from the Catalog window. Table 4-4 lists the properties of the label object. Object Identifier Label Name.
The variable created in the contacts_res.h file is from this name. Label ID Palm OS is used to identify the unique ID number of the object. Left Origin Label The number of pixels in the left position. The full screen left and right length is 160 pixels. The length of the label is determined by the number of text it contains. Top ORIGIN Tariff The number of pixels at the top position. The full screen is up to 160 pixels. The label contains the number of lines of text and the size of the font will determine the height of the label. USABLE determines whether the label is visible on the form. If you are not selected, the label is invisible. This setting is used when you want to change the control or inaccessible to the control. Font tag size of text fonts. You can find the font yourself through the Windows Key Caps utility. Text displayed in the Text tag. The content in the label is generally the name of the application, you or your company's name, copyright information, and programs of the program. I created two labels to make the Contacts fonts than the remaining fonts. Due to the bitmap and tags are not mentioned in the code, there is no longer more than the resource constructor to meet your requirements for different bitmaps and labels. I found the version symbol from the Pilot basic font via the Windows Key Caps utility, and the replication character is in the resource constructor. Add button Create a button at the bottom of the About Form. You can name it OK or any other name. When Contacts.c modified, the function of this button is to close the About Form and return to the Contacts form. Because we have not officially introduced in addition to the initial example, it is not officially introduced, so the following details will be described in detail. The name of the Object Identifier button. The variable created in the contacts_res.h file is from this name. Button ID Palm OS is used to identify the unique ID number of the object. Left Origin button The number of pixels on the left position. The full screen left and right length is 160 pixels. Since the left side of the button is at least one pixel on the left side of the button, the leftmost end of the button should be set 1. For the Bold button, you have to need two pixels. Width button width. And the actual width, it should be added to the normal button, and 2 should be added to the BOLD button. Height button height. And the actual width, it should be added to the normal button, and 2 should be added to the BOLD button. USABLE Decision button is visible on the form. If you are not selected, the button is invisible. This setting is used when you want to change the control or inaccessible to the control. Anchor Left determines how to self-adjustment when the label length is changed when the application is changed. When selected, the right end of the button will be adjacent or shortened; otherwise, the left side of the button is correspondingly elongated or shortened. Frame If selected, the button has a border. Non-bold frame If selected, the button border accounts for a pixel; otherwise, the border accounts for two pixels wide. The size of the font font on the font button. You can find the font you need through the Windows Key Caps utility. The text displayed on the Label button. Name the button OK. When all the properties are set, you will see a graphical interface shown in Figure 4-4. Add Menu Access the About Form by selecting the option to the Option menu entry. Create an OPTION menu and join the Contacts menu bar. The steps are as follows: 2. Select Menus in the Resource Type and name list, and press Ctrl-K to create a new menu; 3. Click the Name area to name Options; 4. Double click Options to open; 5. In the menu bar The title is changed to Options; 6. Press Ctrl-K to create a new menu.
Name it is About Contacts; 7. Turn off the Options menu; 8. Double-click to open the Contact Detail menu bar; 9. Drag the Options menu from the Resource Type and name list to the back of the Contact Detail menu bar Edit menu. When you are finished, your Contacts menu should be shown in Figure 4-5; 10. Close and save Contacts.RSRC. Figure 4-4: Current Form Appearance To Contracts.c To make multiple forms, we need to add code and other parts in Contracts.c. The first addition is an Option menu, and we have to add some code to this menu. Form-loading code wider application Because we have to load multiple forms, we now modify the Form-Loading code to make it easier to operate. In the head of the file, change the myHandleEvent () function name to ContactDetailHandleevent () because this event is only used for Contact Detail forms. After the prototype function modified as follows: // Prototypes for our event handler functions static Boolean contactDetailHandleEvent (EventPtr * event); myHandleEvent () function should be modified as follows head: // Our Contact DETAIL form event handler functions static Boolean contactDetailHandleEvent (EventPtr Event) {Next, we deal with an event called frmopnevent. This event is sent when switching from a form to another. After modifying the event processor to switch the form, I want to modify the form. Word index; // ch.3 a general purpose index fieldptr field; // ch.3 used for manipulating fields // ch.3 get outactiveform (); // ch.4 Parse Events switch (Event- > eType) {// cH.4 form open event case frmOpenEvent: {// cH.3 Get the index of our field index = FrmGetObjectIndex (form, ContactDetailFirstNameField); // cH.3 Get the pointer to our field field = FrmGetObjectPtr (FORM, INDEX); // Ch.3 Set The Editable Text FldSettextHandle (Field, HTEXT); // Ch.2 Draw The form frmdrawform (form); // ch.3 set the focus to outfocus (form, Index);} Break; frmopnevent block, cut the code from the Pilotmain () to the event cycle, put the code here. Thus, when we switch between the form, this code will be executed whenever the form is displayed. This code will be executed several times when performing an application. Before we switch the form, you should first get the contents of the source form text box. This is because all memory associated with the original form will be released when we switch to a new form. This will encounter a big hassle when we return to the original form.
We get the text handle by processing FRMCLOSEEVENT. When switching to another, the current form is logged out, the frmCloseEvent event is triggered. // CH.4 Form close event case frmCloseEvent: {// CH.3 Get the index of our field index = FrmGetObjectIndex (form, ContactDetailFirstNameField); // CH.3 Get the pointer to our field field = FrmGetObjectPtr (form, index ); // ch.4 Unlink Our handle from the field fldsetTextHandle (Field, NULL);} Break; Everything we do here is to get a pointer to the domain, set its text handle to NULL. We need to use a call that will cause the frmopnevent to replace the code we cut from pilotmain (). If we don't do this, what happens. We will always stare at a blank screen because the first form will never be loaded. The function you use to send FRMLOADFORM and FRMOPENFORM events to switch the form is frmgotoform (). The code other than frMgotoform () is as follows: //ch.3 Release The String Resource DMRELEASERESOURCE (HSRC); //ch.4 Go To Our Starting Page frMotoform (ContactDetAiltorm); //ch.2 Our Event LOOP DO {The last code for promoting form loading is to switch event handlers from a form to another form. Each form has its own event processing. A good way is to answer the FRMLOADFORM event, even in the main event loop. The code is as follows: // ch.3 Handle Menu Events IF (MenuHandleevent (Null, & Event, & Error) Continue; // Ch.4 Handle Form Load Events if (Event.Type == frmloadevent) {// ch.4 Initialize Our form switch (event.data.frmLoad.formID) {// cH.4 Contact Detail form case ContactDetailForm: form = FrmInitForm (ContactDetailForm); FrmSetEventHandler (form, contactDetailHandleEvent); break; // cH.4 About form case AboutForm: form = FrMinitform (Aboutform); fmseteventhandler (Form, AboutHandleevent); Break;} frmsetAntactiveform (} // ch.2 Handle Form Events frMdispatchevent); for each of the forms we want to load, we are in the Switch statement Increase the CASE statement to initialize the form and set the corresponding event processing. It is time to do some work in the internal existence of us allocated in the previous chapter. Although our text handle will be released when the application process is removed from memory, we are best to explicitly uninstall it at the end of pilotmain (), because the form no longer releases its text handle.
// Ch.4 deallocate Memory MemHandlefree (htext); // ch.2 We're Done Return (0); the ticker of the program is an important factor associated with the application process crashes. When your program becomes more complicated, your program code is moved everywhere, and order and release memory will save you a lot of time for you. Handling Options menu We will obtain the About form by a practical selection menu item. Because all menu IDs are unique, you only need to add some code for Contacts in existing menu time: // ch.3 Erase the menu Status from the display menuerasestus (null); // ch.4 handle Options menu if (event-> data.Menu.itemid == optionsaboutcontacts) {// ch.4 POP UP UPUPUPFORM (TRUE);} // ch.3 Handle Graffiti Help IF (event-> data.menu.itemID == EditGraffitiHelp) {// cH.3 Pop up the graffiti reference based on // the graffiti state SysGraffitiReferenceDialog (referenceDefault); return (true);} after calling MenuEraseStatus () in MenuEventHandler The increased code in () will run normally. You check the ID of the new selection, then call frmpopusform (). FRMPOPUSFORM () is similar to frmgotoform (), except for the old form, never close. This is appropriate in the About Form, because we know that we will return from the About form to the Contact Detail form. There is no other path other than this. This means that we don't need to do our universal form transform work in the previous chapter. Despite this, we'd better add form transform code so that we don't have to worry about making the Contact Detail form behavior when joining the form. Note: Here we are in the process of processing the Options menu for the EDIT menu. How is this going? It turns out that Contructor gives the unique ID number to all menus items for all menus. Therefore, there is no need to deal with a set of menu items separately. Add an event to the About Form to handle each form should have its own time handle, so we add an event handler for the new About form. First, add a function prototype to the event handler of the About Form, called AboutHandleevent (). The following code: // CH.3 Prototypes for our event handler functions static Boolean contactDetailHandleEvent (EventPtr event); static Boolean aboutHandleEvent (EventPtr event); static Boolean menuEventHandler (EventPtr event); then, the code was added in frmLoadEvent event loop processing. This code will initialize the About Form and add event handler to frmdispatChevent ().
// CH.4 Initialize our form switch (event.data.frmLoad.formID) {// CH.4 Contact Detail form case ContactDetailForm: form = FrmInitForm (ContactDetailForm); FrmSetEventHandler (form, contactDetailHandleEvent); break; // CH. 4 About Form Case ABOUTFORM: FORM = frMinitForm (Aboutform); fmseteventhandler (form, abouthandleevent); break;} The remaining thing is to join the time handler "AboutHandleEvent (). // ch.4 Our About form Event Handler Function Static Boolean AboutHandleEvent (EventPtr Event) {Formptr form; // Ch.4 a Pointer to Our FormTure // Ch.4 Get Our Form Pointer form = frMgetActiveForm (); // Ch.4 respond to the open event if (event-> eType == frmopenevent) {// ch.4 draw the form frmdrawform (form);} // ch.4 return to the calling form if (event-> eType = = CTLSELECTEVENT) {frmreturntoform (0); // ch.4 Always Return True in this case (true);} Event handler The FRMopenevent response is basically called with unique display form: frmdrawform (). It also responds to CTLSELECTEVENT just like our first Hello application, except this time, it does not send alarm, but call frmreturntoform (). The frmreturntoform () function makes the About form, the form of the form (here is the Contact Detail Form) is reactivated. Note: Returning TRUE is important when returning a call. The reason is that the Palm OS tries to fully handle the CLTSeleCte event event, and the processing work includes processing the structure that is eliminated in the invoke frmreturntoform. In order to avoid these memory evil, TRUE is always returned after frmreturntoform, so that the form will disappear immediately. Debugging is back to debug. Your Contact Form looks and works as before. Your About Form will pop up when you select a corresponding item from the Options menu. When you press its OK button, the form returns a Contact Detail form. The Contact Detail Form contains an original EDIT menu and a new Options menu. The About Form does not have a menu bar because we didn't define it. As before, the program started in pilotmain (), followed by the usual path. When the frmloadevent event is processed, it initializes the event handler of the Contact Detail form. Thereafter, the FRMopenevent event is sent to the event handler of the Contact Detail form. There, the event is processed, the form is drawn, and each domain is set as before. Then the program is waiting for the incident.
Contact Detail form is waiting for input status Next? In the next chapter, we will continue to examine more Palm-based control-based controls. The source code is below all the code of the new version of Contacts.c.
// CH.2 The super-include for PalmOS #include // CH.3 Our resource file #include "Contacts_res.h" // CH.3 Prototypes for our event handler functions static Boolean contactDetailHandleEvent (EventPtr event); static Boolean aboutHandleEvent (EventPtr Event); static boolean menueventhandler (Eventptr Event); // ch.3 Our Field Memory Handle Static Handle Htext; // Ch.3 Handle to TEXT IN Our Edit Field #define htext_size 81 // ch.3 Size OF our edit field // cH.4 Constants for ROM revision #define ROM_VERSION_2 0x02003000 #define ROM_VERSION_MIN ROM_VERSION_2 // CH.2 The main entry point DWord PilotMain (Word cmd, Ptr, Word) {DWord romVersion; // cH.4 ROM version Formptr form; // ch.2 a Pointer to Our Form structure handle hsrc; // ch.3 handle to the string resource charptr psrc; // ch.3 Points to the text; // ch.3 Points to the text in the edit field events; romVersion = 0; FtrGet (sysFtrCreator, sysFtrNumROMVersion, & romVersion); // CH.4 If we are below our minimum acceptable ROM revision if (romVersion // ch.3 Lock The Resource, Get The Pointer PSRC = MemHandLock (HSRC); // Ch.3 Allocate Our Field Chunk HText = MemHandleNew (htext_size); if (htext == null) Return (0); // ch .3 LOCK THE MEMORY, GET the POINTER PTEXT = MemHndLock (htext); // Ch.3 Initialize It Strcopy (PTEXT, PSRC); // Ch.3 Unlock The Field's Memory MemHenLock (htext); //CH.3 Unlock the resource's memory MemHandleUnlock (hsrc); // cH.3 Release the string resource DmReleaseResource (hsrc); // cH.4 Go to our starting page FrmGotoForm (ContactDetailForm); // CH.2 Our event loop do {// CH .2 get the next este devtgetevent (& Event, -1); // ch.2 Handle System Events IF (Syshandleevent (& Event)) Continue; // Ch.3 Handle Menu Events IF (MenuHandleEvent (Null, & Event, & Error)) Continue; // ch.4 Handle Form Load Events if (event.type == frmloadevent) {// ch.4 initialize it form (time.data.frmload.form) {// ch.4 Contact Detail Form Case ContactDetailform : form = frMinitform (ContactDetailf) orm); FrmSetEventHandler (form, contactDetailHandleEvent); break; // CH.4 About form case AboutForm: form = FrmInitForm (AboutForm); FrmSetEventHandler (form, aboutHandleEvent); break;} FrmSetActiveForm (form);} // CH.2 Handle Form Events FRMDISPATCHEVENT (& Event); // Ch.2 if it's a stop event, exit} while (event.type! = AppstopeVent); // ch.4 deallocate memory memhandlefree (htext); // ch.2 WE ' RE DONE RETURN (0);} // ch.4 Our Contacts form handler function static boolean contactDetailHandleEvent (eventptr form; // ch.3 a Pointer to Our Form structure word index; // ch.3 a recognor Purpose Index Fieldptr Field; // ch.3 Used for manipulating fields // ch.3 Get outform Pointer form = frMgetActiveForm (); // ch.4 Parse events switch (event-> eType) {// ch.4 Form Open Event Case FRMOPENEVENT: {// cH.3 Get the index of our field index = FrmGetObjectIndex (form, ContactDetailFirstNameField); // cH.3 Get the pointer to our field field = FrmGetObjectPtr (form, index); // cH.3 Set the editable text FLDSETTEXTHANDLE (FIELD, HTEXT); // Ch.2 Draw the form frmdrawform (form); // ch.3 set the focus to outfocus (form, index);} Break; // ch.4 Form Close Event Case frmCloseEvent: {// cH.3 Get the index of our field index = FrmGetObjectIndex (form, ContactDetailFirstNameField); // cH.3 Get the pointer to our field field = FrmGetObjectPtr (form, index); // cH.4 Unlink our Handle from the field fldsetTextHandle (Field, Null);} Break; // ch.3 Parse Menu Events Case Menuevent: Return (MenueventHandler (Event)); Break;} // ch.2 We're Done Return (false); } // ch.4 Our About Form Event handler function static Boolean aboutHandleEvent (EventPtr event) {FormPtr form; // CH.4 A pointer our form structure // CH.4 Get our form pointer form = FrmGetActiveForm to (); // CH.4 Respond to the Open event if (Event-> ETYPE == frmopenevent) {// ch.4 Draw the form frmdrawform (form);} // ch.4 return to the calling formiff == ctlselectevent) {frmreturntoform (0); // ch.4 Always Return True in this case return (true);} // ch.4 We're done return (false);} // ch.3 handle menu events boolean menueventhandler (eventptr av) {FormPtr form; // ch.3 a Pointer to Our Form structure word index; // ch.3 a general purpose control index fieldptr