WriteLog Contest Module Development – Part 4: The Exchange Entry Box

This series of blog posts started in part 1 where I listed the tools you will need. At this point, you should have a module that compiles, shows up in the list of contests in WriteLog, and can run in the debugger. In this part, we’ll shape up the exchange input and define what a QSO will contain.

Look at the exchange field layout in SKCC_WESdat.cpp. The structure exfa_srtu contains a two dimensional array of fields with each row defining one field. The first element is a string with the field caption. “A?” is a place holder for the as-you-go multiplier and “?M” is a running count of the AYG multiplers in the log. Actually, if you create a contest log with this module right now, you would see where these fields are used. In part 2, I demonstrated how to set up VC++ to run WriteLog when you hit F5 to run the program in the debugger. If you followed those directions, you can create a new log while tracing the module’s code. Go ahead and create a contest with the module in progress so you can see where these fields are used.

extern const struct exfa_stru
g_SKCCWESExfLayout[] =
{
{"CALL", CALL_WID, CALL_POS, A_CALL|A_PRMPT|A_MULTI|A_NOTIFY},
{"SNT", RS_WID, SN_POS, A_NUMS|A_NOTIFY|A_RST|A_OVERSTRIKE},
{"RST", RS_WID, RS_POS, A_PRMPT|A_NUMS|A_NOTIFY|A_RST|A_OVERSTRIKE},
{"RCVD", RCVD_WID, RCVD_POS, A_DUPE|A_PRMPT| A_NOSPACE |
A_MULTI|A_REQUIRED|A_NOTIFY|A_OVERSTRIKE},
{"A?", AYG_WID, AYG_POS, A_DUPE|A_PRMPT|A_MULTI|A_REQUIRED|
A_NOTIFY}, //TODO: check name, size and flags
{"ML", MLT_WID, MLT_POS, A_NOED},
{"?M", AYGMULT_WID, AYGMULT_POS, A_NOED}, //todo: NAME OF COLUMN
0 /*must end with a zero entry*/
};

Look at the field called “RCVD.” This one was generated because we selected named multipliers in the wizard. Change RCVD to QTH but don’t change the other constants associated with the field. Those constants are used in other places for handling named multipliers. Change “?M” to “BO” so we can track the bonuses there. The “BO” and “ML” fields are not typed in the exchange but calculated and show up in the log. The “ML” and “BO” are the titles of the columns in the log. Add a field called, NAME. The A_ flags are defined in the Esfsym.h file, which has some useful comments describing their definitions. Rename “A?” to “SKCC” and set the flags as shown below, adding A_NOSPACE to remove the ambiguity of a number with or without spaces.

extern const struct exfa_stru
g_SKCCWESExfLayout[] =
{
{"CALL", CALL_WID, CALL_POS, A_CALL|A_PRMPT|A_MULTI|A_NOTIFY},
{"SNT", RS_WID, SN_POS, A_NUMS|A_NOTIFY|A_RST|A_OVERSTRIKE},
{"RST", RS_WID, RS_POS, A_PRMPT|A_NUMS|A_NOTIFY|A_RST|A_OVERSTRIKE},
// Name is required but spaces are allowed to accommodate clubs, etc.
{"NAME", NAME_WID, NAME_POS, A_PRMPT | A_REQUIRED | A_NOTIFY | A_OVERSTRIKE},
// SKCC number (or power) is required in the exchange.
// SKCC has A_NOSPACE because an SKCC with a space will be different to the computer than same number without one.
{"SKCC", AYG_WID, AYG_POS, A_DUPE | A_PRMPT | A_MULTI | A_REQUIRED | A_NOTIFY | A_NOSPACE},
{"QTH", RCVD_WID, RCVD_POS, A_DUPE | A_PRMPT| A_NOSPACE | A_MULTI|A_REQUIRED | A_NOTIFY | A_OVERSTRIKE},
{"ML", MLT_WID, MLT_POS, A_NOED},
{"BO", AYGMULT_WID, AYGMULT_POS, A_NOED},
0 // must end with a zero entry
};

Define the _WID and _POS constants to match the exchange field layout. The RCVD_WID only needs to be large enough to hold a three character multiplier (plus one for the null, remember). MLT_WID defines the width of the running multiplier column in the log, not a field width in the exchange input box. RS_WID and SN_WID are for the RST and don’t need to be changed. Change the AYG_WID constant to accomodate the SKCC number. AYGMULT_WID is like the MLT_WID constant in that it defines the width of a column in the log. We’ll use that column to show if the Q is a C or T bonus. Add a _WID constant for a new name field. I set the length of the name field to 21 because really, who is going to send you the entire, 70 character name of their club? Resist the temptation to change the name of the AYG contstants! Those constants are used several places so just leave them well alone.

#define CALL_POS -1 /*always*/
// Setting the width of the fields here. Number is width + 1.
#define RCVD_WID 4
#define MLT_WID 3
#define RS_WID 4
#define SN_WID RS_WID
#define AYG_WID 6 // sized for SKCC number
#define AYGMULT_WID 3
#define NAME_WID 21

We began editing the _POS constants back in part 2. Set the width of NAME to 21. Edit the SKCC position constant, changing the length to 6.

// The order of these POS constants doesn't matter but associating them with the
// correct field in exfa_stru DOES matter.
// These define the location of the entry in the variable part of the QSO.
#define RS_POS 0
#define SN_POS (RS_POS + RS_WID)
#define RCVD_POS (SN_POS + SN_WID)
#define MLT_POS (RCVD_POS + RCVD_WID)
#define AYG_POS (MLT_POS + MLT_WID)
#define AYGMULT_POS (AYG_POS + AYG_WID)
#define NAME_POS (AYGMULT_POS + AYGMULT_WID)

The order of the _POS constants is not important but associating them with the correct fields in exfa_stru is very important. These constants define the offset where the fields data will be stored in the variable part of the QSO.

A note on the variable part of the QSO: this block of memory is very important and gets used everywhere in the contest module. There is a potential for nasty buffer overruns with this data structure so take care in making sure the _POS and _WID constants are correct.

We are making headway now. Compile the module and create a contest using it to see how the exchange fields and the log looks. Errors compiling and creating a contest with the module? Go back through and see if you missed something. Review the readme.txt file. Path environment variable? Including the two LIB files in the project? Things should be shaping up now.

WriteLog is Copyright © 1992-2009 by Wayne E. Wright, W5XD.

Creative Commons License
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.

Leave a Reply