<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE rules SYSTEM "ruleDoctype.dtd">
<rules xmlns="ul:rules" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="ul:rules ruleSchema.xsd">

  <!-- rules regarding mouse clicks -->
  <rule name="LeftClickButton">
    <msg type="&WM_LBUTTONDOWN;">
      <store var="clicked"/>
    </msg>
    <msg type="&WM_LBUTTONUP;">
      <equals>
        <constValue value="Button"/>
        <winInfoValue obj="this" winParam="class"/>
      </equals>
      <equals>
        <paramValue obj="clicked" param="window.hwnd"/>
        <paramValue obj="this" param="window.hwnd"/>
      </equals>
    </msg>
    <genMsg delay="100">
      <type>
        <constValue value="&BM_CLICK;"/>
      </type>
      <target>
        <msgInfoValue obj="clicked" msgParam="target"/>
      </target>
    </genMsg>
  </rule>

  <rule name="LeftClickListBox">
    <msg type="&WM_LBUTTONDOWN;">
      <equals>
        <winInfoValue obj="this" winParam="class"/>
        <constValue value="ListBox"/>
      </equals>
      <store var="clicked"/>
    </msg>
    <msg type="&WM_LBUTTONUP;">
      <equals>
        <paramValue obj="this" param="window.hwnd"/>
        <paramValue obj="clicked" param="window.hwnd"/>
      </equals>
      <store var="up"/>
    </msg>
    <genMsg delay="1000">
      <type>
        <constValue value="&LB_SETCURSEL;"/>
      </type>
      <target>
        <msgInfoValue obj="clicked" msgParam="target"/>
      </target>
      <WPARAM>
        <paramValue obj="up" param="scrollPos"/>
      </WPARAM>
    </genMsg>
  </rule>

  
  <!-- The tab change itself works, but the content of the tab is not refreshed. -->
  <rule name="TabChange">
    <msg type="&WM_LBUTTONDOWN;">
      <equals>
        <constValue value="SysTabControl32"/>
        <winInfoValue obj="this" winParam="class"/>
      </equals>
      <store var="clicked"/>
    </msg>
    <msg type="&WM_LBUTTONUP;">
      <equals>
        <paramValue obj="this" param="window.hwnd"/>
        <paramValue obj="clicked" param="window.hwnd"/>
      </equals>
      <store var="up"/>
    </msg>
    <genMsg delay="20">
      <type>
        <constValue value="&TCM_SETCURSEL;"/>
      </type>
      <target>
        <msgInfoValue obj="up" msgParam="target"/>
      </target>
      <WPARAM>
        <paramValue obj="up" param="scrollPos"/>
      </WPARAM>
    </genMsg>
  </rule>


  <rule name="ComboBox">
    <msg type="&WM_LBUTTONDOWN;">
      <equals>
        <winInfoValue obj="this" winParam="class"/>
        <constValue value="ComboBox"/>
      </equals>
      <store var="clicked"/>
    </msg>
    <msg type="&WM_COMMAND;">
      <equals>
        <paramValue obj="this" param="window.hwnd"/>
        <paramValue obj="clicked" param="window.hwnd"/>
      </equals>
      <store var="cmd1">
        <resolveHwnd param="source" storeParam="sourceDesc"/>
      </store>
    </msg>
    <msg type="&WM_COMMAND;" multiple="true">
      <equals>
        <paramValue obj="this" param="source"/>
        <paramValue obj="clicked" param="window.hwnd"/>
      </equals>
      <storeSeq varSeq="cmds">
        <resolveHwnd param="window.hwnd" storeParam="msgTarget"/>
        <resolveHwnd param="source" storeParam="sourceDesc"/>
      </storeSeq>
    </msg>
    <msg type="&WM_LBUTTONUP;">
      <equals>
        <paramValue obj="this" param="window.hwnd"/>
        <paramValue obj="clicked" param="window.hwnd"/>
      </equals>
    </msg>
    <genMsg delay="100">
      <type>
        <constValue value="&WM_SETFOCUS;"/>
      </type>
      <target>
        <msgInfoValue obj="clicked" msgParam="target"/>
      </target>
    </genMsg>
    <genMsg delay="100">
      <type>
        <constValue value="&CB_SHOWDROPDOWN;"/>
      </type>
      <target>
        <msgInfoValue obj="clicked" msgParam="target"/>
      </target>
      <WPARAM>
        <constValue value="1"/>
      </WPARAM>
    </genMsg>
    <!--
    <genMsg delay="100">
      <type>
        <constValue value="273"/>
      </type>
      <target>
        <msgInfoValue obj="cmd1" msgParam="target"/>
      </target>
      <LPARAM>
        <paramValue obj="cmd1" param="sourceDesc"/>
      </LPARAM>
      <WPARAM>
        <paramValue obj="cmd1" param="WPARAM"/>
      </WPARAM>
    </genMsg>
    <genMsgSeq delay="50">
      <type>
        <constValue value="273"/>
      </type>
      <target>
        <seqValue seqObj="cmds" param="msgTarget"/>
      </target>
      <LPARAM>
        <seqValue seqObj="cmds" param ="sourceDesc"/>
      </LPARAM>
      <WPARAM>
        <seqValue seqObj="cmds" param="WPARAM"/>
      </WPARAM>
    </genMsgSeq>-->
  </rule>
  
  <rule name="LeftClickCommand">
    <msg type="&WM_LBUTTONDOWN;">
      <store var="clicked"/>
    </msg>
    <msg type="&WM_LBUTTONUP;">
      <equals>
        <paramValue obj="clicked" param="window.hwnd"/>
        <paramValue obj="this" param="window.hwnd"/>
      </equals>
    </msg>
    <msg type="&WM_COMMAND;">
      <equals>
        <paramValue obj="clicked" param="window.hwnd"/>
        <paramValue obj="this" param="source"/>
      </equals>
      <store var="cmd">
        <resolveHwnd param="source" storeParam="sourceDesc"/>
      </store>
    </msg>
    <genMsg delay="100">
      <type>
        <msgInfoValue obj="cmd" msgParam="type"/>
      </type>
      <target>
        <msgInfoValue obj="cmd" msgParam="target"/>
      </target>
      <LPARAM>
        <paramValue obj="cmd" param="sourceDesc"/>
      </LPARAM>
      <WPARAM>
        <paramValue obj="cmd" param="WPARAM"/>
      </WPARAM>
    </genMsg>
  </rule>

  <rule name="LeftClickSysCommand">
    <msg type="&WM_LBUTTONDOWN;">
      <store var="clicked"/>
    </msg>
    <msg type="&WM_LBUTTONUP;">
      <equals>
        <paramValue obj="clicked" param="window.hwnd"/>
        <paramValue obj="this" param="window.hwnd"/>
      </equals>
    </msg>
    <msg type="&WM_SYSCOMMAND;">
      <store var="cmd"/>
    </msg>
    <genMsg delay="100">
      <storedVar obj="cmd"/>
    </genMsg>
  </rule>

  <rule name="NCLeftClickSysCommand">
    <msg type="&WM_NCLBUTTONDOWN;">
      <store var="clicked"/>
    </msg>
    <msg type="&WM_LBUTTONUP;">
      <equals>
        <paramValue obj="clicked" param="window.hwnd"/>
        <paramValue obj="this" param="window.hwnd"/>
      </equals>
    </msg>
    <msg type="&WM_SYSCOMMAND;">
      <equals>
        <paramValue obj="clicked" param="window.hwnd"/>
        <paramValue obj="this" param="window.hwnd"/>
      </equals>
      <store var="cmd"/>
    </msg>
    <genMsg delay="100">
      <storedVar obj="cmd"/>
    </genMsg>
  </rule>

  <rule name="LeftClickMenuItemCmd">
    <msg type="&WM_LBUTTONDOWN;">
      <store var="clicked"/>
    </msg>
    <msg type="&WM_LBUTTONUP;">
      <equals>
        <paramValue obj="clicked" param="window.hwnd"/>
        <paramValue obj="this" param="window.hwnd"/>
      </equals>
    </msg>
    <msg type="&WM_MENUSELECT;">
      <equals>
        <paramValue obj="clicked" param="window.hwnd"/>
        <paramValue obj="this" param="window.hwnd"/>
      </equals>
    </msg>
    <msg type="&WM_COMMAND;">
      <equals>
        <paramValue obj="this" param="sourceType"/>
        <constValue value="0"/>
      </equals>
      <store var="cmd"/>
    </msg>
    <genMsg delay="100">
      <storedVar obj="cmd"/>
    </genMsg>
  </rule>

 
  <!-- rules involving mouse movement -->
  <rule name="HScroll_TrackBar">
    <msg type="&WM_LBUTTONDOWN;">
      <equals>
        <winInfoValue obj="this" winParam="class"/>
        <constValue value="msctls_trackbar32"/>
      </equals>
      <store var="clicked"/>
    </msg>
    <msg type="&WM_HSCROLL;" multiple="true">
      <equals>
        <paramValue obj="this" param="scrollBarHandle"/>
        <paramValue obj="clicked" param="window.hwnd"/>
      </equals>
      <storeSeq varSeq="scrolls">
        <resolveHwnd param="scrollBarHandle" storeParam="scrollBarTarget"/>
      </storeSeq>
    </msg>    
    <msg type="&WM_LBUTTONUP;">
      <equals>
        <paramValue obj="this" param="window.hwnd"/>
        <paramValue obj="clicked" param="window.hwnd"/>
      </equals>
    </msg>
    <genMsgSeq delay="20">
      <type>
        <constValue value="&TBM_SETPOS;"/>
      </type>
      <target>
        <seqValue seqObj="scrolls" param="scrollBarTarget"/>
      </target>
      <LPARAM>
        <seqValue seqObj="scrolls" param="scrollPos"/>
      </LPARAM>
      <WPARAM>
        <constValue value="1"/>
      </WPARAM>
    </genMsgSeq>
  </rule>


  <rule name="VScroll_TrackBar">
    <msg type="&WM_LBUTTONDOWN;">
      <equals>
        <winInfoValue obj="this" winParam="class"/>
        <constValue value="msctls_trackbar32"/>
      </equals>
      <store var="clicked"/>
    </msg>
    <msg type="&WM_VSCROLL;" multiple="true">
      <equals>
        <paramValue obj="this" param="scrollBarHandle"/>
        <paramValue obj="clicked" param="window.hwnd"/>
      </equals>
      <storeSeq varSeq="scrolls">
        <resolveHwnd param="scrollBarHandle" storeParam="scrollBarTarget"/>
      </storeSeq>
    </msg>
    <msg type="&WM_LBUTTONUP;">
      <equals>
        <paramValue obj="this" param="window.hwnd"/>
        <paramValue obj="clicked" param="window.hwnd"/>
      </equals>
    </msg>
    <genMsgSeq delay="20">
      <type>
        <constValue value="&TBM_SETPOS;"/>
      </type>
      <target>
        <seqValue seqObj="scrolls" param="scrollBarTarget"/>
      </target>
      <LPARAM>
        <seqValue seqObj="scrolls" param="scrollPos"/>
      </LPARAM>
      <WPARAM>
        <constValue value="1"/>
      </WPARAM>
    </genMsgSeq>
  </rule>


  <rule name="HScroll_ScrollBar">
    <msg type="&WM_LBUTTONDOWN;">
      <equals>
        <winInfoValue obj="this" winParam="class"/>
        <constValue value="ScrollBar"/>
      </equals>
      <store var="clicked"/>
    </msg>
    <msg type="&WM_HSCROLL;" multiple="true">
      <equals>
        <paramValue obj="this" param="scrollBarHandle"/>
        <paramValue obj="clicked" param="window.hwnd"/>
      </equals>
      <storeSeq varSeq="scrolls">
        <resolveHwnd param="scrollBarHandle" storeParam="scrollBarTarget"/>
      </storeSeq>
    </msg>
    <msg type="&WM_LBUTTONUP;">
      <equals>
        <paramValue obj="this" param="window.hwnd"/>
        <paramValue obj="clicked" param="window.hwnd"/>
      </equals>
    </msg>
    <genMsgSeq delay="20">
      <type>
        <constValue value="&SBM_SETPOS;"/>
      </type>
      <target>
        <seqValue seqObj="scrolls" param="scrollBarTarget"/>
      </target>
      <LPARAM>
        <constValue value="1"/>
      </LPARAM>
      <WPARAM>
        <seqValue seqObj="scrolls" param="scrollPos"/>
      </WPARAM>
    </genMsgSeq>
  </rule>


  <rule name="VScroll_ScrollBar">
    <msg type="&WM_LBUTTONDOWN;">
      <equals>
        <winInfoValue obj="this" winParam="class"/>
        <constValue value="ScrollBar"/>
      </equals>
      <store var="clicked"/>
    </msg>
    <msg type="&WM_VSCROLL;" multiple="true">
      <equals>
        <paramValue obj="this" param="scrollBarHandle"/>
        <paramValue obj="clicked" param="window.hwnd"/>
      </equals>
      <storeSeq varSeq="scrolls">
        <resolveHwnd param="scrollBarHandle" storeParam="scrollBarTarget"/>
      </storeSeq>
    </msg>
    <msg type="&WM_LBUTTONUP;">
      <equals>
        <paramValue obj="this" param="window.hwnd"/>
        <paramValue obj="clicked" param="window.hwnd"/>
      </equals>
    </msg>
    <genMsgSeq delay="20">
      <type>
        <constValue value="&SBM_SETPOS;"/>
      </type>
      <target>
        <seqValue seqObj="scrolls" param="scrollBarTarget"/>
      </target>
      <LPARAM>
        <constValue value="1"/>
      </LPARAM>
      <WPARAM>
        <seqValue seqObj="scrolls" param="scrollPos"/>
      </WPARAM>
    </genMsgSeq>
  </rule>
  
  <!-- Does not work correctly, if a scrollbar has no handle of its own, e.g., a standard scrollbar of a listbox -->
  <rule name="VScrollNC">
    <msg type="&WM_NCLBUTTONDOWN;">
      <store var="clicked"/>
    </msg>
    <msg type="&WM_VSCROLL;">
      <equals>
        <paramValue obj="this" param="window.hwnd"/>
        <paramValue obj="clicked" param="window.hwnd"/>
      </equals>
      <store var="scrolls"/>
    </msg>
    <genMsg delay="20">
      <type>
        <constValue value="&WM_VSCROLL;"/>
      </type>
      <target>
        <msgInfoValue obj="clicked" msgParam="target"/>
      </target>
      <WPARAM>
        <LOWORD>
          <constValue value="4"/>
        </LOWORD>
        <HIWORD>
          <paramValue obj="scrolls" param="scrollPos"/>
        </HIWORD>
      </WPARAM>
    </genMsg>
  </rule>


  <!--<rule name="VScrollNC">
    <msg type="&WM_NCLBUTTONDOWN;">
      <store var="clicked"/>
    </msg>
    <msg type="&WM_VSCROLL;" multiple="true">
      <equals>
        <paramValue obj="this" param="window.hwnd"/>
        <paramValue obj="clicked" param="window.hwnd"/>
      </equals>
      <storeSeq varSeq="scrolls">
        <resolveHwnd param="window.hwnd" storeParam="scrollBarTarget"/>
      </storeSeq>
    </msg>
    <genMsgSeq delay="20">
      <type>
        <constValue value="&WM_VSCROLL;"/>
      </type>
      <target>
        <seqValue seqObj="scrolls" param="scrollBarTarget"/>
      </target>
      <WPARAM>
        <LOWORD>
          <constValue value="4"/>
        </LOWORD>
        <HIWORD>
          <paramValue obj="scrolls" param="scrollPos"/>
        </HIWORD>
      </WPARAM>
    </genMsgSeq>
  </rule>-->

  <!-- Copy of set focus without kill-focus -->
  <rule name="LeftClickSetFocus">
    <msg type="&WM_LBUTTONDOWN;">
      <equals>
        <winInfoValue obj="this" winParam="class"/>
        <constValue value="Edit"/>
      </equals>
      <store var="clicked"/>
    </msg>
    <msg type="&WM_SETFOCUS;">
      <store var="setfocus"/>
    </msg>
    <msg type="&WM_COMMAND;">
      <equals>
        <paramValue obj="this" param="source"/>
        <paramValue obj="clicked" param="window.hwnd"/>
      </equals>
      <equals>
        <paramValue obj="this" param="sourceType"/>
        <constValue value="256"/>
      </equals>
      <store var="cmd"/>
    </msg>
    <msg type="&WM_LBUTTONUP;">
      <equals>
        <paramValue obj="this" param="window.hwnd"/>
        <paramValue obj="clicked" param="window.hwnd"/>
      </equals>
    </msg>
    <genMsg delay="20">
      <type>
        <constValue value="&WM_SETFOCUS;"/>
      </type>
      <target>
        <msgInfoValue obj="setfocus" msgParam="target"/>
      </target>
      <WPARAM>
        <constValue value="0"/>
      </WPARAM>
    </genMsg>
    <genMsg delay="100">
      <type>
        <constValue value="&WM_COMMAND;"/>
      </type>
      <target>
        <msgInfoValue obj="cmd" msgParam="target"/>
      </target>
      <LPARAM>
        <msgInfoValue obj="setfocus" msgParam="target"/>
      </LPARAM>
      <WPARAM>
        <paramValue obj="cmd" param="WPARAM"/>
      </WPARAM>
    </genMsg>
  </rule>
  
  <!-- Works only partially! -->
  <rule name="LeftClickChangeFocus">
    <msg type="&WM_LBUTTONDOWN;">
      <equals>
        <winInfoValue obj="this" winParam="class"/>
        <constValue value="Edit"/>
      </equals>
      <store var="clicked"/>
    </msg>
    <msg type="&WM_KILLFOCUS;">
      <store var="killfocus"/>
    </msg>
    <msg type="&WM_SETFOCUS;">
      <equals>
        <paramValue obj="this" param="WPARAM"/>
        <paramValue obj="killfocus" param="window.hwnd"/>
      </equals>
      <store var="setfocus"/>
    </msg>
    <msg type="&WM_COMMAND;">
      <equals>
        <paramValue obj="this" param="source"/>
        <paramValue obj="clicked" param="window.hwnd"/>
      </equals>
      <equals>
        <paramValue obj="this" param="sourceType"/>
        <constValue value="256"/>
      </equals>
      <store var="cmd"/>
    </msg>
    <msg type="&WM_LBUTTONUP;">
      <equals>
        <paramValue obj="this" param="window.hwnd"/>
        <paramValue obj="clicked" param="window.hwnd"/>
      </equals>
    </msg>
    <genMsg delay="20">
      <type>
        <constValue value="&WM_KILLFOCUS;"/>
      </type>
      <target>
        <msgInfoValue obj="killfocus" msgParam="target"/>
      </target>
      <WPARAM>
        <msgInfoValue obj="setfocus" msgParam="target"/>
      </WPARAM>
    </genMsg>
    <genMsg delay="20">
      <type>
        <constValue value="&WM_SETFOCUS;"/>
      </type>
      <target>
        <msgInfoValue obj="setfocus" msgParam="target"/>
      </target>
      <WPARAM>
        <msgInfoValue obj="killfocus" msgParam="target"/>
      </WPARAM>
    </genMsg>
    <genMsg delay="100">
      <type>
        <constValue value="&WM_COMMAND;"/>
      </type>
      <target>
        <msgInfoValue obj="cmd" msgParam="target"/>
      </target>
      <LPARAM>
        <msgInfoValue obj="setfocus" msgParam="target"/>
      </LPARAM>
      <WPARAM>
        <paramValue obj="cmd" param="WPARAM"/>
      </WPARAM>
    </genMsg>
  </rule>


  <!-- Rules for keyboard input -->
  <rule name="KeyDown">
    <msg type="&WM_KEYDOWN;">
      <store var="keydown"/>
    </msg>
    <genMsg delay="20">
      <storedVar obj="keydown"/>
    </genMsg>
    <idinfo>
      <paramValue obj="keydown" param="key"/>
    </idinfo>
  </rule>

  <rule name="KeyUp">
    <msg type="&WM_KEYUP;">
      <store var="keyup"/>
    </msg>
    <genMsg delay="20">
      <storedVar obj="keyup"/>
    </genMsg>
    <idinfo>
      <paramValue obj="keyup" param="key"/>
    </idinfo>
  </rule>

  <rule name="SysKeyDown">
    <msg type="&WM_SYSKEYDOWN;">
      <store var="keydown"/>
    </msg>
    <genMsg delay="20">
      <storedVar obj="keydown"/>
    </genMsg>
    <idinfo>
      <paramValue obj="keydown" param="key"/>
    </idinfo>
  </rule>

  <rule name="SysKeyUp">
    <msg type="&WM_SYSKEYUP;">
      <store var="keyup"/>
    </msg>
    <genMsg delay="20">
      <storedVar obj="keyup"/>
    </genMsg>
    <idinfo>
      <paramValue obj="keyup" param="key"/>
    </idinfo>
  </rule>


  <!-- What follows are coordinate-based rules. They are "hail mary" rules that try to salvage events that cannot be matched or replayed in a coordinate independent way (yet). -->
  <rule name ="LeftClickCoordinates">
    <msg type="&WM_LBUTTONDOWN;">
      <store var="clicked"/>
    </msg>
    <msg type="&WM_LBUTTONUP;">
      <equals>
        <paramValue obj="clicked" param="window.hwnd"/>
        <paramValue obj="this" param="window.hwnd"/>
      </equals>
      <store var="up"/>
    </msg>
    <genMsg delay="20">
      <type>
        <constValue value="&WM_LBUTTONDOWN;"/>
      </type>
      <target>
        <msgInfoValue obj="clicked" msgParam="target"/>
      </target>
      <LPARAM>
        <LOWORD>
          <paramValue obj="clicked" param="point.x"/>
        </LOWORD>
        <HIWORD>
          <paramValue obj="clicked" param="point.y"/>
        </HIWORD>
      </LPARAM>
      <WPARAM>
        <paramValue obj="clicked" param="WPARAM"/>
      </WPARAM>
    </genMsg>
    <genMsg delay="20">
      <type>
        <constValue value="&WM_LBUTTONUP;"/>
      </type>
      <target>
        <msgInfoValue obj="up" msgParam="target"/>
      </target>
      <LPARAM>
        <LOWORD>
          <paramValue obj="up" param="point.x"/>
        </LOWORD>
        <HIWORD>
          <paramValue obj="up" param="point.y"/>
        </HIWORD>
      </LPARAM>
      <WPARAM>
        <paramValue obj="up" param="WPARAM"/>
      </WPARAM>
    </genMsg>
  </rule>
  
  <rule name ="NCLeftClickCoordinates">
    <msg type="&WM_NCLBUTTONDOWN;">
      <store var="clicked"/>
    </msg>
    <msg type="&WM_LBUTTONUP;">
      <equals>
        <paramValue obj="clicked" param="window.hwnd"/>
        <paramValue obj="this" param="window.hwnd"/>
      </equals>
      <store var="up"/>
    </msg>
    <genMsg delay="20">
      <type>
        <constValue value="&WM_NCLBUTTONDOWN;"/>
      </type>
      <target>
        <msgInfoValue obj="clicked" msgParam="target"/>
      </target>
      <LPARAM>
        <LOWORD>
          <paramValue obj="clicked" param="point.x"/>
        </LOWORD>
        <HIWORD>
          <paramValue obj="clicked" param="point.y"/>
        </HIWORD>
      </LPARAM>
      <WPARAM>
        <paramValue obj="clicked" param="WPARAM"/>
      </WPARAM>
    </genMsg>
    <genMsg delay="20">
      <type>
        <constValue value="&WM_LBUTTONUP;"/>
      </type>
      <target>
        <msgInfoValue obj="up" msgParam="target"/>
      </target>
      <LPARAM>
        <LOWORD>
          <paramValue obj="up" param="point.x"/>
        </LOWORD>
        <HIWORD>
          <paramValue obj="up" param="point.y"/>
        </HIWORD>
      </LPARAM>
      <WPARAM>
        <paramValue obj="up" param="WPARAM"/>
      </WPARAM>
    </genMsg>
  </rule>
  
</rules>
