Page 1 of 1
Problem adding and removing NoActivate on-the-fly
Posted: 27 Jan 2022, 16:34
by TheBeginner
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
Re: Problem adding and removing NoActivate on-the-fly
Posted: 27 Jan 2022, 20:11
by mikeyww
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
Re: Problem adding and removing NoActivate on-the-fly
Posted: 28 Jan 2022, 02:40
by TheBeginner
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
}
Re: Problem adding and removing NoActivate on-the-fly
Posted: 28 Jan 2022, 06:37
by mikeyww
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.
Re: Problem adding and removing NoActivate on-the-fly
Posted: 28 Jan 2022, 12:00
by TheBeginner
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
Re: Problem adding and removing NoActivate on-the-fly
Posted: 28 Jan 2022, 12:44
by mikeyww
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.
Re: Problem adding and removing NoActivate on-the-fly
Posted: 29 Jan 2022, 04:02
by TheBeginner
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
Re: Problem adding and removing NoActivate on-the-fly Topic is solved
Posted: 29 Jan 2022, 04:48
by TheBeginner
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
Re: Problem adding and removing NoActivate on-the-fly
Posted: 29 Jan 2022, 06:54
by mikeyww
Looks cool. Thanks for sharing the solution.
Re: Problem adding and removing NoActivate on-the-fly
Posted: 29 Jan 2022, 07:04
by amateur+
I've also stolen it to my library
.