Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #Requires AutoHotkey 2.0
- /*
- [easiest way to have it always look basically fine by hiding the ad entirely unless tooltips are shown in certain areas, but remember that some Outlook tooltips have multiple lines of text
- and the search bar needs to hide the overlays and btn entirely, by detecting when the user has clicked inside the input field]
- |
- [make an algorithm that goes over every Outlook tooltip pixel of the mentioned row until there is no Outlook tooltip pixel found, then I know exactly how big the Outlook tooltip is and then
- I can simply have two rectangles resized so that it leaves a gap between them for the Outlook tooltip. but if the Outlook tooltip starts at the first overlay row pixel then I only need to
- have one rectangle, at the right side, being resized to leave a gap on the left side for the Outlook tooltip, and vice versa if the tooltip is at the last overlay row pixel, then I only
- need to have one rectangle, at the left side, being resized to leave a gap on the right side for the Outlook tooltip. these amounts of rectangles are about only one side of the ad section,
- top/bottom, so one/two rectangles above and one/two rectangles below. checking both top and bottom, to change either side or both as needed]
- |
- I can make rectangle GUIs (perhaps even using programmatically generated gradients) and then when the cursor hovers the bar directly above or below the ad section, which contains buttons.
- then I can detect if any pixels one row below the bar that's above the ad section have changed color, and if any pixels one row above the bar that's below the ad section have changed color.
- in which case I can temporarily hide the GUIs that are showing Outlook tooltips, until the cursor no longer hovers the bars. using my PointerDeviceHook w/ Move
- */
- F1::Reload()
- A_WinDelay := -1
- A_CoordModePixel := "Screen" ; For the LButton hotkey variant feature that skips inbox resize line clicks and for HandleActivatedWindowOutlookEvent
- A_CoordModeMouse := "Screen" ; For the LButton hotkey variant feature that skips inbox resize line clicks
- EVENT_SYSTEM_FOREGROUND := 0x0003
- EVENT_SYSTEM_MINIMIZEEND := 0x0017
- HookEvent(EVENT_SYSTEM_FOREGROUND, HandleActivatedWindowOutlookEvent)
- HookEvent(EVENT_SYSTEM_MINIMIZEEND, HandleActivatedWindowOutlookEvent)
- customOutlookRefreshButtonMouseEventHook := PointerDeviceHook("Move", HandleCustomOutlookRefreshButtonMouseEvent, true)
- HandleActivatedWindowOutlookEvent(hWinEventHook, event, hWnd, *)
- {
- static isManagingCustomOutlookRefreshButton := false ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; not up-to-date, so how about renaming to isManagingCustomOutlookOverlays
- if (WinActive("E-mail ahk_class Olk Host"))
- {
- if (!isManagingCustomOutlookRefreshButton)
- {
- isManagingCustomOutlookRefreshButton := true
- ; Loading custom refresh btn for New Outlook or else merely making it always-on-top if it's already loaded
- if (!IsSet(adButtonOverlayedRefreshButtonGui))
- {
- Sleep(10) ; This is necessary to make WinGetClientPos retrieve the restored position
- WinGetClientPos(&outlookX, &outlookY,, &outlookHeight)
- while (PixelGetColor(outlookX + 619, outlookY + 146) != 0xFFFFFF) ; Random white [Adv] pixel
- continue ; NEEDS TIMEOUT AND GOTTA CHECK TOP LEFT CORNER WHITE PIXEL + BOTTOM RIGHT CORNER WHITE PIXEL (not one random white pixel)
- global mobileAppButtonOverlayedRemoverGui := Gui("-Caption")
- mobileAppButtonOverlayedRemoverGui.BackColor := "Black" ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"141414"
- WinSetExStyle("+0x08000000L", mobileAppButtonOverlayedRemoverGui) ; Adds WS_EX_NOACTIVATE
- mobileAppButtonOverlayedRemoverGui.Show("x" outlookX + 55 " y" outlookY + outlookHeight - 70 " w295 h65 NoActivate")
- GroupAdd("CustomOutlookNonClickableOverlays", "ahk_id " mobileAppButtonOverlayedRemoverGui.Hwnd) ;;;;;;;;;;;;;;;;;;;; remove from group before closing the wnd
- global adButtonOverlayedBgGui := Gui("-Caption") ;;;;;;;;;;;;;;;;;;;; +AlwaysOnTop -Caption
- adButtonOverlayedBgGui.BackColor := "Black"
- WinSetTransparent(1, adButtonOverlayedBgGui)
- WinSetExStyle("+0x08000000L", adButtonOverlayedBgGui) ; Adds WS_EX_NOACTIVATE
- adButtonOverlayedBgGui.Show("x" outlookX + 358 " y" outlookY + 132 " w375 h81 NoActivate")
- GroupAdd("CustomOutlookNonClickableOverlays", "ahk_id " adButtonOverlayedBgGui.Hwnd) ;;;;;;;;;;;;;;;;;;;; remove from group before closing the wnd
- global adButtonOverlayedInnerBgGui := Gui("-Caption") ;;;;;;;;;;;;;;;;;;;; +AlwaysOnTop -Caption
- adButtonOverlayedInnerBgGui.BackColor := "White" ;292929"
- ;WinSetTransparent(200, adButtonOverlayedInnerBgGui) ;REMOVE WHEN DONE
- WinSetExStyle("+0x08000000L", adButtonOverlayedInnerBgGui) ; Adds WS_EX_NOACTIVATE
- WinSetExStyle("+0x20", adButtonOverlayedInnerBgGui) ; Adds WS_EX_TRANSPARENT to let clicks pass-through
- adButtonOverlayedInnerBgGui.Show("x" outlookX + 368 " y" outlookY + 142 " w354 h66 NoActivate")
- global adButtonOverlayedRefreshButtonBgGui := Gui("-Caption") ;;;;;;;;;;;;;;;;;;;; +AlwaysOnTop -Caption
- adButtonOverlayedRefreshButtonBgGui.BackColor := "292929"
- WinSetExStyle("+0x08000000L", adButtonOverlayedRefreshButtonBgGui) ; Adds WS_EX_NOACTIVATE
- WinSetExStyle("+0x20", adButtonOverlayedRefreshButtonBgGui) ; Adds WS_EX_TRANSPARENT to let clicks pass-through
- adButtonOverlayedRefreshButtonBgGui.Show("x" outlookX + 395 " y" outlookY + 157 " w300 h37 NoActivate")
- global adButtonOverlayedRefreshButtonGui := Gui("-Caption") ;;;;;;;;;;;;;;;;;;;; +AlwaysOnTop -Caption
- adButtonOverlayedRefreshButtonGui.SetFont("s13", "Calibri")
- adButtonOverlayedRefreshButtonGui.AddButton("x0 y0 w300", "Refresh e-mails").OnEvent("Click", (*) => FocusHiddenButton())
- hiddenButton := adButtonOverlayedRefreshButtonGui.AddButton("-Tabstop y-100")
- ;..Gui.AddText("x0 y0 w50 h50 BackgroundFF00FF");can hide parts w/ multiple of these with WinSetTransColor for all non-Button GUIs, but it's better to repeat a region algorithm
- WinSetExStyle("+0x08000000L", adButtonOverlayedRefreshButtonGui) ; Adds WS_EX_NOACTIVATE
- WinSetTransparent(175, adButtonOverlayedRefreshButtonGui)
- adButtonOverlayedRefreshButtonGui.Show("x" outlookX + 395 " y" outlookY + 157 " w300 h37 NoActivate")
- ;ToolTip("LOADED")
- customOutlookRefreshButtonMouseEventHook.Start()
- }
- else
- {
- ;Sleep(10)
- mobileAppButtonOverlayedRemoverGui.Opt("+AlwaysOnTop")
- mobileAppButtonOverlayedRemoverGui.Opt("-AlwaysOnTop")
- adButtonOverlayedBgGui.Opt("+AlwaysOnTop")
- adButtonOverlayedBgGui.Opt("-AlwaysOnTop")
- adButtonOverlayedInnerBgGui.Opt("+AlwaysOnTop")
- adButtonOverlayedInnerBgGui.Opt("-AlwaysOnTop")
- adButtonOverlayedRefreshButtonBgGui.Opt("+AlwaysOnTop")
- adButtonOverlayedRefreshButtonBgGui.Opt("-AlwaysOnTop")
- adButtonOverlayedRefreshButtonGui.Opt("+AlwaysOnTop")
- adButtonOverlayedRefreshButtonGui.Opt("-AlwaysOnTop")
- ;ToolTip("NO LONGER OVERLAPPED")
- }
- isManagingCustomOutlookRefreshButton := false
- }
- }
- else if (IsSet(adButtonOverlayedRefreshButtonGui) && !WinExist(A_ScriptName " ahk_class AutoHotkeyGUI ahk_id " hWnd) && !isManagingCustomOutlookRefreshButton)
- {
- isManagingCustomOutlookRefreshButton := true
- if (WinGetMinMax("E-mail ahk_class Olk Host") = -1) ; Detects minimized wnd (Outlook is no longer being used)
- {
- customOutlookRefreshButtonMouseEventHook.Stop()
- WinClose(mobileAppButtonOverlayedRemoverGui)
- WinClose(adButtonOverlayedBgGui)
- WinClose(adButtonOverlayedInnerBgGui)
- WinClose(adButtonOverlayedRefreshButtonBgGui)
- WinClose(adButtonOverlayedRefreshButtonGui)
- global adButtonOverlayedRefreshButtonGui := unset
- ;ToolTip("CLOSED")
- }
- isManagingCustomOutlookRefreshButton := false
- }
- FocusHiddenButton() => PostMessage(0x0028, hiddenButton.Hwnd, true) ; 0x0028 = WM_NEXTDLGCTL
- }
- HookEvent(event, fnObj, pid := 0) => DllCall("SetWinEventHook", "UInt", event, "UInt", event, "Ptr", 0, "Ptr", CallbackCreate(fnObj), "UInt", pid, "UInt", 0, "UInt", 0)
- HandleCustomOutlookRefreshButtonMouseEvent(eventInfo)
- {
- ;THESE SPLIT GUI(S) HAVE NOT BEEN MADE YET, SO IT'S TEMPORARILY USING THE OLD ONE. CAN REPLACE THE TWO UNCOMMENTED LINES WITH THE TWO COMMENTED LINES, ONCE THE GUI HAS BEEN SPLIT
- ; topLeftAdButtonOverlayedInnerBgGui.GetClientPos(&topLeftAdButtonOverlayedInnerBgGuiX, &topLeftAdButtonOverlayedInnerBgGuiY)
- ; bottomLeftAdButtonOverlayedInnerBgGui.GetClientPos(, &bottomLeftAdButtonOverlayedInnerBgGuiY,, &bottomLeftAdButtonOverlayedInnerBgGuiHeight)
- adButtonOverlayedInnerBgGui.GetClientPos(&topLeftAdButtonOverlayedInnerBgGuiX, &topLeftAdButtonOverlayedInnerBgGuiY)
- adButtonOverlayedInnerBgGui.GetClientPos(, &bottomLeftAdButtonOverlayedInnerBgGuiY,, &bottomLeftAdButtonOverlayedInnerBgGuiHeight) ;NOT SURE IF THIS IS NECESSARY ANYMORE, SEE IF USED LATER
- if (eventInfo.Pt.Y >= topLeftAdButtonOverlayedInnerBgGuiY - 54 && eventInfo.Pt.Y <= topLeftAdButtonOverlayedInnerBgGuiY - 23) ; Detects cursor on menubar directly above inbox
- {
- ;hasFoundOutlookToolTipAtBottomLeftOfAd := false
- startTime := A_TickCount
- loop
- {
- if (hasFoundOutlookToolTipAtTopLeftOfAd := PixelGetColor(topLeftAdButtonOverlayedInnerBgGuiX, topLeftAdButtonOverlayedInnerBgGuiY - 1) != 0x292929)
- {
- ;[I DON'T THINK I NEED THIS AFTER ALL, MAKES IT TAKE EVEN LONGER AND THEN I'D HAVE TO INCREASE THE TIMEOUT.. IS LIKELY MUCH FASTER TO SIMPLY ALWAYS SET BOTTOM WIDTH AS WELL]
- ;hasFoundOutlookToolTipAtBottomLeftOfAd := PixelGetColor(topLeftAdButtonOverlayedInnerBgGuiX
- ; , bottomLeftAdButtonOverlayedInnerBgGuiY + bottomLeftAdButtonOverlayedInnerBgGuiHeight) != 0x292929
- break
- }
- ; Timeout for when the tooltip should have faded-in if there was one
- if (A_TickCount - startTime > 300)
- {
- ToolTip("[TIMEOUT] ON TOP BTN BAR!!!! " eventInfo.Pt.Y "`nhasFoundOutlookToolTipAtTopLeftOfAd: " hasFoundOutlookToolTipAtTopLeftOfAd) ;"`nhasFoundOutlookToolTipAtBottomLeftOfAd: "
- ;hasFoundOutlookToolTipAtBottomLeftOfAd) ; BOTH BOOLS ALWAYS FALSE
- return
- }
- Sleep(10)
- }
- ;
- ToolTip("ON TOP BTN BAR!!!! " eventInfo.Pt.Y "`nhasFoundOutlookToolTipAtTopLeftOfAd: " hasFoundOutlookToolTipAtTopLeftOfAd) ;"`nhasFoundOutlookToolTipAtBottomLeftOfAd: "
- ;hasFoundOutlookToolTipAtBottomLeftOfAd) ; FIRST BOOL ALWAYS TRUE
- ;[COULD PROBABLY DO IT THE WAY I INITIALLY PLANNED BUT THEN IT ONLY WORKS FOR HOW MY OWN OUTLOOK CURRENTLY IS ORGANIZED, THE BUTTONS AND THEIR TOOLTIPS.. THE NEW SOLUTION THE LINE BELOW
- ;THIS ONE IS ALSO NOT PERFECT BECAUSE THE TOOLTIP COULD THEN PERHAPS GO PARTIALLY THROUGH THE CUSTOM BTN.. THEN GOTTA MESS WITH WinSetTransColor/WinSetRegion, IT'S JUST A BIG MESS.. AND NEEDS BINARY SEARCH
- ;TO DO AT MOST 9 PixelGetColor CALLS FOR FULL WIDTH OF AD BTN OVERLAY (TAKES ABOUT 140 MSEC), INSTEAD OF 354 CALLS (TAKES ABOUT 5891 MSEC!!)]
- ;[I GUESS I'LL HAVE TO DO THIS INSTEAD: FIRST HORIZONTAL ROW OF BLACK PIXELS, THEN AT THE END OF THE ROW OF BLACK PIXELS, TEMPORARILY TURNING THE AD BTN OVERLAYS OFF SO IT CAN CHECK <-\
- ;VERTICALLY AS WELL, TO SEE WHERE THE BLACK PIXELS STOP GOING DOWNWARDS FROM THE RIGHT EDGE OF THE TOOLTIP.. THAT'S LIKE A SAFE SPOT WITH ONLY BLACK PIXELS TO EXPECT. THEN CHANGING THE \
- ;AD BTN OVERLAYS AND TURNING THEM BACK ON. AND WHEN THE PIXEL AT THE TOP ISN'T DETECT ANYMORE IN A NEW MOUSEMOVE EVENT, IT RESETS THE AD BTN OVERLAYS] |
- ;[NO NEED TO LOOP OVER BOTTOM PIXELS OFC] |
- ;[REV0, SKIP]IF BOOL_1 = TRUE, THEN { LOOP OVER TOP PIXELS, USING RESULT FOR TOP-RIGHT GUI WIDTH AND IF BOOL_2 = TRUE THEN ALSO FOR BOTTOM-RIGHT GUI WIDTH } |
- ;IF BOOL_1 = TRUE, THEN { LOOP OVER HORIZONTAL TOP PIXELS, USING RESULT FOR TOP-RIGHT GUI WIDTH AND BOTTOM-RIGHT GUI WIDTH, [π¨π¦π π« π’π₯ π¦π’π ππ§πππ‘π πππ¦π ππ’π₯ πππππ‘π ππ‘π§?], LOOP OVER VERTICAL TOP /
- ;PIXELS FROM TOP TO BOTTOM, USING RESULT FOR TOP-RIGHT GUI HEIGHT AND BOTTOM-RIGHT GUI HEIGHT, [π¨π¦π π¬ π’π₯ π¦π’π ππ§πππ‘π πππ¦π ππ’π₯ πππππ‘π ππ‘π§? IT'S PROBABLY F'D, SEE OTHER SUGGESTION ABOVE PSEUDOCODE]}
- }
- else
- ToolTip("OFF TOP BTN BAR " eventInfo.Pt.Y)
- }
- #HotIf (MouseIsOver("ahk_group CustomOutlookNonClickableOverlays"))
- *LButton::WinActivate("E-mail ahk_class Olk Host")
- ; Makes Outlook active when it needs to be while a click is happening on the custom refresh button
- #HotIf (MouseIsOverCustomOutlookRefreshButton())
- *LButton::
- {
- WinActivate("E-mail ahk_class Olk Host")
- Send("{LButton down}")
- KeyWait("LButton")
- Send("{LButton up}")
- WinActivate("E-mail ahk_class Olk Host")
- }
- ; CURRENTLY ONLY WORKS FOR OUTLOOK DARK MODE
- #HotIf (MouseIsOver("E-mail ahk_class Olk Host"))
- *LButton::
- {
- WinGetClientPos(&outlookX, &outlookY,,, "E-mail ahk_class Olk Host")
- MouseGetPos(&cursorX, &cursorY)
- ; I have retrieved screen pos of pixels while in maximized Outlook wnd. Then made pos relative by incrementing once, since Outlook's x,y client pos was -1,-1 and I've added that to it
- switch (cursorX)
- {
- ; Skips clicks on left side of inbox that otherwise allows you to resize, which interferes with the Outlook overlays feature
- case outlookX + 354, outlookX + 355, outlookX + 356, outlookX + 357:
- resizeLinePixelRowStart := outlookX + 353
- if (cursorY >= outlookY + 136)
- for (iteratedPixel in [0x141414, 0x141414, 0x3D3D3D, 0x3D3D3D])
- if (PixelGetColor(resizeLinePixelRowStart + A_Index, cursorY) = iteratedPixel)
- return
- ; Skips clicks on right side of inbox that otherwise allows you to resize, which interferes with the Outlook overlays feature
- case outlookX + 733, outlookX + 734, outlookX + 735, outlookX + 736:
- resizeLinePixelRowStart := outlookX + 732
- switch (cursorY)
- {
- case outlookY + 124:
- for (iteratedPixel in [0x0F0F0F, 0x0F0F0F, 0x0F0F0F, 0x0F0F0F])
- if (PixelGetColor(resizeLinePixelRowStart + A_Index, cursorY) = iteratedPixel)
- return
- case outlookY + 125:
- for (iteratedPixel in [0x101010, 0x101010, 0x101010, 0x101010])
- if (PixelGetColor(resizeLinePixelRowStart + A_Index, cursorY) = iteratedPixel)
- return
- case outlookY + 126:
- for (iteratedPixel in [0x121212, 0x121212, 0x121212, 0x121212])
- if (PixelGetColor(resizeLinePixelRowStart + A_Index, cursorY) = iteratedPixel)
- return
- case outlookY + 127, outlookY + 128:
- for (iteratedPixel in [0x131313, 0x131313, 0x131313, 0x131313])
- if (PixelGetColor(resizeLinePixelRowStart + A_Index, cursorY) = iteratedPixel)
- return
- case outlookY + 129, outlookY + 130, outlookY + 131, outlookY + 132:
- for (iteratedPixel in [0x141414, 0x141414, 0x141414, 0x141414])
- if (PixelGetColor(resizeLinePixelRowStart + A_Index, cursorY) = iteratedPixel)
- return
- case outlookY + 133:
- for (iteratedPixel in [0x131313, 0x141414, 0x141414, 0x141414])
- if (PixelGetColor(resizeLinePixelRowStart + A_Index, cursorY) = iteratedPixel)
- return
- case outlookY + 134:
- for (iteratedPixel in [0x121212, 0x141414, 0x141414, 0x141414])
- if (PixelGetColor(resizeLinePixelRowStart + A_Index, cursorY) = iteratedPixel)
- return
- case outlookY + 135:
- for (iteratedPixel in [0x121212, 0x131313, 0x141414, 0x141414])
- if (PixelGetColor(resizeLinePixelRowStart + A_Index, cursorY) = iteratedPixel)
- return
- default:
- if (cursorY >= outlookY + 136)
- for (iteratedPixel in [0x111111, 0x131313, 0x141414, 0x141414])
- if (PixelGetColor(resizeLinePixelRowStart + A_Index, cursorY) = iteratedPixel)
- return
- }
- }
- Send("{LButton down}"), KeyWait("LButton"), Send("{LButton up}")
- }
- class Point
- {
- X: i32, Y: i32
- }
- /*
- Example usage: (pointerDeviceEventHook := PointerDeviceHook("Move|LButton Down|LButton Up", HandlePointerDeviceEvent)).Start()
- /** @param {PointerDeviceHook.EventInfo} eventInfo Pointer device event info */`
- HandlePointerDeviceEvent(eventInfo)
- {
- ToolTip(Format("
- (
- x{1}, y{2}
- EventAction : {3}
- EventKey : {4}
- KeyUsageCount : {5}
- KeyUsageTime : {6}
- PressDuration : {7}
- IsPenAction : {8}
- )", eventInfo.Pt.X, eventInfo.Pt.Y, eventInfo.Action, eventInfo.Key, eventInfo.KeyUsageCount, eventInfo.KeyUsageTime, eventInfo.KeyPressDuration, eventInfo.IsPenAction))
- }
- */
- class PointerDeviceHook
- {
- class InternalEventInfo
- {
- Pt: Point
- MouseData: i32 ; Necessary cast to `Int`
- Flags: u32
- Time: u32
- ExtraInfo: uptr
- }
- class EventInfo
- {
- Pt => this._IsPtAdaptive ? PointerDeviceHook.EventInfo.LatestPt : this._Pt
- /** @prop {string} Action The event action */
- Action => this._IsActionAdaptive ? (PointerDeviceHook.EventInfo.LatestAction ?? this._Action) : this._Action
- /** @prop {string} Key The event key */
- Key => PointerDeviceHook.EventInfo.IsKeyPressedDown ? PointerDeviceHook.EventInfo.RetainedKey : this._Key
- /** @prop {integer} KeyUsageCount Count how many times a key gets pressed in a short time (KeyUsageCountTimeThreshold) */
- KeyUsageCount => PointerDeviceHook.EventInfo.IsKeyPressedDown ? PointerDeviceHook.EventInfo.RetainedKeyUsageCount : this._KeyUsageCount
- /** @prop {string} KeyUsageTime The time when the event key was pressed, scrolled, or used for a pen action */
- KeyUsageTime => PointerDeviceHook.EventInfo.IsKeyPressedDown ? PointerDeviceHook.EventInfo.RetainedKeyUsageTime : this._KeyUsageTime
- /** @prop {integer} KeyPressDuration The time elapsed since this key was pressed */
- KeyPressDuration => (this.KeyUsageTime ? A_TickCount - this.KeyUsageTime : 0)
- /** @prop {integer} IsPenAction Whether or not the event is caused by a pen pointer device (not detected when using drawing tablet) */
- IsPenAction => PointerDeviceHook.EventInfo.IsKeyPressedDown ? PointerDeviceHook.EventInfo.RetainedIsPenAction : this._IsPenAction
- /** @prop {boolean} IsKeyPressedDown The hook does not repeatedly trigger the down event while a key is pressed down, so those `onEvent` callbacks use timer & keeps relevant info */
- static IsKeyPressedDown := false
- static __New() => this.LatestPt := Point()
- __New() => this._Pt := Point()
- }
- /** @prop {Map} MsgList A list of message codes and actions (the commented wheel actions can also be used in the `PointerDeviceHook` constructor) */
- MsgList := Map(
- 512, "Move",
- 513, "LButton Down",
- 514, "LButton Up",
- 516, "RButton Down",
- 517, "RButton Up",
- 519, "MButton Down",
- 520, "MButton Up",
- 523, "XButton{:d} Down",
- 524, "XButton{:d} Up")
- ;ββ, "WheelUp"
- ;ββ, "WheelDown"
- /** @prop {integer} ProcHandle SetWindowsHookEx */
- ProcHandle := 0
- /** @prop {Map} PriorKeyObjects The map logs the time of when keys were previously pressed, as well as the count (both saved inside an object which is associated with a key) */
- PriorKeyObjects := Map()
- /** @prop {integer} KeyUsageCountTimeThreshold The time in which the usage of the event key gets counted, or reset when the time threshold is reached (milliseconds) */
- KeyUsageCountTimeThreshold := 500
- /**
- * @param {string} [action="All"] Move, LButton Down, MButton Up, etc (the `MsgList` property shows all of them)
- * @param {(hookObj) => Integer} onEvent This callback gets called on the event (to block mouse actions the callback must return true w/ default value `shouldMaintainResponsiveness`)
- * @param {integer} [shouldMaintainResponsiveness=false] Default is False, causing it to call `onEvent` in this thread in favor of mouse-action-blocking capability (consider using timer
- * in `onEvent`). Specify True to call it in a different thread if the `onEvent` code causes considerable mouse lag, as a result the Proc becomes incapable of blocking mouse actions
- * @param {integer} [criticalMode=0] Default is Disabled Mode. A (positive) Enabled Mode value is the message check interval. Specifying -1 turns on Critical but disables message checks
- */
- __New(action := "All", onEvent := (*) => 0, shouldMaintainResponsiveness := false, criticalMode := 0)
- {
- static WM_LBUTTONDOWN := 0x0201, WM_LBUTTONUP := 0x0202, WM_RBUTTONDOWN := 0x0204, WM_RBUTTONUP := 0x0205, WM_MBUTTONDOWN := 0x0207, WM_MBUTTONUP := 0x0208, WM_MOUSEWHEEL := 0x020A
- , WM_XBUTTONDOWN := 0x020B, WM_XBUTTONUP := 0x020C, LLMHF_INJECTED := 0x00000001, MI_WP_SIGNATURE := 0xFF515700, SIGNATURE_MASK := 0xFFFFFF00
- ; This callback gets executed when a pointer-device hook event occurs. The fast mode should be used only when it is known exactly which thread(s) this callback will be called from
- this.InternalCallback := CallbackCreate(PointerDeviceProc, (criticalMode && criticalMode != "Off") ? "F" : unset, 3)
- PointerDeviceProc(nCode, wParam, lParam)
- {
- if (criticalMode = -1 || criticalMode)
- Critical(criticalMode)
- internalEventInfo := StructFromPtr(PointerDeviceHook.InternalEventInfo, lParam)
- eventInfo := PointerDeviceHook.EventInfo()
- ; `internalEventInfo.MouseData` contains a reserved low-order word, which we don't need, and the high-order word is the leftmost 16 bits (bitshift removes the rest).
- ; `PointerDeviceHook.EventInfo.IsKeyPressedDown` is mainly set at this point so that the up event will also stop the repeated down event timer when the up action isn't hooked
- switch (wParam)
- {
- case WM_MOUSEWHEEL: eventInfo._Action := (internalEventInfo.MouseData >> 16) > 0 ? "WheelUp" : "WheelDown", PointerDeviceHook.EventInfo.IsKeyPressedDown := false
- case WM_XBUTTONDOWN: eventInfo._Action := Format(this.MsgList[wParam], internalEventInfo.MouseData >> 16), PointerDeviceHook.EventInfo.IsKeyPressedDown := true
- case WM_XBUTTONUP: eventInfo._Action := Format(this.MsgList[wParam], internalEventInfo.MouseData >> 16), PointerDeviceHook.EventInfo.IsKeyPressedDown := false
- case WM_LBUTTONDOWN, WM_RBUTTONDOWN, WM_MBUTTONDOWN: eventInfo._Action := this.MsgList[wParam], PointerDeviceHook.EventInfo.IsKeyPressedDown := true
- case WM_LBUTTONUP, WM_RBUTTONUP, WM_MBUTTONUP: eventInfo._Action := this.MsgList[wParam], PointerDeviceHook.EventInfo.IsKeyPressedDown := false
- default: eventInfo._Action := this.MsgList.Has(wParam) ? this.MsgList[wParam] : 0
- }
- if (nCode < 0 || (action != "All" && !InStr(action, eventInfo._Action)))
- return CallNextHookEx(nCode, wParam, lParam)
- eventInfo._IsPtAdaptive := eventInfo._IsActionAdaptive := false
- eventInfo._KeyUsageTime := eventInfo._KeyUsageCount := eventInfo._Key := 0
- eventInfo._Pt.X := internalEventInfo.Pt.X
- eventInfo._Pt.Y := internalEventInfo.Pt.Y
- if (eventInfo._Action && eventInfo._Action != "Move")
- {
- if (!this.PriorKeyObjects.Has(eventInfo._Action))
- this.PriorKeyObjects[eventInfo._Action] := {Time: internalEventInfo.Time, Count: 0}
- priorKey := this.PriorKeyObjects[eventInfo._Action]
- eventInfo._Key := eventInfo._Action
- eventInfo._KeyUsageCount := priorKey.Count += internalEventInfo.Time - priorKey.Time < this.KeyUsageCountTimeThreshold ? 1 : -priorKey.Count + 1 ; Resets to 1 if false
- eventInfo._KeyUsageTime := priorKey.Time := internalEventInfo.Time
- eventInfo._IsPenAction := DetermineIsPenAction(internalEventInfo.ExtraInfo)
- if (PointerDeviceHook.EventInfo.IsKeyPressedDown)
- {
- keyDownEventInfo := eventInfo.Clone()
- keyDownEventInfo._IsPtAdaptive := keyDownEventInfo._IsActionAdaptive := true
- PointerDeviceHook.EventInfo.LatestPt.X := eventInfo._Pt.X
- PointerDeviceHook.EventInfo.LatestPt.Y := eventInfo._Pt.Y
- PointerDeviceHook.EventInfo.LatestAction := unset
- PointerDeviceHook.EventInfo.RetainedKey := eventInfo._Key
- PointerDeviceHook.EventInfo.RetainedKeyUsageCount := eventInfo._KeyUsageCount
- PointerDeviceHook.EventInfo.RetainedKeyUsageTime := internalEventInfo.Time
- PointerDeviceHook.EventInfo.RetainedIsPenAction := eventInfo._IsPenAction
- SetTimer(() => (this.ProcHandle && PointerDeviceHook.EventInfo.IsKeyPressedDown ? onEvent(keyDownEventInfo) : SetTimer(, 0)), 50)
- }
- }
- else if (PointerDeviceHook.EventInfo.IsKeyPressedDown)
- {
- PointerDeviceHook.EventInfo.LatestPt.X := eventInfo._Pt.X
- PointerDeviceHook.EventInfo.LatestPt.Y := eventInfo._Pt.Y
- PointerDeviceHook.EventInfo.LatestAction := eventInfo._Action
- }
- else
- eventInfo._IsPenAction := DetermineIsPenAction(internalEventInfo.ExtraInfo)
- if (shouldMaintainResponsiveness)
- {
- SetTimer(() => onEvent(eventInfo), -1)
- return CallNextHookEx(nCode, wParam, lParam)
- }
- else
- return onEvent(eventInfo) && !(internalEventInfo.Flags & LLMHF_INJECTED) ? true : CallNextHookEx(nCode, wParam, lParam)
- }
- DetermineIsPenAction(extraInfo) => ((extraInfo & SIGNATURE_MASK) = MI_WP_SIGNATURE)
- CallNextHookEx(nCode, wParam, lParam) => DllCall("CallNextHookEx", "Ptr", 0, "Int", nCode, "UPtr", wParam, "Ptr", lParam)
- }
- /** Warning: Take caution when blocking mouse actions, you should not call this inside a mouse hotkey prefixed w/ the (~) tilde symbol (to make `Stop` unblock mouse actions properly) */
- Start()
- {
- if (!this.ProcHandle)
- this.ProcHandle := DllCall("SetWindowsHookEx", "Int", WH_MOUSE_LL := 14, "Ptr", this.InternalCallback, "Ptr", GetModuleHandle(), "UInt", 0)
- GetModuleHandle() => DllCall("GetModuleHandle", "UInt", 0, "Ptr")
- }
- Stop()
- {
- if (this.ProcHandle && DllCall("UnhookWindowsHookEx", "Ptr", this.ProcHandle))
- this.ProcHandle := 0
- }
- __Delete() => (this.InternalCallback && (this.Stop(), CallbackFree(this.InternalCallback), this.InternalCallback := 0))
- }
- MouseIsOver(winTitle, winText?, excludeTitle?, excludeText?) => (MouseGetPos(,, &winId), WinExist(winTitle " ahk_id " winId, winText?, excludeTitle?, excludeText?))
- MouseIsOverCustomOutlookRefreshButton()
- {
- try return (MouseGetPos(,, &winId, &control), WinExist(A_ScriptName " ahk_class AutoHotkeyGUI ahk_id " winId) && control = "Button1")
- return false
- }
- ; ------------------------------------------------------------------------ BELOW ARE SOME OTHER FILES I HAD ------------------------------------------------------------------------
- /*
- WS_EX_NOACTIVATE is useless? maybe not, the click skip didn't work so that seemed useless but it's also supposed to skip activation through other means
- */
- /*
- [When it's done, reply / edit reply with Lorenzo501 in issue of the two github repos that tried to fix it but failed, one I have starred with Lorenzo501, and one with Infinity-Surfer that
- needs to unstar, also edit the msg in the ExplorerPatcher's newoutlookpatcher channel, and maybe test Tgames' Outlook trick on laptop, could mention it on the issue discussions too]
- [When it's done, should probably make the stuff in the WinEvent handler use "try" in case Outlook crashes.. go kill the process and see if there's an error]
- [On Outlook foreground event, resize and move event, but these events should get hooked in HandleCreatedOutlookEvent when it ends because Outlook is temporarily transparent and active]
- [Make sure the other Outlook features still work, because they probably relied on Outlook being active but especially if the new Refresh btn gets clicked, Outlook might be seen as inactive
- but maybe I can just make the LButton hotkey use MouseIsOver instead of WinActive.. I doubt there's a better solution]
- [make it search for the white pixels in case the layout has been stretched, because then [Adv] moves with it]
- These are always there when you check for the position within the wnd instead of the screen (resizing/moving the wnd doesn't matter then apart from keeping it in the top-left corner).
- I can check on several points in the wnd ad section to detect if there are white pixels of the [Adv] symbol, and only then mask the ad section.
- [I have already removed the Sync button that you have by default in the View tab]
- [Mention in Time Saver to multi-line automation comment that the Sync button in the View tab of New Outlook is replaced by a "Refresh e-mails" button that overlays the ad section
- and that it's recommended to do the following: Go to the View tab > More options > Customize > Uncheck Synchronize > Save]
- To put something actually useful in the empty ad section, just add a button that says "Refresh e-mails" and when clicked, sends F9
- Verzonden en ontvangen e-mail synchroniseren: F9
- [Make sure to only use dark colors for the GUI when dark mode is used, otherwise light colors. and only need to check for it in the Outlook foreground event, not the resize and move event]
- FFFFFF on [Adv] and 292929 around/inside [Adv] << ON DARK MODE
- 000000 on [Adv] and FFFFFF around/inside [Adv] << ON LIGHT MODE
- --------[x]--[y]
- top-left corner of ad
- Screen: 356, 131
- Window: 364, 139
- Client: 357, 132
- bottom-left corner of ad
- Screen: 356, 210
- Window: 364, 218
- Client: 357, 211
- top-right corner of ad
- Screen: 732, 131
- Window: 740, 139
- Client: 733, 132
- bottom-right corner of ad
- Screen: 732, 210
- Window: 740, 218
- Client: 733, 211
- */
- /*
- #Requires AutoHotkey 2.0
- A_CoordModePixel := "Screen"
- loop
- {
- a := PixelGetColor(615, 145)
- b := PixelGetColor(616, 145)
- c := PixelGetColor(617, 145)
- d := PixelGetColor(618, 145)
- e := PixelGetColor(619, 145)
- f := PixelGetColor(620, 145)
- g := PixelGetColor(621, 145)
- h := PixelGetColor(622, 145)
- i := PixelGetColor(623, 145)
- j := PixelGetColor(624, 145)
- k := PixelGetColor(625, 145)
- tooltip("615 = " a "`n616 = " b "`n617 = " c "`n618 = " d "`n619 = " e "`n620 = " f "`n621 = " g "`n622 = " h "`n623 = " i "`n624 = " j "`n625 = " k)
- }
- */
- /*
- #Requires AutoHotkey 2.0
- A_CoordModePixel := "Screen"
- ; 732, 123
- ; to
- ; 735, 260
- F8::
- {
- currentX := 732
- currentY := 123
- A_Clipboard := ""
- loop ; TO FIND OUT ALL COLORS OF THE RESIZE LINE ON THE RIGHT
- {
- loop
- {
- if (currentX = 732)
- A_Clipboard .= "732-735," currentY " = "
- A_Clipboard .= PixelGetColor(currentX, currentY) ", "
- if (currentX = 735)
- {
- currentX := 732
- A_Clipboard .= "`n"
- break
- }
- else
- ++currentX
- }
- if (currentY = 260)
- break
- else
- ++currentY
- }
- ToolTip("Done")
- }
- these need to skip clicks when the color ΜΆuΜΆnΜΆdΜΆeΜΆr near the cursor is found but also the pixel next to it (the other pixel), to make sure that the resize element is being hovered and not
- something with the same color
- Screen X and color [RESIZE LINE ON THE LEFT]:
- 353, 141414
- 354, 141414
- 355, 3D3D3D
- 356, 3D3D3D
- Screen X, Y and color [RESIZE LINE ON THE RIGHT, MORE COMPLICATED COLORS AT THE TOP]:
- 732, 123
- to
- 735, 260
- RESULTS: check these two pixels when on any of these four pixels (X axes from top to bottom)
- X Y __||__ __||__ __1
- 732-735,123 = 0x0F0F0F, 0x0F0F0F, 0x0F0F0F, 0x0F0F0F,_1
- 732-735,124 = 0x101010, 0x101010, 0x101010, 0x101010,_1
- 732-735,125 = 0x121212, 0x121212, 0x121212, 0x121212,__2!
- 732-735,126 = 0x131313, 0x131313, 0x131313, 0x131313,
- 732-735,127~= 0x131313, 0x131313, 0x131313, 0x131313,__4!
- /732-735,128 = 0x141414, 0x141414, 0x141414, 0x141414,
- 732-735,129 = 0x141414, 0x141414, 0x141414, 0x141414,
- 732-735,130 = 0x141414, 0x141414, 0x141414, 0x141414,
- 732-735,131 = 0x141414, 0x141414, 0x141414, 0x141414,_1!
- /732-735,132~= 0x131313, 0x141414, 0x141414, 0x141414, ..__1!
- 732-735,133 = 0x121212, 0x141414, 0x141414, 0x141414, ___1!
- 732-735,134/=_0x121212,/0x131313,/0x141414,_0x141414, ____126!..
- /732-735,135 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,136 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,137 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,138 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,139 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,140 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,141 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,142 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,143 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,144 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,145 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,146 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,147 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,148 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,149 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,150 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,151 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,152 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,153 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,154 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,155 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,156 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,157 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,158 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,159 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,160 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,161 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,162 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,163 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,164 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,165 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,166 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,167 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,168 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,169 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,170 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,171 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,172 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,173 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,174 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,175 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,176 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,177 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,178 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,179 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,180 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,181 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,182 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,183 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,184 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,185 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,186 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,187 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,188 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,189 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,190 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,191 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,192 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,193 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,194 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,195 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,196 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,197 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,198 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,199 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,200 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,201 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,202 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,203 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,204 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,205 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,206 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,207 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,208 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,209 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,210 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,211 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,212 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,213 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,214 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,215 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,216 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,217 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,218 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,219 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,220 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,221 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,222 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,223 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,224 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,225 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,226 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,227 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,228 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,229 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,230 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,231 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,232 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,233 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,234 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,235 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,236 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,237 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,238 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,239 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,240 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,241 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,242 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,243 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,244 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,245 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,246 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,247 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,248 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,249 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,250 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,251 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,252 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,253 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,254 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,255 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,256 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,257 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,258 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,259 = 0x111111, 0x131313, 0x141414, 0x141414,
- 732-735,260 = 0x111111, 0x131313, 0x141414, 0x141414,
- */
Advertisement
Comments
-
- ;WinSetTransColor is better but here's some WinSetRegion test code:
- #Requires AutoHotkey 2.0
- #SingleInstance Force
- ; --- PART 1: Example Setup (You will replace this with your actual GUI/Window setup) ---
- ; Assume these are your main GUI's (the one that will get the hole) details
- ; These are the screen coordinates and dimensions you used to SHOW your main GUI.
- mainX := 100
- mainY := 100
- mainWidth := 600
- mainHeight := 400
- mainGui := Gui("-Caption")
- mainGui.Title := "Main GUI (Always On Top)"
- mainGui.BackColor := "Gray" ; To clearly see the hole
- mainGui.Opt("+AlwaysOnTop") ; Make it always on top
- mainGui.AddButton("x220 y350 w300", "Refresh e-mails")
- mainGui.Show("x" mainX " y" mainY " w" mainWidth " h" mainHeight)
- ; Assume these are your child window's (the one being covered) details
- ; These are the screen coordinates and dimensions of the window that will define the hole.
- childX := 450
- childY := 400
- childWidth := 300
- childHeight := 150
- childGui := Gui("-Caption")
- childGui.Title := "Child Window (Visible Through Hole)"
- childGui.BackColor := "Navy"
- childGui.Add("Text", "cWhite", "I am the child window!")
- childGui.Show("x" childX " y" childY " w" childWidth " h" childHeight)
- ; Give windows a moment to appear
- Sleep 100
- ; --- PART 2: Core Logic to Create the Hole in mainGui ---
- ; IMPORTANT: Get the *current actual screen position* of the main GUI.
- ; This is important in case it was moved after being shown.
- WinGetPos(&CurrentMainScreenX, &CurrentMainScreenY, &CurrentMainWidth, &CurrentMainHeight, "ahk_id " mainGui.Hwnd)
- ; 1. Calculate the hole's coordinates *relative to the main GUI's top-left corner (0,0)*
- ; The WinSetRegion command expects relative coordinates for both the outer and inner polygons.
- HoleLeftRelative := childX - CurrentMainScreenX
- HoleTopRelative := childY - CurrentMainScreenY
- HoleRightRelative := HoleLeftRelative + childWidth
- HoleBottomRelative := HoleTopRelative + childHeight
- ; 2. Construct the outer polygon string (representing the entire main GUI)
- ; Coordinates are 0-0 up to its current actual width and height.
- OuterPolygonString := "0-0 " CurrentMainWidth "-0 " CurrentMainWidth "-" CurrentMainHeight " 0-" CurrentMainHeight " 0-0"
- ; 3. Construct the inner polygon string (representing the hole)
- InnerPolygonString := ""
- InnerPolygonString .= HoleLeftRelative "-" HoleTopRelative " "
- InnerPolygonString .= HoleRightRelative "-" HoleTopRelative " "
- InnerPolygonString .= HoleRightRelative "-" HoleBottomRelative " "
- InnerPolygonString .= HoleLeftRelative "-" HoleBottomRelative " "
- InnerPolygonString .= HoleLeftRelative "-" HoleTopRelative ; Close the polygon
- ; 4. Combine the outer and inner polygons into the final region string
- RegionStringForWinSetRegion := OuterPolygonString " " InnerPolygonString
- ; 5. Apply the region to your main GUI
- WinSetRegion(RegionStringForWinSetRegion, "ahk_id " mainGui.Hwnd)
- ; --- PART 3: Event Handlers (for clean exit) ---
- mainGui_OnClose() {
- ExitApp
- }
- childGui_OnClose() {
- ExitApp
- }
Add Comment
Please, Sign In to add comment
Advertisement