Jump to content

[SOLVED] - help, add right click option on header of active file/window/program


Go to solution Solved by ioa747,

Recommended Posts

Posted (edited)

Hi, I want to add my WinSetOnTop script on any active file/program/window when i right click on the header, I want to add it here, is it possible???

image.png.5e5e1f7b0b6a3bce9bd063cec6f6e948.png 

 

what i have now is this, it is manually added only, if i click SetOnTop my script will run.

image.png.fc562fbe71fe3b7d7bad8fab08d1329e.png

 

Func OnTop()
    If $OnTop = 0 Then
        $hWnd = WinGetHandle("[ACTIVE]")
        WinSetOnTop($hWnd, "", $WINDOWS_ONTOP)
        $OnTop += 1
    Else
        WinSetOnTop($hWnd, "", $WINDOWS_NOONTOP)
        $OnTop -= 1
    EndIf

EndFunc   ;==>OnTop
Edited by 232showtime
added script

ill get to that... i still need to learn and understand a lot of codes graduated.gif

Correct answer, learn to walk before you take on that marathon.

Posted

I am not sure what your intentions are.  Showing a trivial OnTop function doesn't help us much understanding the whole issue.  Please make a runable script that we can actually run and see what it is producing and explain precisely what you want to achieve.

Posted (edited)

I want to set any active files/folders/window to always on top and I want to add the script on right click contextmenu options, this is what i have now

Global $Title, $OnTop

HotKeySet("`", "OnTop")

Func OnTop()
    If $OnTop = 0 Then
        $Title = WinGetTitle("[ACTIVE]")
        WinSetOnTop($hWnd, "", $WINDOWS_ONTOP)
        $OnTop = 1
        ConsoleWrite($Title & @CRLF)
    Else
        ConsoleWrite($Title & @CRLF)
        WinSetOnTop($Title, "", $WINDOWS_NOONTOP)
        $OnTop = 0
    EndIf
EndFunc   ;==>OnTop

 

Edited by 232showtime

ill get to that... i still need to learn and understand a lot of codes graduated.gif

Correct answer, learn to walk before you take on that marathon.

Posted
#include <AutoItConstants.au3>

Global $Title, $OnTop

HotKeySet("`", "OnTop")

While 1
    Sleep(100)
WEnd

Func OnTop()
    If $OnTop = 0 Then
        $Title = WinGetTitle("[ACTIVE]")
        WinSetOnTop($Title, "", $WINDOWS_ONTOP)
        $OnTop = 1
        ConsoleWrite($Title & @CRLF)
    Else
        ConsoleWrite($Title & @CRLF)
        WinSetOnTop($Title, "", $WINDOWS_NOONTOP)
        $OnTop = 0
    EndIf
EndFunc   ;==>OnTop

 

ill get to that... i still need to learn and understand a lot of codes graduated.gif

Correct answer, learn to walk before you take on that marathon.

Posted (edited)

Maybe as an explanation @232showtime, @Nine is asking about a working code snippet that can be used.
After that we probably would give you hints about how to integrate you program into the context menus (by the registry).

Best regards
Sven

Edited by SOLVE-SMART

Stay innovative!

Spoiler

🌍 Au3Forums

🎲 AutoIt (en) Cheat Sheet

📊 AutoIt limits/defaults

💎 Code Katas: [...] (comming soon)

🎭 Collection of GitHub users with AutoIt projects

🐞 False-Positives

🔮 Me on GitHub

💬 Opinion about new forum sub category

📑 UDF wiki list

✂ VSCode-AutoItSnippets

📑 WebDriver FAQs

👨‍🏫 WebDriver Tutorial (coming soon)

Posted

Ok, your program works for a single window using a hotkey, you cannot set multiple windows on top and then make some non on top.  Is that intentional ?

What is this thing about context menus ?  Please explain in more detail.  Do you want to add an option on any single context menus shown by any program/window ?

Posted
3 minutes ago, Nine said:

What is this thing about context menus ?  Please explain in more detail.  Do you want to add an option on any single context menus shown by any program/window ?

I want to select and right click the file/window that i want to be always on top, 

I manually added it in registry context menu its working for folders only,  i googled it but still nothing,

image.png.7cb0cd43f7f314d07e4cb9dd50a0ae6d.png

ill get to that... i still need to learn and understand a lot of codes graduated.gif

Correct answer, learn to walk before you take on that marathon.

Posted
6 minutes ago, 232showtime said:

I manually added it in registry context menu its working for folders only,

You did not answer my first question.  So I must guess it is intentional and you do want it for a single program. Since you are targeting a single program, what is this program ?

For a single program manually entering it in a context menu is the straightforward way.  Now you seem to claim that you have a script that is working for folders only, can you show this script and a print screen of the registry section.  I do not understand how a SetOnTop is working for folders only (that does not make much sense to me).

ps. I need to extract from you every piece of information, it would be nice if you could provide a more complete description.

Posted

It is a bit confusing...
As I understand 232showtime wants to extend the contextmenu of every window (e.g. "Explorer") so he can select and start his tool "SetOnTop" to bring this Windows "OnTop". Is that right?

But when you click on a Window it gets already OnTop...  No need for your Tool.

Or is it that you want to get any Window to "Topmost" so it stays OnTop?

/A-Jay

Rule #1: Always do a backup         Rule #2: Always do a backup (backup of rule #1)

Posted

In case it helps OP, I use frequently without issue an old portable freeware program (2012) named "Topmost Toggle version 1.9.2.0" still found at Softpedia, here is the link . The review stipulates Win7 so I got no idea if it works on Win 10 / 11 (I guess it should work, you'll have to test)

TopmostToggle.png.c39d3437f77f50cb0e59c02fc5675162.png

When I got any window that I want to stay on top for a while, then Ctrl + right click on the window header keeps it on top. If I don't want it on top anymore (but still open), than another Ctrl + right click on its header toggles its state.

As you seem to need it accessible for any active window, then you should run "Toggle Topmost" and keep it constantly in Systray, so Ctrl + right click will be constantly checked on any window header.

Hope it helps.

 

"I think you are searching a bug where there is no bug..."

Posted (edited)

everyone, sorry for my bad english, im trying to achieve is to set to always on top on any file/folders/window that i want to stay on top by doing a right click on the header, same like this

image.png.4d7ef0e4dfdbc44368bc8f400dc3f370.png

what i did is i add my script manually to registry, my script, "SetOnTop" is included if i right click on desktopBG(left) & in the body of folders(right), by right clicking and selecting SetOnTop on the empty folder body will toggle SetOnTop on/off.

image.png.9abebadf44b03813beddad0aa1fd2bf6.png      image.png.05369b8557a7c56bc4b29f8f2d17b334.png

 

but if i right click on the header of any opened files/folders/windows, my script is not included in the right click options.

image.png.cc4f5d3fa8863e2baecedaa9891e572e.png

 

my goal is to right click the header of any files/folders/window that i want to be always on top. just like this toggle on/off my script via right click options.

image.png.2d758f04120c7daf66be57eef64a5162.png

image.png.2d1781a2db3074b5c8e5bef8c8bb3d96.png

 

sorry for any confusion, still trying to search registry to include my script.

15 hours ago, Nine said:

what is this program ?

it is intentional, .pdf, .jpeg .xlsx, .docx, [Class:CabinetWClass] etc... any active window/files/programs

 

right now, my script is working only on single active file/folders/window via hotkeys and using it for now.

 

#include <AutoItConstants.au3>

Global $Title, $OnTop

HotKeySet("`", "OnTop")

While 1
    Sleep(100)
WEnd

Func OnTop()
    If $OnTop = 0 Then
        $Title = WinGetTitle("[ACTIVE]")
        WinSetOnTop($Title, "", $WINDOWS_ONTOP)
        $OnTop = 1
        ConsoleWrite($Title & @CRLF)
    Else
        ConsoleWrite($Title & @CRLF)
        WinSetOnTop($Title, "", $WINDOWS_NOONTOP)
        $OnTop = 0
    EndIf
EndFunc   ;==>OnTop

 

@pixelsearch is this safe to use? 

12 hours ago, pixelsearch said:

"Topmost Toggle version 1.9.2.0"

Edited by 232showtime

ill get to that... i still need to learn and understand a lot of codes graduated.gif

Correct answer, learn to walk before you take on that marathon.

  • Solution
Posted (edited)

Here's a script that does it with the Ctrl + Win + T hotkey.

#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7
#AutoIt3Wrapper_Res_ProductName=WinTogleOnTop.au3
#AutoIt3Wrapper_Res_Description=Togle Window OnTop with 'Ctrl + Win + T'
#AutoIt3Wrapper_Res_Fileversion=0.0.0.1
#AutoIt3Wrapper_Icon=WinTogleOnTop.ICO

#include <WindowsConstants.au3>
#include <WinAPISys.au3>

TraySetIcon("WinTogleOnTop.ico")
Opt("TrayAutoPause", 0)

Global $g_ActWnd

HotKeySet("#^t", "Cmd_WinTogleOnTop")  ; Ctrl + Win + T" & @CRLF

;**********************************
While Sleep(50)
    _GetActiveWindow()
WEnd
;**********************************

;----------------------------------------------------------------------------------------
Func _GetActiveWindow()

    Local $AnyWindow = WinGetHandle("[ACTIVE]")

    If $g_ActWnd <> $AnyWindow Then
        $g_ActWnd = $AnyWindow
        ;ConsoleWrite("$g_ActWnd=" & $g_ActWnd & "; " & WinGetTitle($g_ActWnd) & @CRLF)
    EndIf

EndFunc   ;==>_GetActiveWindow
;----------------------------------------------------------------------------------------
Func Cmd_WinTogleOnTop()
    Local $iStyle = _WinAPI_GetWindowLong($g_ActWnd, $GWL_EXSTYLE)
    Local $iStyleTopMost = BitOR($iStyle, $WS_EX_TOPMOST)
    Local $aWPos = WinGetPos($g_ActWnd)
    If $iStyle = $iStyleTopMost Then
        WinSetOnTop($g_ActWnd, "", 0)
        ToolTip(" ", $aWPos[0], $aWPos[1], "Normal", 1)
    Else
        WinSetOnTop($g_ActWnd, "", 1)
        ToolTip(" ", $aWPos[0], $aWPos[1], "On top", 3)
    EndIf
    Sleep(1000)
    ToolTip("")
EndFunc   ;==>Cmd_WinTogleOnTop
;----------------------------------------------------------------------------------------

 

Edited by ioa747
update

I know that I know nothing

Posted (edited)

thanks @ioa747 very good example for me to learn more.

 

thanks for everyone's effort.

Edited by 232showtime

ill get to that... i still need to learn and understand a lot of codes graduated.gif

Correct answer, learn to walk before you take on that marathon.

  • 232showtime changed the title to [SOLVED] - help, add right click option on header of active file/window/program
Posted (edited)

FWIW, I felt that the tool (mentioned above) would be kind of fun to make, so there you go :

#include <WinAPISysWin.au3>
#include <WinAPISys.au3>
#include <WinAPIConstants.au3>
#include <WindowsConstants.au3>
#include <Misc.au3>
#include <GuiMenu.au3>
#include <GUIConstants.au3>
#include <ColorConstants.au3>

Opt("MustDeclareVars", True)

Global Const $tagTITLEBARINFOEX = "int cbSize;" & $tagRECT & ";dword rgstate[6];dword rgrect[24]"
Global $bRight, $hMSHook, $hMSProc, $hWnd

If Not _Singleton("AutoIt SetOnTop Tool", 1) Then Exit MsgBox($MB_OK, "Error", "Tool already loaded")
HotKeySet("{END}", Terminate)

Example()

Func Example()
  $hMSProc = DllCallbackRegister(MouseProc, "long", "int;wparam;lparam")
  $hMSHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, DllCallbackGetPtr($hMSProc), _WinAPI_GetModuleHandle(0))
  OnAutoItExitRegister(CleanUP)

  While Sleep(100)
    If $bRight Then
      $bRight = False
      ToggleSetOnTop()
    EndIf
  WEnd
EndFunc   ;==>Example

Func MouseProc($nCode, $wParam, $lParam)
  If $nCode < 0 Then Return _WinAPI_CallNextHookEx($hMSHook, $nCode, $wParam, $lParam)
  If ($wParam = $WM_RBUTTONDOWN Or $wParam = $WM_RBUTTONUP) And _IsPressed("11") Then
    $hWnd = GetWindow()
    If $hWnd Then
      $bRight = $wParam = $WM_RBUTTONUP
      Return 1
    EndIf
  EndIf
  Return _WinAPI_CallNextHookEx($hMSHook, $nCode, $wParam, $lParam)
EndFunc   ;==>MouseProc

Func ToggleSetOnTop()
  Local $iTop = BitAND(_WinAPI_GetWindowLong($hWnd, $GWL_EXSTYLE), $WS_EX_TOPMOST)
  Local $aPos = MouseGetPos()
  Local $hGUI = GUICreate("", 200, 32, $aPos[0], $aPos[1], $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
  GUISetBkColor(0xD0D0D0)
  Local $idLabel = GUICtrlCreateLabel($iTop ? "Topmost OFF" : "Topmost ON", 0, 0, 200, 32, $SS_CENTERIMAGE + $SS_CENTER)
  GUICtrlSetFont(-1, 18, Default, Default, "Arial")
  GUICtrlSetColor(-1, $iTop ? $COLOR_RED : $COLOR_GREEN)
  GUISetState()
  While WinActive($hGUI)
    Switch GUIGetMsg()
      Case $GUI_EVENT_CLOSE
        ExitLoop
      Case $idLabel
        WinSetOnTop($hWnd, "", $iTop ? $WINDOWS_NOONTOP : $WINDOWS_ONTOP)
        ExitLoop
    EndSwitch
  WEnd
  GUIDelete()
EndFunc   ;==>ToggleSetOnTop

Func CleanUP()
  _WinAPI_UnhookWindowsHookEx($hMSHook)
  DllCallbackFree($hMSProc)
EndFunc   ;==>CleanUP

Func Terminate()
  Exit
EndFunc   ;==>Terminate

Func GetWindow()
  Local Static $tPoint = DllStructCreate($tagPOINT)
  Local Static $tTITLEBARINFOEX = DllStructCreate($tagTITLEBARINFOEX)
  DllStructSetData($tTITLEBARINFOEX, "cbSize", DllStructGetSize($tTITLEBARINFOEX))

  $tPoint.X = MouseGetPos(0)
  $tPoint.Y = MouseGetPos(1)
  Local $hWin =  _WinAPI_GetAncestor(_WinAPI_WindowFromPoint($tPoint), $GA_ROOT)
  _SendMessage($hWin, $WM_GETTITLEBARINFOEX, 0, DllStructGetPtr($tTITLEBARINFOEX))
  If $tTITLEBARINFOEX.top + $tTITLEBARINFOEX.bottom + $tTITLEBARINFOEX.left + $tTITLEBARINFOEX.right = 0 Then Return 0
  If $tTITLEBARINFOEX.bottom <= $tTITLEBARINFOEX.top Then $tTITLEBARINFOEX.bottom = $tTITLEBARINFOEX.top + 35
  If $tPoint.X >= $tTITLEBARINFOEX.left And $tPoint.X <= $tTITLEBARINFOEX.right And $tPoint.Y >= $tTITLEBARINFOEX.top And $tPoint.Y <= $tTITLEBARINFOEX.bottom Then
   Return $hWin
  EndIf
  Return 0
EndFunc   ;==>GetWindow

Latest version :  2025-02-01 07:01

Edited by Nine
Posted
1 hour ago, Nine said:

small bug

I tweaked the code to debug:

Spoiler
#include <WinAPISysWin.au3>
#include <WinAPISys.au3>
#include <WinAPIConstants.au3>
#include <WindowsConstants.au3>
#include <Misc.au3>
#include <GuiMenu.au3>
#include <GUIConstants.au3>
#include <ColorConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
Opt("MustDeclareVars", True)

Global $bRight, $hMSHook, $hMSProc, $hWnd, $g_iMouseProc = 2

If Not _Singleton("AutoIt SetOnTop Tool", 1) Then Exit MsgBox($MB_OK, "Error", "Tool already loaded")
HotKeySet("{END}", Terminate)

Example()

Func Example()
    $hMSProc = DllCallbackRegister(MouseProc, "long", "int;wparam;lparam")
    $hMSHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, DllCallbackGetPtr($hMSProc), _WinAPI_GetModuleHandle(0))
    OnAutoItExitRegister(CleanUP)

    While Sleep(100)
        ToolTip("MouseProc: " & $g_iMouseProc) ; for debug
        If $bRight Then
            $bRight = False
            ToggleSetOnTop()
        EndIf
        $g_iMouseProc = 0
    WEnd
EndFunc   ;==>Example

Func MouseProc($nCode, $wParam, $lParam)
    $g_iMouseProc = 1
    Local $iCtrlKey = _IsPressed("11")
    If Not $iCtrlKey Then _WinAPI_CallNextHookEx($hMSHook, $nCode, $wParam, $lParam)
    Local Static $tPoint = DllStructCreate($tagPOINT)
    If $nCode < 0 Then Return _WinAPI_CallNextHookEx($hMSHook, $nCode, $wParam, $lParam)
    If ($wParam = $WM_RBUTTONDOWN Or $wParam = $WM_RBUTTONUP) And $iCtrlKey Then
        $tPoint.X = MouseGetPos(0)
        $tPoint.Y = MouseGetPos(1)
        $hWnd = _WinAPI_WindowFromPoint($tPoint)
        Local $hParent = _WinAPI_GetAncestor($hWnd, $GA_ROOT)
        If $hWnd = $hParent Then
            $bRight = $wParam = $WM_RBUTTONUP
            Return 1
        EndIf
    EndIf
    Return _WinAPI_CallNextHookEx($hMSHook, $nCode, $wParam, $lParam)
EndFunc   ;==>MouseProc

Func ToggleSetOnTop()
    Local $iTop = BitAND(_WinAPI_GetWindowLong($hWnd, $GWL_EXSTYLE), $WS_EX_TOPMOST)
    Local $aPos = MouseGetPos()
    Local $hGUI = GUICreate("", 200, 32, $aPos[0], $aPos[1], $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
    Local $idLabel = GUICtrlCreateLabel($iTop ? "Topmost OFF" : "Topmost ON", 0, 0, 200, 32, $SS_CENTERIMAGE + $SS_CENTER, BitOR($WS_EX_CLIENTEDGE, $WS_EX_STATICEDGE))
    GUICtrlSetFont(-1, 18, Default, Default, "Arial")
    GUICtrlSetColor(-1, $iTop ? $COLOR_RED : $COLOR_GREEN)
    GUISetState()
    While WinActive($hGUI)
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
            Case $idLabel
                WinSetOnTop($hWnd, "", $iTop ? $WINDOWS_NOONTOP : $WINDOWS_ONTOP)
                ExitLoop
        EndSwitch
    WEnd
    GUIDelete()
    WinActivate($hWnd)
EndFunc   ;==>ToggleSetOnTop

Func CleanUP()
    _WinAPI_UnhookWindowsHookEx($hMSHook)
    DllCallbackFree($hMSProc)
EndFunc   ;==>CleanUP

Func Terminate()
    Exit
EndFunc   ;==>Terminate

and find that the MouseProc() gets unhooked ?. No idea why. Running x86 here.

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Posted

Got the same problem as you after awhile.  Could you try with the original code (so we have the same base) commenting the line :

;$bRight = $wParam = $WM_RBUTTONUP

It will never show the GUI but it never looses its hook...Feels like déjà vu (I really hope not :sweating:)

Posted

Ok it seems to be a weird thing again.  By removing the line 

WinActivate($hWnd)

at the end of the ToggleSetOnTop function solves the problem.  No idea yet on why !

Found another problem though, some programs (like calculator) don't have the right ancestor.  Now I need to figure out how to get the right handle of the selected window.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...