title: Different behaviours encountered when posting a mouse scroll message to different windows with win32gui
body: <p>I was trying to send scroll commands to a window in the background, when I encountered strange behaviours that I don't really understand.</p>
  <p><strong>The Script</strong></p>
  <p>I wrote a script to illustrate what I encountered. To have it work, I used a Windows 10 system, and had <em>one</em> mail window and <em>one</em> command prompt window open in the background (not minimised). The script sends a scroll command to both windows with the mouse pointer located at the middle of the window.</p>
  <p>In both windows, the cursor should hover over a region that allows for scrolling. The difference lies in the fact that for the mail window, only a portion of the window allows for scrolling (I used these windows because it is most likely that everyone using Windows has these applications).</p>
  <pre><code>import win32gui as wgui
  import win32api as wapi
  import win32con as wcon
  
  # This script is meant to try sending scroll messages to a window.
  
  
  def callback(hwnd, win_list):
      &quot;&quot;&quot; Callback for win32gui.EnumWindows : appends the hwnd to win_list.&quot;&quot;&quot;
      win_list.append(hwnd)
  
  
  def find_specific_window(tag):
      &quot;&quot;&quot;  This function finds a specific window and returns its handle and name.
      :param tag: A key word that describes the window we look for.
  
      .. note:
      Always stops at the first match.
      &quot;&quot;&quot;
      win_list = []
      wgui.EnumWindows(callback, win_list)
  
      # Find the first window with the tag in its name:
      hwnd = None
      name = None
      for h in win_list:
          n = wgui.GetWindowText(h)
          if tag in n:
              name = n
              hwnd = h
              break
      return hwnd, name
  
  
  def scroll_bg(hwnd, pointer_x, pointer_y, child=True, delta=1):
      &quot;&quot;&quot; Performs a scroll on a background window with handle hwnd (might need to use FindWindowEx).
      :param pointor_x: relative horizontal position of the mouse (y is vertical).
      :param child: Boolean telling whether to operate on the top child window or the main window.
      &quot;&quot;&quot;
      # Take the top child window handle
      if child:
          hwnd = wgui.FindWindowEx(hwnd, None, None, None)
  
      # Transform the mouse coordinates into pixels for the given window.
  
      # Obtain the window dimensions
      rect = wgui.GetWindowRect(hwnd)
  
      w = rect[2]  # Width
      h = rect[3]  # Height
  
      x_pix = int(round(w * pointer_x))
      y_pix = int(round(h * pointer_y))
  
      print(&quot;In scroll_bg: the coordinates for the window {} are : ({}, {})&quot;.format(hwnd, x_pix, y_pix))
  
      # Transform them for the function
      lparam = wapi.MAKELONG(x_pix, y_pix)
  
      # Transform into wparam
      wparam = wapi.MAKELONG(0, - delta * wcon.WHEEL_DELTA) 
      
      # Hover to the pointer position.
      wgui.PostMessage(hwnd, wcon.WM_MOUSEMOVE, 0, lparam)
  
      # Scroll
      wgui.PostMessage(hwnd, wcon.WM_MOUSEWHEEL, wparam, lparam)
      wgui.PostMessage(hwnd, wcon.WM_MOUSEMOVE, 0, lparam)
  
  
  if __name__ == '__main__':
  
      window1_tag = &quot;Mail&quot;
      window2_tag = &quot;Command&quot;
  
      hwnd1 = find_specific_window(window1_tag)
      hwnd2 = find_specific_window(window2_tag)
  
      print(&quot;first window handle: {}, second window handle: {}&quot;.format(hwnd1, hwnd2))
  
      # In both windows we set the pointer at the middle.
      scroll_bg(hwnd1[0], 1/2, 1/2)
      scroll_bg(hwnd2[0], 1/2, 1/2, False)
  
  </code></pre>
  <p>In the script, I defined a <code>scroll_bg</code> function that can send the scroll instruction to a given window, identified by <code>hwnd</code>, or its first child (by setting <code>child=True</code>).</p>
  <p><strong>My Script Result</strong></p>
  <p>Running this script I can observe that the scroll has correctly been sent to the Command Prompt window, but nothing changed for the Mail window, despite targetting scrollable areas in both windows. I must note that I also tried sending the scroll message to the parent window, by running <code>scroll_bg(hwnd1[0], 1/2, 1/2, False)</code>, but it didn't work either.</p>
  <p><strong>More Details</strong></p>
  <p>I must also note that I observed this issue in the same context as this <a href="https://stackoverflow.com/questions/69761948/is-it-possible-to-send-a-drag-command-to-an-inactive-window-in-the-background-u">question.</a> I wanted to send scroll commands instead of dragging, and managed to successfully scroll in certain areas while not in others (for the same game).</p>
  <p>I further observed that giving a scroll command would do the same animation as a click. The weird part about it is that changing the position of <code>pointer_x</code> didn't change the position of the animation, and it occurred at the left border of the window (horizontal pixel = 0). It looks like the <code>pointer_x</code> is set to 0, and this would explain the script results.</p>
  <p>An other point worth mentioning is that maybe the scroll commands can only be interpreted by some other child window and that the <code>wgui.PostMessage</code> function sends the scroll commands to the wrong window thus they are not interpreted correctly. I'm a bit confused as to which window I should send the commands to. For instance, in the case of the game, posting messages to the parent window would not work and I had to send them to the first child. So, perhaps, the results of the script could be explained by the fact that I'm not sending to the correct child.</p>
  <p><em>Versions</em> I am using:</p>
  <ul>
  <li><code>pywin32</code> v: 300</li>
  <li><code>python</code>  v: 3.7.1</li>
  </ul>
  <p>Thank you for your time, and any advice is welcome ! :)</p>