BrunoStivicevic Posted October 16, 2022 Share Posted October 16, 2022 All, I'm using the Windows application Picasa 3 and I need to overlap its native menu by a custom GUI menu which has to stay always in front of Picasa window. I manage to do it by means of the following simple code: $hGUI_Arch_menu = GUICreate($menuname, @DesktopWidth, 20,-3,0,-1,$WS_EX_TOOLWINDOW,$hwndPicasa) There are however few serious limitations. As the GUI menu has to overlap *ALWAYS* the native menu as it would be hooked to Picasa, I managed to make it work only if the Picasa window is maximized and therefore it cannot be moved on screen or restored to "not-maximized" status. I can live with it, but, the GUI menu appears also on top of any other window, when Picasa app is behind other windows. That is a serious threat to the general functionality of this solution. I would expect that specifying a handle to the parent window ($hwndPicasa), the GUI will follow the status of the Picasa window, but it is not the case. Now, the questions: 1- is it possible to make the GUI menu follow the front/back status of Picasa window, so to go back of other windows (when Picasa is behind other windows), but continuing to stay in front of the Picasa window? 2- is it possible to "hook" the GUI menu to the Picasa window in the way it follows its position and width? THE WHOLE STORY: Picasa is a freeware, discarded by Google, but functional and installable. Its user interface is not editable, so it is impossible to remove or add options to the menu. Unfortunately, in the role I use it (as a front end of a big distributable archive of pics and videos dedicated to the animals' advocacy), many default functionalities exposed in menu are potential breakdowns of the archive's integrity, therefore, the only solution I've found it to cover the whole main menu with the more adequate replacement menu. Thanks in advance for any suggestion, Kind regards, Bruno Link to comment Share on other sites More sharing options...
Dan_555 Posted October 16, 2022 Share Posted October 16, 2022 I would try it with the Ressouce Hacker It can work in some cases, while in others it does not. Make a backup copy of the exe or dll which you are editing. Some of my script sourcecode Link to comment Share on other sites More sharing options...
Nine Posted October 16, 2022 Share Posted October 16, 2022 Have you tried to manage the menu with _GUICtrlMenu_* functions ? “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
BrunoStivicevic Posted October 16, 2022 Author Share Posted October 16, 2022 2 hours ago, Dan_555 said: I would try it with the Ressouce Hacker It can work in some cases, while in others it does not. Make a backup copy of the exe or dll which you are editing. Thanks, but in this case it doesn't function. To be more precise, it doesn't show any menu option. Apparently, the menu is constructed outside of the resources. Link to comment Share on other sites More sharing options...
BrunoStivicevic Posted October 16, 2022 Author Share Posted October 16, 2022 (edited) 2 hours ago, Nine said: Have you tried to manage the menu with _GUICtrlMenu_* functions ? Thanks for your reply. I manage the menu with the mentioned functions. The problem is in the GUI window of the menu itself... BTW, perhaps I misunderstood your question... if you're proposing that I manage the native menu of Picasa with the GUI functions, it doesn't work as the Picasa menu is not following the Windows standards... Edited October 16, 2022 by BrunoStivicevic Link to comment Share on other sites More sharing options...
Nine Posted October 16, 2022 Share Posted October 16, 2022 1 hour ago, BrunoStivicevic said: if you're proposing that I manage the native menu of Picasa with the GUI functions Yes that was the purpose of my question, since I don't use nor know Picasa. Have you explore UIAutomation ? Maybe you could change menu items, and monitor menu selection ? Not sure if it is possible though...Good luck. “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
BrunoStivicevic Posted October 16, 2022 Author Share Posted October 16, 2022 1 hour ago, Nine said: Yes that was the purpose of my question, since I don't use nor know Picasa. Have you explore UIAutomation ? Maybe you could change menu items, and monitor menu selection ? Not sure if it is possible though...Good luck. Thanks for your reply. Nothing works with Picasa menu as it is non standard... I hope someone will answer on the GUI window part of the question. Link to comment Share on other sites More sharing options...
pixelsearch Posted October 16, 2022 Share Posted October 16, 2022 (edited) Something to play with : expandcollapse popup#include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <WindowsConstants.au3> Global $g_hGUI, $g_hGUI2 Example() Func Example() $g_hGUI = GUICreate("Picasa", 400, 200, -1, -1, $WS_OVERLAPPEDWINDOW) Local $aPos = WinGetPos($g_hGUI) Local $idButton_1 = GUICtrlCreateButton("Button 1", 100, 170, 85, 25) Local $idButton_Close = GUICtrlCreateButton("Close", 215, 170, 85, 25) $g_hGUI2 = GUICreate("Covering PopUp", 50, 50, $aPos[0], $aPos[1], $WS_POPUP, $WS_EX_TOPMOST) GUISetBkColor(0xFF0000) ; red GUIRegisterMsg($WM_MOVE, "WM_MOVE") GUISetState(@SW_SHOW, $g_hGUI) GUISetState(@SW_SHOW, $g_hGUI2) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE, $idButton_Close ExitLoop Case $idButton_1 MsgBox($MB_TOPMOST, "Title", "Button_1 pressed") EndSwitch WEnd GUIDelete($g_hGUI2) GUIDelete($g_hGUI) EndFunc ;==>Example ;=========================================== Func WM_MOVE($hWnd, $iMsg, $wParam, $lParam) If $hWnd = $g_hGUI Then Local $aPos = WinGetPos($g_hGUI) WinMove($g_hGUI2, "", $apos[0], $apos[1]) EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_MOVE Edit: that's just a start. Maybe the WinApi functions dealing with z-order could be used in the loop to have $g_hGUI2 stick to $g_hGUI1 when there is a new active window, maybe... Edited October 16, 2022 by pixelsearch Link to comment Share on other sites More sharing options...
BrunoStivicevic Posted October 16, 2022 Author Share Posted October 16, 2022 (edited) Thanks, pixelsearch, will try it and let you know... Edited October 16, 2022 by BrunoStivicevic Link to comment Share on other sites More sharing options...
BrunoStivicevic Posted October 17, 2022 Author Share Posted October 17, 2022 Hi Pixelsearch, I tested it a bit on the real Picasa window. As I need to display the GUI menu and a custom title bar (sorry I didn't mention it!), I excluded $WS_POPUP as an option, as it shows only the menu without the title bar (although it's interesting to see how to get a menu alone; thanks for the tip!). Moreover, I excluded the $WS_EX_TOPMOST as it forces the menu on top of all other non topmost windows (which I want to avoid in the first place). At the end, experimenting various combinations, one of the simplest seems to work as required, avoiding covering the top part of other apps, but including the "will-not-move-on-mouse-drag", "do-not-appear" in the Alt+Tab sequence and "stay-on-top-of-Picasa-window": $hGUI_Arch_menu = GUICreate($menuname, $apos[2], 20, $aPos[0]+3, $apos[1]+3, -1, -1, $hwndPicasa) So it works, except one detail: I need to disable the minimize button in the GUI menu title bar so the menu never minimizes (the close button already doesn't do anything, and the maximize button appears disabled). I tried some attempts with various styles and ex-styles but unfortunately some of them break also the basic requirements, achieved by the -1 defaults. Therefore the question: how can I get rid of the minimize button, keeping the rest? I read the related help more than once but it looks like the solution escapes to my brain... ehm... Thanks a million, with kindest regards, Bruno Link to comment Share on other sites More sharing options...
pixelsearch Posted October 17, 2022 Share Posted October 17, 2022 Maybe something like this ? #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Local $hGUI = GUICreate("No mini, No maxi", 400, 200, -1, -1, _ BitXOR($GUI_SS_DEFAULT_GUI, $WS_MINIMIZEBOX)) ; mini 0, Maxi 0, red X 1 GUISetState() Do Until GUIGetMsg() = $GUI_EVENT_CLOSE GuiDelete($hGUI) Link to comment Share on other sites More sharing options...
pixelsearch Posted October 17, 2022 Share Posted October 17, 2022 A couple of lines to add if you want also to grey the X button (you still can close the GUI by keying Escape) #include <GUIMenu.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Local $hGUI = GUICreate("No mini, No maxi, No red X", 400, 200, -1, -1, _ BitXOR($GUI_SS_DEFAULT_GUI, $WS_MINIMIZEBOX)) ; mini 0, Maxi 0, red X 1 Local $hMenu = _GUICtrlMenu_GetSystemMenu($hGUI) _GUICtrlMenu_EnableMenuItem($hMenu, $SC_CLOSE, $MF_GRAYED, False) ; red X 0 GUISetState() Do Until GUIGetMsg() = $GUI_EVENT_CLOSE GuiDelete($hGUI) Link to comment Share on other sites More sharing options...
BrunoStivicevic Posted October 17, 2022 Author Share Posted October 17, 2022 Thanks, thanks, thanks! Both work as a charm! So the BitXOR is removing items... I guess I should know it already, but also my brain is removing items that has troubles with 😞. And I had no clue that one can disable not only the menu items but also the icons... wow! Kindest regards Bruno Link to comment Share on other sites More sharing options...
pixelsearch Posted October 17, 2022 Share Posted October 17, 2022 Bruno, As you don't need any of the 3 buttons (minimize, maximize, close), then you could use a GUI style = 0 For example, if you run the GUICtrlCreateMenu example from the help file, you could do this by changing this line... GUICreate("My GUI menu", 300, 200) ...to that one GUICreate("My GUI menu", 300, 200, -1, -1, 0) ; Style 0 = $WS_OVERLAPPED (also named $WS_TILED) Link to comment Share on other sites More sharing options...
pixelsearch Posted October 18, 2022 Share Posted October 18, 2022 Hi everybody It was an interesting challenge to study OP's questions. Here are my final results in 2 nearly similar scripts. 1) First script just to play with, using a GUI (popup style) to cover constantly the upper left corner of a non-AutoIt application. The application can be maximized, minimized, restored, resized or moved. Important variables are : * $hWnd = handle of the non-AutoIt application. It may be Picasa, a Browser, NotePad, whatever... * $g_hGUI = handle of the GUI that will cover the upper left corner of $hWnd * $hAbove = handle of the window placed just above $hWnd in the z-order list expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPISysWin.au3> Global $g_hGUI ; as in future script (with menu) which will register a message Example() Func Example() Local $hWnd, $hAbove, $sWndTitle = " I'm Picasa Window" If WinExists($sWndTitle) Then $hWnd = WinGetHandle($sWndTitle) WinActivate($hWnd) Else Run("notepad.exe") $hWnd = WinWait("[CLASS:Notepad]", "", 10) WinSetTitle($hWnd, "", $sWndTitle) EndIf Local $aPos_Old = WinGetPos($hWnd), $aPos_New $g_hGUI = GUICreate("Covering PopUp", 50, 50, $aPos_Old[0] + 2, $aPos_Old[1] + 2, $WS_POPUP) GUISetBkColor(0xFF0000) ; red GUISetState() While 1 If GUIGetMsg() = $GUI_EVENT_CLOSE Or Not WinExists($hWnd) Then ExitLoop ; Esc key leaves too $aPos_New = WinGetPos($hWnd) If $aPos_Old[0] <> $aPos_New[0] Or $aPos_Old[1] <> $aPos_New[1] Then WinMove($g_hGUI, "", $aPos_New[0] + 2, $aPos_New[1] + 2) $aPos_Old = $aPos_New EndIf $hAbove = _WinAPI_GetWindow($hWnd, $GW_HWNDPREV) ; which window is just above $hWnd in z-order ? If $g_hGUI <> $hAbove Then ; if it's not $g_hGUI then force $g_hGUI to be just above $hWnd in z-order _WinAPI_SetWindowPos($g_hGUI, $hAbove, 0, 0, 0, 0, BitOr($SWP_NOMOVE, $SWP_NOSIZE)) EndIf WEnd GUIDelete($g_hGUI) If WinExists($hWnd) Then WinClose($hWnd) EndFunc ;==>Example 2) Second script, with $g_hGUI corresponding to a GUI without any style, but including a menu which covers constantly the menu of the non-AutoIt application (OP's need). Of course, adjusting GUI coords (width & height) will depend on the application : expandcollapse popup#include <GUIConstantsEx.au3> #include <MenuConstants.au3> #include <MsgBoxConstants.au3> #include <WindowsConstants.au3> #include <WinAPISysWin.au3> Global $g_hGUI Example() Func Example() Local $hWnd, $hAbove, $sWndTitle = "Here we have an endless title: this is Picasa Window" If WinExists($sWndTitle) Then $hWnd = WinGetHandle($sWndTitle) WinActivate($hWnd) Else Run("notepad.exe") $hWnd = WinWait("[CLASS:Notepad]", "", 10) WinSetTitle($hWnd, "", $sWndTitle) EndIf Local $aPos_Old = WinGetPos($hWnd), $aPos_New ;======== $g_hGUI = GUICreate("Covering Menu", 250, 50, $aPos_Old[0] + 2, $aPos_Old[1] + 2, 0) ; 0 = $WS_OVERLAPPED Local $idFilemenu = GUICtrlCreateMenu("&File") Local $idFileitem = GUICtrlCreateMenuItem("Open", $idFilemenu) GUICtrlSetState(-1, $GUI_DEFBUTTON) Local $idRecentfilesmenu = GUICtrlCreateMenu("Recent Files", $idFilemenu) GUICtrlCreateMenuItem("", $idFilemenu) GUICtrlCreateMenuItem("Save", $idFilemenu) GUICtrlSetState(-1, $GUI_DISABLE) Local $idExititem = GUICtrlCreateMenuItem("Exit", $idFilemenu) Local $idHelpmenu = GUICtrlCreateMenu("?") Local $idInfoitem = GUICtrlCreateMenuItem("Info", $idHelpmenu) ;======== GUIRegisterMsg($WM_SYSCOMMAND, "WM_SYSCOMMAND") GUISetState() Local $sFile While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE, $idExititem ; Esc key leaves too (no X button in this covering GUI) ExitLoop Case $idFileitem WinSetState($hWnd, "", @SW_DISABLE) $sFile = FileOpenDialog("Choose file...", @TempDir, "All (*.*)", 0, "", $g_hGUI) If @error <> 1 Then GUICtrlCreateMenuItem($sFile, $idRecentfilesmenu) WinSetState($hWnd, "", @SW_ENABLE) Case $idInfoitem WinSetState($hWnd, "", @SW_DISABLE) MsgBox($MB_TOPMOST, "Info", "Only a test...", 0, $g_hGUI) WinSetState($hWnd, "", @SW_ENABLE) EndSwitch If Not WinExists($hWnd) Then ExitLoop ; user closed Picasa window $aPos_New = WinGetPos($hWnd) If $aPos_Old[0] <> $aPos_New[0] Or $aPos_Old[1] <> $aPos_New[1] Then WinMove($g_hGUI, "", $aPos_New[0] + 2, $aPos_New[1] + 2) $aPos_Old = $aPos_New EndIf $hAbove = _WinAPI_GetWindow($hWnd, $GW_HWNDPREV) ; which window is just above $hWnd in z-order ? If $g_hGUI <> $hAbove Then ; if it's not $g_hGUI then force $g_hGUI to be just above $hWnd in z-order _WinAPI_SetWindowPos($g_hGUI, $hAbove, 0, 0, 0, 0, BitOr($SWP_NOMOVE, $SWP_NOSIZE)) EndIf WEnd GUIDelete($g_hGUI) If WinExists($hWnd) Then WinClose($hWnd) EndFunc ;==>Example ;================================================ Func WM_SYSCOMMAND($hWnd, $iMsg, $wParam, $lParam) ; msdn: in WM_SYSCOMMAND messages, the four low-order bits of the wParam parameter are used internally by the system. ; To obtain the correct result when testing the value of wParam, an application must combine the value 0xFFF0 with ; the wParam value by using the bitwise AND operator. If $hWnd = $g_hGUI And BitAND($wParam, 0xFFF0) = $SC_MOVE Then Return False Return $GUI_RUNDEFMSG EndFunc ;==>WM_SYSCOMMAND If you guys find a bug or think about some improvements, please share your thoughts here. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now