Professor_Bernd Posted December 28, 2020 Author Share Posted December 28, 2020 32 minutes ago, GokAy said: I only used very simple ones and only in VBA (Excel). Unfortunately in VBScript you don't have access to the Windows API! To stay with VB: VB (.Net or Classic) is much more powerful than VBA, like Godzilla to a human. VBA is much more powerful than VBScript, like a human to an ant. 35 minutes ago, GokAy said: So, my understanding is you need to: I think you are right about that. You can find the code in my post in the last spoiler and then at the very bottom: "Func _WinAPI_GetCaretPos_Patch() ..." Unfortunately the function doesn't work, so I'm looking for the correct DLLCall. You can find the error description above the spoiler. Link to comment Share on other sites More sharing options...
Professor_Bernd Posted December 28, 2020 Author Share Posted December 28, 2020 (edited) Here is a demo showing the return of _WinAPI_GetCaretPos_Patch() by @jpm. The return is always X: 0, Y: 0. How to write the function so that it returns the correct caret position? expandcollapse popup; ; _WinAPI_GetCaretPos() / _WinAPI_GetCaretPos_Patch() ; ; Without the patch the return is always 0. ; With the patch the return is an array and each item is always 0. ; ; Demo 1, 2020-12-28. Professor Bernd. ; Start the script and put the caret in different places in the editor. ; The return is always X: 0, Y: 0. #include <GUIConstantsEx.au3> #include <WinAPIRes.au3> Example() Func Example() Local $aCaretPos Local $hGui = GUICreate("Example", 250, 100) GUISetState(@SW_SHOW, $hGui) Local $hTimer = TimerInit() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch If TimerDiff($hTimer) > 400 Then ; Writing every X ms to Console is enough. $aCaretPos = _WinAPI_GetCaretPos_Patch() If IsArray($aCaretPos) Then ConsoleWrite("X: " & $aCaretPos[0] & " Y: " & $aCaretPos[1] & @CRLF) $hTimer = TimerInit() EndIf WEnd GUIDelete($hGui) EndFunc ;==>Example Func _WinAPI_GetCaretPos_Patch() Local $tPOINT = DllStructCreate($tagPOINT) Local $aRet = DllCall('user32.dll', 'bool', 'GetCaretPos', 'struct*', $tPOINT) If @error Or Not $aRet[0] Then Return SetError(@error + 10, @extended, 0) Local $aResult[2] For $i = 0 To 1 $aResult[$i] = DllStructGetData($tPOINT, $i + 1) Next Return $aResult EndFunc ;==_WinAPI_GetCaretPos Edited December 28, 2020 by Professor_Bernd Link added. Link to comment Share on other sites More sharing options...
GokAy Posted December 28, 2020 Share Posted December 28, 2020 (edited) 51 minutes ago, Professor_Bernd said: I think you are right about that. You can find the code in my post in the last spoiler and then at the very bottom: "Func _WinAPI_GetCaretPos_Patch() ..." Missed this one, sorry. Exactly what I had in mind. (Is $tagPOINT an AutoIT struct type?) All zeros for me with the Patched function btw. Edited December 28, 2020 by GokAy Link to comment Share on other sites More sharing options...
GokAy Posted December 28, 2020 Share Posted December 28, 2020 I will link 2 pages, and you will tell me what to do with it 😛 I don't know either, but for anyone experienced with these stuff maybe they can interpret or propose something useful for your case. https://www.codeproject.com/Articles/34520/Getting-Caret-Position-Inside-Any-Application He is using GetGUIThreadInfo: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getguithreadinfo Professor_Bernd 1 Link to comment Share on other sites More sharing options...
mikell Posted December 28, 2020 Share Posted December 28, 2020 Yes , I already saw the example provided in the help for _WinAPI_GetGUIThreadInfo which is a nice alternative, but it doesn't work either for gui which use non-Windows components (like browsers or so) Professor_Bernd 1 Link to comment Share on other sites More sharing options...
Professor_Bernd Posted December 28, 2020 Author Share Posted December 28, 2020 Looks very interesting! Thanks a lot! I will have a closer look at it. Maybe someone with more experience can already say something about it? Same to the DLLCall in the post above: Can anyone comment on how to make it work? DllCall('user32.dll', 'bool', 'GetCaretPos', 'struct*', $tPOINT) Link to comment Share on other sites More sharing options...
Professor_Bernd Posted December 28, 2020 Author Share Posted December 28, 2020 First test with the example from the AutoIt help for "_WinAPI_GetGUIThreadInfo()" looks good. I just changed the GUI to a non-focusable GUI without border, and added a button to close the GUI. There is no stealing of the focus and no eating of clicks or double clicks. Very good so far! Unfortunately, the coordinates in an MDI application like SciTE or PSPad are not correct and would need to be converted accordingly. I've also tried around a bit, but I only have the other "wicked" functions available. WinGetPos(), ControlGetFocus() and ControlGetPos(). But they cause the mentioned problems again! Maybe you guys feel like finding a solution? 👍 You can use the demo here as a base and use WinMove($hForm, "", $aInfo[7], $aInfo[8]) to position the non-focusable window. Spoiler expandcollapse popup; ; _WinAPI_GetGUIThreadInfo() Tests ; ; Demo 1, 2020-12-28, Professor Bernd. ; ; First test with the example from the AutoIt help for "_WinAPI_GetGUIThreadInfo()" ; looks good. I just changed the GUI to a non-focusable GUI without border, and ; added a button to close the GUI. ; There is no stealing of the focus and no eating of clicks or double clicks. #include <GUIConstantsEx.au3> #include <WinAPISysWin.au3> #include <WindowsConstants.au3> ; Local $hForm = GUICreate('', 240, 268, 10, 10, BitOR($WS_CAPTION, $WS_POPUP), $WS_EX_TOPMOST) Local $hForm = GUICreate('', 260, 268, 10, 10, _ BitOR($WS_POPUP, $WS_BORDER), BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST, $WS_EX_NOACTIVATE)) Global $btnClose = GUICtrlCreateButton("X", 230, 10, 24, 24) GUICtrlCreateLabel('Thread state:', 20, 18, 90, 14) GUICtrlCreateLabel('Active window:', 20, 40, 90, 14) GUICtrlCreateLabel('Keyboard focus:', 20, 62, 90, 14) GUICtrlCreateLabel('Mouse capture:', 20, 84, 90, 14) GUICtrlCreateLabel('Active menu:', 20, 106, 90, 14) GUICtrlCreateLabel('Move or size loop:', 20, 128, 90, 14) GUICtrlCreateLabel('Caret:', 20, 150, 90, 14) GUICtrlCreateLabel('Left:', 20, 172, 90, 14) GUICtrlCreateLabel('Top:', 20, 194, 90, 14) GUICtrlCreateLabel('Width:', 20, 216, 90, 14) GUICtrlCreateLabel('Height:', 20, 238, 90, 14) Local $a_idInput[11] For $i = 0 To 10 $a_idInput[$i] = GUICtrlCreateLabel('', 114, 18 + 22 * $i, 116, 14) Next GUISetState(@SW_SHOWNOACTIVATE) Local $hWnd, $aInfo, $iPID Do $hWnd = WinGetHandle('[ACTIVE]') $aInfo = _WinAPI_GetGUIThreadInfo(_WinAPI_GetWindowThreadProcessId($hWnd, $iPID)) If Not @error Then WinSetTitle($hForm, '', WinGetTitle($hWnd)) $aInfo[0] = '0x' & Hex($aInfo[0], 8) Else WinSetTitle($hForm, '', '') Dim $aInfo[11] For $i = 0 To 10 $aInfo[$i] = '' Next $hWnd = 0 EndIf For $i = 0 To 10 If StringCompare(GUICtrlRead($a_idInput[$i]), $aInfo[$i]) Then GUICtrlSetData($a_idInput[$i], $aInfo[$i]) EndIf Next Until GUIGetMsg() = $btnClose Link to comment Share on other sites More sharing options...
GokAy Posted December 28, 2020 Share Posted December 28, 2020 Nice to hear progress. 14 minutes ago, Professor_Bernd said: Unfortunately, the coordinates in an MDI application like SciTE or PSPad are not correct and would need to be converted accordingly. Would turning them to screen coordinates work? https://www.autoitscript.com/autoit3/docs/libfunctions/_WinAPI_ClientToScreen.htm Link to comment Share on other sites More sharing options...
Professor_Bernd Posted December 28, 2020 Author Share Posted December 28, 2020 Func MoveMyForm($_hWnd, $_ActiveWin, $_ActiveCtrl, $_iX, $_iY) Local $tPoint = DllStructCreate("int X;int Y") DllStructSetData($tPoint, "X", $_iX) DllStructSetData($tPoint, "Y", $_iY) _WinAPI_ClientToScreen($_hWnd, $tPoint) WinMove($hForm, "", DllStructGetData($tPoint, "X"), DllStructGetData($tPoint, "Y")) EndFunc This was also the first thing I tried. Unfortunately, it doesn't work (for me). But maybe I did something wrong? Link to comment Share on other sites More sharing options...
GokAy Posted December 28, 2020 Share Posted December 28, 2020 Where do we call the MoveMyForm func? Also, I wonder if $hForm being declared as local causing an issue.. Link to comment Share on other sites More sharing options...
Professor_Bernd Posted December 28, 2020 Author Share Posted December 28, 2020 (edited) Since I'm in the middle of testing, everything is a bit messy. But it should work if you call it at the end of the do loop. ... ; WinMove($hForm, "", $aInfo[7], $aInfo[8]) MoveMyForm($hWnd, $aInfo[1], $aInfo[2], $aInfo[7], $aInfo[8]) Until GUIGetMsg() = $btnClose @GokAy 5 minutes ago, GokAy said: Also, I wonder if $hForm being declared as local causing an issue.. In AutoIt, it's a cheat: "Local" in the global scope is still "Global". Edited December 28, 2020 by Professor_Bernd Link to comment Share on other sites More sharing options...
GokAy Posted December 28, 2020 Share Posted December 28, 2020 (edited) well working for me ??? or maybe I am missing something.. Changes: 1. #include <WinAPIConv.au3> 2. Global $hForm = .... expandcollapse popup; ; _WinAPI_GetGUIThreadInfo() Tests ; ; Demo 1, 2020-12-28, Professor Bernd. ; ; First test with the example from the AutoIt help for "_WinAPI_GetGUIThreadInfo()" ; looks good. I just changed the GUI to a non-focusable GUI without border, and ; added a button to close the GUI. ; There is no stealing of the focus and no eating of clicks or double clicks. #include <GUIConstantsEx.au3> #include <WinAPISysWin.au3> #include <WindowsConstants.au3> #include <WinAPIConv.au3> ; Local $hForm = GUICreate('', 240, 268, 10, 10, BitOR($WS_CAPTION, $WS_POPUP), $WS_EX_TOPMOST) Global $hForm = GUICreate('', 260, 268, 10, 10, _ BitOR($WS_POPUP, $WS_BORDER), BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST, $WS_EX_NOACTIVATE)) Global $btnClose = GUICtrlCreateButton("X", 230, 10, 24, 24) GUICtrlCreateLabel('Thread state:', 20, 18, 90, 14) GUICtrlCreateLabel('Active window:', 20, 40, 90, 14) GUICtrlCreateLabel('Keyboard focus:', 20, 62, 90, 14) GUICtrlCreateLabel('Mouse capture:', 20, 84, 90, 14) GUICtrlCreateLabel('Active menu:', 20, 106, 90, 14) GUICtrlCreateLabel('Move or size loop:', 20, 128, 90, 14) GUICtrlCreateLabel('Caret:', 20, 150, 90, 14) GUICtrlCreateLabel('Left:', 20, 172, 90, 14) GUICtrlCreateLabel('Top:', 20, 194, 90, 14) GUICtrlCreateLabel('Width:', 20, 216, 90, 14) GUICtrlCreateLabel('Height:', 20, 238, 90, 14) Local $a_idInput[11] For $i = 0 To 10 $a_idInput[$i] = GUICtrlCreateLabel('', 114, 18 + 22 * $i, 116, 14) Next GUISetState(@SW_SHOWNOACTIVATE) Local $hWnd, $aInfo, $iPID Do $hWnd = WinGetHandle('[ACTIVE]') $aInfo = _WinAPI_GetGUIThreadInfo(_WinAPI_GetWindowThreadProcessId($hWnd, $iPID)) If Not @error Then WinSetTitle($hForm, '', WinGetTitle($hWnd)) $aInfo[0] = '0x' & Hex($aInfo[0], 8) Else WinSetTitle($hForm, '', '') Dim $aInfo[11] For $i = 0 To 10 $aInfo[$i] = '' Next $hWnd = 0 EndIf For $i = 0 To 10 If StringCompare(GUICtrlRead($a_idInput[$i]), $aInfo[$i]) Then GUICtrlSetData($a_idInput[$i], $aInfo[$i]) EndIf Next MoveMyForm($hWnd, $aInfo[1], $aInfo[2], $aInfo[7], $aInfo[8]) Until GUIGetMsg() = $btnClose Func MoveMyForm($_hWnd, $_ActiveWin, $_ActiveCtrl, $_iX, $_iY) Local $tPoint = DllStructCreate("int X;int Y") DllStructSetData($tPoint, "X", $_iX) DllStructSetData($tPoint, "Y", $_iY) _WinAPI_ClientToScreen($_hWnd, $tPoint) WinMove($hForm, "", DllStructGetData($tPoint, "X"), DllStructGetData($tPoint, "Y")) EndFunc Edit: Hmm, still wont get the output window of SciTe correct. Edited December 28, 2020 by GokAy Link to comment Share on other sites More sharing options...
GokAy Posted December 28, 2020 Share Posted December 28, 2020 (edited) New post instead of edit: The position of the GUI change a bit for different windows. It may be due to what the remarks of the page I linked earlier is stating. I don't know how to implement it though, if it is so. Another Edit: The differences are vertical though, not horizontal. The remark is about horizontal. Kinda confused.. REMARKS This function succeeds even if the active window is not owned by the calling process. If the specified thread does not exist or have an input queue, the function will fail. This function is useful for retrieving out-of-context information about a thread. The information retrieved is the same as if an application retrieved the information about itself. For an edit control, the returned rcCaret rectangle contains the caret plus information on text direction and padding. Thus, it may not give the correct position of the cursor. The Sans Serif font uses four characters for the cursor: REMARKS Cursor character Unicode code point CURSOR_LTR 0xf00c CURSOR_RTL 0xf00d CURSOR_THAI 0xf00e CURSOR_USA 0xfff (this is a marker value with no associated glyph) To get the actual insertion point in the rcCaret rectangle, perform the following steps. Call GetKeyboardLayout to retrieve the current input language. Determine the character used for the cursor, based on the current input language. Call CreateFont using Sans Serif for the font, the height given by rcCaret, and a width of zero. For fnWeight, call SystemParametersInfo(SPI_GETCARETWIDTH, 0, pvParam, 0). If pvParam is greater than 1, set fnWeight to 700, otherwise set fnWeight to 400. Select the font into a device context (DC) and use GetCharABCWidths to get the B width of the appropriate cursor character. Add the B width to rcCaret.left to obtain the actual insertion point. The function may not return valid window handles in the GUITHREADINFO structure when called to retrieve information for the foreground thread, such as when a window is losing activation. Edited December 28, 2020 by GokAy Link to comment Share on other sites More sharing options...
Professor_Bernd Posted December 28, 2020 Author Share Posted December 28, 2020 34 minutes ago, GokAy said: Another Edit: The differences are vertical though, not horizontal. The mismatches are both vertical and horizontal. It's just not noticeable in SciTE because the "Edit" is almost at horizontal position 0, relative to the SciTE main window. Here is a screenshot of how it looks in PSPad when you have a larger area on the left with a different control. The mouse cursor shows where the caret is. I think you also have Notepad++? If so, you can test it there by showing the Project Panel taking up space on the left edge. Spoiler I think I found a solution. I'll clean up the code a bit more and post it then. Link to comment Share on other sites More sharing options...
GokAy Posted December 28, 2020 Share Posted December 28, 2020 Ok, this one works with SciTE output as well (changed bit inside move func, also the call to move func, but as it is sending $aInfo[2] as activewin handle). If this helps maybe it can be improved. Not quite right but better perhaps. Tested with: 1. SciTE main window 2. SciTE output 3. Notepad++ 4. Windows Run menu (unintentional test while starting notepad ) 5. Notepad Still some issues with Excel, was better with earlier version. expandcollapse popup; ; _WinAPI_GetGUIThreadInfo() Tests ; ; Demo 1, 2020-12-28, Professor Bernd. ; ; First test with the example from the AutoIt help for "_WinAPI_GetGUIThreadInfo()" ; looks good. I just changed the GUI to a non-focusable GUI without border, and ; added a button to close the GUI. ; There is no stealing of the focus and no eating of clicks or double clicks. #include <GUIConstantsEx.au3> #include <WinAPISysWin.au3> #include <WindowsConstants.au3> #include <WinAPIConv.au3> ; Local $hForm = GUICreate('', 240, 268, 10, 10, BitOR($WS_CAPTION, $WS_POPUP), $WS_EX_TOPMOST) Global $hForm = GUICreate('', 260, 268, 10, 10, _ BitOR($WS_POPUP, $WS_BORDER), BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST, $WS_EX_NOACTIVATE)) Global $btnClose = GUICtrlCreateButton("X", 230, 10, 24, 24) GUICtrlCreateLabel('Thread state:', 20, 18, 90, 14) GUICtrlCreateLabel('Active window:', 20, 40, 90, 14) GUICtrlCreateLabel('Keyboard focus:', 20, 62, 90, 14) GUICtrlCreateLabel('Mouse capture:', 20, 84, 90, 14) GUICtrlCreateLabel('Active menu:', 20, 106, 90, 14) GUICtrlCreateLabel('Move or size loop:', 20, 128, 90, 14) GUICtrlCreateLabel('Caret:', 20, 150, 90, 14) GUICtrlCreateLabel('Left:', 20, 172, 90, 14) GUICtrlCreateLabel('Top:', 20, 194, 90, 14) GUICtrlCreateLabel('Width:', 20, 216, 90, 14) GUICtrlCreateLabel('Height:', 20, 238, 90, 14) Local $a_idInput[11] For $i = 0 To 10 $a_idInput[$i] = GUICtrlCreateLabel('', 114, 18 + 22 * $i, 116, 14) Next GUISetState(@SW_SHOWNOACTIVATE) Local $hWnd, $aInfo, $iPID Do $hWnd = WinGetHandle('[ACTIVE]') $aInfo = _WinAPI_GetGUIThreadInfo(_WinAPI_GetWindowThreadProcessId($hWnd, $iPID)) If Not @error Then WinSetTitle($hForm, '', WinGetTitle($hWnd)) $aInfo[0] = '0x' & Hex($aInfo[0], 8) Else WinSetTitle($hForm, '', '') Dim $aInfo[11] For $i = 0 To 10 $aInfo[$i] = '' Next $hWnd = 0 EndIf For $i = 0 To 10 If StringCompare(GUICtrlRead($a_idInput[$i]), $aInfo[$i]) Then GUICtrlSetData($a_idInput[$i], $aInfo[$i]) EndIf Next MoveMyForm($hWnd, $aInfo[2], $aInfo[2], $aInfo[7], $aInfo[8]) Until GUIGetMsg() = $btnClose Func MoveMyForm($_hWnd, $_ActiveWin, $_ActiveCtrl, $_iX, $_iY) Local $aPos = WinGetPos($_ActiveWin) Local $iX = ($aPos="") ? (0):($aPos[0]) Local $iY = ($aPos="") ? (0):($aPos[1]) Local $tPoint = DllStructCreate("int X;int Y") DllStructSetData($tPoint, "X", $_iX + $iX) DllStructSetData($tPoint, "Y", $_iY + $iY) _WinAPI_ClientToScreen(_WinAPI_GetTopWindow ( $_ActiveWin ), $tPoint) WinMove($hForm, "", DllStructGetData($tPoint, "X"), DllStructGetData($tPoint, "Y")) EndFunc Professor_Bernd 1 Link to comment Share on other sites More sharing options...
GokAy Posted December 28, 2020 Share Posted December 28, 2020 (edited) Check the code above, works perfectly with all (topleft of GUI is at caret) all as in notepad, notepad++ with/without project panel, scite, scite output Edit: That little bugger gets in the way like this though 😛 Maybe add a little offset so you can see what you are doing better? Edited December 28, 2020 by GokAy Link to comment Share on other sites More sharing options...
Professor_Bernd Posted December 28, 2020 Author Share Posted December 28, 2020 Hell yeah, you're amazing! You found almost the same solution as I did: WinGetPos(). 19 minutes ago, GokAy said: but as it is sending $aInfo[2] as activewin handle There you set yourself a little trap. $aInfo[2] is the active control that gets the keyboard input. This is passed to the function "MoveMyForm()" as second parameter. You also passed it as the first parameter and treated it as if it were the active window. Thus you have a false/positive bug in "_WinAPI_GetTopWindow ( $_ActiveWin )" which is actually "_WinAPI_GetTopWindow ( $_ActiveCtrl )". However, edits do not have child windows, so the function always returns 0. So you could also use: ; _WinAPI_ClientToScreen(_WinAPI_GetTopWindow ( $_ActiveWin ), $tPoint) _WinAPI_ClientToScreen(0, $tPoint) WinMove($hForm, "", DllStructGetData($tPoint, "X"), DllStructGetData($tPoint, "Y")) EndFunc But that doesn't change the fact that your code works! 👍 30 minutes ago, GokAy said: That little bugger gets in the way like this though 😛 Maybe add a little offset so you can see what you are doing better? That's correct and I thought exactly the same in my code and included "$iYAdjust = $_iCaretHeight", which is also supplied by "_WinAPI_GetGUIThreadInfo()". GokAy 1 Link to comment Share on other sites More sharing options...
GokAy Posted December 28, 2020 Share Posted December 28, 2020 (edited) Heh, was just testing it and found about "_WinAPI_GetTopWindow ( $_ActiveWin )" always returning 0. Good thing you posted about it. No need for me to continue. So are you done with this bit finally? Please post the final code too when you are done. Edit: And with this correction, it works within Excel as well. If you select a cell, it gets in the way but topleft of cell and GUI align. If you edit the cell, it is again at correct position. Addressbar works, formula bar works. VBA Editor kind of works, it is aligned with caret horizontally but vertical is off by something like 1-1.5 line height. Maybe a titlebar? Edited December 28, 2020 by GokAy Link to comment Share on other sites More sharing options...
Professor_Bernd Posted December 28, 2020 Author Share Posted December 28, 2020 Can you please test it, in all programs available to you? expandcollapse popup; ; _WinAPI_GetGUIThreadInfo() + WinGetPos() Tests ; ; There is no stealing of the focus and no eating of clicks or double clicks. ; ; Demo 3, 2020-12-28, Professor Bernd. ; ; Basis for this demo is the example from the AutoIt help for "_WinAPI_GetGUIThreadInfo()". ; Added is my function "MoveMyForm", which is used to get the caret position relative to the screen. ; ; The demo is limited to the essentials and has no additional features or error handling. #include <GUIConstantsEx.au3> #include <WinAPIConv.au3> #include <WinAPISysWin.au3> #include <WindowsConstants.au3> ; Local $hForm = GUICreate('', 240, 268, 10, 10, BitOR($WS_CAPTION, $WS_POPUP), $WS_EX_TOPMOST) Global $hForm = GUICreate('', 260, 330, 10, 10, _ BitOR($WS_POPUP, $WS_BORDER), BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST, $WS_EX_NOACTIVATE)) Global $btnClose = GUICtrlCreateButton("X", 230, 10, 24, 24) GUICtrlCreateLabel('Thread state:', 20, 18, 90, 14) GUICtrlCreateLabel('Active window:', 20, 40, 90, 14) GUICtrlCreateLabel('Keyboard focus:', 20, 62, 90, 14) GUICtrlCreateLabel('Mouse capture:', 20, 84, 90, 14) GUICtrlCreateLabel('Active menu:', 20, 106, 90, 14) GUICtrlCreateLabel('Move or size loop:', 20, 128, 90, 14) GUICtrlCreateLabel('Caret:', 20, 150, 90, 14) GUICtrlCreateLabel('Left:', 20, 172, 90, 14) GUICtrlCreateLabel('Top:', 20, 194, 90, 14) GUICtrlCreateLabel('Width:', 20, 216, 90, 14) GUICtrlCreateLabel('Height:', 20, 238, 90, 14) GUICtrlCreateLabel('ActiveWin:', 20, 260, 90, 14) GUICtrlCreateLabel('ActiveCtrl:', 20, 282, 90, 14) GUICtrlCreateLabel('ActvCtrlClName:', 20, 304, 90, 14) Local $a_idInput[14] For $i = 0 To 13 $a_idInput[$i] = GUICtrlCreateLabel('', 114, 18 + 22 * $i, 116, 14) Next GUISetState(@SW_SHOWNOACTIVATE) Local $hWnd, $aInfo, $iPID, $aActiveWinPos Do $hWnd = WinGetHandle('[ACTIVE]') $aInfo = _WinAPI_GetGUIThreadInfo(_WinAPI_GetWindowThreadProcessId($hWnd, $iPID)) If Not @error Then WinSetTitle($hForm, '', WinGetTitle($hWnd)) $aInfo[0] = '0x' & Hex($aInfo[0], 8) Else WinSetTitle($hForm, '', '') Dim $aInfo[11] For $i = 0 To 10 $aInfo[$i] = '' Next $hWnd = 0 EndIf For $i = 0 To 10 If StringCompare(GUICtrlRead($a_idInput[$i]), $aInfo[$i]) Then GUICtrlSetData($a_idInput[$i], $aInfo[$i]) EndIf Next ; Debug-Info $aActiveWinPos = WinGetPos($aInfo[1]) If IsArray($aActiveWinPos) Then GUICtrlSetData($a_idInput[11], "X: " & $aActiveWinPos[0] & " Y: " & $aActiveWinPos[1]) EndIf MoveMyForm($aInfo[2], $aInfo[7], $aInfo[8], $aInfo[10]) Until GUIGetMsg() = $btnClose Func MoveMyForm($_ActiveCtrl, $_iX, $_iY, $_iCaretHeight) Local $iXAdjust = 0 Local $iYAdjust = $_iCaretHeight Local $aActiveCtrlPos = WinGetPos($_ActiveCtrl) If IsArray($aActiveCtrlPos) Then ; Debug-Info GUICtrlSetData($a_idInput[12], "X: " & $aActiveCtrlPos[0] & " Y: " & $aActiveCtrlPos[1]) GUICtrlSetData($a_idInput[13], _WinAPI_GetClassName($_ActiveCtrl)) Local $aReturn[2] = [0, 0] ; Create an array to store the x, y position. $aReturn[0] = $aActiveCtrlPos[0] + $_iX + $iXAdjust $aReturn[1] = $aActiveCtrlPos[1] + $_iY + $iYAdjust WinMove($hForm, "", $aReturn[0], $aReturn[1]) ; Return $aReturn ; Else ; Return SetError(1, 0, $aReturn) ; Return the array and set @error to 1. EndIf EndFunc Link to comment Share on other sites More sharing options...
GokAy Posted December 28, 2020 Share Posted December 28, 2020 Works with: 1. Notepad 2. Notepad++ with/without Project Panel 3. Windows Run 4. Excel cell select, cell edit, addressbar, formulabar. Kind of works in VBA Editor as I mentioned earlier, there is some 1-1.5 line height vertical offset, GUI is above) 5. Windows Explorer (editing a file/folder name) 6. Free Commander XE - 3rd party Explorer (editing a file/folder name) 7. Desktop (editing a file/folder name) Doesn't work: 1. Chrome (sticks to topleft corner) 2. Command Prompt (doesn't even budge from where it was) 3. PyCharm - Phyton Editor (sticks to topleft corner) 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