Difference between revisions of "API"

From Win-Test Wiki
Jump to navigation Jump to search
m (→‎Re-map Ä key with /P for Field Day: Put Ä in brackets to clearly indicate that it is a key)
m (→‎ESM Script (embedded into Win-Test): Show how ESM uses standard messages.)
Line 435: Line 435:
 
====ESM Script (embedded into Win-Test)====
 
====ESM Script (embedded into Win-Test)====
 
For convenience, you can find below the current ESM (Enter Sends Message) embedded script. Note that the real returned values are somewhat different from the ones described above, because of the nature of this script (embedded), but it is a good source of inspiration for your own masterpiece. As Lua is an interpreted language, the good news is that you can edit your script while WT is running. No need to exit WT, enter modifications, and start WT again. Just edit esm.wts while WT is running, save it, and try it immediately!
 
For convenience, you can find below the current ESM (Enter Sends Message) embedded script. Note that the real returned values are somewhat different from the ones described above, because of the nature of this script (embedded), but it is a good source of inspiration for your own masterpiece. As Lua is an interpreted language, the good news is that you can edit your script while WT is running. No need to exit WT, enter modifications, and start WT again. Just edit esm.wts while WT is running, save it, and try it immediately!
 +
 +
The script assumes the following messages have been programmed into the [[Menu:Options#Modify_standard_messages...|Standard CW messages]] dialog:
 +
 +
'''  F1''' => CQ<br>
 +
'''  F2''' => RST + Exchange<br>
 +
'''  F5''' => $LOGGED<br>
 +
'''  F7''' => ? or Again (Phone)<br>
 +
'''  F4''' => $MYCALL<br>
 +
'''  INSERT''' => Sends exchange (CW and RTTY)<br>
 +
'''  PLUS''' => TU and Enter QSO<br>
 +
 +
Here is the source code for '''esm.wts'''.  To change the behavior, save it in the Win-Test scripts directory (File | Explore | /scripts directory), then edit it.
  
 
<code>
 
<code>

Revision as of 22:44, 7 December 2010

List of Win-Test API Functions

Compiled from information found on the WT reflector on October 7, 2009 ([1], [2]).

Newer API documentation from the Win-Test developers may be found at http://download.win-test.com/v4/lua/LuaApiDoc.txt.

Class wtApp

wtApp:AlertBox(Text) Opens a standard Windows alert box with text.
wtApp:CallScript(strScript) Call a wts script (no extension required in strScript). Can return a number only (or nothing)
wtApp:GetAppPath() Win-Test installation directory path
wtApp:GetKeyState() Returns the modifers keys status when the function is called.
wtApp:GetCfgPath() \cfg directory path
wtApp:GetCtyPath() \countryFiles directory path
wtApp:GetDatabasePath() \databases directory path
wtApp:GetExtraPath() \extras directory path
wtApp:GetLogPath() Current log directory path
wtApp:GetOpPath() \ops directory path
wtApp:GetScriptPath() \scripts directory path
wtApp:InputInteger(Prompt, Title, Default) If Title or Prompt is empty, a default text is used
wtApp:InputNumber(Prompt, Title, Default) If Title or Prompt is empty, a default text is used
wtApp:InputText(Prompt, Title, Default) If Title or Prompt is empty, a default text is used
wtApp:IsPostKeyProcess() Return true if the current script is executed after the assigned key has been processed by WT, and false otherwise
wtApp:MessageBox(Text, Type, Title) Display a Message box with the specified text, using the specified Type and message box Title (shown in the title bar of the message box window). Type 0 is an ordinary message box with an [OK] button, type 1 has both an [OK] and a [Cancel] button. The return code indicates the button pressed by the user (which may be ignored). Return code 1 means the [OK] button was pressed, return code 2 means the [Cancel] button was pressed. See the Microsoft Windows MessageBox API documentation for more details about supported message box types and return codes.
wtApp:SendAltKey(Key) Key is a letter, a number, or a function key ("F1".."F12" + "Insert" + "Plus" + "Esc")
wtApp:SendCtrlKey(Key) Key is a letter, a number, or a function key ("F1".."F12" + "Insert" + "Plus" + "Esc")
wtApp:SendFKey(Key [, ModifierKeys]) Send Functions keys (and Insert and Plus). Key is one of "F1".."F12" + "Insert" + "Plus" + "Esc". Modifier Keys (optional) indicates the modifier keys (Ctrl = 4, Alt = 2, Shift = 1, None = 0 - can be combined via addition, e.g., 6 = Ctrl+Alt). If this argument is missing or -1, the current modifier keys are used.
wtApp:SendKeyCode(Code [, ModifierKeys]) Send a key by its ASCII code. Keycode is an ASCII code. ModifierKeys (optional) indicates the modifier keys (Ctrl = 4, Alt = 2, Shift = 1, None = 0 - can be combined via addition, e.g., 6 = Ctrl+Alt). If this argument is missing or -1, the current modifier keys are used.
wtApp:SetWindowColor(ChildWndId, nRed, nGreen, nBlue, nColorIndex) Set the nColorIndex color of the child window designated by its windowID (see the wtConstants list). If ChildWndId is < 0, it applies to the main window. If nColorIndex is omitted (or set to 0), it applies to the background color All colors must be <= 255.
wtApp:ShowWindow(ChildWndId) Show the child window designated by its windowID (see the wtConstants list)
wtApp:Sleep(Time) Time expressed in milliseconds.
wtApp:TextCommand(Text) Send WT text command to application
wtApp:ToggleWindow(ChildWndId) Toggle the child window designated by its windowID (see the wtConstants list)
wtApp:WizzWindow(ChildWndId) "Wizz" (shake or vibrate) the child window designated by its windowID (see the wtConstants list). Can be used to draw attention to a particular window.

Class wtContest

wtContest:IsExchangeRequired() Return a boolean. True if the current contest requires an exchange (associated with RST)
wtContest:GetContestId() Return the current contestID

Class wtKeyer

wtKeyer:GetCwSpeed() Return the CW speed in wpm (return 0 in case of error).
wtKeyer:GrabHighlightedCallsign() Works only in RTTY mode and grabs the currently highlighted callsign from the RX window.
wtKeyer:Play(Message) Message is a plain string to be played, a saved message ($F1 etc.) or a variable ($xxx)
wtKeyer:PlayAdditionalMsg(AdditionalMsgIndex) Play the additional CW/RTTY messages (Alt-C set)
wtKeyer:SetCwSpeed(Speed) Set CW speed in wpm.
wtKeyer:Stop() Stop the current message

Class wtOp

wtOp:GetCallsign() Return the current op callsign
wtOp:GetNick() Return the current op nick

Class wtQso

wtQso:IsCallsignEmpty() Return a boolean : True if the callsign field of the active QSO is empty
wtQso:IsCallsignIncomplete() Return a boolean : True if the callsign field of the active QSO contains a "?"
wtQso:IsExchangeEmpty() Return a boolean : True if the exchange field of the active QSO is empty
wtQso:IsExchangeSent() Return a boolean : True if the exchangeSent flag of the active QSO is set
wtQso:SetExchangeSent() Set the exchangeSent flag of the active QSO (see wtQso::IsExchangeSent()) - Similar to the use of $SETEXCHSENT
wtQso:ResetExchangeSent() Reset the exchangeSent flag of the active QSO (see wtQso::IsExchangeSent()) - Similar to the use of $RSTEXCHSENT
wtQso:ClearStatus() Clear the status flags of the active QSO
wtQso:GetModeId() Return the mode ID of the active Qso
wtQso:IsCallsignRepeated() Return a boolean. True if the callsign hasn't changed since the last Enter
wtQso:IsOperatingModeRun() Return a boolean. True if the operating mode of the active QSO is RUN (and False if S&P)
wtQso:IsModePhone() Return a boolean. True if the mode of the active QSO is Phone (SSB and FM), and False otherwise
wtQso:IsQsoApproved() Return a boolean. True if all requested fields of the active QSO are filled (contest dependent)
wtQso:IsDupe() Return a boolean. True if the current callsign is a dupe
wtQso:IsCurrentFieldCallsign() Return a boolean : True if the current field is the callsign field
wtQso:IsCurrentFieldExchange() Return a boolean : True if the current field is an exchange field
wtQso:IsCurrentFieldOther() Return a boolean : True if the current field is not the callsign field or an exchange field
wtQso:IsCurrentFieldEmpty() Return a boolean : True if the current field is empty (except RST for the exchange field)
wtQso:IsCurrentFieldPrimaryRadio() Return a boolean : True if the current field is in the primary radio (main log)
wtQso:IsCurrentFieldSecondryRadio() Return a boolean : True if the current field is in the secondary radio

Class wtRadio*

The following generic functions can by applied to: wtRadio (the active one), wtRadioInactive (the non-active one), wtRadioPrimary (the one that is in the main log wnd) wtRadioSecondary (the one that is in the secondary log wnd) wtRadio1 and wtRadio2.

WARNING: Some functions may not work because of the CAT protocol or radio hardware limitations.

wtRadio*:GetFreq() Return freq of the active VFO of the designated radio freq is expressed in kHz
wtRadio*:GetFreq(NVfo) Return freq of the designated VFO (0 => VFO A, 1 => VFO B) of the designated radio freq is expressed in kHz
wtRadio*:GetFreqInactiveVfo() Return freq of the inactive VFO of the designated radio freq is expressed in kHz
wtRadio*:GetTypeId() Return type of radio
wtRadio*:GetManufacturerId() Return manufacturer of radio
wtRadio*:SetFreq(freq) Set freq of the active VFO of the designated radio freq is expressed in kHz
wtRadio*:SetFreq(freq, nVfo) Set freq of the designated VFO (0 => VFO A, 1 => VFO B) of the designated radio freq is expressed in kHz
wtRadio*:SetFreqInactiveVfo(freq) Set freq of the inactive VFO of the designated radio freq is expressed in kHz
wtRadio*:SetFreqSubVfo(freq) Set freq of the sub VFO of the designated radio freq is expressed in kHz
wtRadio*:SetSplit(freq) Set split ON and the split frequency on the designated radio freq is expressed in kHz
wtRadio*:ResetSplit() Reset split on the designated radio
wtRadio*:IsSplit() Return false or true whether the split is set or not on the designated radio
wtRadio*:GetRadioId() Return the radioID (0 => RADIO_1, 1 => RADIO_2) of the designated radio
wtRadio*:Send(catString) Send the ASCII catString to the designated radio
wtRadio*:SendHex(hexString) Send the hexString to the designated radio. The hexString must contain only 0-9 and A-F characters and must have an even length. Ex "02DFA8" etc.

Win-Test API Constants

Constants are not guaranteed to remain constant in Lua. The name of the constant could be accidentally reassigned to refer to some other object or value. Unfortunately, there is no easy way to generate code that prevents this. You will just have to be careful.

Child windows IDs

WT_WND_SUMMARY = 0;
WT_WND_GRIDSQUAREMAP = 1;
WT_WND_CHECKPARTIAL = 2;
WT_WND_RATESHEET = 3;
WT_WND_CLOCK = 4;
WT_WND_VUMETER = 5;
WT_WND_RATE = 6;
WT_WND_GAB = 7;
WT_WND_MAP = 8;
WT_WND_CHECKCOUNTRY = 9;
WT_WND_ZONE = 10;
WT_WND_MULT = 11;
WT_WND_NP1 = 12;
WT_WND_RADIO1 = 13;
WT_WND_RADIO2 = 14;
WT_WND_PACKETCLUSTER = 15;
WT_WND_DXCLUSTERANN = 16;
WT_WND_SOLAR = 17;
WT_WND_PILEUP = 18;
WT_WND_STATUS = 19;
WT_WND_SKED = 20;
WT_WND_CHECKCALL = 21;
WT_WND_SECONDARYRADIO = 22;
WT_WND_RTTY1 = 23;
WT_WND_RTTY2 = 24;
WT_WND_QSYWIZARD = 25;
WT_WND_EXTRAINFO = 26;
WT_WND_ZONE2 = 27;
WT_WND_ROTATORS = 28;
WT_WND_CONTESTRECORDER = 29;

Supported contests IDs

WT_CONTEST_IARU_VHF = 1;
WT_CONTEST_IARU_UHF = 2;
WT_CONTEST_IARU_CW = 3;
WT_CONTEST_IARU_HF = 4;
WT_CONTEST_IARU_R1_50MHZ = 5;
WT_CONTEST_REF_THF = 10;
WT_CONTEST_REF_DDFM_50MHZ = 11;
WT_CONTEST_THF_EU = 20;
WT_CONTEST_THF_EU_50_70 = 21;
WT_CONTEST_THF_EU_GRIDSQUARE = 30;
WT_CONTEST_THF_EU_GRIDSQUARE_50_70 = 31;
WT_CONTEST_THF_EU_GRIDSQUARE_NO_DIST = 32;
WT_CONTEST_THF_EU_GRIDSQUARE_NO_DIST_50_70 = 33;
WT_CONTEST_REF_HF = 100;
WT_CONTEST_ARRL_DX = 101;
WT_CONTEST_ARRL_10 = 102;
WT_CONTEST_ARRL_160 = 103;
WT_CONTEST_ARRL_SWEEPSTAKES = 104;
WT_CONTEST_ARRL_FD = 105;
WT_CONTEST_ARRL_RU = 106;
WT_CONTEST_ARRL_UHF_AUG = 130;
WT_CONTEST_ARRL_VHF_JAN = 131;
WT_CONTEST_ARRL_VHF_JUN = 132;
WT_CONTEST_ARRL_VHF_SEP = 133;
WT_CONTEST_REF_160 = 150;
WT_CONTEST_CQWW_DX = 200;
WT_CONTEST_CQWW_WPX = 201;
WT_CONTEST_CQWW_160 = 202;
WT_CONTEST_CQWW_VHF = 250;
WT_CONTEST_RDXC = 300;
WT_CONTEST_RDAC = 301;
WT_CONTEST_CIS = 302;
WT_CONTEST_R_160 = 303;
WT_CONTEST_RRTC = 304;
WT_CONTEST_RAEM = 305;
WT_CONTEST_DXPEDITION_HF = 400;
WT_CONTEST_DXPEDITION_VHF = 410;
WT_CONTEST_ALL_ASIAN = 500;
WT_CONTEST_SPDXC = 600;
WT_CONTEST_JIDX = 700;
WT_CONTEST_KCJ = 701;
WT_CONTEST_KCJ_TOPBAND = 702;
WT_CONTEST_YUDXC = 800;
WT_CONTEST_CQM = 900;
WT_CONTEST_ARI = 1000;
WT_CONTEST_ARI_SEZIONI = 1001;
WT_CONTEST_ARI_40_80 = 1002;
WT_CONTEST_BALTIC = 1100;
WT_CONTEST_KING_OF_SPAIN = 1200;
WT_CONTEST_IOTA = 1300;
WT_CONTEST_RSGB_160 = 1301;
WT_CONTEST_RSGB_80_CC = 1302;
WT_CONTEST_RSGB_CMW = 1303;
WT_CONTEST_RSGB_15_10 = 1304;
WT_CONTEST_RSGB_AFS = 1305;
WT_CONTEST_WAEDC = 1400;
WT_CONTEST_WAG = 1401;
WT_CONTEST_DARC_XMAS = 1402;
WT_CONTEST_DARC_10 = 1403;
WT_CONTEST_YODXC = 1500;
WT_CONTEST_EU_HF = 1600;
WT_CONTEST_SCC = 1601;
WT_CONTEST_OCDXC = 1700;
WT_CONTEST_TOECC = 1800;
WT_CONTEST_SAC = 1900;
WT_CONTEST_NRAU_BALTIC = 1901;
WT_CONTEST_NAC = 1902;
WT_CONTEST_SARTG = 1903;
WT_CONTEST_QP_TX = 2000;
WT_CONTEST_EU_SPRINT = 2100;
WT_CONTEST_UKDXC = 2200;
WT_CONTEST_OKOMDXC = 2300;
WT_CONTEST_STEW_PERRY = 2400;
WT_CONTEST_GACW_DX = 2401;
WT_CONTEST_NINE_KCC_15 = 2402;
WT_CONTEST_FOC_MARATHON = 2403;
WT_CONTEST_LOTW = 2404;
WT_CONTEST_AP_SPRINT = 2405;
WT_CONTEST_JARTS = 2406;
WT_CONTEST_MARCONI_HF = 2407;
WT_CONTEST_LZDX = 2500;
WT_CONTEST_CROATIAN_CW = 2600;
WT_CONTEST_UBADX = 2700;
WT_CONTEST_UBA_SPRING_80M = 2701;
WT_CONTEST_UBA_SPRING_6M = 2702;
WT_CONTEST_UBA_SPRING_2M = 2703;
WT_CONTEST_ON_80M = 2704;
WT_CONTEST_ON_6M = 2705;
WT_CONTEST_ON_2M = 2706;
WT_CONTEST_RAC_DAY = 2800;
WT_CONTEST_RAC_WINTER = 2801;
WT_CONTEST_PACC = 2900;
WT_CONTEST_HELVETIA = 3000;
WT_CONTEST_HELVETIA_VHF = 3001;
WT_CONTEST_IARU_FD_R1_GENERIC = 3100;
WT_CONTEST_IARU_FD_R1_DARC = 3101;
WT_CONTEST_IARU_FD_R1_RSGB = 3102;
WT_CONTEST_UFT_HF = 3200;
WT_CONTEST_AGCW_HNY = 3300;
WT_CONTEST_HA_DX = 3400;
WT_CONTEST_NAQP = 3500;
WT_CONTEST_NA_SPRINT = 3501;
WT_CONTEST_NCCC_SPRINT = 3600;
WT_CONTEST_CQIR = 3700;

Supported modes IDs

WT_MODE_CW = 0;
WT_MODE_SSB = 1;
WT_MODE_RTTY = 2;
WT_MODE_FM = 3;
WT_MODE_PSK = 4;
WT_MODE_PKT = 5;
WT_MODE_HELL = 6;
WT_MODE_SAT = 7;

Supported status keys IDs

WT_KEY_SHIFT = 1;
WT_KEY_ALT = 2;
WT_KEY_CTRL = 4;

Radio Constants

WT_RADIO_MAX = 2;

WT_RADIO_VFOA = 0;
WT_RADIO_VFOB = 1;

WT_RADIO_1 = 0;
WT_RADIO_2 = 1;

Advanced Programming Examples

ESM Script (embedded into Win-Test)

For convenience, you can find below the current ESM (Enter Sends Message) embedded script. Note that the real returned values are somewhat different from the ones described above, because of the nature of this script (embedded), but it is a good source of inspiration for your own masterpiece. As Lua is an interpreted language, the good news is that you can edit your script while WT is running. No need to exit WT, enter modifications, and start WT again. Just edit esm.wts while WT is running, save it, and try it immediately!

The script assumes the following messages have been programmed into the Standard CW messages dialog:

F1 => CQ
F2 => RST + Exchange
F5 => $LOGGED
F7 => ? or Again (Phone)
F4 => $MYCALL
INSERT => Sends exchange (CW and RTTY)
PLUS => TU and Enter QSO

Here is the source code for esm.wts. To change the behavior, save it in the Win-Test scripts directory (File | Explore | /scripts directory), then edit it.

-- v1.2 All variables in messages replaced by keypresses
-- v1.1 Dupes taken into account in the S&P mode
-- v1.0 Initial version

-- Send functions

function sendCq()
   wtQso:ResetExchangeSent();
   wtApp:SendFKey("F1");  -- Always use the function key
end;

function sendExchangeRun()
   wtApp:SendFKey(wtQso:IsModePhone() and "F2" or "INSERT"); -- Ternary Operator
   wtQso:SetExchangeSent();
end;

function sendExchangeAgain()
   if (wtQso:IsModePhone()) then
      wtApp:SendFKey("F2");
   else
      wtApp:SendFKey("F5"); -- $LOGGED
      wtApp:SendFKey("F7"); -- ?
   end;
end;

function sendTu()
   wtApp:SendFKey("PLUS");
   wtQso:ClearStatus();
end;

function sendQuestionMark()
   wtQso:ResetExchangeSent();
   wtApp:SendFKey("F7"); -- Again ?
end;

function sendMyCall()
   wtApp:SendFKey("F4"); -- My call
end;

function sendExchangeSAndP()
   wtApp:SendFKey("F2");
   wtQso:SetExchangeSent();
end;


-- ESM core code

-- Return 0 (or return nothing) if we want the CR
-- to be processed also by WT (ie log QSO) and -1 if not.

if (wtQso:IsOperatingModeRun()) then -- Run
   if (wtContest:IsExchangeRequired()) then -- Usual contests
      if (wtQso:IsExchangeEmpty() or not wtQso:IsQsoApproved()) then
         if (wtQso:IsCallsignEmpty()) then
            sendCq();
         else
            if (wtQso:IsCallsignRepeated()) then
               sendExchangeAgain();
            else
               sendExchangeRun();
            end;
         end;
      else
         if (wtQso:IsExchangeSent()) then
            sendTu()
         else
            sendExchangeRun();
         end;
      end;
   else -- DXPed etc.
      if (not wtQso:IsQsoApproved()) then
         if (wtQso:IsCallsignEmpty()) then
            sendCq();
         else
            if (wtQso:IsCallsignRepeated()) then
               sendExchangeAgain();
            else
               sendExchangeRun();
            end;
         end;
      else
         if (wtQso:IsExchangeSent()) then
            sendTu();
         else
            sendExchangeRun();
         end;
      end;
   end;
else -- S&P : The automatic exchange fill (if enabled) is disabled by WT
   if ( (wtQso:IsExchangeEmpty() and wtContest:IsExchangeRequired())
     or not wtQso:IsQsoApproved() ) then
      if (wtQso:IsCallsignEmpty()) then
         sendQuestionMark();
      else
         if (not wtQso:IsDupe()) then -- Call only if not dupe
            sendMyCall();
         end;
      end;
   else
      if (wtQso:IsExchangeSent()) then
         wtQso:ClearStatus();
         return 0; -- Log it silently
      else
         if (not wtQso:IsDupe()) then -- Sent exchange only if not dupe
            sendExchangeSAndP();
         end;
      end;
   end;
end;

return -1; -- This script overrides the Win-Test CR process

Alternative ESM Script (provided by F5VIH/SV3SJ)

At the top of the script you will find a variable setting:

shortcq = false;

Setting it to true, it will convert the CQ calling and the TU part of the QSO in short forms (a la 5b4agn) and the exact contents of the messages are defined in the two lines that follow the shortcq setting. I have also added the possibility to have an exchange filled in and no call (in that case the script sends CL?)

I must say I am very impressed by the functionality that WT opens to the users with lua scripts. I would really like to see more API calls made available and WT functions using scripts (programmable keys, even SO2R, etc).

In the mean time if you have suggestions to improve the script let me know. I can easily inlcude them.

----------------------------------- 
-- Wintest ESM - Nick, F5VIH/SV3SJ
-- Set "shortCQ to true or false
-----------------------------------

shortcq = false;
shortCQ = "$MYCALL";
shortTU = "$CORRECT ++TU-- $CR";

-- Send functions

function sendCq()
 wtQso:ResetExchangeSent();
 if (wtQso:IsModePhone()) then
   wtApp:SendFKey("F1");
 else
   if (shortcq) then
     wtKeyer:Play(shortCQ);
   else
     wtApp:SendFKey("F1");  -- Always use the function key
   end;
 end;
end;
function sendExchangeRun()
 if (wtQso:IsModePhone()) then
   wtApp:SendFKey("F2");
   wtKeyer:Play("$CR");
 else
   wtKeyer:Play("$INSERT");
 end;
 wtQso:SetExchangeSent();
end;

function sendExchangeAgain()
 if (wtQso:IsModePhone()) then
   wtApp:SendFKey("F2");
 else
   wtKeyer:Play("$F5 $F7"); -- $LOGGED ?
 end;
end;

function sendTu()
 if (wtQso:IsModePhone()) then
   if (shortcq) then
     wtKeyer:Play("$CR");
     wtApp:SendFKey("F5");
   else
     wtApp:SendFKey("PLUS");
   end;
 else
   if (shortcq) then
     wtKeyer:Play(shortTU);
   else
     wtKeyer:Play("$PLUS");
   end;
 end;
 wtQso:ClearStatus();
end;

function sendQuestionMark()
 wtQso:ResetExchangeSent();
 if (wtQso:IsModePhone()) then
   wtApp:SendFKey("F7"); -- Again ?
 else
   wtKeyer:Play("$F7");
 end;
end;

function sendMyCall()
 if (wtQso:IsModePhone()) then
   wtApp:SendFKey("F4"); -- My call
 else
   wtKeyer:Play("$F4");
 end;
end;

function sendExchangeSAndP() -- Sends appropriate exchange when in S&P mode
 if (wtQso:IsModePhone()) then
   wtApp:SendFKey("F2"); -- 5NN EXCHANGE
 else
   wtKeyer:Play("$F2");
 end;
 wtQso:SetExchangeSent();
end;

function sendAskForCall()
 if (wtQso:IsModePhone()) then
   wtApp:SendFKey("F7"); -- AGN
 else
   wtKeyer:Play("CL?");
 end;
end;

function askForNumber()
 if (wtQso:IsModePhone()) then
   wtApp:SendFKey("F6"); -- NR AGN
 else
  wtKeyer:Play("$F6");
 end;
end;

function askWithPartialCall()
 if (wtQso:IsModePhone()) then
   wtApp:SendFKey("F7"); -- AGN
 else
   wtKeyer:Play("$F5 ?");
  end;
 end;

-- ESM core code

-- Return 0 (or return nothing) if we want the CR
-- to be processed also by WT (ie log QSO) and -1 if not.

if (wtQso:IsOperatingModeRun()) then -- Run Mode
 if (wtContest:IsExchangeRequired()) then -- Usual contests requiring an exchange
  if (wtQso:IsCallsignEmpty()) then
    if (wtQso:IsExchangeEmpty()) then
      sendCq();
    else -- we ve got an exchange but not a call, ask for the call
      sendAskForCall();
    end;
  else -- call is not empty
    if (wtQso:IsExchangeSent()) then -- we have sent the exchage
      if (not wtQso:IsQsoApproved()) then
        if (wtQso:IsCurrentFieldCallsign() and not wtQso:IsExchangeEmpty()) then
          askWithPartialCall();
        end;
        if (wtQso:IsCurrentFieldCallsign() and wtQso:IsExchangeEmpty()) then
         wtQso:ResetExchangeSent();
         sendExchangeRun();
         if (wtQso:IsCurrentFieldCallsign()) then wtKeyer:Play("$SPACEBAR") end;
        end;
        if (wtQso:IsCurrentFieldExchange() and wtQso:IsExchangeEmpty()) then
          askForNumber();
        end;
      else -- qso has valid call and exchange
        if (wtQso:IsCurrentFieldExchange()) then
          sendTu();
        else -- current field is not exchange (should be callsign)
         if (wtQso:IsCurrentFieldCallsign()) then
          wtQso:ResetExchangeSent();
          sendExchangeRun();
          if (wtQso:IsCurrentFieldCallsign()) then wtKeyer:Play("$SPACEBAR") end;
         end;
        end;
      end;

    else -- have not sent exchange and we are in the call field
      sendExchangeRun();
       if (wtQso:IsCurrentFieldCallsign()) then wtKeyer:Play("$SPACEBAR") end;
    end;
 end;

 else -- The contest doesnt require an exchange to be received e.g. DXPed etc.
   if (not wtQso:IsQsoApproved()) then
     if (wtQso:IsCallsignEmpty()) then
       sendCq();
     else
       if (wtQso:IsCallsignRepeated()) then
         sendExchangeAgain();
       else
         sendExchangeRun();
       end;
     end;
   else
     if (wtQso:IsExchangeSent()) then
       sendTu();
     else
       sendExchangeRun();
     end;
   end;
 end;

else -- S&P : The automatic exchange fill (if enabled) is disabled by WT
 if ( (wtQso:IsExchangeEmpty() and wtContest:IsExchangeRequired()) or not wtQso:IsQsoApproved() ) then
   if (wtQso:IsCallsignEmpty()) then
     sendQuestionMark();
   else
     if (not wtQso:IsDupe()) then -- Call only if not dupe
       sendMyCall();
     end;
   end;
 else
   if (wtQso:IsExchangeSent()) then
     wtQso:ClearStatus();
     wtKeyer:Play("$CR");
     return -1; -- Log it silently
   else
     if (not wtQso:IsDupe()) then -- Sent exchange only if not dupe
       sendExchangeSAndP();
     end;
   end;
 end;
end;

return -1; -- This script overrides the Win-Test CR process

Grab next call from partner window

The following script was kindly provided by Hank Lonberg, KR7X. It remaps the [~] key to grab the next callsign from the partner window and send an exchange.

wtKeyer:Play("$CORRECT TU $CR NOW $GRABPARTNER $NEXT $GUESSEXCH $F2 $13");

Re-map [Ä] key with /P for Field Day

Practical in Field Day where a lot of stations are signing "/P" - especially with a German keyboard layout.

-- add /P to a callsign for Field Day operations
wtApp:SendKeyCode(47);
wtApp:SendKeyCode(112);

Change background of Main Window depening on RUN/S&P Mode

The idea to this script was provided by GW3NJW. Name this script RunSPSwitch.wts nd have it assigned to ctrl-Tab

if (wtApp:IsPostKeyProcess()) then
  if (wtQso:IsOperatingModeRun()) then
    wtApp:SetWindowColor(-1, 0, 165, 165);
  else
    wtApp:SetWindowColor(-1, 128,128,128);
  end;
else
  return 1; -- Triggers a post key process call
end;