Problem with WinSet, Style with previously determined style Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
hoppfrosch
Posts: 443
Joined: 07 Oct 2013, 04:05
Location: Rhine-Maine-Area, Hesse, Germany
Contact:

Problem with WinSet, Style with previously determined style

04 Apr 2017, 06:26

I'm trying to get a windows style and later on to apply this style to another window. Here's my simplified example:

Code: Select all

Run notepad.exe,,, oPID
WinWait ahk_pid %oPID%
hWnd := WinExist("ahk_pid" oPID)
WinGet, origStyle, Style, ahk_id %hwnd%
WinKill, ahk_id %hwnd%

MsgBox % "Original Style was <" origStyle ">"

Run notepad.exe,,, oPID2
WinWait ahk_pid %oPID2%
hWnd2 := WinExist("ahk_pid" oPID2)
try {
	WinSet, Style, %origStyle%, ahk_id %hwnd2%
} catch e {
	MsgBox % e.File "`n" e.what "`n" e.Message	
}
WinKill, ahk_id %hwnd2%
Running this example an exception is thrown.
:?: Why? What does this exception mean?


-----
AutoHotkey : v1.1.25.01 Unicode 32-bit (Installed)
SystemOS : WIN_7 64-bit Service Pack 1 v6.1.7601 (WIN32_NT)
Last edited by hoppfrosch on 04 Apr 2017, 07:00, edited 1 time in total.
Guest

Re: Problem with WinSet, Style with previously determined style

04 Apr 2017, 06:57

Not sure but perhaps 0x14CF0000 is not a valid value for style and it should be "translated" see a discussion here https://autohotkey.com/board/topic/2904 ... -am/page-2
User avatar
hoppfrosch
Posts: 443
Joined: 07 Oct 2013, 04:05
Location: Rhine-Maine-Area, Hesse, Germany
Contact:

Re: Problem with WinSet, Style with previously determined style

04 Apr 2017, 07:45

Guest wrote:Not sure but perhaps 0x14CF0000 is not a valid value for style and it should be "translated"
If this is the case, I would consider this as a "bug": the command WinGet should return a value by default, which is a valid input value for WinSet ...

What's the correct way to set the window style of a window exactly to the style of another window?
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Problem with WinSet, Style with previously determined style

04 Apr 2017, 10:15

Which style are you trying to get? ;) What you get is a combination of all styles.
This is my guess,

Code: Select all

style:=0x14CF0000 
styles:=[]
while style
	if (style & 2**(A_Index))
		styles.push(2**A_Index), style^=2**A_Index
for k, v in styles
	str.= format("0x{:x}",v)  "`n" 
MsgBox, % str
I dont know why you get an error, errorlevel is 0.
Cheers.
User avatar
hoppfrosch
Posts: 443
Joined: 07 Oct 2013, 04:05
Location: Rhine-Maine-Area, Hesse, Germany
Contact:

Re: Problem with WinSet, Style with previously determined style

04 Apr 2017, 23:42

Helgef wrote:Which style are you trying to get? ;) What you get is a combination of all styles.
I'm aware of this. I thought my central question was clear - but it wasn't:

What's the correct way to set all styles (WS_XXXX) of one window exactly to the same styles of another window?

This question arose, when I tried to stored "properties" (Position, size, styles, stylesEX, etc.) of a single window. Later on I tried to recreate a window with exactly the same properties ...
Helgef wrote:I dont know why you get an error, errorlevel is 0.
Good question ... at least my program ends ungracefully if there's no exception handling, If there's exception handling, an exception is caught.
just me
Posts: 9453
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Problem with WinSet, Style with previously determined style

05 Apr 2017, 00:55

Code: Select all

Run notepad.exe,,, oPID
WinWait ahk_pid %oPID%
hWnd := WinExist("ahk_pid" oPID)
WinGet, origStyle, Style, ahk_id %hwnd%
WinKill, ahk_id %hwnd%

MsgBox % "Original Style was <" origStyle ">"

Run notepad.exe,,, oPID2
WinWait ahk_pid %oPID2%
hWnd2 := WinExist("ahk_pid" oPID2)
WinSet, Style, %origStyle%, ahk_id %hwnd2%
MsgBox, ErrorLevel: %ErrorLevel%
; try {
; 	WinSet, Style, %origStyle%, ahk_id %hwnd2%
; } catch e {
; 	MsgBox % e.File "`n" e.what "`n" e.Message "`n" e.extra
; }
WinKill, ahk_id %hwnd2%
Brings up "ErrorLevel: 1" here.
WinSet, Style wrote:ErrorLevel is set to 1 upon failure and 0 upon success. Failure occurs if the target window is not found or the style is not allowed to be applied.
Some styles cannot be 'changed' after the window has been created.
User avatar
hoppfrosch
Posts: 443
Joined: 07 Oct 2013, 04:05
Location: Rhine-Maine-Area, Hesse, Germany
Contact:

Re: Problem with WinSet, Style with previously determined style

05 Apr 2017, 02:16

just me wrote:
WinSet, Style wrote:ErrorLevel is set to 1 upon failure and 0 upon success. Failure occurs if the target window is not found or the style is not allowed to be applied.
Some styles cannot be 'changed' after the window has been created.
I 've already seen this - but how can I separate the styles which can/cannot be applied from a WinGet, Style .... returned style? Which are the styles which cannot be applied? Is there any further documentation on this anywhere?
just me
Posts: 9453
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Problem with WinSet, Style with previously determined style

05 Apr 2017, 02:19

I don't know. Try to set single style bits and see if it is working.

Edit:

Code: Select all

0x14CF0000

0x10000000 - WS_VISIBLE
0x04000000 - WS_CLIPSIBLINGS

0x00400000 - WS_BORDER
0x00800000 - WS_DLGFRAME
----------
0x00C00000 - WS_CAPTION

0x00010000 - WS_TABSTOP
0x00020000 - WS_MINIMIZEBOX
0x00040000 - WS_SIZEBOX
0x00080000 - WS_SYSMENU
----------
0x00CF0000 - WS_OVERLAPPEDWINDOW
User avatar
hoppfrosch
Posts: 443
Joined: 07 Oct 2013, 04:05
Location: Rhine-Maine-Area, Hesse, Germany
Contact:

Re: Problem with WinSet, Style with previously determined style

05 Apr 2017, 02:36

Thx for your support - I came up with the following:

Code: Select all

Run notepad.exe,,, oPID
WinWait ahk_pid %oPID%
hWnd := WinExist("ahk_pid" oPID)
WinGet, origStyle, Style, ahk_id %hwnd%
WinKill, ahk_id %hwnd%

MsgBox % "Original Style was <" origStyle ">"

styles:=[]
while origStyle
	if (origStyle & 2**(A_Index))
		styles.push(2**A_Index), origStyle^=2**A_Index

Run notepad.exe,,, oPID2
WinWait ahk_pid %oPID2%
hWnd2 := WinExist("ahk_pid" oPID2)
		
strNot := ""
strSet := ""
for k, v in styles {
	str := format("0x{:x}",v) 
	try {
		WinSet, Style, %str%, ahk_id %hwnd2%
		strSet .= str "`n"
	} catch e {
		strNot .= str "`n"
	}
}
WinKill, ahk_id %hwnd2%
MsgBox % "Styles which have been set:`n" strSet "Style NOT set:`n" strNot
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Problem with WinSet, Style with previously determined style

05 Apr 2017, 02:39

hoppfrosch wrote:I thought my central question was clear
Maybe my reading wasn't clear ;)
just me wrote:Brings up "ErrorLevel: 1" here.
It seems it either throws an error (in if try block) or sets errorlevel (if not in try block).
hoppfrosch wrote:Which are the styles which cannot be applied? Is there any further documentation on this anywhere?
Window Styles wrote: Window Styles
The following are the window styles. After the window has been created, these styles cannot be modified, except as noted.
Source
Cheers!

Edit:
hoppfrosch wrote: I came up with the following:
:thumbup:
just me
Posts: 9453
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Problem with WinSet, Style with previously determined style

05 Apr 2017, 02:53

@Helgef, thanks for the link, I didn't remember.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Problem with WinSet, Style with previously determined style

05 Apr 2017, 03:01

just me wrote:@Helgef, thanks for the link, I didn't remember.
Np.
Also, note the link to the ExStyles. There is no mention (at the top of the page) of those styles not being changable after the window is created, I didn't read all descriptions though. So hopefully those styles are easier to work with.

Finally, @hoppfrosch, make sure you use the latest version of ahk, to avoid further inconvenience, since there was recently a bug fix for winset.
User avatar
hoppfrosch
Posts: 443
Joined: 07 Oct 2013, 04:05
Location: Rhine-Maine-Area, Hesse, Germany
Contact:

Re: Problem with WinSet, Style with previously determined style

05 Apr 2017, 03:20

Hmmm - my solution above isn't what I hoped for ...even more problems occured, Running the solution the output looks like this:
komodo_2017-04-05_09-47-30.png
komodo_2017-04-05_09-47-30.png (31.39 KiB) Viewed 3567 times
As you can see, my notepad-window does not have an border, no captionbar, no minimizebox, etc. anymore after applying the "new" styles - unless the script opened a normal notepad window, having all the styles before applying the "new" styles.

Any ideas?
Last edited by hoppfrosch on 05 Apr 2017, 03:25, edited 1 time in total.
User avatar
hoppfrosch
Posts: 443
Joined: 07 Oct 2013, 04:05
Location: Rhine-Maine-Area, Hesse, Germany
Contact:

Re: Problem with WinSet, Style with previously determined style

05 Apr 2017, 03:23

Helgef wrote: Finally, @hoppfrosch, make sure you use the latest version of ahk, to avoid further inconvenience, since there was recently a bug fix for winset.
I usually update AutoHotkey as soon as possible - currently I'm using AutoHotkey : v1.1.25.01 Unicode 32-bit
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Problem with WinSet, Style with previously determined style

05 Apr 2017, 03:29

hoppfrosch wrote:Any ideas?
Maybe use the + option for the style to apply it, eg, WinSet,Style, +SOME_STYLE, .... Without the + you would set the style to be just SOME_STYLE.
User avatar
hoppfrosch
Posts: 443
Joined: 07 Oct 2013, 04:05
Location: Rhine-Maine-Area, Hesse, Germany
Contact:

Re: Problem with WinSet, Style with previously determined style

05 Apr 2017, 03:58

Helgef wrote:Maybe use the + option for the style to apply it, eg, WinSet,Style, +SOME_STYLE, .... Without the + you would set the style to be just SOME_STYLE.
Yes this helps in the example above. Thanks.

But my problem isn't solved yet completly: What if I removed a style in the original Window?

Modification from above Solution:

Code: Select all

Run notepad.exe,,, oPID
WinWait ahk_pid %oPID%
hWnd := WinExist("ahk_pid" oPID)
; #####################
; Remove a style
WinSet, Style, -0x20000, ahk_id %hwnd%
; #####################
WinGet, origStyle, Style, ahk_id %hwnd%

MsgBox % "Original Style was <" origStyle ">"

WinKill, ahk_id %hwnd%


styles:=[]
while origStyle
	if (origStyle & 2**(A_Index))
		styles.push(2**A_Index), origStyle^=2**A_Index

Run notepad.exe,,, oPID2
WinWait ahk_pid %oPID2%
hWnd2 := WinExist("ahk_pid" oPID2)

Sleep 2000

strNot := ""
strSet := ""
for k, v in styles {
	str := format("0x{:x}",v) 
	str := "+" str
	try {
		WinSet, Style, %str%, ahk_id %hwnd2%
		strSet .= str "`n"
	} catch e {
		strNot .= str "`n"
	}
}
WinKill, ahk_id %hwnd2%
MsgBox % "Styles which have been set:`n" strSet "Style NOT set:`n" strNot 
As you see I remove a style (MINIMIZEBOX) from the original notepad - how can I determine which styles have to be removed in the second notepad?

There seems to be some math needed - have to think about it. :think:
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Problem with WinSet, Style with previously determined style

05 Apr 2017, 04:38

Try this, I added some ; added comments :D

Code: Select all

;	https://autohotkey.com/boards/viewtopic.php?p=141176#p141176
;	Problem with WinSet, Style with previously determined style - AutoHotkey Community - Opera

Run notepad.exe,,, oPID
WinWait ahk_pid %oPID%
hWnd := WinExist("ahk_pid" oPID)
; #####################
; Remove a style
WinSet, Style, -0x20000, ahk_id %hwnd%
;WinSet, Style, -0xC00000, ahk_id %hwnd%								; Added for test, removing caption (This is a combination of two styles it seems)
; #####################
WinGet, origStyle, Style, ahk_id %hwnd%

MsgBox % "Original Style was <" origStyle ">"

WinKill, ahk_id %hwnd%


styles:=styleSplit(origStyle) 											; Added function

Run notepad.exe,,, oPID2
WinWait ahk_pid %oPID2%
hWnd2 := WinExist("ahk_pid" oPID2)

; Get the new styles
WinGet, origStyleNewNotepad, Style, ahk_id %hwnd2%									; Added	
stylesToRemove:= stylesDiff(origStyleNewNotepad,origStyle)  						; Determine styles in the new notepad, not present in the first.


Sleep 2000

strNot := ""
strSet := ""
for k, v in styles {
	str := format("0x{:x}",v) 
	str := "+" str
	try {
		WinSet, Style, %str%, ahk_id %hwnd2%
		strSet .= str "`n"
	} catch e {
		strNot .= str "`n"
	}
}
for k, style in stylesToRemove {										; Added
	str := format("-0x{:x}",style) 
	try {
		WinSet, Style, % -style, % "ahk_id " hwnd2
		strRemoved.= str  "`n" 
	} catch e {
		strRemovedFail.= str  "`n" 
	}
}
Sleep, 2000														; Added
WinKill, ahk_id %hwnd2%
MsgBox % "Styles which have been set:`n" strSet "Style NOT set:`n" strNot 
MsgBox % "Styles which have been removed from the new notepad:`n" strRemoved "Style failed to be removed:`n" strRemovedFail ; Added

; Added functions
stylesDiff(st1,st2){
	; Returns those styles present in st1 but not st2
	return styleSplit((st1 ^ st2) & st1)
}

styleSplit(styles){
	; A measure against inf loop should be taken.
	stylesArr:=[]
	while styles
		if (styles & 2**(A_Index))
			stylesArr.push(2**A_Index), styles^=2**A_Index
	return stylesArr
}
User avatar
hoppfrosch
Posts: 443
Joined: 07 Oct 2013, 04:05
Location: Rhine-Maine-Area, Hesse, Germany
Contact:

Re: Problem with WinSet, Style with previously determined style  Topic is solved

05 Apr 2017, 05:22

@helgef - Thanks! I'll give it a try.

I came up with the following solution (needs to be polished):

Code: Select all

; Create a test window, modify the style - this is the original style to be reconstructed
Run notepad.exe,,, oPID
WinWait ahk_pid %oPID%
hWnd := WinExist("ahk_pid" oPID)
WinSet, Style, -0x20000, ahk_id %hwnd%  ; Remove a style (MinimizeBox)
WinGet, origStyle, Style, ahk_id %hwnd%

origStyles := SplitHex(origStyle)

Str := "Original Style was <" origStyle ">`n"
for k, v in origstyles {
	hex := format("0x{:x}",k) 
	Str .= hex " "
}

WinKill, ahk_id %hwnd%

; ##############################################################################
; Create a new window, modify the style - on this window has to be applied the original style
Run notepad.exe,,, oPID2
WinWait ahk_pid %oPID2%
hWnd2 := WinExist("ahk_pid" oPID2)
WinSet, Style, -0x800000, ahk_id %hwnd2%  ; Remove a style (Border)
WinGet, currStyle, Style, ahk_id %hwnd2%

currStyles := SplitHex(currStyle)

Str .= "`n`nCurrent Style is <" currStyle ">`n"
for k, v in currStyles {
	hex := format("0x{:x}",k) 
	Str .= hex " "
}


; ##############################################################################
; Determine the differences between the scurrent style and original style 
modStyles := []

Str .= "`n`nStyle-Modifications: "
for k, v in currStyles {
  ; Styles which are in current window, but not in original have to be REMOVED
	if (!origStyles.HasKey(k)) {
		modStyles[k] := "-" ; Save the sign - style has to be removed!
		
		hex := format("0x{:x}",k) 
		Str .= "-" hex 
	}
}
for k, v in origStyles {
	; Styles which are in original window, but not in current have to be ADDED
	if (!currStyles.HasKey(k)) {
		modStyles[k] := "+"  ; Save the sign - style has to be added!
		hex := format("0x{:x}",k) 
		Str .= "+" hex 
	}
}

	
; Apply the style differences
for k, v in modStyles {
	hex := format("0x{:x}",k) 
	hex := v hex
	try {
		WinSet, Style, %hex%, ahk_id %hwnd2%
		strSet .= hex " "
	} catch e {
		strNot .= hex " "
	}
}
str .= "`n`nStyles which have been set: " strSet "`nStyles NOT set: " strNot

WinGet, finalStyle, Style, ahk_id %hwnd2%

finalStyles := SplitHex(finalStyle)

Str .= "`n`nFinal Style is <" finalStyle ">`n"
for k, v in finalStyles {
	hex := format("0x{:x}",k) 
	Str .= hex " "
}
MsgBox % str

WinKill, ahk_id %hwnd2%

ExitApp

; Split a number into its single bits
SplitHex(hex) {
	obj:=[]
	while hex {
		if (hex & 2**(A_Index)) {
			obj[2**A_Index] := "+"
			hex^=2**A_Index
		}
	}
	return obj
} 
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Problem with WinSet, Style with previously determined style

05 Apr 2017, 06:25

Nice hoppfrosch. Just too be on the safe side, you might want to modify yourSplitHex(hex) function to something like this,

Code: Select all

SplitHex(hex) {
	obj:=[]
	while hex && A_Index < 65 { ; Added second condition to avoid inf-loop in case, eg splithex(1) is called.
		if (hex & 2**(A_Index)) {
			obj[2**A_Index] := "+"
			hex^=2**A_Index
		}
	}
	return obj
} 
Cheers.
User avatar
hoppfrosch
Posts: 443
Joined: 07 Oct 2013, 04:05
Location: Rhine-Maine-Area, Hesse, Germany
Contact:

Re: Problem with WinSet, Style with previously determined style

05 Apr 2017, 08:30

Thanks - I will add this to my function!

Now I have at least a working solution to be integrated into my library (restoring window properties on reopening a window) - unless I would have preferred an easy "Use simply the output of WinGet, Style ... as input for WinSet, Style ..." ;-)

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: No registered users and 247 guests