title: Create a HUD using Python
body: <p>I'm trying to program a HUD for a third-party application using Python. </p>
  
  <p>I was already able to make sure that my HUD follows the third-party application when the third-party application moves but I struggle to ensure that the HUD always appears at the top of the third-party application and vanishes when it is minimized or when an other application goes to the foreground. </p>
  
  <p>I have tried some functions of the Window API (<a href="https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setwindowpos" rel="nofollow noreferrer">SetWindowPos</a>, <a href="https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-bringwindowtotop" rel="nofollow noreferrer">BringWindowToTop</a> and <a href="https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setforegroundwindow" rel="nofollow noreferrer">SetForegroundWindow</a>)  but none of these gave me the expected result : the HUD always remains behind the third-party application. </p>
  
  <p>Here is a simple code sample to illustrate my problem:</p>
  
  <pre><code>import sys
  from PyQt4.QtGui import *
  from PyQt4.QtCore import *
  
  import ctypes
  import ctypes.wintypes
  
  user32 =  ctypes.windll.user32
  HUD_WIDTH = 100
  HUD_HEIGHT = 50 
  WINDOW_NAME = "Window name" #Replace this by the name of an opened window 
  
  EVENT_OBJECT_LOCATIONCHANGE = 0x800B
  EVENT_SYSTEM_FOREGROUND = 0x0003
  WINEVENT_OUTOFCONTEXT = 0x0000
  EVENT_SYSTEM_MINIMIZEEND = 0x0017
  
  class Hud(QLabel):
      def __init__(self,window_handle):
          super().__init__()
          self.initUI()
          self.window_handle = window_handle
          rect = ctypes.wintypes.RECT()
          user32.GetWindowRect(window_handle,ctypes.byref(rect))
          self.window_x = rect.left
          self.window_y = rect.top
          self.setFollowWindow()
  
  def initUI(self):
      self.setWindowFlags(Qt.Window | Qt.FramelessWindowHint)   
      self.resize(HUD_WIDTH,HUD_HEIGHT)   
      p = self.palette()
      p.setColor(self.backgroundRole(), Qt.black)
      p.setColor(self.foregroundRole(),Qt.white)
      self.setPalette(p)  
      self.setWindowOpacity(0.7)
      self.setText("Hello")
      self.setAlignment(Qt.AlignCenter)
      self.show()
  
  def mousePressEvent(self,event):
      self.click_x_coordinate = event.x()
      self.click_y_coordinate = event.y()
  
  def mouseMoveEvent(self,event):
      self.move(event.globalX()-self.click_x_coordinate,event.globalY()-self.click_y_coordinate)
  
  def setFollowWindow(self):
      WinEventProcType = ctypes.WINFUNCTYPE(
          None, 
          ctypes.wintypes.HANDLE,
          ctypes.wintypes.DWORD,
          ctypes.wintypes.HWND,
          ctypes.wintypes.LONG,
          ctypes.wintypes.LONG,
          ctypes.wintypes.DWORD,
          ctypes.wintypes.DWORD
      )
      def callback(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime):
          if idObject != -9: #Avoids mouse events
              if event == EVENT_OBJECT_LOCATIONCHANGE and hwnd == self.window_handle:
                  rect = ctypes.wintypes.RECT()
                  user32.GetWindowRect(hwnd,ctypes.byref(rect))
                  self.move(self.x() + rect.left - self.window_x,self.y() + rect.top - self.window_y)
                  self.window_x = rect.left
                  self.window_y = rect.top 
              elif event == EVENT_SYSTEM_FOREGROUND or event == EVENT_SYSTEM_MINIMIZEEND:
                  if hwnd == self.window_handle:
                      user32.SetWindowPos(self.winId().__int__(),-1,self.x(),self.y(),self.width(),
                              self.height())
  
      self.WinEventProc = WinEventProcType(callback)        
      user32.SetWinEventHook.restype = ctypes.wintypes.HANDLE
      self.hook = user32.SetWinEventHook(
          EVENT_SYSTEM_FOREGROUND,
          EVENT_OBJECT_LOCATIONCHANGE,
          0,
          self.WinEventProc,
          0,
          0,
          WINEVENT_OUTOFCONTEXT
      )
  class MainWindow(QMainWindow):
      def __init__(self):
          super(MainWindow,self).__init__()
          self.initUI()
      def initUI(self):
          self.launch_hud_button = QPushButton("Launch HUD",self)
          self.launch_hud_button.clicked.connect(self.launchHud)
          self.show()
      def launchHud(self):
          window_handle = user32.FindWindowW(0,WINDOW_NAME)
          if window_handle != 0 :
              self.hud = Hud(window_handle)
  
  if __name__ == '__main__':
      app = QApplication(sys.argv)
      main_window = MainWindow()
      sys.exit(app.exec_())
  </code></pre>
  
  <p>I have also tried to set the third party application as the parent of my HUD using <a href="https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setparent" rel="nofollow noreferrer">SetParent</a> but when doing so, my HUD isn't displayed at all. </p>
  
  <p>Do you have any suggestion to make it work using Window API or something else ? </p>