Palmos Development Tutorial - 12

zhaozj2021-02-08  223

Chapter 12 Professional Programming Tips As the program grows, we will find a lot of problems. These issues may not appear when preparing a few thousand lines of code, but when you are coded or more and the program is written by different programmers, there is a runtime issue. This requires procedures for well-thoughtable structures and detailed comments. At the time of the preparation of large procedures, consider two points: 1 How to make the program easy to maintain 2 how to make the program can be reused (Reuse) Of course, we want to make the program can be seen by anyone, easy to maintain and reuse. Especially for Palm OS, it is very efficient to take such a strategy because of many of its application forms. Although the PC's processor speed and memory are rapid, it is necessary to use the processor and memory on the Palm OS now. But you can't ignore maintainability, only have good maintenanceability to make the code easier to optimize. In this chapter, we will contact a lot of professional programming strategies. In the process of learning, we will also establish some reusable modules based on these strategies, I hope you can get benefits in these programming strategies. Through this chapter, you can make a solid foundation for you to create a Palm OS application. Type protection variables and portability portability is one of the key factors that can be reused. Portability means that the code can make very few modifications can be compiled by different compilers; and only the interface and code separation (because the interface is generally based on the system, the code should work on different platforms) Improve portability. In the next few chapters, we will prove the contents mentioned below. The user interface and program code of the calculator are separated so that the calculator program can be easily applied to the Windows or Macintosh platform. To make the program work under different compilers and systems, using type protection variables is one of the main ways. Maybe you still don't know what type of protection variable, but in this book we have been using type protection variables - at least the type of protection variable using the Palm OS version. Type protection variables refer to: Not use data types in standard C, such as int or char, but using the command typedef from the defined data type. Z why type protection is so important? This is because in Standard C, such as INT is 16 bits in the CodeWarrior C compiler, and in other common compilers include GCC, its length is 32 bits. If you use the data type Int in many places and want to convert from the CodeWarrior to GCC, the data structure is changed due to the length of the type INT, and the data structure is changed, and the size of the database record has to be changed. If the situation is serious, the program will not run at all. More than just type INT can cause portability problems. There are also other types of such problems, such as data type char, in Japan, and char is 16 bits, rather than the 8-bit referred to. Therefore, if you want to make the program being international, you need to re-do a lot of work. The type of protection variable and Palm OS, my opinion is if you write a Palm OS-based user interface code, use the Palm OS type protection variable. In the development of Palm OS, its developers will carefully process these types of protection variables. This way you will find that you can easily upgrade an existing version to a new version as long as you use the correct type of protection variable. If you write the code, you will work on other operating system platforms, and you should use your own defined data type. Of course, it is no longer possible to call the PALM OS function, call these functions with the function name of its own definition, or use the #define statement to modify the function name in the header file to call these functions. Using Hungarian NOTATION When you look at a bulk code, it is easy to forget the data type of the variable defined in the function header.

Using Hungary symbols is a good way to solve this problem because it allows others to understand. In the Hungarian symbol, it uses some letters at the beginning of the variable, allowing you to remember the data type of the variable. For example, "C" represents Char, "P" represents a pointer, so CPBuffer represents a char * variable to a buffer. The Hungarian symbol has a lot of styles. In Table 12-1, it is my two versions, I found that they can apply well in C, C and Mac, Windows, Unix, of course, also include Palm OS. In the next section, I will all use these symbols to define variables. Alphabetical data type description and example a [] array symbol: char cabuffer [20] b byte 8 byte digital variable: byte bflags c char Byte: CHAR CD DWORD 32 bytes Digital variable: DWord DCOUNTER E Enum enumeration type Variables: Spevent-> ETYPE F float 32 byte floating point number: Float Fresult G Global global variable, you can use in all modules: App_t GsApp H Handle is Void * in some systems, other int: voidhand HRECORD I INT Integer Variables: Int ICOUNTER JK ConST Confinition or Return Value in C Definitions L Long Long IValue M Member Structure or Class Member Variable: Char McAbuffer [20] N Double 64-bit floating point number : Double Nbignum o Boolean Boolean, true or false: Boolean OfirstPass P P P P P P P P P P P P Pinger: Void * VPPointer QR RAW Binary Data Class (C ) s Struct Structure or Class: SEVENT T TEXT Text Class (C ) U UNSIGNED No Sign Number: Unsigned Bong Ulnumber V VoID Empty Data Type: Void * VPPointer W Word word, generally 16 bytes: Word WRMBER XYZ can reuse main module we will start from beginning, although it is boring but you will have a lot of gains. The first step we first create a routine that is like the Hello program in the second chapter. But our new program will be more easily reused and extended to larger programs. Learning how to create a main program framework is not difficult. First open the CodeWarrior IDE to create a program called CCulator. Remove all the files in the source file and resource folder and clear all the files in the SRC folder. Create a new resource engineering from the constructor to save it as a Calculator.RSRC. Press CTRL-K to create a new form. Open the form and place a button to the middle of the form. Using this button will be tested to our program is running. Then we will create a real user interface for the calculator. The program's interface is shown in Figure 12-1: We also add a warning called LowromVersionError. When the Palm device version we use is too old to support the function used in the program, you will pop up this warning box, as shown in Figure -12: Now add some source code to the project. 1. Open the CodeWarrior IDE and select Project | CREATE New Group; 2. Name it AppinCludes. This will put your files.

The project puts the default creation of a header file called Caculator_res.h into the folder; 3. Add Caculator_RES.H to this new group. The main.c module now creates a new file called Main.c, put it in the Appsource group. This module includes an entry of an application and event loop to be reused. The details are as follows: /////main.c // main entry point and event loop. // Copyright (c) 1999, Robert Mykland. // Note Ten very good habits, actually this is also Program maintainability key. As a professional programmer, if you have written a lot of code but there is no comment, then this programmer will not increase again and will become exhausted. The level cannot be improved because no one can understand his procedure and cannot make a defect in the process; it becomes exhausted because he has to use it in this annoying program. Remember, you want to comment, don't make this. Sometimes I feel very lucky because I mainly use the assembly language when I just learn. If you don't comment, you have to spend a lot of time to make a few things you wrote in a few weeks. This is also the case using C, but the degree is different. If you have a few hundred thousand lines of code with other 12 people, it is necessary to write it to the program in the form of a comment. In the past, I often I can't afford to write something in the comment. Now I have basically had a general format. For example: I will write as the comment as shown in each module, and some people like to write the version number. It is necessary to write the version number to the source control system (Source Control System), otherwise, I think there is no use of the version number. Note: What is the Source Control System? This is a tool for storing and returning the different version numbers. When a large BUG is found, you can use the procedure that can run and the crash, which changes you have done. You can also divide the code into different versions. If you and other programmers develop a big program, the source program control system will guarantee that you and their modification of the program will prevent the program from not unify. Totally, for professional programmers, the source program control system is an important tool. /////////////Clude "app.h" // the definitions for this application You may ask: Where is pilot.h to go? The header file app.h is the file we're customized, which will include all functions used in our program, which is pilot.h as header files. In a sense, this is a custom pilot.h, which adds our own needs. I think even for a big program, this is also a good way. If your header file is large, it causes a lot of time to spend a lot of time during compile, so you can let the CodeWarrior pre-transformed this file so that the compilation speed is greatly accelerated. /// // Global protoypes // /// DWORD PILOTMAIN (Word, PTR, WORD); // main entry point. Boolean Processevent (long); // processes the next event. These are the function defined in this module prototype. We have been using a function prototype, but what role is there? Function prototype can enhance the maintenanceability of functions. When the function prototype is defined, it can be guaranteed to pass the mismatched parameters to the function.

If such errors occur, there will be some difficult to understand, and these errors are not easy to find. However, in C is allowed to call the function without using a function prototype. In order to ensure the correct use of these functions, we will define another version in the header file app.h. The function prototype definition of this module head can guarantee the matching and definition of the parameters. / // local variables // //////////////////////////////////////////////////////////////////////////> The partition defines a local variable. This variable looks like a speech error. It is defined in App.h. Behind we will explain this variable in detail. It defines the event handler of the form in the program. In fact, this #define statement defines a function, we can also define this event handler with a lot of other common methods. I want to use uppercase letters or other striking formats to represent it, so that others (also have their own time after reading code), you can see the definition in this header file in order to understand it. What role is there. /// Global functionS // // // ------------------------------------ -------------------------------------- DWORD PILOTMAIN (// ------- -------------------------------------------------- ------------------- // The main entry point for this application. // ALWAYS RETURNS ZERO. // ------------- -------------------------------------------------- ------------- Word WCMD, // The launch code ptr, // the launch parameter block word // The launch flags // ------------ -------------------------------------------------- -------------- {This is one of the forms I often use. I think this is very good, because it is very clear, it is easy to find the head of this function in a very long function module. First, the content of the function and its return value are first, and the meaning of each variable and parameters will be made later. Some people also like to join the version number, but I don't want to do this, because there is no practical meaning. DWord dROMVersion; // Get the ROM version dROMVersion = 0; FtrGet (sysFtrCreator, sysFtrNumROMVersion, & dROMVersion); // Alert and bail if the ROM version is too low if (dROMVersion

In our Caculator example, the floating-point libraries used are only in Palm OS 2.0 and higher, so we define constants ROM_VERSION_MIN to ROM_VERSION_2. This way as we use different app.h to make main.c on different platforms, "hub" connecting each module together is written in app.h. // if this is not a Normal launch, don't launch if (wcmd! = SysapplaunchcmdnormAllaunch) Return (0); // initialize all parts of the application appinit (); the above code is also very familiar. First, it is determined that the function Appinit () initialization program is called normally, which initializes all the data to be run in the application. For example: In the Contacts program, we use Appinit () to open the database, in detail in the specific definition below. // Go to the starting form frmgotoform (startform); an event is incident to load STARTFORM. But we have no form called StartForm, which is defined in app.h as CalcForm. This is another trick we enable main.c to be reused. When we need to change the start form, we only need to change App.h without doing a lot of modifications in main.c. // Wait Indefinitely For Events Errtry {While (True) Processevent (-1);} // stop the application errcatch (}} errendcatch // clean up before exit appstop (); // We're done return (0 );} This code is basically the same as the event loop code we have in contact with our front, but the function call in the loop is in a separate function processevent (). This way we can control the event how the other part of the program is on, in the following chapter, you will find how it does this. After Errcatch (), we call AppStop (). Like Appinit (), it is defined in the app.h to connect to a link to different program modules, clear the program parameters before exiting the program. As you can see, even normal procedures are also stopped in this CATCH module, so appstop () should call at the exit of the module.

Here is our event handler: // ---------------------------------------- ------------------------------------ Boolean Processevent (// --------- -------------------------------------------------- ----------------- // Waits for and processes the next es q// Returns false if The queue is empty. // ----------- -------------------------------------------------- --------------- long ltimeout // Time to wait in 100ths of a second, -1 = forver // --------------- -------------------------------------------------- ---------- {Note Time Control Parameters in the Introduction Event, which is useful in controlling animation production and sound. Since Palm OS is a single task operating system, we need to control the runtime of the program. You may want to ask why pilotmain () does not return a value and processevent () returns a Bur. In the later program (such as in animation), we may want to know how the event is running so that the animation is smoother. At this time we will call processEvent () to process or refresh other functions. EventType sevent; // u uT Word Werror Event Handler // Get The Next Event EVTGTGETEVENT (& Sevent, LTIMEOUT); Some familiar variables are defined, and the function EVTGETEVENT () is called later. Note that this function passes our time parameters to the system. // if it's a stop event, exit if (sevent.type == appstopevent) {// exit errthrow (0);} Stop event processing has changed in previous comparedment. It is not just returning to main (), but feeds back the function errthrow () to the Errcatch () module in mi.c. Why can't we do it like this? If we call function processevent () and receive an appstopevent in other parts of the program, it is not a value to the main (), but returns a value to other places. So we need a mechanism, no matter where I receive AppStopevent, the error processor will be safe as C. // if it's a nil event, returnueue Empty if (sevent.type == nilevent) return (false); this is a new check action in the loop. When the event queue is empty, Palm OS will issue a Nilevent. Due to the previous program, we let Palm OS wait, we have never received this incident. Now after receiving Nilevent, we know that the event queue is empty.

When doing some time-consuming work, if you call ProcessSevent to periodically refresh the event queue, it will use the field. Therefore, it is important to return a specific value. // Handle System Events IF (True); // Handle Menu Events IF (MenuHandleevent (Null, & Sevent, & Werror) Return (TRUE); above is some common functions, we use them to handle system events And menu events. // load a form if (sevent.type == frmloadevent) {Word wformid; // the form ID forptr spform; // point wformid = sevent.data.frmload.formID; // initialize The form spform = frMinitform (wformid); // Establish The Event Handler FRMSETEVENTHANDLER (SPFORM, GETEVENTHANDLER (WFORMID)); // Point Events To Our FormSetActiveform (SPFORM); here is a normal form loading code. You look very familiar, first get the form of the form from the event structure, then initialize and draw the form. However, pay attention to getEventHandler () in FRMSETEVENTHANDLER (). This function is defined in App.h, which can obtain matching form IDs in accordance with the corresponding event handle, which allows us to process all forms in Main.c in the same way. So this code is that we don't have to know what forms in the program, you can reuse these code for processing. // Handle form Events frmdispatchevent (& sevent); // We're Done Return (TRUE);} This is the last point of Processevent (). We allocate the remaining events into the active form. If there is still an event that does not process, the function will return true. Main.h module header file main.h has definitions that support main.c, and have the function definitions added to the app.h to customize main.c. Create a main.h file into the source file, add it to the Calculator project and save it in AppinCludes.

Here is its detailed code: #ifndef main_h #define main_h // // main.h // definitions for the main entry point. // copyright (c) 1999, Robert Mykland. All Rights reserved. //// / / / / / / / Global prototypes // /// DWORD PILOTMAIN (Word, PTR, WORD); // main entry point. Boolean Processevent (long); // processes the next evenet. //// Constants ////// the different versions of PalmOS // Pilot 1000 and Pilot 5000 #define ROM_VERSION_1 0x01003001 // PalmPilot and PalmPilot Professional #define ROM_VERSION_2 0x02003000 // Palm III, IIIx, and V #define ROM_VERSION_3 0x03003000 #endif // MAIN_H at the beginning of the program is two Pretreatment instruction: #ifndef main_h and #define main_h, the corresponding at the end of the program, there is also a pre-processing instruction: #ENDIF. If Main_h is not defined, # ifndef and #endif This will skip all the code in the middle of the pre-processed instruction, and Main_h will be defined in their internal. The pre-processing instruction is to ignore the contents of the compiler have been ignored to prevent repeated compilation. In some more programs, for convenience, head files are not referred to in the same file. At this time, you can compile the code, but don't worry that the functions in the file are not defined. These preprocessing instructions can avoid making compilers spend some unnecessary time to make some duplicate compilation work. The contents of the standard head module are the function prototype in main.c, because they are exactly the same as the function definitions in the source file, so if there is a little bit between the two, the compiler will give an error warning. At the end of the function, it is defined for the constant of the version number of the Palm OS. In order to make the future discretion, the version number is defined in the header file (if there is no defined in the system). This is because the number of hexadecimal numbers representing the version number is difficult to quote and understand. If it is not defined, there will be a lot of trouble in the future. The fcalc.c module has only one event handler in FCALC.C. Create a new file called Fcalc.c and saved in the project's SRC folder. Here is the detailed code of FCALC.C. After the code we are familiar with the header file, it is the function prototype of the event handler.

// // fcalc.c // code for the "CALC" form. // Copyright (c) 1999, Robert Mykland. All rights reserved. // // // inclus // // #include "app.h" ///// Global prototypes //// Boolean CalcFormentHandler (eventptr speak); // // Global functions // // // ------------ -------------------------------------------------- -------------- Boolean CalcFormEventHandler (// ----------------------------- ------------------------------------------- // Handles Events for This form. // Returns True if it full full handled the Event. // ---------------------------------- ------------------------------------------------------------------------------------------------- -------------------------------------------------- ----------------------- {// Handle The Event Switch (SpEvent-> ETYPE) {// a control was selected Case CTLSELECTEVENT: / / SOUND AN Alarm SndPlaySystemsound (Sndalarm); Return (false); // a menu item WAS SELECTED CASE MENUEVENT: // Handle The Menu Event CalcFormMenueventhandler (SP Event); Return (TRUE);} // We're Done Return (false);} When a button is pressed, the function issues a prompt sound. When the menu option is selected, we call the function calcformmenueventhandler () to process, it It is actually a macro defined in App.h, allowing us to call this function when you select a menu in other programs. Note that when we press the button, the return value of the function is False. This is because Palm OS also needs further processing buttons to press graphics. Remember, in general, when the function returns false, it is desirable that the system ignores this event, but in the menu event (Memuevent), if you return false after processing a menu event, Palm OS will send a warning, it seems to appear. What is wrong. After the program is prepared, we can add this program to other applications. For example: In a financial information software, we can make it a pop-up window, and then calculate according to the needs of the main window. The fcalc.h module fcalc.h is the header file of the fcalc.c. Create a new file, name it fcalc.h, and save it in the SRC folder of the Caculator project. Like main.h, Fcalc.h also has pre-processed instructions # ifdef, # define, # Endif, etc. to prevent compilers from doing useless.

The code in Fcalc.h defines the function prototype in the fcalc.c to ensure that this function is defined and the parameter is transmitted correctly when calling this function. #ifndef fcalc_h #define fcalc_h // // fcalc.h // definitions for the "CALC" form. // Copyright (c) 1999, Robert Mykland. All rights reserved. //// // Global prototypes // // / / / // boolean CalcFormEventHandler (EventPtr Spevent); #ENDIF / / FCALC_H You may ask, how can I only define a function in such a header file? The key to this problem is that there is only one function now. However, it is important to note that we must first have a complete start framework for future expansion, and leave space for future code. If you never expand, it doesn't matter, so you can find a function easier. App.h module header file app.h will summarize the header files of all modules. Create a new file, name it app.h and store it in the SRC folder. Add it in the project and place it in AppinCludes. Let's take a step by step to analyze the code: #ifndef app_h #define app_h // // app.h // definitions for the application. // CopyRight (c) 1999, Robert Mykland. All Rights Reserved. // // / / / / / Include // all the palot.h> // all the palm incdude #include "calculator_res.h" // resource definitions #include "fcalc.h" // definitions for the "CALC" form #include "main .h "// definitions for the main entry point app.h looks very similar to our previous edited header files, first is #ifndef and #define pre-processing instructions, and then the definition of some header files. The first is the definition of the pilot.h header file. Since we will use App.h header files in the source file, you must define pilot.h here. The next is the resource header file. Note that because pilot.h is the system header file, we are included in <>, our custom header file is included in quotation marks. Here is the header file definition of Fcalc.c, app.h is divided into several parts to handle individual source files, so that we can easily take the necessary and sufficient code from the program to other modules in the future. . / // definitions for forc.c // // The menu Event Handler Macro for the "CALC" Form #define CalcFormMenueventHandler (SpEvent) This is the definition of the menu handler. There is no practical meaning in the current definition, and there is no content in the code, because the Calc form has no menu. I deliberately leave a space in the braces called the function, the macro starts running after the first space after the macro name, so when you add a parameter to the macro, it is made to compile normal, care not to leave space. Note: The macro is only used when necessary, because the use of macros is very dangerous. The general function can use prototype to check the parameters of the function, and for macro, there is no function prototype. If you pass the wrong parameters to the macro, you will hardly check it out.

We use macros here to create a quick and easy "function", except that they are referenced in the source file, they do not occupy code space. We don't want to add a function in the header file, because it will be executed when they are called each time. Then the following is the definition of main.c, first is the prototype of the function getEventHandler (), where there is a definition we haven't seen before: Event_Handler_List. // Definitions for main.c // // The prototype for getEventHandler () static FormEventHandlerPtr getEventHandler (Word); // This creates the function getEventHandler, // which returns the event handler for a given form // in this application #. define EVENT_HANDLER_LIST / static FormEventHandlerPtr getEventHandler (Word wFormID) / {/ switch (wFormID) / {/ case AboutForm: / return (aboutFormEventHandler); / case CalcForm: / return (calcFormEventHandler); / case PrefsForm: / return (prefsFormEventHandler); / } / return (null); /} event_handler_list is actually the definition of the function getEventHandler (). In Main.c, pre-processor replaces this function with this definition. We can use the #define statement anywhere, which actually looks out in the text compiler. The backslash behind each line can ignore the preprocessor's line interruption, and when the line break is encountered, the # define statement will stop, so we have no backslash in getEventHandler (). . Now, getEventHandler () is only associated with CalcFormEventHandler () in form CalcForm. If you want to add a form and an event handler, we can expand directly in the header file. // This defines the macro that initializes the app #define appInit () // This defines the macro that cleans up the app #define appStop () // This application works on PalmOS 2.0 and above #define ROM_VERSION_MIN ROM_VERSION_2 // Define the starting Form #define StartForm CalcForm // Definitions for MOPTIONS.C // // Menu ID Name Conversions #define OptionsAbout OptionsAboutCalculator #Endif // App_H Here is a macro definition of appinit () and appstop (). But they have not really meaningful now. The final version of the file is defined in the lowest version of this program is Version 2.0, where variables use the definition in main.c. We also define that the start form is CalcForm. Finally, the #ENDIF statement, don't forget this end statement, otherwise there is a strange mistake when compiling.

Creating a main purpose of files such as app.h is to save runtime and try to modify the code in the header file without modifying in the source file. There is a lot of benefits because you modify the code, it may introduce Bug, but in general, constants in the modification program can reduce the opportunity to introduce bugs. If you set the code's modification in some header files, you can reduce the ratio of the original procedure that has been modified. If a programmer generally does not introduce bugs in the program, such a program structure is also good, because even if there is a good comment in the program, it is necessary to spend some time to understand the program and modify. If you will change in the header file with a good file structure, you will have fewer time to learn the details of each module. Debugging all modules has been completed, and now start debugging. If there is no accident, the running program interface is shown below: The program starts from the function pilotmain (). The initialization process is as follows: Check the ROM version and check the run code, then call the function frmogormoform (), which will generate two events to be processed: frmloadevent and frmopnevent, then enter an unlimited event loop. FRMLoadEvent causes processevent (), which will get the form of the form from the event structure and initialize the form, and then wait for other events. If you press the OK button, a prompt sound will be issued.

Program list: Below is the source code of app.h: #ifndef app_h #define app_h /// App.h // Definitions for the application. // CopyRight (c) 1999, Robert Mykland. All Rights Reserved. // ///////////Clude // all the palm incrudes #include "cagculator_res.h" // resource definitions #include "fabout.h" // definitions for the "about" form # a INCLUDE "fcalc.h" // definitions for the "CALC" form #include "fprefs.h" // definitions for the "prefs" form #include "main.h" // definitions for the main entry point #include "MOPTIONS .h "// definitions for the" options "menu /// //////////// // definitions for forc / // definitions for FCAlc (SPEVENT) / / / DEFINITIONS for FCALC .c // // The menu Event Handler Macro for the "CALC" Form #define CalcFormMenueventHandler (Spevent) / {/ OptionsmenueventHandler (SpEvent); /} // // /////// Menu Event Handler Macro for the "prefs" form #define prefsformmenueventhandler (Spevent) // Definitions for main.c // // The prototype for getEventHandler () static FormEventHandlerPtr getEventHandler (Word); // This creates the function getEventHandler, // which returns the event handler for a given form // in this application #. define EVENT_HANDLER_LIST / static FormEventHandlerPtr getEventHandler (Word wFormID) / {/ switch (wFormID) / {/ case AboutForm: / return (aboutFormEventHandler); / case CalcForm: / return (calcFormEventHandler); / case PrefsForm: / return (prefsFormEventHandler); / } / return (null);

/} // This defines the macro that initializes the app #define appInit () // This defines the macro that cleans up the app #define appStop () // This application works on PalmOS 2.0 and above #define ROM_VERSION_MIN ROM_VERSION_2 // Define The Starting Form #define StartForm Calcform // Definitions for MOPTIONS.C // // Menu ID Name Conversions #define Optionsabout OptionsaboutCalculator #ENDIF / / App_H below is Main. All source code: // // main.c ////// Main entry point and event loop. // Copyright (C) 1999, Robert Mykland. All rights reserved. // // inclus // // #include "app.h" // the definitions for this application ///////////// // DWord Pilotmain (Word, PTR, WORD); // main entry point. Boolean Processevent (long); // processes the next evenet. // Local variables // / /////////////////////////// Handler List event_handler_list // // // // // ----------------------------------- ---------------------------------------- DWORD PILOTMAIN (// ---- ------------------------------------- --------------------------------- // The main entry point for this application. // always returns zero . ------------------------------------------------------------------------------------------------------- ----------------------------- Word wcmd, // the launch code ptr, // the launch parameter block word) // the Launch flags // ---------------------------------------------- ------------------------------ {DWORD DROMVERSION; // Get The Rom Version DromVersion = 0; ftrGet (sysftrcreator, sysftrnumromversion, & dROMVersion); // Alert and bail if the ROM version is too low if (dROMVersion

ROM_VERSION_2) {AppLaunchWithCommand (sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL);} return (0);} // If this is not a normal launch, do not launch if (wCmd = sysAppLaunchCmdNormalLaunch) return (0);! // Initialize all parts of the application appInit (); // Go to the starting form FrmGotoForm (StartForm); // Wait indefinitely for events ErrTry {while (true) processEvent (-1);} // Stop the application ErrCatch (lError) {} ErrEndCatch // Clean Up Before Exit AppStop (); // We're Done Return (0);} // -------------------------- -------------------------------------------------- Boolean Processevent (// ------------------------------------------- ----------------------------- // Waits for and processes the next es q r e e e e . ------------------------------------------------------------------------------------------------------- ----------------------------- long ltimeout // Time to wait in 100ths of a second, -1 = forever // -------------------------------------------------- ------------- ------------ {EventType sevent; // u er g g g e e t etet g g;;;;;; a nil event, return queue empty if (sEvent.eType == nilEvent) return (false); // Handle system events if (SysHandleEvent (& sEvent)) return (true); // Handle menu events if (MenuHandleEvent (NULL, & sEvent Return (TRUE); // Load a formness; {word wformid; // the form ID formptr spform; // points to the form // Get the ID wformid = sevent. Data.frmload.form; // initialize the form spform = frMinitform (wformid);

// Establish the event handler FrmSetEventHandler (spForm, getEventHandler (wFormID)); // Point events to our form FrmSetActiveForm (spForm); // Draw the form FrmDrawForm (spForm);} // Handle form events FrmDispatchEvent (& sEvent); / / If it's a stop event, exit if (sevent.type == appstopevent) {// exit errthrow (0);} // We're done return (TRUE);} Reusable About Forms in this section, We will add two forms and their corresponding code to the project: About Form, this program about dialogs; Prefs form, a dialog used to display priority. In this chapter we just add an OK button to present them on these two forms to show their existence. Document Calculator.rsrc's Content Add We will add an About Form, a prefs form, and a menu item to the form. 1. Run the constructor and open the file caculator.rsrc; 2. Create a framework of the About Form, we will copy the CALC form and make some modifications; 3. Select the CALC form; 4. Select Edit | Copy and press CTRL- C copy form; 5. Select Edit | Paste and press CTRL-V to paste the form to the constructor, and a dialog box appears to display the ID of the form; 6. Select the unique ID; 7. The name of the form is changed to "about"; 8. Double-click Open the About Form, enter the Form Property option; The button of the form is coincident, so that it can be easily switched with the CALC form. When everything is completed, the About Form should be shown in Figure 12-3: Create a prefs form now. Copy paste the About Form and rename "prefs". Change the title attribute to "Caculator Preference" to move the button down 20 pixels, and the completed form should be shown in Figure 12-4: Then add a menu bar to switch between two new window bodies. First create a menu bar from the menu resource type and list and press CTRL-K, name "CALC". Select Resource Type to create a new menu and press CTRL-K and name it "Options". Double-click Open the menu bar to drag a menu into the menu editing box. Name the menu Options, then press Ctrl-K to add menu items, and name it as preferences ..., the shortcut is "R". Another menu item named About Calculator. After the design is complete, the menu column is shown below: The fabout.c module will now add code to our new form and menu. The following is the source code of Fabout.c. It includes an event handler of the About form and the prototype of these functions. Because it is very similar to FCalc.c, I recommend copying the FCALC.C to make modifications on this basis. Finally, don't forget to save Fabout.c under Appsource.

// // fabout.c // code for the "about" form. // copyright (c) 1999, Robert Mykland. All rights reserved. // // // inclus // // #include "app.h" ///// Global prototypes //// Boolean AboutFormEventHandler (eventptr speak); // // Global functions // // // ------------ -------------------------------------------------- -------------- Boolean AboutFormEventHandler (// ----------------------------- ------------------------------------------- // Handles Events for This form. // Returns True if it full full handled the Event. // ---------------------------------- ------------------------------------------------------------------------------------------------- -------------------------------------------------- ----------------------- {// Handle The Event Switch (SpEvent-> ETYPE) {// a control wage selected case ctlselectEvent: // Return To THE CALLING FORM frmreturntoform (0); return (false); // a menu item was selected Case Menuevent: // Handle The menu Event Aboutformmenueventhand LER (SpEvent); Return (True);} // We're Done Return (False);} In AboutFormEventHandler (), we handle two types of events. If a button is pressed, then call frmreturntoform () to give the control to the form to be referenced. With this function, we can create a pop-up form that can only be called by the function frmpopupForm () and cannot be called by frmgotoform (). Since the About Form is usually popped up, do not affect the reusability of the code. For menus events, we call the function aboutFormEventHandler (). It is a macro we are in app.h. This macro definition is given in the header file, you can reuse this code on the menu in different programs. Fabout.h module This header file and Calc's header file is inherently consistent, so we copy fcalc.h and rename it to fabout.h. Add it to the project and place it under AppinCludes.

The modification code is consistent with the following: #ifndef fabout_h #define found_h // // fabout.h // definitions for the "About" form. // Copyright (c) 1999, Robert Mykland. All Rights reserved. /////////////// / // Global prototypes ///// Boolean AboutFormEventHandler (EventPtr Spevent); #ENDIF / / FABOUT_H FPREFS.C Module The source file of FPREFS.C. Currently, in addition to "About" to "FPREF", the other all and fabout.c are the same. Copy the fabout.c and make the corresponding modification and add it to the Calclulator project under AppinCludes. // // fprefs.c // code for the "prefs" form. // copyright (c) 1999, Robert Mykland. All rights reserved. // // inclus // // #include "app.h" ///// Boolean prefsFormEventHndler (eventptr speak); // // Global functions // // // ------------ -------------------------------------------------- -------------- Boolean prefsformeventhandler (// ----------------------------- ------------------------------------------- // Handles Events for This form. // Returns True if it full full handled the Event. // ---------------------------------- ------------------------------------------------------------------------------------------------- -------------------------------------------------- ----------------------- {// Handle The Event Switch (SpEvent-> ETYPE) {// a control wage selected case ctlselectEvent: // Return To The calling form frmreturntoform (0); Return (false); // a menu item was successmed Case Menuevent: // Handle The menu Event PrefusformMenueventhand LER (SpEvent); Return (True);} // We're Done Return (false);} fprefs.h module This header file and the header of CALC and About are basically consistent, copying fabout.h and will Renamed FPREFS.H. Add it to the project and place it under AppinCludes.

Here's the modifications you want: #ifndef fprefs_h #define fprefs_h // // fprefs.h // definitions for the "prefs" form. // CopyRight (c) 1999, Robert Mykland. All Rights reserved. //// // Global Prototypes // /// Boolean PrefsFormEventHandler (EventPtr Spevent); #ENDIF / / FPREFS_H MOPTIONS.C Module Options menu source code only one event handler. Copy a .c file from the source file and add it to the project under AppSource, make the corresponding modification according to the following code list: ////MOPTIONS.C // Code for the "options" menu. // CopyRight ( c) 1999, Robert Mykland. All rights reserved. // ///////////////////////// Boolean Optionsmenueventhandler (EventPtr Spevent); // // Global Functions // // // ------------------------------- ------------------------------------------ Boolean Optionsmenueventhandler (// - -------------------------------------------------- ------------------------ // Handles Events for this form. // Returns True if it full 50---- -------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------- - {Switch (Spevent-> Data.Menu.itemid) {// The About Menu Item Was Selected Case OptionsAbout: frMpopupform (Aboutform); Return (True); // The Prefs Menu Item Was Selected Case OptionsPreferences : Frmpopupform; return (true);} // we're done return (false);} When the menu item is selected, we call FRMPOPFORM () to pop up the corresponding form. If the menu item and the form ID match True, returns false. MOPTIONS.H Module This file and the previous header file are also very similar, only the prototype of an event handler.

Copy any one of the previous header files, then add it to the project under AppinCludees, the corresponding modifications are as follows: #ifndef moptions_h #define moptions_h ///MOPTIONS.H // definitions for the THE "options" menu. // copyright (c) 1999, Robert Mykland. All rights reserved. // /////// Boolean optionsmenueventhandler (eventptr speak); #ENDIF / / MOPTIONS_H App.h Content Add to include the newly built module in app.h, we need to add some code, first is the new header file: // // include // all the palm incdude # Include "Calculator_res.h" // resource definitions #include "found.h" // definitions for the "about" form #include "fcalc.h" // definitions for the "CALC" form #include "fprefs.h" / / Definitions for the "prefs" form #include "main.h" // definitions for the main entry point #include "moptions.h" // definitions for the "options" MENU Add new header file to app.h In, I usually arrange these file names in the order of letters, so you can easily find the desired header file. ////////////////////////////////////Out "form #define aboutformmenueventhandler (spEvent) / // definitions for fcalc.c // // The menu Event Handler Macro For the "CALC" Form #define CalcFormMenueventHandler (SpEvent) / {/ optionsmenueventhandler (SpEvent); /} Fabout.c and the program entry required for Fabout.c and FpRef.c Similar to the Fcalc.c. Then add the corresponding macro for the respective menus. In addition, since we add menu, what should I do if the menu handles macro. In the macro we call the function optionMenueventHandler () to process the various options for the menu. The code is added to the getEventHandler () function so that our new form can be triggered.

// This creates the function getEventHandler, // which returns the event handler for a given form // in this application #define EVENT_HANDLER_LIST / static FormEventHandlerPtr getEventHandler (Word wFormID) / {/ switch (wFormID) / {/ case AboutForm:. / Return (AboutFormEventrandler); / CASE CALCFORM: / RETURN (CALCFORMEVENTHANDLER); / CASE prefsform: / return (prefsformEventHandler); /} / return (null); /} The INOTFORME and the PREFS form The same, there is no need to make other modifications in main.c. Add definitions to the Option menu: // definitions for moptions.c // // Menu ID Name Conversions #define Optionsabout OptionsaboutCalculator Because the constant menu item is defined because of the constant menu items in Calculator_res.h, we should abstract it does not contain it, such as " Calculator ", etc., the general name of the text based on the specific program, make it reused.

The list below is all of the new app.h's total code: #ifndef app_h #define app_h // // App.h // Definitions for the application. // CopyRight (c) 1999, Robert Mykland. All rights reserved. // ///////////Clude // all the palm incrudes #include "cagculator_res.h" // resource definitions #include "fabout.h" // definitions for the "about" form # INCLUDE "fcalc.h" // definitions for the "CALC" form #include "fprefs.h" // definitions for the "prefs" form #include "main.h" // definitions for the main entry point #include "MOPTIONS .h "// definitions for the" options "menu /// //////////// // definitions for forc / // definitions for FCAlc (SPEVENT) / / / DEFINITIONS for FCALC .c // // The menu Event Handler Macro for the "CALC" Form #define CalcFormMenueventHandler (Spevent) / {/ OptionsmenueventHandler (SpEvent); /} // // /////// Menu Event Handler Macro for the "prefs" form #define prefsformmenueventhandler (Spevent) // Definitions for main.c // // The prototype for getEventHandler () static FormEventHandlerPtr getEventHandler (Word); // This creates the function getEventHandler, // which returns the event handler for a given form // in this application #. define EVENT_HANDLER_LIST / static FormEventHandlerPtr getEventHandler (Word wFormID) / {/ switch (wFormID) / {/ case AboutForm: / return (aboutFormEventHandler); / case CalcForm: / return (calcFormEventHandler); / case PrefsForm: / return (prefsFormEventHandler); / } / return (null);

/} // This defines the macro that initializes the app #define appInit () // This defines the macro that cleans up the app #define appStop () // This application works on PalmOS 2.0 and above #define ROM_VERSION_MIN ROM_VERSION_2 // Define The Starting form #define StartForm CalcForm // Definitions for moptions.c // // Menu ID Name Conversions #define Optionsabout OptionsaboutCalculator #Endif // App_h debugging is time to debug, the interface should be the same as before. When you press the prefs or About option on the menu bar, the corresponding form will jump out. When the respective OK buttons are pressed, return to the CALC form. As before, the program starts from pilotmain (), followed by regular route, and the FRMLoadEvent event generated by ProcessEvent () initializes the new menu bar of the form. The program then enters an infinite loop to wait for the trigger of the event. If you press the OK button, the system will issue a warning sound. Object-oriented programming object-oriented programming is to make the code easier to be maintained and reuse. Based on a paragraph or variable in other code, the encapsulation and abstract method is used to make BUGS significantly. As long as you understand the relationship between each code part, you can find and correct these BUGS. The reuse of the code is that the dependence between each code section is reduced, so that it can be applied from a useful code from the object-oriented program to other projects. According to people's views on face-to-face objects, people may think that it is a unique programming method that it is a scam. Maybe you are right, that is, no matter whether it is worth, I also talk about the object-oriented programming. First, object-oriented programming should be a programming design principle, not how much relationship with the programming language you are using. Indeed, like C and Java easy to implement object-oriented methods, but the convenience of the application should be provided by object-oriented principles. After nearly ten years, the use of object-oriented languages ​​such as SmallTalk, C and Java, I know that if a person is proficient in Java's grammar, it does not mean that he really knows how effective, valuable use of objects. Truely important should be to understand object-oriented concepts and design patterns, know why use these ideas and design principles more effectively and more valuable. Object-oriented programming is also a tool, which is nothing differences, if you use it, it will damage the abuse of other tools. No one will be in the room, because the hammer is the latest product. However, I saw that many people are not correct because of the object-oriented programming methods, and the results are more harmful. C , Java and Palm OS are generally speaking, I also like to use C and Java. But I don't advocate it in Palm OS is that the use of these languages ​​in Palm OS does not bring any benefits. What we get is just a more bloated, and the run is slower. When there is a small, concise as a class library developed by Palm OS or C and Java, I will use it. Maybe I will write one. Fortunately, in the development of Palm OS applications, we can get some meaningful revelation from the object-oriented principles. As I said earlier, the key is to master the principle of object-oriented.

Below, I will introduce you some of the most popular concepts programmed to objects and give some skills to use these principles in C procedures. The basic principle of object-oriented object-oriented objects is to place data structures and their applications in an entity called objects. The idea of ​​data packages is to protect the data structure to avoid damage to the object's external code. If you comply with this principle, when the data structure is destroyed, you can determine that the problem must be inside the object, unless there is so-called "Wild Pointer". "Wild Pointer" means that the pointer does not point to a specific location. For example, the following code will cause "Wild Pointer". Char * cpbuffer = 2000; In the case of "Wild Pointer", maybe there is a non-transport object to be designated by it, so it will cause some problems. Therefore, it is best to thrift, carefully use the pointer. The data package is easily implemented in C. Dividing the code of each object into a separate file and declare the variable as a static variable. This prevents them from being called by functions in other files. If the object wants to access variables in other objects, you can declare the variable as global variables, but don't make too much declaration of global variables. Do not pass the pointers of the data structure to the object outside the object, but let the function pass a data structure for you to fill in or create a copy of the original data to represent a function. The principle of data abstract data abstraction refers to the data structure in an object does not depend on the data structure in any other object. Therefore, an object can rewrite or completely changing its basic variable without affecting the validity of code or data in other objects. The use of data abstraction is to reconstruct the object, making the program more easily reuse and maintain without affecting the other parts of the system. Obviously, do not use "internal messages" in the data structure of other objects. To see them as a blackbox. Don't think you know the size of the data structure of other objects, but use sizeof (); don't think you know where the variable is in the data. The meaning of inheritance inheritance means that the specific content is added to the general object to generate its sub-object. This avoids you spending a lot of time to generate and have the same objects in many places. One way to achieve inheritance in C is to use the #define statement. Suppose you have a simple list box, now you want to produce a list box. In this list box, other and simple list boxes are identical in addition to adding browsing. The following is a simple list box function prototype: VoidHand slCreateList (void); Void slDestroy (VoidHand); Void slAddToList (VoidHand, lidtitem_t *); Void slSaveList (VoidHand, FILE *); Void slLoadList (VoidHand, FILE *); In an Browse the list of header files, you can define: #define ilCreatList slCreatList; #define ilDestroyList slDestroyList #define ilAddtoList slAddToList #define ilSaveList slSaveList; #define ilLoadList slLoadList void ilGetFirst (VoidHand, listitem_t *); void ilGetNext (voidHand, listitem_t * ); Polymorphism, refers to a set of objects that can be unified. For example, we can delete a list of box entries without having to manage the list box or a browse list box. The polymorphism can be achieved by using a pointer in C. Note that the pointer to the object when the list is saved in the delete function, when the function deletelistItem () is called, use this variable to delete the recorded record.

转载请注明原文地址:https://www.9cbs.com/read-2751.html

New Post(0)