Problem adding and removing NoActivate on-the-fly Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
TheBeginner
Posts: 91
Joined: 19 Oct 2018, 12:05

Problem adding and removing NoActivate on-the-fly

Post by TheBeginner » 27 Jan 2022, 16:34

I'm trying to change an extended style of the window GUI +E0x08000000 -E0x08000000
the problem is if the caret is already in a component it doesn't work, I need to click on another edit control again for it to work

Am I doing something wrong?

Code: Select all

global MyGuiHwnd

Gui, +HwndMyGuiHwnd
Gui, +AlwaysOnTop +E0x08000000 
Gui Add,Edit, vEdit1 ,  
Gui Add,Edit, vEdit2 , 
Gui Show,  y50 w300 ; NoActivate

Return

g::
WinSet, ExStyle, -0x08000000, % "ahk_id " . MyGuiHwnd ; Add NoActivate
ToolTip, % "Successful? " ErrorLevel
Return

h::
WinSet, ExStyle, +0x08000000, % "ahk_id " . MyGuiHwnd ; Add NoActivate
ToolTip, % "Successful? " ErrorLevel
Return

User avatar
mikeyww
Posts: 26605
Joined: 09 Sep 2014, 18:38

Re: Problem adding and removing NoActivate on-the-fly

Post by mikeyww » 27 Jan 2022, 20:11

One idea is below. It might need some adjustments.

Code: Select all

WS_EX_NOACTIVATE = 0x08000000
Gui, +AlwaysOnTop +E%WS_EX_NOACTIVATE% +HwndhWnd
Gui, Add, Edit, vEdit1
Gui, Add, Edit, vEdit2
Gui, Show, w300 NoActivate

g::
WinSet, ExStyle, -%WS_EX_NOACTIVATE%, ahk_id %hWnd%
SoundBeep, 1500
Return

h::
WinSet, ExStyle, +%WS_EX_NOACTIVATE%, ahk_id %hWnd%
WinGet, win, List
Loop, %win%
 WinGetTitle, ttitle, % winTitle := "ahk_id " win%A_Index%
Until (ttitle > "" && win%A_Index% != hWnd)
WinActivate, %winTitle%
SoundBeep, 1000
Return

TheBeginner
Posts: 91
Joined: 19 Oct 2018, 12:05

Re: Problem adding and removing NoActivate on-the-fly

Post by TheBeginner » 28 Jan 2022, 02:40

Thanks mikeyww, I just tried your solution, but when testing the same problem exists.
when entering an edit component I want to remove the NoActivate and 0x08000000 so it will be possible to enter text into that component
but once you leave the component I want to return the window to a NoActivate +E0x08000000 state

the problem is, although the error level indicates 0 that window still act as NoActivate unless clicking on the Edit1,or Edit2 component a second time
at the code I have so far is

Code: Select all

global MyGuiHwnd

OnMessage( 0x111, "WM_Command" )

Gui, +HwndMyGuiHwnd
Gui, +AlwaysOnTop +E0x08000000 
Gui, Add, Button, gSendABC , ABC
Gui Add,Edit, vEdit1 hwndEC1, 
Gui Add,Edit, vEdit2 hwndEC2, 
Gui Show, y50 w300 NoActivate


Return

WM_Command( wp, lp ) {
    Global EC1,EC2

    If ( (wp >> 16) = 0x100 && ( lp=EC1||lp=EC2 ) ) { ; EN_SETFOCUS 
        
        WinSet, ExStyle, -0x08000000, % "ahk_id " . MyGuiHwnd ; Add NoActivate
        ToolTip, % "0x100 Successful? " ErrorLevel
        
    }

    If ( (wp >> 16) = 0x200 && ( lp=EC1||lp=EC2 ) ) { ; EN_KILLFOCUS 
        WinSet, ExStyle, +0x08000000, % "ahk_id " . MyGuiHwnd ; Add NoActivate
        ToolTip, % "0x200 Successful? " ErrorLevel
    }
}

GuiClose:
ExitApp

SendABC() {
    send ABCABC
}


User avatar
mikeyww
Posts: 26605
Joined: 09 Sep 2014, 18:38

Re: Problem adding and removing NoActivate on-the-fly

Post by mikeyww » 28 Jan 2022, 06:37

So what is the actual effect that you are trying to achieve other than AHK's own NoActivate option?

Code: Select all

Gui, +AlwaysOnTop
Gui, Add,Edit, vEdit1 hwndEC1
Gui, Add,Edit, vEdit2 hwndEC2
Gui, Show, y50 w300 NoActivate
What the script does: "It will be possible to enter text into that component [control], but once you leave the component [control], I want to return the window to a NoActivate... state." Is your script meant to block other controls that are not part of your posted script?

I do see the issue that you raised. It seems to have something to do with what is happening with OnMessage or the WinSet, as the GUI itself cannot be moved until clicked a second time. Sorry I did not come up with a solution. Others here probably know the answer.

The following demonstration also illustrates the problem. The resolution of your issue in your script would seem to lie in the resolution of the same issue in this demonstration. Interesting to note that this script does not contain any WinSet command.

Code: Select all

Gui, +AlwaysOnTop
Gui, Add, Edit, w250 hwndEC1
Gui, Add, Edit, wp   hwndEC2
Gui, Show,, Test
OnMessage(0x111, "WM_COMMAND")
Return

WM_COMMAND( wp, lp ) {
 Global
 If (lp != EC1 && lp != EC2)
  Return
 Switch wp >> 16 {
  Case 0x100: SoundBeep, 1500
 }
}
A workaround could be to set a timer instead of using the OnMessage.

TheBeginner
Posts: 91
Joined: 19 Oct 2018, 12:05

Re: Problem adding and removing NoActivate on-the-fly

Post by TheBeginner » 28 Jan 2022, 12:00

So what is the actual effect that you are trying to achieve other than AHK's own NoActivate option?
Note that I have a mix of buttons and edit Controls the buttons require no activate like the one I've left in the previous code, they just sent a bunch of text
Sometimes I need to use controls to enter some information, shat's why I need to deactivate it when a control is in focus and remove it when a control is out of focus

The following demonstration also illustrates the problem. The resolution of your issue in your script would seem to lie in the resolution of the same issue in this demonstration. Interesting to note that this script does not contain any WinSet command.
Yes, that's strange,
and haven't been able to figure it out

User avatar
mikeyww
Posts: 26605
Joined: 09 Sep 2014, 18:38

Re: Problem adding and removing NoActivate on-the-fly

Post by mikeyww » 28 Jan 2022, 12:44

I still do not entirely understand the need for the intended functionality, but OK. I imagine that someone on the forum will have the explanation about WM_COMMAND.

If helpful, note that you can create a GUI control that is hidden. You can then activate it if needed. That might still not help you in resolving the issue.

TheBeginner
Posts: 91
Joined: 19 Oct 2018, 12:05

Re: Problem adding and removing NoActivate on-the-fly

Post by TheBeginner » 29 Jan 2022, 04:02

i still do not entirely understand the need for the intended functionality, but OK.
Maybe that's part of the issue, was there anything in particular that you found unclear in the way I described what I'm trying to accomplish?
Because there might be another way to solve the same problem if the description of the issues clearer.

I'll try and phrase it another way

My main program window is set to NoActivate, that interface includes mostly buttons, those buttons send strings to the active window when clicked
I want to add to that interface edit components so I can modify the strings that will be sent when clicking the buttons.
The problem is when the window is set to NoActivate typing in the edit component passes through to the active window (the expected behavior), so what I'm trying to do is make those edit components active again temporarily when I enter text in them.

Hopefully I have explained it better, since maybe there is a different way to do that
haven't been able to solve it yet

TheBeginner
Posts: 91
Joined: 19 Oct 2018, 12:05

Re: Problem adding and removing NoActivate on-the-fly  Topic is solved

Post by TheBeginner » 29 Jan 2022, 04:48

Found a solution, there is this class by tmplinshi, that builds on this article
http://www.codeproject.com/Articles/32563/Virtual-On-Screen-Keyboard-Example
It uses a different onMessage approach not the focus / kill focus messages

Source
viewtopic.php?t=7611

In case it's lost

Code: Select all

/*
	Makes the Gui window NoActivate but Clickable
	
	Usage: 
		Gui_NoActivate(GuiHwnd, EnableEdit := False, Disable_RButton := False)

	Parameters:
		GuiHwnd    - The Gui's hwnd
		EnableEdit - True or False (default). Whether activates the GUI when an Edit Control is focused.
		Disable_RButton - True or False (default)
*/
Gui_NoActivate(p*) {
	Gui_NoActivate.Apply(p*)
}

Class Gui_NoActivate {
	static WS_EX_NOACTIVATE := 0x08000000

	Apply(GuiHwnd, EnableEdit := False, Disable_RButton := False) {
		Gui, %GuiHwnd%: +LastFound ; WinTitle is not working for WinSet
		WinSet, ExStyle, % "+" this.WS_EX_NOACTIVATE

		OnMessage( 0xA1, ObjBindMethod(this, "WM_NCLBUTTONDOWN") )
		OnMessage( 0xA0, ObjBindMethod(this, "WM_NCMOUSEMOVE")   )
		If EnableEdit {
			OnMessage( 0x06, ObjBindMethod(this, "WM_ACTIVATE") )
			OnMessage( 0x201, ObjBindMethod(this, "WM_LBUTTONDOWN") )
		}
		If Disable_RButton
			OnMessage( 0x204, ObjBindMethod(this, "Disable_RButton") ) ; WM_RBUTTONDOWN

		this.GuiHwnd := GuiHwnd
	}

	; Remove WS_EX_NOACTIVATE style, when Gui is dragging
	WM_NCLBUTTONDOWN(wParam, lParam, msg, hwnd) {
		this.pre_hForegroundWnd := msg ? DllCall("GetForegroundWindow") : ""
		WinSet, ExStyle, % "-" this.WS_EX_NOACTIVATE, ahk_id %hwnd%
		DllCall("SetForegroundWindow", "Uint", hwnd)
	}

	; Re-add WS_EX_NOACTIVATE style, when Gui is dragging finished
	WM_NCMOUSEMOVE() {
		If !this.pre_hForegroundWnd || GetKeyState("LButton", "P")
			Return
		WinSet, ExStyle, % "+" this.WS_EX_NOACTIVATE, % "ahk_id " this.GuiHwnd
		DllCall("SetForegroundWindow", "Uint", this.pre_hForegroundWnd)
		this.pre_hForegroundWnd := ""
	}

	; Detect if clicked on an edit control
	WM_LBUTTONDOWN(wParam, lParam, msg, hwnd) {
		SendMessage, 0x00BA, 0, 0,, ahk_id %hwnd% ; EM_GETLINECOUNT = 0x00BA
		If (errorLevel > 0) {
			this.WM_NCLBUTTONDOWN(0, 0, 0, this.GuiHwnd) ; Activate the Gui window
			this.WinWaitNotActive := True
		}
	}

	WM_ACTIVATE(wParam) {
		If this.WinWaitNotActive && (wParam = 0) { ; Gui is deactivated
			this.WinWaitNotActive := ""
			WinSet, ExStyle, % "+" this.WS_EX_NOACTIVATE, % "ahk_id " this.GuiHwnd
		}
	}

	Disable_RButton() {
		Return 0
	}
}

Code: Select all

Gui, +AlwaysOnTop +HwndhGui
Gui, Add, Button,    w150 gSendChr, a
Gui, Add, Button, ys wp   gSendChr, h
Gui, Add, Button, ys wp   gSendChr, k
Gui, Show, NA, On Screen Keyboard Demo
Gui_NoActivate(hGui)
Return

SendChr:
	k := GetKeyState("CapsLock", "T") ? Format("{:U}", A_GuiControl) : A_GuiControl
	SendInput, % "{" k "}"
Return

#Include Gui_NoActivate.ahk

User avatar
mikeyww
Posts: 26605
Joined: 09 Sep 2014, 18:38

Re: Problem adding and removing NoActivate on-the-fly

Post by mikeyww » 29 Jan 2022, 06:54

Looks cool. Thanks for sharing the solution. :thumbup:

amateur+
Posts: 655
Joined: 09 Oct 2021, 15:43

Re: Problem adding and removing NoActivate on-the-fly

Post by amateur+ » 29 Jan 2022, 07:04

I've also stolen it to my library :).
Have found any drawback in my code or approach? Please, point it out. /The moderator ordered to remove the rest of the signature, I had obeyed.
And I really apologize for our russian president. Being a citizen of an aggressor country is very shameful. Personally I tried to avoid this trying to defend elections from fraud being a member of the election commission of one of the precincts but only was subjected to a hooligan attack and right before the vote count was illegally escorted from the polling station and spent the night behind bars (in jail) in a result of illegal actions of corrupt policemen.

Post Reply

Return to “Ask for Help (v1)”