commit d4115dc05af1433557deb82afc97ee7167d7810e Author: unknown Date: Tue May 19 12:39:34 2015 +0200 initial commit diff --git a/awesomeIt.au3 b/awesomeIt.au3 new file mode 100644 index 0000000..68ed1f0 --- /dev/null +++ b/awesomeIt.au3 @@ -0,0 +1,234 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "includes\BlockInputEx.au3" + +#include "includes\_Monitor.au3" +#include "includes\_Subarray.au3" + +Opt("WinTitleMatchMode", 4) +Global Const $SC_DRAGMOVE = 0xF012 + +_hideTaskbar() + +$visibleWindows = _getVisibleWindowList() +$tilableWindows = _createTilableWindowList($visibleWindows) + +For $i = 0 To UBound($tilableWindows) - 1 + ConsoleWrite(WinGetTitle($tilableWindows[$i]) & " ==> " & _getContainingMonitor($tilableWindows[$i]) & @CRLF) +Next + +Local $hControl, $hWin, $hOldWin, $aMousePos +$hOldWin = "" + + +While Not _IsPressed("1B") + $aMousePos = MouseGetPos() + + If _IsPressed("5B") And _IsPressed("02") Then + $hControl = _WindowFromPoint($aMousePos[0],$aMousePos[1]) + ; Since _WindowFromPoint() can return 'sub' windows, or control handles, we should seek the owner window + $hWin = _WinAPI_GetAncestor($hControl, 2) + $pos = WinGetPos($hWin) + MouseMove($pos[0] + $pos[2], $pos[1] + $pos[3], 0) + While _IsPressed("5B") And _IsPressed("02") + _BlockInputEx ( 1, "", "0x5B|0x5C|{UP}" ) + $mousePos = MouseGetPos() + WinMove($hWin, "", $pos[0], $pos[1], $mousePos[0] - $pos[0], $mousePos[1] - $pos[1]) + WEnd + While _IsPressed("5B") Or _IsPressed("02") + ToolTip("Ater idle loop") + _BlockInputEx ( 0, "", "0x5B|0x5C|{UP}" ) + WEnd + _BlockInputEx ( 0, "", "0x5B|0x5C|{UP}" ) + EndIf + + + Sleep(1) +WEnd + + +_showTaskbar() + +Func _windowFromPoint($iX,$iY) + Local $stInt64,$aRet,$stPoint=DllStructCreate("long;long") + DllStructSetData($stPoint,1,$iX) + DllStructSetData($stPoint,2,$iY) + $stInt64=DllStructCreate("int64",DllStructGetPtr($stPoint)) + $aRet=DllCall("user32.dll","hwnd","WindowFromPoint","int64",DllStructGetData($stInt64,1)) + If @error Then Return SetError(2,@error,0) + If $aRet[0]=0 Then Return SetError(3,0,0) + Return $aRet[0] +EndFunc + +; Simple function to hide the windows taskbar +Func _hideTaskbar() + WinSetState("[CLASS:Button; TITLE:Start]", "", @SW_HIDE) + WinSetState("[CLASS:Shell_TrayWnd]", "", @SW_HIDE) +EndFunc + +; This just reverts _hideTaskbar() +Func _showTaskbar() + WinSetState("[CLASS:Button; TITLE:Start]", "", @SW_SHOW) + WinSetState("[CLASS:Shell_TrayWnd]", "", @SW_SHOW) +EndFunc + +Func _toggleBorder($hwnd) + $iOldStyle = _WinAPI_GetWindowLong($hwnd, $GWL_STYLE) + $iNewStyle = BitXOR($iOldStyle, $WS_BORDER) + _WinAPI_SetWindowLong($hwnd, $GWL_STYLE, $iNewStyle) + _WinAPI_SetWindowPos($hwnd, 0, 0, 0, 0, 0, BitOR($SWP_FRAMECHANGED, $SWP_NOMOVE, $SWP_NOSIZE)) +EndFunc + +; Returns an array of visible windows. +; All windows, which have the "Window is visible" bit set, count as visible +Func _getVisibleWindowList() + Local $visibleList[0] + $plist = ProcessList() + For $i = 1 To $plist[0][0] + $hwndList = _ProcessGetWindow($plist[$i][1]) + If IsArray($hwndList) Then + For $a = 1 To $hwndList[0] + $hwnd = $hwndList[$a] + $applState = WinGetState($hwnd) + $title = WinGetTitle($hwnd) + If (BitOR($applState, 2) == $applState) And $title <> "" Then + _ArrayAdd($visibleList, $hwnd) + EndIf + Next + EndIf + Next + + Return $visibleList +EndFunc + +; Returns an array with window styles +; $array[0] = Window styles +; $array[1] = Extended window styles +Func _getStyleOfWindow($hwnd) + Local $style[0] + $aStyle = _WinAPI_GetWindowLong($hwnd, $GWL_STYLE) + If @error == 0 Then + _ArrayAdd($style, $aStyle) + Else + _ArrayAdd($style, -1) + EndIf + $aExStyle = _WinAPI_GetWindowLong($hwnd, $GWL_EXSTYLE) + If @error == 0 Then + _ArrayAdd($style, $aExStyle) + Else + _ArrayAdd($style, -1) + EndIf + Return $style +EndFunc + +; Iterates over an array of hwnds and returns an array of tilable window hwnds +Func _createTilableWindowList($windowList) + Local $tilableWindowList[0] + For $i = 0 To UBound($windowList) - 1 + If _isTilable($windowList[$i]) Then + _ArrayAdd($tilableWindowList, $windowList[$i]) + EndIf + Next + Return $tilableWindowList +EndFunc + +; I assume, that a window should be tiles, if it has a thick frame +Func _isTilable($hwnd) + $styles = _getStyleOfWindow($hwnd) + If BitAND($styles[1], $WS_EX_DLGMODALFRAME) <> $WS_EX_DLGMODALFRAME Then + Return True + Else + Return False + EndIf +EndFunc + +; #FUNCTION# ============================================================================================================================ +; Name...........: _ProcessGetWindow +; +; Description ...: Returns an array of HWNDs containing all windows owned by the process $p_PID, or optionally a single "best guess." +; +; Syntax.........: _ProcessGetWindow( $p_PID [, $p_ReturnBestGuess = False ]) +; +; Parameters ....: $p_PID - The PID of the process you want the Window for. +; $p_ReturnBestGuess - If True, function will return only 1 reult on a best-guess basis. +; The "Best Guess" is the VISIBLE window owned by $p_PID with the longest title. +; +; Return values .: Success - Return $_array containing HWND info. +; $_array[0] = Number of results +; $_array[n] = HWND of Window n +; +; Failure - Returns 0 +; +; Error - Returns -1 and sets @error +; 1 - Requires a non-zero number. +; 2 - Process does not exist +; 3 - WinList() Error +; +; Author ........: Andrew Bobulsky, contact: RulerOf . +; Remarks .......: The reverse of WinGetProcess() +; ======================================================================================================================================= + +Func _ProcessGetWindow( $p_PID, $p_ReturnBestGuess = False ) + Local $p_ReturnVal[1] = [0] + Local $p_WinList = WinList() + + If @error Then ;Some Error handling + SetError(3) + Return -1 + EndIf + + If $p_PID = 0 Then ;Some Error handling + SetError(1) + Return -1 + EndIf + + If ProcessExists($p_PID) = 0 Then ;Some Error handling + ConsoleWrite("_ProcessGetWindow: Process " & $p_PID & " doesn't exist!" & @CRLF) + SetError(2) + Return -1 + EndIf + + For $i = 1 To $p_WinList[0][0] Step 1 + Local $w_PID = WinGetProcess($p_WinList[$i][1]) + If $w_PID = $p_PID Then + $p_ReturnVal[0] += 1 + _ArrayAdd($p_ReturnVal, $p_WinList[$i][1]) + EndIf + Next + + If $p_ReturnVal[0] > 1 Then + If $p_ReturnBestGuess Then + Do + Local $i_State = WinGetState($p_ReturnVal[2]) + Local $i_StateLongest = WinGetState($p_ReturnVal[1]) + Select + Case BitAND($i_State, 2) And BitAND($i_StateLongest, 2) ;If they're both visible + If StringLen(WinGetTitle($p_ReturnVal[2])) > StringLen(WinGetTitle($p_ReturnVal[1])) Then ;And the new one has a longer title + _ArrayDelete($p_ReturnVal, 1) ;Delete the "loser" + $p_ReturnVal[0] -= 1 ;Decrement counter + Else + _ArrayDelete($p_ReturnVal, 2) ;Delete the failed challenger + $p_ReturnVal[0] -= 1 + EndIf + Case BitAND($i_State, 2) And Not BitAND($i_StateLongest, 2) ;If the new one's visible and the old one isn't + _ArrayDelete($p_ReturnVal, 1) ;Delete the old one + $p_ReturnVal[0] -= 1 ;Decrement counter + Case Else ;Neither window is visible, let's just keep the first one. + _ArrayDelete($p_ReturnVal, 2) + $p_ReturnVal[0] -= 1 + EndSelect + Until $p_ReturnVal[0] = 1 + EndIf + Return $p_ReturnVal + ElseIf $p_ReturnVal[0] = 1 Then + Return $p_ReturnVal ;Only 1 window. + Else + Return 0 ;Window not found. + EndIf +EndFunc diff --git a/includes/BlockInputEx.au3 b/includes/BlockInputEx.au3 new file mode 100644 index 0000000..ed6e2a7 --- /dev/null +++ b/includes/BlockInputEx.au3 @@ -0,0 +1,442 @@ +#Region Header + +#CS UDF Info +;Extended (advanced) function to block mouse & keyboard inputs. +; +; This UDF supports few features that built-in BlockInput() function does not. +; Here is a quick "features list": +;---------------------------------------------------------------------- +;* Block seperately mouse or keyboard input. +;* Block specific keyboard/mouse keys/clicks. +; [+] Not only hex keys are supported, string keys (such as {ENTER}) is also valid. +;* Block all keyboard/mouse keys *except* specific keys/events. +;* Block keys by CLASS Name (see UDF documentation). +;* Block inputs only for specific window. +;* BlockInput does not re-enables input after pressing Ctrl+Alt+Del. +;---------------------------------------------------------------------- +; +; AutoIt Version: 3.2.12.1+ +; Author: G.Sandler (a.k.a MrCreatoR). Initial idea and hooks example by rasim. +; +; Remarks: This UDF, same as built-in BlockInput function, can not block Ctrl+Alt+Del, however, it will not re-enable the input. +; +; +;================== +; History version: +;================== +; [v1.8 - 12.05.2013, 12:16] +; * Fixed issue when some numeric keyboard keys was not blocked. +; * Fixed issue when ALT+Tab was not blocked. + +; [v1.7 - 04.05.2012, 18:45] +; * Now by default the UDF affects only on user-input, the same as standard BlockInput function. Can be changed with additional parameter $iBlockAllInput, if set to 1, then all input will be blocked, not just the user's. +; * Added optional parameter $iBlockAllInput to allow block only user-input (default 0, block only user-input). +; * Minor fixes. +; +; [v1.6 - 04.04.2011, 22:30] +; * Fixed (again, caused by fix with re-enabled input) an issue with held down "Alt + Ctrl" keys after the user was called "Alt + Ctrl + Del". +; * Fixed an issue with wrong parameter passed to _WinAPI_CallNextHookEx. Thanks to Ascend4nt. +; + Added remarks to the UDF header. +; + Added "Example - Block TaskMan.au3". +; +; [v1.5 - 11.10.2010, 22:20] +; * Fixed an issue with re-enabled input after pressing Ctrl+Alt+Del. +; * Now the $hWindows parameter can be used for mouse blocking. +; For that reason the $i_MouseHookGetAncestorHwnd variable was added to the UDF, +; if user sets it to 0, then the $hWindows is compared to currently hovered window handle, otherwise (1 - default) it's compared to ancestor of the hovered window/control. +; +; [v1.4 - 03.08.2010, 12:00] +; + AutoIt 3.3.6.1 support. +; * Fixed an issue with held down "Alt + Ctrl" keys after the user was called "Alt + Ctrl + Del". It was causing a problems to use HotKeySet later. +; * Fixed examples to be compatible with AutoIt 3.3.6.1. +; * Minor "cosmetic" changes. +; +; [v1.3 - 24.09.2009, 23:00] +; + Added _BlockInputEx Example (Pass Lock) +; * Fixed few examples. +; * Fixed spell mistakes in the UDF. +; +; [v1.2 - 16.01.2009, 21:00] +; + Added key strings support. +; Now users can set simple hotkey strings for Exclude/Include parameters + Group chars, i.e: "[Group]|{UP}|{DOWN}" +; (See UDF documentation) +; + Added mouse events blocking support to the $sExclude/$sInclude parameters. +; + Added example for mouse events blocking. +; +; [v1.1 - 16.01.2009] +; + Added CLASSes support (see UDF documentation), thanks to FireFox for the idea and the keys lists. +; + Added example for CLASS usage. +; * Changed behaviour of $iBlockMode parameter as following: +; +; 1 - Block All +; <= 0 - UnBlock all +; 2 - Block only mouse +; 3 - Block only keyboard. +; +; * Fixed hard-crash that related to incorrect BlockInput releasing process (only callbacks was released, not the window hooks). +; +; [v1.0 - 15.01.2009] +; First release. +#CE + +#include-once +#include +#include +#include + +If @AutoItVersion >= '3.3.2.0' Then + Execute('OnAutoItExitRegister("__BlockInputEx_OnAutoItExit")') +Else + Execute('Assign("i_OptOEF", Opt("OnExitFunc", "__BlockInputEx_OnAutoItExit"), 2)') +EndIf + +#EndRegion Header + +#Region Global Variables + +Global $ah_MouseKeyboard_WinHooks[8] +Global $s_KeyboardKeys_Buffer +Global $i_MouseHookGetAncestorHwnd = 1 + +#EndRegion Global Variables + +#Region Public Functions + +; #FUNCTION# ==================================================================================================================== +; Name...........: _BlockInputEx +; Description ...: Disable/enable the mouse and/or keyboard. Supporting blocking (by include/exclude) of seperate keys. +; Syntax.........: _BlockInputEx( [iBlockMode [, sExclude [, sInclude [, hWindows [, $iBlockAllInput]]]]] ) +; +; Parameters ....: $iBlockMode - [Optional] Set the block mode. +; 1 - Block All +; <= 0 - UnBlock all +; 2 - Block only mouse +; 3 - Block only keyboard. +; +; $sExclude - [Optional] Keys hex/string-list (| delimited) to *exclude* when blocking. +; [*] All keys will be blocked, except the keys in $sExclude list. +; [!] This list supports keys CLASSes, +; key strings as supported in HotKeySet() function, +; and seperate mouse events classes, see "Remarks" for more details. +; +; +; +; $sInclude - [Optional] Keys hex/string-list (| delimited) to *include* when blocking. +; [*] Only these keys will be blocked, the $sExclude ignored in this case. +; [!] This list supports keys CLASSes, +; key strings as supported in HotKeySet() function, +; and seperate mouse events classes, see "Remarks" for more details. +; +; $hWindows - [Optional] Window handles list (| delimited) to limit the blocking process. +; +; $iBlockAllInput - [Optional] If this parameter is 0 (default), +; then only user input will be blocked (the same behaviour as standard BlockInput function), otherwise all input will be blocked (including *Send and Mouse* functions). +; +; Return values .: Success - 1. +; Failure - 0 and set @error to 1. This can happend only when passing wrong parameters. +; +; Author ........: G.Sandler (a.k.a MrCreatoR), Rasim -> Initial idea and hooks example. +; Thanks to FireFox for other block methods, it gave me a starting point for adding the "keys classes" support. +; +; +; Modified.......: +; Remarks .......: * This UDF includes OnAutoItExit function to release the callback/hooks resources. +; +; * $sExclude and $sInclude parameters supporting keys/mouse classes as hex or as string, +; [!] The hex keys list can be found in _IsPressed documentation section. +; Here is a full list of supported classess/events: +; ======= KeyBoard ======= +; [:FUNC:] +; [:ALPHA:] +; [:NUMBER:] +; [:ARROWS:] +; [:SPECIAL:] +; [GROUP_abcd] -> Use raw chars/key strings inside squere brackets. +; {KEY} -> Standard keys support ({F1}, {ENTER} etc.). +; +; ========= Mouse ========= +; {MMOVE} -> Mouse move event +; {MPDOWN} -> Mouse Primary Down event +; {MPUP} -> Mouse Primary Up event +; {MSDOWN} -> Mouse Secondary Down event +; {MSUP} -> Mouse Secondary Up event +; {MWDOWN} -> Mouse WHEEL Button Down event +; {MWUP} -> Mouse WHEEL Button Up event +; {MWSCROLL} -> Mouse WHEEL Scroll event +; {MSPDOWN} -> Mouse Special Button Down event +; {MSPUP} -> Mouse Special Button Up event +; +; +; * See also built-in BlockInput() documentation. +; +; Related .......: BlockInput()? +; Link ..........; http://www.autoitscript.com/forum/index.php?s=&showtopic=87735 +; Example .......; Yes +; =============================================================================================================================== +Func _BlockInputEx($iBlockMode = -1, $sExclude = "", $sInclude = "", $hWindows = "", $iBlockAllInput = 0) + If $iBlockMode < -1 Or $iBlockMode > 3 Then Return SetError(1, 0, 0) ;Only -1 to 3 modes are supported. + + If $iBlockMode <= 0 Then Return __BlockInputEx_UnhookWinHooks_Proc() + + Local $pStub_KeyProc = 0, $pStub_MouseProc = 0, $hHook_Keyboard = 0, $hHook_Mouse = 0 + Local $hHook_Module = _WinAPI_GetModuleHandle(0) + + For $i = 0 To 3 + If $ah_MouseKeyboard_WinHooks[$i] > 0 Then + __BlockInputEx_UnhookWinHooks_Proc() + ExitLoop + EndIf + Next + + If $iBlockMode = 1 Or $iBlockMode = 2 Then + $pStub_MouseProc = DllCallbackRegister("__BlockInputEx_MouseHook_Proc", "int", "int;ptr;ptr") + $hHook_Mouse = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, DllCallbackGetPtr($pStub_MouseProc), $hHook_Module, 0) + EndIf + + If $iBlockMode = 1 Or $iBlockMode = 3 Then + $pStub_KeyProc = DllCallbackRegister("__BlockInputEx_KeyBoardHook_Proc", "int", "int;ptr;ptr") + $hHook_Keyboard = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($pStub_KeyProc), $hHook_Module, 0) + EndIf + + $ah_MouseKeyboard_WinHooks[0] = $pStub_KeyProc + $ah_MouseKeyboard_WinHooks[1] = $pStub_MouseProc + $ah_MouseKeyboard_WinHooks[2] = $hHook_Keyboard + $ah_MouseKeyboard_WinHooks[3] = $hHook_Mouse + $ah_MouseKeyboard_WinHooks[4] = "|" & __BlockInputEx_Parse_vmCodesList_CLASSes(__BlockInputEx_Parse_vkCodesList_CLASSes($sInclude)) & "|" + $ah_MouseKeyboard_WinHooks[5] = "|" & __BlockInputEx_Parse_vmCodesList_CLASSes(__BlockInputEx_Parse_vkCodesList_CLASSes($sExclude)) & "|" + $ah_MouseKeyboard_WinHooks[6] = "|" & $hWindows & "|" + $ah_MouseKeyboard_WinHooks[7] = $iBlockAllInput + + Return 1 +EndFunc + +#EndRegion Public Functions + +#Region Internal Functions + +;KeyBoard hook processing function +Func __BlockInputEx_KeyBoardHook_Proc($nCode, $wParam, $lParam) + If $nCode < 0 Then + Return _WinAPI_CallNextHookEx($ah_MouseKeyboard_WinHooks[2], $nCode, $wParam, $lParam) + EndIf + + Local $KBDLLHOOKSTRUCT = DllStructCreate("dword vkCode;dword scanCode;dword flags;dword time;ptr dwExtraInfo", $lParam) + Local $iFlags = DllStructGetData($KBDLLHOOKSTRUCT, "flags") + Local $iDec_vkCode = DllStructGetData($KBDLLHOOKSTRUCT, "vkCode") + Local $vkCode = "0x" & Hex($iDec_vkCode, 2) + + If Not StringInStr($s_KeyboardKeys_Buffer, $iDec_vkCode & '|') Then + $s_KeyboardKeys_Buffer &= $iDec_vkCode & '|' + EndIf + + Local $sInclude = $ah_MouseKeyboard_WinHooks[4] + Local $sExclude = $ah_MouseKeyboard_WinHooks[5] + Local $hWnds = $ah_MouseKeyboard_WinHooks[6] + Local $iBlockAllInput = $ah_MouseKeyboard_WinHooks[7] + + If $iBlockAllInput = 0 And BitAND($iFlags, 16) Then + Return _WinAPI_CallNextHookEx($ah_MouseKeyboard_WinHooks[2], $nCode, $wParam, $lParam) + EndIf + + If (StringInStr($s_KeyboardKeys_Buffer, '165|') And StringInStr($s_KeyboardKeys_Buffer, '163|') And StringInStr($s_KeyboardKeys_Buffer, '46|')) Or _ + (StringInStr($s_KeyboardKeys_Buffer, '164|') And StringInStr($s_KeyboardKeys_Buffer, '162|') And StringInStr($s_KeyboardKeys_Buffer, '46|')) Then + + Sleep(10) + $s_KeyboardKeys_Buffer = "" + + Return _WinAPI_CallNextHookEx($ah_MouseKeyboard_WinHooks[2], $nCode, $wParam, $lParam) ;Continue processing + EndIf + + If $sInclude <> "||" Then ;Include proc + If StringInStr($sInclude, "|" & $vkCode & "|") And ($hWnds = "||" Or StringInStr($hWnds, "|" & WinGetHandle("[ACTIVE]") & "|")) Then + Return 1 ;Block processing! + EndIf + Else ;Exclude proc + If Not StringInStr($sExclude, "|" & $vkCode & "|") And ($hWnds = "||" Or StringInStr($hWnds, "|" & WinGetHandle("[ACTIVE]") & "|")) Then + Return 1 ;Block processing! + EndIf + EndIf + + Return _WinAPI_CallNextHookEx($ah_MouseKeyboard_WinHooks[2], $nCode, $wParam, $lParam) ;Continue processing +EndFunc + +;Mouse hook processing function +Func __BlockInputEx_MouseHook_Proc($nCode, $wParam, $lParam) + If $nCode < 0 Then Return _WinAPI_CallNextHookEx($ah_MouseKeyboard_WinHooks[3], $nCode, $wParam, $lParam) ;Continue processing + + Local $MOUSEHOOKSTRUCT = DllStructCreate("ptr pt;hwnd hwnd;uint wHitTestCode;ulong_ptr dwExtraInfo", $lParam) + Local $iExtraInfo = DllStructGetData($MOUSEHOOKSTRUCT, "dwExtraInfo") + Local $iMouse_Event = BitAND($wParam, 0xFFFF) + ;Add mouse exclude/include actions support... + + Local $sInclude = $ah_MouseKeyboard_WinHooks[4] + Local $sExclude = $ah_MouseKeyboard_WinHooks[5] + Local $hWnds = $ah_MouseKeyboard_WinHooks[6] + Local $iBlockAllInput = $ah_MouseKeyboard_WinHooks[7] + + If $iBlockAllInput = 0 And $iExtraInfo <> 0 Then + Return _WinAPI_CallNextHookEx($ah_MouseKeyboard_WinHooks[3], $nCode, $wParam, $lParam) ;Continue processing + EndIf + + If $sInclude <> "||" Then ;Include proc + If StringInStr($sInclude, "|" & $iMouse_Event & "|") And ($hWnds = "||" Or StringInStr($hWnds, "|" & __BlockInputEx_WinGetHovered() & "|")) Then + Return 1 ;Block processing! + EndIf + Else ;Exclude proc + If Not StringInStr($sExclude, "|" & $iMouse_Event & "|") And ($hWnds = "||" Or StringInStr($hWnds, "|" & __BlockInputEx_WinGetHovered() & "|")) Then + Return 1 ;Block processing! + EndIf + EndIf + + Return _WinAPI_CallNextHookEx($ah_MouseKeyboard_WinHooks[3], $nCode, $wParam, $lParam) ;Continue processing +EndFunc + +;Releases callbacks and Unhook Windows hooks +Func __BlockInputEx_UnhookWinHooks_Proc() + ;Release KeyBoard callback function + If $ah_MouseKeyboard_WinHooks[0] > 0 Then + DllCallbackFree($ah_MouseKeyboard_WinHooks[0]) + $ah_MouseKeyboard_WinHooks[0] = 0 + EndIf + + ;Release Mouse callback function + If $ah_MouseKeyboard_WinHooks[1] > 0 Then + DllCallbackFree($ah_MouseKeyboard_WinHooks[1]) + $ah_MouseKeyboard_WinHooks[1] = 0 + EndIf + + ;Release KeyBoard Window hook + If IsPtr($ah_MouseKeyboard_WinHooks[2]) Then + _WinAPI_UnhookWindowsHookEx($ah_MouseKeyboard_WinHooks[2]) + $ah_MouseKeyboard_WinHooks[2] = 0 + EndIf + + ;Release Mouse Window hook + If IsPtr($ah_MouseKeyboard_WinHooks[3]) Then + _WinAPI_UnhookWindowsHookEx($ah_MouseKeyboard_WinHooks[3]) + $ah_MouseKeyboard_WinHooks[3] = 0 + EndIf + + Return 1 +EndFunc + +Func __BlockInputEx_Parse_vkCodesList_CLASSes($sList) + $sList = StringRegExpReplace($sList, "(?i)\{(Ctrl|Shift|Alt)\}", "{L$1}|{R$1}") ;Fix for Ctrl/Shift/Alt keys (add L/R to them) + + Local $a_vkCode_List = StringSplit($sList, "|") + Local $sRet_Keys = "" + + For $i = 1 To $a_vkCode_List[0] + Switch $a_vkCode_List[$i] + Case "[:FUNC:]" + $a_vkCode_List[$i] = "0x70|0x71|0x72|0x73|0x74|0x75|0x76|0x77|0x78|0x79|0x7A|0x7B|0x7C|0x7D|0x7E|0x7F|0x80H|0x81H|0x82H|0x83H|0x84H|0x85H|0x86H|0x87H" + Case "[:ALPHA:]" + $a_vkCode_List[$i] = "0x41|0x42|0x43|0x44|0x45|0x46|0x47|0x48|0x49|0x4A|0x4B|0x4C|0x4D|0x4E|0x4F|0x50|0x51|0x52|0x53|0x54|0x55|0x56|0x57|0x58|0x59|0x5A" + Case "[:NUMBER:]" + $a_vkCode_List[$i] = "0x30|0x31|0x32|0x33|0x34|0x35|0x36|0x37|0x38|0x39|0x60|0x61|0x62|0x63|0x64|0x65|0x66|0x67|0x68|0x69" + Case "[:ARROWS:]" + $a_vkCode_List[$i] = "0x25|0x26|0x27|0x28" + Case "[:SPECIAL:]" + $a_vkCode_List[$i] = "0x08|0x09|0x0C|0x0D|0x10|0x11|0x12|0x13|0x14|0x1B|0x20|0x21|0x22|" & _ + "0x23|0x24|0x29|0x2A|0x2B|0x2C|0x2D|0x2E|0x5B|0x5C|0x6A|0x6B|0x6C|" & _ + "0x6D|0x6E|0x6F|0x90|0x91|0xA0|0xA1|0xA2|0xA3|0xA4|0xA5|0xBA|0xBB|" & _ + "0xBC|0xBD|0xBE|0xBF|0xC0|0xDB|0xDC|0xDD" + Case Else + $a_vkCode_List[$i] = __BlockInputEx_KeyStr_To_vkCode($a_vkCode_List[$i]) + EndSwitch + + $sRet_Keys &= $a_vkCode_List[$i] & "|" + Next + + Return StringRegExpReplace($sRet_Keys, "\|+$", "") +EndFunc + +Func __BlockInputEx_Parse_vmCodesList_CLASSes($sList) + Local Const $MOUSE_MOVE_EVENT = 512 + Local Const $MOUSE_PRIMARYDOWN_EVENT = 513 + Local Const $MOUSE_PRIMARYUP_EVENT = 514 + Local Const $MOUSE_SECONDARYDOWN_EVENT = 516 + Local Const $MOUSE_SECONDARYUP_EVENT = 517 + Local Const $MOUSE_WHEELDOWN_EVENT = 519 + Local Const $MOUSE_WHEELUP_EVENT = 520 + Local Const $MOUSE_WHEELSCROLL_EVENT = 522 + Local Const $MOUSE_SPECIALBUTTONDOWN_EVENT = 523 + Local Const $MOUSE_SPECIALBUTTONUP_EVENT = 524 + + Local $a_vmCode_List = StringSplit($sList, "|") + Local $sRet_Keys = "" + + For $i = 1 To $a_vmCode_List[0] + Switch $a_vmCode_List[$i] + Case "{MMOVE}" + $a_vmCode_List[$i] = $MOUSE_MOVE_EVENT + Case "{MPDOWN}" + $a_vmCode_List[$i] = $MOUSE_PRIMARYDOWN_EVENT + Case "{MPUP}" + $a_vmCode_List[$i] = $MOUSE_PRIMARYUP_EVENT + Case "{MSDOWN}" + $a_vmCode_List[$i] = $MOUSE_SECONDARYDOWN_EVENT + Case "{MSUP}" + $a_vmCode_List[$i] = $MOUSE_SECONDARYUP_EVENT + Case "{MWDOWN}" + $a_vmCode_List[$i] = $MOUSE_WHEELDOWN_EVENT + Case "{MWUP}" + $a_vmCode_List[$i] = $MOUSE_WHEELUP_EVENT + Case "{MWSCROLL}" + $a_vmCode_List[$i] = $MOUSE_WHEELSCROLL_EVENT + Case "{MSPDOWN}" + $a_vmCode_List[$i] = $MOUSE_SPECIALBUTTONDOWN_EVENT + Case "{MSPUP}" + $a_vmCode_List[$i] = $MOUSE_SPECIALBUTTONUP_EVENT + EndSwitch + + $sRet_Keys &= $a_vmCode_List[$i] & "|" + Next + + Return StringRegExpReplace($sRet_Keys, "\|+$", "") +EndFunc + +Func __BlockInputEx_KeyStr_To_vkCode($sKeyStr) + Local $sRet_Keys = "", $aDelim_Keys[1] + Local $aKeys = StringSplit("{LMouse}|{RMouse}|{}|(MMouse}|{}|{}|{}|{BACKSPACE}|{TAB}|{}|{}|{}|{ENTER}|{}|{}|{SHIFT}|{CTRL}|{ALT}|{PAUSE}|{CAPSLOCK}|{}|{}|{}|{}|{}|{}|{ESC}|{}|{}|{}|{]|{SPACE}|{PGUP}|{PGDN}|{END}|{HOME}|{LEFT}|{UP}|{RIGHT}|{DOWN}|{SELECT}|{PRINTSCREEN}|{}|{PRINTSCREEN}|{INSERT}|{DEL}|{}|0|1|2|3|4|5|6|7|8|9|{}|{}|{}|{}|{}|{}|{}|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|{LWIN}|{RWIN}|{APPSKEY}|{}|{SLEEP}|{numpad0}|{numpad1}|{numpad2}|{numpad3}|{numpad4}|{numpad5}|{numpad6}|{numpad7}|{numpad8}|{numpad9}|{NUMPADMULT}|{NUMPADADD}|{}|{NUMPADSUB}|{NUMPADDOT}|{NUMPADDIV}|{F1}|{F2}|{F3}|{F4}|{F5}|{F6}|{F7}|{F8}|{F9}|{F10}|{F11}|{F12}|{F13}|{F14}|{F15}|{F16}|{F17}|{F18}|{F19}|{F20}|{F21}|{F22}|{F23}|{F24}|{}|{}|{}|{}|{}|{}|{}|{}|{NUMLOCK}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{LSHIFT}|{RSHIFT}|{LCTRL}|{RCTRL}|{LALT}|{RALT}|{BROWSER_BACK}|{BROWSER_FORWARD}|{BROWSER_REFRESH}|{BROWSER_STOP}|{BROWSER_SEARCH}|{BROWSER_FAVORITES}|{BROWSER_HOME}|{VOLUME_MUTE}|{VOLUME_DOWN}|{VOLUME_UP}|{MEDIA_NEXT}|{MEDIA_PREV}|{MEDIA_STOP}|{MEDIA_PLAY_PAUSE}|{LAUNCH_MAIL}|{LAUNCH_MEDIA}|{LAUNCH_APP1}|{LAUNCH_APP2}|{}|{}|;|{+}|,|{-}|.|/|`|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|[|\|]|'", "|") + + If StringRegExp($sKeyStr, "\A\[|\]\z") Then + $sKeyStr = StringRegExpReplace($sKeyStr, "\A\[|\]\z", "") + $sKeyStr = StringRegExpReplace($sKeyStr, "(.)", "\1|") + $sKeyStr = StringRegExpReplace($sKeyStr, "\|+$", "") + + $aDelim_Keys = StringSplit($sKeyStr, "") + EndIf + + For $i = 1 To $aKeys[0] + If $aDelim_Keys[0] > 1 Then + For $j = 1 To $aDelim_Keys[0] + If $aKeys[$i] = $aDelim_Keys[$j] Then $sRet_Keys &= "0x" & Hex($i, 2) & "|" + Next + Else + If $aKeys[$i] = $sKeyStr Then Return "0x" & Hex($i, 2) + EndIf + Next + + If $sRet_Keys = "" Then Return $sKeyStr + Return StringRegExpReplace($sRet_Keys, "\|+$", "") +EndFunc + +Func __BlockInputEx_WinGetHovered() + Local $iOld_Opt_MCM = Opt("MouseCoordMode", 1) + Local $aRet = DllCall("user32.dll", "int", "WindowFromPoint", "long", MouseGetPos(0), "long", MouseGetPos(1)) + Opt("MouseCoordMode", $iOld_Opt_MCM) + + If $i_MouseHookGetAncestorHwnd Then + $aRet = DllCall("User32.dll", "hwnd", "GetAncestor", "hwnd", $aRet[0], "uint", 2) ;$GA_ROOT + EndIf + + Return HWnd($aRet[0]) +EndFunc + +;Called when script exits to release resources. +Func __BlockInputEx_OnAutoItExit() + _BlockInputEx(0) +EndFunc + +#EndRegion Internal Functions diff --git a/includes/_Monitor.au3 b/includes/_Monitor.au3 new file mode 100644 index 0000000..450fc0c --- /dev/null +++ b/includes/_Monitor.au3 @@ -0,0 +1,166 @@ +#cs ---------------------------------------------------------------------------- + + AutoIt Version: 3.3.12.0 + Author: Sqozz + + Script Function: + Template AutoIt script. + +#ce ---------------------------------------------------------------------------- + +Func _getPrimaryMonDimensions() + $allMonitors = _WinAPI_EnumDisplayMonitors() + ; [0] ==> X-Pos + ; [1] ==> Y-Pos + ; [2] ==> Width + ; [3] ==> Height + Dim $primaryMonitor[4] + + For $i = 1 To $allMonitors[0][0] + $aData = _WinAPI_GetMonitorInfo ( $allMonitors[$i][0] ) + If $aData[2] == 1 Then + $primaryMonitor[0] = DllStructGetData($aData[0], 1) + $primaryMonitor[1] = DllStructGetData($aData[0], 2) + $primaryMonitor[2] = DllStructGetData($aData[0], 3) + $primaryMonitor[3] = DllStructGetData($aData[0], 4) + EndIf + Next + + Return $primaryMonitor +EndFunc + +Func _calcDimensions($secondaryMonitor) + ; [0] ==> X-Pos + ; [1] ==> Y-Pos + ; [2] ==> Width + ; [3] ==> Height + Dim $secondaryMonitorRealDim[4] + $primaryMonitor = _getPrimaryMonDimensions() + $secondaryMonitorRealDim[0] = $secondaryMonitor[0] + $secondaryMonitorRealDim[1] = $secondaryMonitor[1] + $secondaryMonitorRealDim[2] = $secondaryMonitor[2] - $secondaryMonitor[0] + $secondaryMonitorRealDim[3] = $secondaryMonitor[3] - $secondaryMonitor[1] + + Return $secondaryMonitorRealDim +EndFunc + +Func _genMonitorList() + $physicalMonitors = _WinAPI_EnumDisplayMonitors() + Dim $monitors[$physicalMonitors[0][0]][5] + + For $i = 1 To $physicalMonitors[0][0] + ; [0] ==> X-Pos + ; [1] ==> Y-Pos + ; [2] ==> Width + ; [3] ==> Height + ; [4] ==> Handle + Dim $monitor[4] + + $aData = _WinAPI_GetMonitorInfo ( $physicalMonitors[$i][0] ) + $monitor[0] = DllStructGetData($aData[0], 1) + $monitor[1] = DllStructGetData($aData[0], 2) + $monitor[2] = DllStructGetData($aData[0], 3) + $monitor[3] = DllStructGetData($aData[0], 4) + + If $aData[2] <> 1 Then + $monitor[0] = DllStructGetData($aData[0], 1) + $monitor[1] = DllStructGetData($aData[0], 2) + $monitor[2] = DllStructGetData($aData[0], 3) + $monitor[3] = DllStructGetData($aData[0], 4) + $monitor = _calcDimensions($monitor) + EndIf + + $monitors[$i - 1][0] = $monitor[0] + $monitors[$i - 1][1] = $monitor[1] + $monitors[$i - 1][2] = $monitor[2] + $monitors[$i - 1][3] = $monitor[3] + $monitors[$i - 1][4] = $physicalMonitors[$i][0] + Next + + Return $monitors +EndFunc + + +Func _getContainingMonitor($hwnd) + $monitors = _genMonitorList() + $desiredWinPos = _WinGetClientPos($hwnd) + $containingMonitor = Null + + If _WinAPI_IsIconic($hwnd) Then + Return "Iconic" + Else + Return _WinAPI_MonitorFromWindow($hwnd) + EndIf +#cs === THIS IS OLD CODE === + ; Find containing monitor by the upper left corner of the application + $OldDeltaX = 99999999999 + $OldDeltaY = 99999999999 + $deltaX = 0 + $deltaY = 0 + For $i = 0 To UBound($monitors) - 1 + If $desiredWinPos[0] >= $monitors[$i][0] And $desiredWinPos[1] >= $monitors[$i][1] And $desiredWinPos[0] <= $monitors[$i][0] + $monitors[$i][2] And $desiredWinPos[1] <= $monitors[$i][1] + $monitors[$i][3] Then + $deltaX = $desiredWinPos[0] - $monitors[$i][0] + $deltaY = $desiredWinPos[1] - $monitors[$i][1] + If $deltaX < $OldDeltaX And $deltaY < $OldDeltaY Then + $OldDeltaX = $deltaX + $OldDeltaY = $deltaY + $containingMonitor = $monitors[$i][4] + Else + ConsoleWrite("Second monitor found but delta is to high" & @CRLF) + EndIf + + ;ConsoleWrite("=== " & WinGetTitle($hwnd) & " ===" & @CRLF) + ;ConsoleWrite("$desiredWinPos[0] ("&$desiredWinPos[0]&") >= (" & $monitors[$i][0] & ") $monitors[$i][0]" & @CRLF) + ;ConsoleWrite("$desiredWinPos[1] ("&$desiredWinPos[1]&") >= (" & $monitors[$i][1] & ") $monitors[$i][1]" & @CRLF) + ;ConsoleWrite("$desiredWinPos[0] ("&$desiredWinPos[0]&") <= (" & $monitors[$i][0] + $monitors[$i][2] & ") $monitors[$i][0] + $monitors[$i][2]" & @CRLF) + ;ConsoleWrite("$desiredWinPos[1] ("&$desiredWinPos[1]&") <= (" & $monitors[$i][1] + $monitors[$i][3] & ") $monitors[$i][1] + $monitors[$i][3]" & @CRLF) + EndIf + Next + + ; If no monitor was found, check if maybe the end of the application is visible + If $containingMonitor == Null Then + $step = 100 + ; Try to find containing monitor by checking each pixel of the window + ; This needs much computing power, so we first check in steps of 100 and go down to 1 until we found it + While $step > 0 + For $i = 0 To UBound($monitors) - 1 + For $width = 1 To $desiredWinPos[2] Step $step + For $height = 1 To $desiredWinPos[2] Step $step + If $desiredWinPos[0] + $width >= $monitors[$i][0] And $desiredWinPos[1] + $height >= $monitors[$i][1] And $desiredWinPos[0] + $width <= $monitors[$i][0] + $monitors[$i][2] And $desiredWinPos[1] + $height <= $monitors[$i][1] + $monitors[$i][3] Then + $containingMonitor = $monitors[$i][4] + ExitLoop + EndIf + Next + If $containingMonitor <> Null Then ExitLoop + Next + If $containingMonitor <> Null Then ExitLoop + Next + If $containingMonitor <> Null Then ExitLoop + $step -= 1 + WEnd + EndIf + + Return $containingMonitor +#ce +EndFunc + + +Func _WinGetClientPos($hwnd) + Local $client = _WinAPI_GetClientRect($hwnd) + Local $window = _WinAPI_GetWindowRect($hwnd) + Local $cRight = DllStructGetData($client, "Right") + Local $cBottom = DllStructGetData($client, "Bottom") + Local $wTop = DllStructGetData($window, "Top") + Local $wLeft = DllStructGetData($window, "Left") + Local $wRight = DllStructGetData($window, "Right") + Local $wBottom = DllStructGetData($window, "Bottom") + Local $borderLTR = (DllStructGetData($window, "Right") - DllStructGetData($window, "Left")) - DllStructGetData($client, "Right") + Local $borderTop = (DllStructGetData($window, "Bottom") - DllStructGetData($window, "Top")) - DllStructGetData($client, "Bottom") + Local $realPos[4] + $realPos[0] = $wLeft + ($borderLTR/2) + $realPos[1] = $wTop + ($borderTop/2) + $realPos[2] = ($wRight - $wLeft) - $borderLTR + $realPos[3] = ($wBottom - $wTop) - ($borderTop/2) - ($borderLTR/2) + + Return $realPos +EndFunc \ No newline at end of file diff --git a/includes/_Subarray.au3 b/includes/_Subarray.au3 new file mode 100644 index 0000000..2975a5f --- /dev/null +++ b/includes/_Subarray.au3 @@ -0,0 +1,31 @@ +#cs ---------------------------------------------------------------------------- + + AutoIt Version: 3.3.12.0 + Author: Sqozz + + Script Function: + Template AutoIt script. + +#ce ---------------------------------------------------------------------------- + +; Inserts an array into an array +; Returns the position, where the new array inside the parent array is living +; For Example: use _ArrayGetFromArray($mainArray, _ArrayAddToArray($mainArray, $arrayToAdd)) to get $arrayToAdd +Func _ArrayAddToArray(ByRef $mainArray, $arrayToAdd) + $indexOfNew = _ArrayAdd($mainArray, "") ; Create a new entry in the desired array + $mainArray[$indexOfNew] = $arrayToAdd + Return $indexOfNew +EndFunc + +Func _ArrayGetFromArray($mainArray, $indexToGet) + $subArray = $mainArray[$indexToGet] + Return $subArray +EndFunc + +Func _InsertArrayToArray(ByRef $mainArray, $arrayToAdd, $indexToInsert, $secondIndex = Null ) + If $secondIndex <> Null Then + $mainArray[$indexToInsert][$secondIndex] = $arrayToAdd + Else + $mainArray[$indexToInsert] = $arrayToAdd + EndIf +EndFunc \ No newline at end of file diff --git a/playground.au3 b/playground.au3 new file mode 100644 index 0000000..7a3685f --- /dev/null +++ b/playground.au3 @@ -0,0 +1,254 @@ +#cs ---------------------------------------------------------------------------- + + AutoIt Version: 3.3.12.0 + Author: Sqozz + + Script Function: + Template AutoIt script. + +#ce ---------------------------------------------------------------------------- + +#include "includes\_Subarray.au3" +#include "includes\_Monitor.au3" +#include +#include +#include +#include +#include +#include +#include + + +_POC_CustomTaskbar() + +; === POC for _Subarray UDF +Func _POC_Subarray() + #include + Local $array[0] + Local $array2[0] + Local $subsubarray[0] + + _ArrayAdd($subsubarray, "value1 in subsubarray") + _ArrayAdd($subsubarray, "value2 in subsubarray") + + _ArrayDisplay($subsubarray) + + _ArrayAddToArray($array2, $subsubarray) + _ArrayAddToArray($array, $array2) + + $array_2 = _ArrayGetFromArray($array, 0) + $sub = _ArrayGetFromArray($array_2, 0) + ConsoleWrite($sub[0] & @CRLF) +EndFunc + +; === This creates a huge green box on each monitor. +; Each of this box contains all windows which are currently on this monitor +Func _POC_CustomTaskbar() + ; Create a GUI with various controls. + $monitors = _genMonitorList() + Dim $hGUIList[0][2] + + Dim $ElementList[0] + Dim $UIElementContainer[0][2] ; Element[0] == HWND of GUICreate; Element[1] == Array of all elements contained in this UI + + $windowList = _getVisibleWindowList() + Dim $winWithMon[0][2] + For $i = 0 To UBound($windowList) - 1 + $winIndex = _ArrayAdd($winWithMon, WinGetTitle($windowList[$i])) + $winWithMon[$winIndex][1] = _WinAPI_MonitorFromWindow($windowList[$i]) + Next + + ;This loop creates a taskbar for each monitor. Full width and 20px height + For $i = 0 To UBound($monitors) - 1 + _ArrayAdd($UIElementContainer, GUICreate($monitors[$i][4], $monitors[$i][2], 200, $monitors[$i][0], $monitors[$i][1], BitOR($WS_SYSMENU,$WS_POPUP,$WS_CLIPSIBLINGS), BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))) + GUISetBkColor ("0x00FF00") + + $elementY = 0 + For $a = 0 To UBound($winWithMon) - 1 + If $winWithMon[$a][1] == $monitors[$i][4] Then + GUICtrlCreateLabel ( $winWithMon[$a][0], 0, ($elementY * 20)) + $elementY += 1 + EndIf + Next + Next + ;Now $UIElementContainer[n][0] is filled with every handle of each GUI + + ;Now we create a label on each of this + ;For $i = 0 To UBound($UIElementContainer) - 1 + ; GUISwitch($UIElementContainer[$i][0]) + ; $id = GUICtrlCreateLabel ( "Autosome!", 0, 0 ) + ; $idBtn = GUICtrlCreateButton( "Hello on " & $id, 100, 0 ) + ; _ArrayAdd($ElementList, $id) + ; _ArrayAdd($ElementList, $idBtn) + ; _InsertArrayToArray($UIElementContainer, $ElementList, $i, 1) + + ; ReDim $ElementList[0] + ;Next + + For $i = 0 To UBound($UIElementContainer) - 1 + GUISetState(@SW_SHOW, $UIElementContainer[$i][0]) + Next + + While Not _IsPressed("1B") ; ESC to exit + Switch GUIGetMsg() + Case $GUI_EVENT_CLOSE + ExitLoop + + EndSwitch + WEnd + + For $i = 0 To UBound($UIElementContainer) - 1 + GUIDelete($UIElementContainer[$i][0]) + Next +EndFunc + + + + +; Returns an array of visible windows. +; All windows, which have the "Window is visible" bit set, count as visible +Func _getVisibleWindowList() + Local $visibleList[0] + $plist = ProcessList() + For $i = 1 To $plist[0][0] + $hwndList = _ProcessGetWindow($plist[$i][1]) + If IsArray($hwndList) Then + For $a = 1 To $hwndList[0] + $hwnd = $hwndList[$a] + $applState = WinGetState($hwnd) + $title = WinGetTitle($hwnd) + If (BitOR($applState, 2) == $applState) And $title <> "" Then + _ArrayAdd($visibleList, $hwnd) + EndIf + Next + EndIf + Next + + Return $visibleList +EndFunc + +; Returns an array with window styles +; $array[0] = Window styles +; $array[1] = Extended window styles +Func _getStyleOfWindow($hwnd) + Local $style[0] + $aStyle = _WinAPI_GetWindowLong($hwnd, $GWL_STYLE) + If @error == 0 Then + _ArrayAdd($style, $aStyle) + Else + _ArrayAdd($style, -1) + EndIf + $aExStyle = _WinAPI_GetWindowLong($hwnd, $GWL_EXSTYLE) + If @error == 0 Then + _ArrayAdd($style, $aExStyle) + Else + _ArrayAdd($style, -1) + EndIf + Return $style +EndFunc + +; Iterates over an array of hwnds and returns an array of tilable window hwnds +Func _createTilableWindowList($windowList) + Local $tilableWindowList[0] + For $i = 0 To UBound($windowList) - 1 + If _isTilable($windowList[$i]) Then + _ArrayAdd($tilableWindowList, $windowList[$i]) + EndIf + Next + Return $tilableWindowList +EndFunc + +; I assume, that a window should be tiles, if it has a thick frame +Func _isTilable($hwnd) + $styles = _getStyleOfWindow($hwnd) + If BitAND($styles[1], $WS_EX_DLGMODALFRAME) <> $WS_EX_DLGMODALFRAME Then + Return True + Else + Return False + EndIf +EndFunc + +; #FUNCTION# ============================================================================================================================ +; Name...........: _ProcessGetWindow +; +; Description ...: Returns an array of HWNDs containing all windows owned by the process $p_PID, or optionally a single "best guess." +; +; Syntax.........: _ProcessGetWindow( $p_PID [, $p_ReturnBestGuess = False ]) +; +; Parameters ....: $p_PID - The PID of the process you want the Window for. +; $p_ReturnBestGuess - If True, function will return only 1 reult on a best-guess basis. +; The "Best Guess" is the VISIBLE window owned by $p_PID with the longest title. +; +; Return values .: Success - Return $_array containing HWND info. +; $_array[0] = Number of results +; $_array[n] = HWND of Window n +; +; Failure - Returns 0 +; +; Error - Returns -1 and sets @error +; 1 - Requires a non-zero number. +; 2 - Process does not exist +; 3 - WinList() Error +; +; Author ........: Andrew Bobulsky, contact: RulerOf . +; Remarks .......: The reverse of WinGetProcess() +; ======================================================================================================================================= + +Func _ProcessGetWindow( $p_PID, $p_ReturnBestGuess = False ) + Local $p_ReturnVal[1] = [0] + Local $p_WinList = WinList() + + If @error Then ;Some Error handling + SetError(3) + Return -1 + EndIf + + If $p_PID = 0 Then ;Some Error handling + SetError(1) + Return -1 + EndIf + + If ProcessExists($p_PID) = 0 Then ;Some Error handling + ConsoleWrite("_ProcessGetWindow: Process " & $p_PID & " doesn't exist!" & @CRLF) + SetError(2) + Return -1 + EndIf + + For $i = 1 To $p_WinList[0][0] Step 1 + Local $w_PID = WinGetProcess($p_WinList[$i][1]) + If $w_PID = $p_PID Then + $p_ReturnVal[0] += 1 + _ArrayAdd($p_ReturnVal, $p_WinList[$i][1]) + EndIf + Next + + If $p_ReturnVal[0] > 1 Then + If $p_ReturnBestGuess Then + Do + Local $i_State = WinGetState($p_ReturnVal[2]) + Local $i_StateLongest = WinGetState($p_ReturnVal[1]) + Select + Case BitAND($i_State, 2) And BitAND($i_StateLongest, 2) ;If they're both visible + If StringLen(WinGetTitle($p_ReturnVal[2])) > StringLen(WinGetTitle($p_ReturnVal[1])) Then ;And the new one has a longer title + _ArrayDelete($p_ReturnVal, 1) ;Delete the "loser" + $p_ReturnVal[0] -= 1 ;Decrement counter + Else + _ArrayDelete($p_ReturnVal, 2) ;Delete the failed challenger + $p_ReturnVal[0] -= 1 + EndIf + Case BitAND($i_State, 2) And Not BitAND($i_StateLongest, 2) ;If the new one's visible and the old one isn't + _ArrayDelete($p_ReturnVal, 1) ;Delete the old one + $p_ReturnVal[0] -= 1 ;Decrement counter + Case Else ;Neither window is visible, let's just keep the first one. + _ArrayDelete($p_ReturnVal, 2) + $p_ReturnVal[0] -= 1 + EndSelect + Until $p_ReturnVal[0] = 1 + EndIf + Return $p_ReturnVal + ElseIf $p_ReturnVal[0] = 1 Then + Return $p_ReturnVal ;Only 1 window. + Else + Return 0 ;Window not found. + EndIf +EndFunc \ No newline at end of file