diff --git a/Makefile b/Makefile
index 46b5c4c5cf1c2f65006d55a128b0c01f92b178f3..aed31a5aa8614ff46d21f0ce21b96706fec1ac1d 100644
--- a/Makefile
+++ b/Makefile
@@ -18,7 +18,7 @@
 COMPONENT  = MousSetup
 TARGET     = !RunImage
 INSTTYPE   = app
-APP_OBJS   = Main MouseType Settings ToolboxE WimpE WimpM
+APP_OBJS   = Main MouseType Settings ToolboxE WimpE WimpM ScrollTypes
 LIBS       = ${CONLIB} ${EVENTLIB} ${TBOXLIB} ${WIMPLIB}
 CINCLUDES  = -Itbox:,C:,<Lib$Dir>.ConfigLib.
 INSTAPP_FILES = !Boot !Run !RunImage Res \
diff --git a/Resources/UK/Messages b/Resources/UK/Messages
index 0adc03bf4a17327c5475e835b499dce04bcd4e9e..903302ef201a1cff59a0a92acdc48434247a32c5 100644
--- a/Resources/UK/Messages
+++ b/Resources/UK/Messages
@@ -10,3 +10,8 @@ NoneAvail:No mouse drivers are available
 NewType:You are about to change the mouse type to '%s'. If you do not have this sort of mouse connected the pointer will stop working. Do you want to continue with the reconfiguration?
 Err_NoDefCMOS:Cannot find default CMOS file
 Err_Alloc:Not enough free memory
+Err_BadClass:Resource file is corrupt
+Type_Pointer:Window under the pointer
+Type_Focus:Window with input focus
+Type_FocusOrPointer:Input focus or under pointer
+Type_FavourHigher:Highest of input focus or pointer
diff --git a/Resources/UK/Res,fae b/Resources/UK/Res,fae
index cee54d9029220ad509a7391c2ef8165e5d2c0887..69fb0d3da7683f729544af0d17f3d0779733c2a9 100644
Binary files a/Resources/UK/Res,fae and b/Resources/UK/Res,fae differ
diff --git a/VersionNum b/VersionNum
index 3848a32ef78f21cc2be9b58b1a56b6a4df631c0c..747377927e0705212ec26552c7af541d2339ea45 100644
--- a/VersionNum
+++ b/VersionNum
@@ -1,23 +1,21 @@
-/* (0.16)
+/* (0.17)
  *
  * This file is automatically maintained by srccommit, do not edit manually.
- * Last processed by srccommit version: 1.1.
  *
  */
-#define Module_MajorVersion_CMHG        0.16
+#define Module_MajorVersion_CMHG        0.17
 #define Module_MinorVersion_CMHG        
-#define Module_Date_CMHG                03 Aug 2013
+#define Module_Date_CMHG                28 Mar 2020
 
-#define Module_MajorVersion             "0.16"
-#define Module_Version                  16
+#define Module_MajorVersion             "0.17"
+#define Module_Version                  17
 #define Module_MinorVersion             ""
-#define Module_Date                     "03 Aug 2013"
+#define Module_Date                     "28 Mar 2020"
 
-#define Module_ApplicationDate          "03-Aug-13"
+#define Module_ApplicationDate          "28-Mar-20"
 
 #define Module_ComponentName            "MousSetup"
-#define Module_ComponentPath            "castle/RiscOS/Sources/SystemRes/Configure2/PlugIns/MousSetup"
 
-#define Module_FullVersion              "0.16"
-#define Module_HelpVersion              "0.16 (03 Aug 2013)"
-#define Module_LibraryVersionInfo       "0:16"
+#define Module_FullVersion              "0.17"
+#define Module_HelpVersion              "0.17 (28 Mar 2020)"
+#define Module_LibraryVersionInfo       "0:17"
diff --git a/c/Main b/c/Main
index 53faac3da619ca9bb996e4ad7b10c2ec64af20d6..f8bf0763fdc6353849260f8dd9b9af2329405d00 100644
--- a/c/Main
+++ b/c/Main
@@ -31,14 +31,18 @@ Date		Who	Change
 /* Toolbox */
 #include "event.h"
 #include "toolbox.h"
+#include "window.h"
 /* Common */
 #include "error.h"
 #include "misc.h"
+#include "message.h"
 /* Local headers */
 #include "Main.h"  /* includes prototypes for this file */
 #include "ToolboxE.h"
 #include "WimpE.h"
 #include "WimpM.h"
+#include "Settings.h"
+#include "ScrollTypes.h"
 
 #define	WimpVersion	((int) 310)
 
@@ -47,12 +51,64 @@ Date		Who	Change
 	BOOL		quit = FALSE;
 	ObjectId	mainwindow_id;
 	MessagesFD	messages;
+	const _kernel_oserror err_alloc = { 0, "Err_Alloc" };
+	BOOL		wheel_supported;
 
 /* Static global variables */
 
 static	WimpPollBlock	poll_block;
 static	IdBlock		id_block;
 
+static ObjectId auto_scrollbar(const char *windowname)
+{
+  int  screeny;
+  ObjectTemplateHeader *objtemplate;
+  WindowTemplate       *wintemplate;
+  WimpWindow           *windef;
+  ObjectId              window_id;
+
+  /* Read the window object in by hand */
+  throw (toolbox_template_lookup (0, windowname, &objtemplate));
+  if (objtemplate->object_class != Window_ObjectClass) {
+    static const _kernel_oserror e = { 0, "Err_BadClass" };
+    message_error(messages, e);
+  }
+  wintemplate = objtemplate->body;
+  windef = &wintemplate->window;
+  screeny = _swi (OS_ReadModeVariable, _INR(0,1) | _RETURN(2), -1, 12) <<
+            _swi (OS_ReadModeVariable, _INR(0,1) | _RETURN(2), -1, 5);
+
+  /* Calculate the window height compared with the screen and
+   * turn the vertical scrollbar on if it doesn't fit
+   */
+  if ((windef->visible_area.ymax - windef->visible_area.ymin) >= screeny) {
+    windef->flags |= WimpWindow_VScroll;
+  }
+  else {
+    windef->flags &= ~WimpWindow_VScroll;
+  }
+  throw (toolbox_create_object (Toolbox_CreateObject_InCore, objtemplate, &window_id));
+  return window_id;
+}
+
+/*---------------------------------------------------------------------------*
+ * grey_gadget                                                               *
+ *                                                                           *
+ * Grey a a gadget.                                                          *
+ *                                                                           *
+ * In: objectid = ID of the object containing the gadget.                    *
+ *     gadgetid = ID of the gadget.                                          *
+ *---------------------------------------------------------------------------*/
+
+static void grey_gadget(int objectid, int gadgetid)
+{
+  unsigned int flags;
+
+  throw(gadget_get_flags(0, objectid, gadgetid, &flags));
+  flags=flags | Gadget_Faded;
+  throw(gadget_set_flags(0, objectid, gadgetid, flags));
+}
+
 /******	main() ************************************************************\
 
 In:		Command line option:
@@ -70,11 +126,33 @@ int main (int argc, char *argv[])
   throw (event_initialise (&id_block));
   throw (event_set_mask (wimpe_mask));
 
+  /* Disable the scroll wheel settings if the OS/Wimp doesn't support scrolling
+     (no WindowScroll module loaded). No need to read/write a config file which
+     will have no effect. */
+  wheel_supported = (_swix(OS_CLI,_IN(0),"RMEnsure WindowScroll 0") == NULL);
+
   /* Register for messages and events */
   wimpm_register ();
   wimpe_register ();
   toolboxe_register ();
 
+  /* Create & initialise window */
+  mainwindow_id = auto_scrollbar("Mouse");
+  scrolltypes_init ();
+  if (!wheel_supported)
+  {
+    grey_gadget(mainwindow_id, mainwindow_wheelspeedlabel);
+    grey_gadget(mainwindow_id, mainwindow_wheelspeedslow);
+    grey_gadget(mainwindow_id, mainwindow_wheelspeed);
+    grey_gadget(mainwindow_id, mainwindow_wheelspeedfast);
+    grey_gadget(mainwindow_id, mainwindow_linescroll);
+    grey_gadget(mainwindow_id, mainwindow_wheeltarget);
+    grey_gadget(mainwindow_id, mainwindow_wheeltargetlabel);
+  }
+  misc_openwindow (mainwindow_id, TRUE);
+  settings_read (cmos_read);
+  choices_read ();
+
   /* Go */
   error_recover_point();
   while (!quit) {
diff --git a/c/ScrollTypes b/c/ScrollTypes
new file mode 100644
index 0000000000000000000000000000000000000000..7ae9cf9791d7bb061f9ac9a572407e19ede8ed5d
--- /dev/null
+++ b/c/ScrollTypes
@@ -0,0 +1,106 @@
+/* Copyright 2020 Acorn Computers Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* Clib */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "swis.h"
+#include "Global/ModHand.h"
+#include "Global/RISCOS.h"
+/* Toolbox */
+#include "wimplib.h"
+#include "gadgets.h"
+/* Common */
+#include "cmos.h"
+#include "message.h"
+#include "str.h"
+#include "misc.h"
+/* Local headers */
+#include "Main.h"
+#include "ScrollTypes.h"  /* includes prototypes for this file */
+#include "Settings.h"
+
+#define NUM_TYPES 4
+
+static const char *scroll_types[NUM_TYPES] =
+{
+  /* n.b. tail end of each identifier must match the *WimpScroll setting */
+  "Type_Pointer",
+  "Type_Focus",
+  "Type_FocusOrPointer",
+  "Type_FavourHigher",
+};
+
+static char *scroll_descs[NUM_TYPES];
+
+void scrolltypes_init (void)
+{
+  /* Construct list of choices */
+  int len = 0;
+  for (int i=0;i<NUM_TYPES;i++)
+  {
+    const char *text = message_lookup_direct(messages,scroll_types[i]);
+    len += str_len(text)+1;
+  }
+  char *buf = malloc(len);
+  if (!buf)
+  {
+    message_error(messages, err_alloc);
+    exit(1);
+  }
+  for (int i=0;i<NUM_TYPES;i++)
+  {
+    scroll_descs[i] = buf;
+    const char *text = message_lookup_direct(messages,scroll_types[i]);
+    len = str_len(text);
+    memcpy(buf, text, len);
+    buf[len] = (i==NUM_TYPES-1 ? 0 : ',');
+    buf += len+1;
+  }
+  /* Initialise the string set */
+  throw(stringset_set_available(0, mainwindow_id, mainwindow_wheeltarget, scroll_descs[0]));
+  /* Now go back and null-terminate the options, ready for getselection */
+  for (int i=1;i<NUM_TYPES;i++)
+  {
+    scroll_descs[i][-1] = 0;
+  }
+}
+
+void scrolltypes_setselection (const char *value)
+{
+  for(int i=0;i<NUM_TYPES;i++)
+  {
+    if (!strcmp(value,scroll_types[i] + 5))
+    {
+      throw (stringset_set_selected (0, mainwindow_id, mainwindow_wheeltarget, scroll_descs[i]));
+      return;
+    }
+  }
+}
+
+const char *scrolltypes_getselection (void)
+{
+  char choice[256];
+  stringset_get_selected(0, mainwindow_id, mainwindow_wheeltarget, choice, 256, NULL);
+  for(int i=0;i<NUM_TYPES;i++)
+  {
+    if (!strcmp(choice,scroll_descs[i]))
+    {
+      return scroll_types[i] + 5;
+    }
+  }
+  return NULL;
+}
diff --git a/c/Settings b/c/Settings
index baa73750f8c700e688d380f0261f7a0aa1885d79..f25597cf29a4ba74450092202fc0e37e0b12a5a1 100644
--- a/c/Settings
+++ b/c/Settings
@@ -34,6 +34,8 @@ Date		Who	Change
 #include <string.h>
 #include "swis.h"
 #include "Global/OsWords.h"
+#include "Global/FileTypes.h"
+#include "Interface/HighFSI.h"
 /* Toolbox */
 #include "toolbox.h"
 #include "window.h"
@@ -41,10 +43,12 @@ Date		Who	Change
 /* Common */
 #include "cmos.h"
 #include "misc.h"
+#include "message.h"
 /* local headers */
 #include "Main.h"
 #include "MouseType.h"
 #include "Settings.h"  /* includes prototypes for this file */
+#include "ScrollTypes.h"
 
 #define mousespeed_slider_upperbound	((int) 9)
 
@@ -150,3 +154,129 @@ BOOL settings_write (void)
 //
   return TRUE;
 }
+
+/******	choices_default() *************************************************\
+
+Purpose:	Update GUI to default settings for Choices
+
+\**************************************************************************/
+
+void choices_default(void)
+{
+  if (!wheel_supported)
+  {
+    return;
+  }
+  throw (optionbutton_set_state (0, mainwindow_id, mainwindow_linescroll, 0));
+  scrolltypes_setselection("Pointer");
+  slider_set_value(0, mainwindow_id, mainwindow_wheelspeed, 40);
+}
+
+/******	parse_wimpscroll_command() ****************************************\
+
+Purpose:	Parse the given *WimpScroll command argument list and update
+		the GUI.
+In:		Settings string to parse
+
+\**************************************************************************/
+
+static void parse_wimpscroll_command(const char *arg_string)
+{
+  /* Parse the settings */
+  void *buf[64];
+  _kernel_oserror *e = _swix(OS_ReadArgs,_INR(0,3),"Type,LineScroll/S,Speed/E",arg_string,buf,sizeof(buf));
+  if (e)
+  {
+    throw(e);
+    return;
+  }
+
+  if (buf[0])
+  {
+    scrolltypes_setselection((char *) buf[0]);
+  }
+
+  throw (optionbutton_set_state (0, mainwindow_id, mainwindow_linescroll, (buf[1] != NULL) ? 1 : 0));
+
+  if (buf[2])
+  {
+    const char *speed = (const char *) buf[2];
+    if (*speed == 0)
+    {
+      int speed_value = speed[1] + (speed[2]<<8) + (speed[3]<<16) + (speed[4]<<24);
+      throw (slider_set_value (0, mainwindow_id, mainwindow_wheelspeed, speed_value));
+    }
+  }
+}
+
+/******	choices_read() ****************************************************\
+
+Purpose:	Reads current settings from Choices, reflect them in GUI
+
+\**************************************************************************/
+
+void choices_read(void)
+{
+  if (!wheel_supported)
+  {
+    return;
+  }
+
+  /* Set GUI to default settings */
+  choices_default();
+
+  /* Read WindowScroll settings */
+  FILE *fp;
+  char  string[1024];
+
+  fp = fopen(ChoicesFileRO, "r");
+  if (fp != NULL)
+  {
+      while (fgets(string, 1024, fp))
+      {
+          if (strncmp(string, "X WimpScroll ", 13)==0) parse_wimpscroll_command(string+13);
+      }
+      fclose(fp);
+  }
+}
+
+/******	choices_write() ***************************************************\
+
+Purpose:	Reads current settings from GUI, save them to Choices,
+		and apply them.
+
+\**************************************************************************/
+
+void choices_write(void)
+{
+  if (!wheel_supported)
+  {
+    return;
+  }
+
+  FILE *fp;
+  int linescroll,speed;
+  const char *scrolltype = scrolltypes_getselection();
+
+  throw (slider_get_value (0, mainwindow_id, mainwindow_wheelspeed, &speed));
+  throw (optionbutton_get_state (0, mainwindow_id, mainwindow_linescroll, &linescroll));
+
+  fp = fopen(ChoicesFile, "w");
+  if (fp != NULL)
+  {
+    fprintf(fp,
+            "X WimpScroll -Type %s %s-Speed %d\n",
+            scrolltype,
+            (linescroll ? "-LineScroll ":""),
+            speed);
+    fclose(fp);
+  }
+  _swix(OS_File, _INR(0,2),
+        OSFile_SetType,
+        ChoicesFile,
+        FileType_Obey);
+
+  char string[256];
+  sprintf(string, "Filer_Run %s", ChoicesFile);
+  _swix(OS_CLI, _IN(0), string);
+}
diff --git a/c/ToolboxE b/c/ToolboxE
index 491db84eb2b041e6fa966ed90460e69e97fc90d9..6731d8fd332c619270eca9c192fca45c863ad0bc 100644
--- a/c/ToolboxE
+++ b/c/ToolboxE
@@ -44,7 +44,6 @@ Date		Who	Change
 
 static int toolboxe_actionbuttonselected (int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle);
 static int toolboxe_stringsetabouttobeshown (int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle);
-static int toolboxe_objectautocreated (int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle);
 
 int toolboxe_events [5] =     { ActionButton_Selected,
 				StringSet_AboutToBeShown,
@@ -55,7 +54,6 @@ void toolboxe_register (void)
 {
   throw (event_register_toolbox_handler (-1, ActionButton_Selected, toolboxe_actionbuttonselected, NULL));
   throw (event_register_toolbox_handler (-1, StringSet_AboutToBeShown, toolboxe_stringsetabouttobeshown, NULL));
-  throw (event_register_toolbox_handler (-1, Toolbox_ObjectAutoCreated, toolboxe_objectautocreated, NULL));
 }
 
 /******	toolboxe_actionbuttonselected() ***********************************\
@@ -69,13 +67,19 @@ static int toolboxe_actionbuttonselected (int event_code, ToolboxEvent *event, I
   switch (id_block->self_component) {
     case mainwindow_default:
       settings_read (cmos_default);
+      choices_default ();
       break;
     case mainwindow_cancel:
       if (!(event->hdr.flags & 1)) quit = TRUE;
-      else settings_read (cmos_read);
+      else
+      {
+        settings_read (cmos_read);
+        choices_read ();
+      }
       break;
     case mainwindow_set:
       if (settings_write ()) if (!(event->hdr.flags & 1)) quit = TRUE;
+      choices_write ();
       break;
   }
   return 1;
@@ -95,7 +99,6 @@ static int toolboxe_stringsetabouttobeshown (int event_code, ToolboxEvent *event
   newcrc = mousetype_getavailable (&buffer);
   if (buffer == NULL)
   {
-    static const _kernel_oserror err_alloc = { 0, "Err_Alloc" };
     message_error(messages, err_alloc);
     return 1;
   }
@@ -109,17 +112,3 @@ static int toolboxe_stringsetabouttobeshown (int event_code, ToolboxEvent *event
 
   return 1;
 }
-
-/******	toolboxe_objectautocreated() **************************************\
-
-Purpose:	Handles Toolbox_ObjectAutoCreated event
-
-\**************************************************************************/
-
-static int toolboxe_objectautocreated (int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
-{
-  mainwindow_id = id_block->self_id;
-  misc_openwindow (mainwindow_id, TRUE);
-  settings_read (cmos_read);
-  return 1;
-}
diff --git a/h/Main b/h/Main
index efb1a54e4c06d0f8594573f236a4c158fcc73681..690a1232c47dd7110534501b1734de2c35ee7923 100644
--- a/h/Main
+++ b/h/Main
@@ -37,6 +37,8 @@ Date		Who	Change
 extern BOOL quit;
 extern ObjectId mainwindow_id;
 extern MessagesFD messages;
+extern const _kernel_oserror err_alloc;
+extern BOOL wheel_supported;
 
 /* Prototypes */
 
diff --git a/h/ScrollTypes b/h/ScrollTypes
new file mode 100644
index 0000000000000000000000000000000000000000..986a0c55cd9f1acce3ec5240627326ffbb14279c
--- /dev/null
+++ b/h/ScrollTypes
@@ -0,0 +1,25 @@
+/* Copyright 2020 Acorn Computers Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __scrolltypes_h
+#define __scrolltypes_h
+
+/* Prototypes */
+
+extern void scrolltypes_init (void);
+extern void scrolltypes_setselection (const char *value);
+extern const char *scrolltypes_getselection (void);
+
+#endif
diff --git a/h/Settings b/h/Settings
index 17b21b1220057643be058edec27a9f384066429f..34f5beee5d6a38599f646b5e28c11e0147330dd7 100644
--- a/h/Settings
+++ b/h/Settings
@@ -59,6 +59,16 @@ Date		Who	Change
 #define mainwindow_set			((ComponentId) 0x100)
 #define mainwindow_cancel		((ComponentId) 0x101)
 #define mainwindow_default		((ComponentId) 0x102)
+#define mainwindow_wheelspeedlabel	((ComponentId) 0x201)
+#define mainwindow_wheelspeedslow	((ComponentId) 0x202)
+#define mainwindow_wheelspeed		((ComponentId) 0x203)
+#define mainwindow_wheelspeedfast	((ComponentId) 0x204)
+#define mainwindow_linescroll		((ComponentId) 0x205)
+#define mainwindow_wheeltarget		((ComponentId) 0x206)
+#define mainwindow_wheeltargetlabel	((ComponentId) 0x207)
+
+#define ChoicesFile           "<Choices$Write>.Boot.Tasks.WimpScroll"
+#define ChoicesFileRO         "Choices:Boot.Tasks.WimpScroll"
 
 /* Global variables */
 
@@ -69,4 +79,8 @@ extern const cmos cmos_details [];
 extern void settings_read (int(*get)(cmos item, void *messages));
 extern BOOL settings_write (void);
 
+extern void choices_default(void);
+extern void choices_read(void);
+extern void choices_write(void);
+
 #endif