Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

[Solved]DLLCall(SetParent) problems with displaying windows


  • Please log in to reply
5 replies to this topic
Zed Gecko
  • Members
  • 149 posts
  • Last active:
  • Joined: 23 Sep 2006
When i display other top-level windows in an AHK-GUI,
severe displaying/redrawing problems occur on the contained windows.
The happen randomly
when either the contained or the containing windows are resized, minimized or restored.

i tried several workarounds (e.g Winset, Redraw or adding the WS_CHILD-style to the contained windows) but nothing solved this problem completely.

this script "adds" other windows to it´s own GUI,
when you Ctrl-Click on the windows TitleBar.
It "releases" them when close the AHK-GUI.
Pressing Ctrl+1 will start some of the fixes i tried:
;Gui, 1: +E0x00010000L
Gui, 1: Show, x0 y0 w800 h600
Gui, 1: +LastFound
GUI_id := WinExist()
return

~^LButton:: ;add the window under the mouse to the ahk-GUI
hk_result =
CoordMode, Mouse, Screen
MouseGetPos, hk_x, hk_y, hk_id, hk_control
if IsOverTitleBar(hk_x, hk_y, hk_id)
{
	hk_result := Set_Parent(hk_id, GUI_id)
	if (hk_result = "")
		return
	else
	{
;		WinSet, Style, +0x40000000,  ahk_id %hk_id%
		capturelist .= hk_id . "-" . hk_result . "`n`r"
		Gui, 1: Show
	}
}
return


^1:: ; try to fix the redrawing problem
Winset, Redraw, , ahk_id %GUI_id%
tmp_cl_1 =
tmp_cl_2 =
loop, parse, capturelist, `n, `r 
{
	StringSplit, tmp_cl_, A_LoopField, -,
	Winset, Redraw, , ahk_id %tmp_cl_1%
;	WinHide, ahk_id %tmp_cl_1%
;	WinShow, ahk_id %tmp_cl_1%
}
return


Set_Parent(Child_Handle, Parent_Handle) 
{
  
  Return DllCall( "SetParent", "uint", Child_Handle, "uint", Parent_Handle ) ; success = handle to previous parent, failure =null
}

IsOverTitleBar(x, y, hWnd)
{
   SendMessage, 0x84,, (x & 0xFFFF) | (y & 0xFFFF) << 16,, ahk_id %hWnd%
   if ErrorLevel in 2,3,8,9,20,21
      return true
   else
      return false
}

GuiClose:
tmp_cl_1 =
tmp_cl_2 =
loop, parse, capturelist, `n, `r 
{
	StringSplit, tmp_cl_, A_LoopField, -,
;	WinSet, Style, -0x40000000,  ahk_id %tmp_cl_1%
	Set_Parent(tmp_cl_1, tmp_cl_2)
}
ExitApp
return

Does anybody know, why it happens or how it can be solved?
(i´m running on Win2K here, not tested on other versions)
code removed due to protest.
http://www.autohotke...pic.php?t=81795

Z_Gecko
  • Guests
  • Last active:
  • Joined: --
i also tried:
assign the WS_CLIPCHILDREN style to the ahk_GUI
sending the WM_PAINT Message to the contained windows
assign the WM_CHILD style to the contained windows
all without success.

I´m out of options now and still got no clue.

Z_Gecko
  • Guests
  • Last active:
  • Joined: --
impatient *BUMP*

YMP
  • Members
  • 424 posts
  • Last active: Apr 05 2012 01:18 AM
  • Joined: 23 Dec 2006

i also tried:
assign the WS_CLIPCHILDREN style to the ahk_GUI

For me on XP SP2, WS_CLIPCHILDREN seems to solve the problem. Without that, the child is apparently painted over.
;Gui, 1: +E0x00010000L 
Gui, +0x2000000               ; +WS_CLIPCHILDREN
Gui, 1:Show, x0 y0 w800 h600
Gui, 1:+LastFound 
GUI_id := WinExist() 
return 


Z_Gecko
  • Guests
  • Last active:
  • Joined: --

For me on XP SP2, WS_CLIPCHILDREN seems to solve the problem.

thanks, that is interesting.
I will try to find me a XP-machine myself to try this out.
Does someone know why or how this happens.

And could someone test the script on other windows versions, please.

Zed Gecko
  • Members
  • 149 posts
  • Last active:
  • Joined: 23 Sep 2006
i finally got it to work properly:
; http://support.microsoft.com/kb/112181/en-us/
Gui, 1: [color=red]+0x16000000[/color] +Resize
;Gui, 1: +0x02000000L +Resize
Gui, 1: Show, x0 y0 w800 h600
Gui, 1: +LastFound
GUI_id := WinExist()
return

~^LButton::
hk_result =
CoordMode, Mouse, Screen
MouseGetPos, hk_x, hk_y, hk_id, hk_control
if IsOverTitleBar(hk_x, hk_y, hk_id)
{
	hk_result := Set_Parent(hk_id, GUI_id)
	if (hk_result = "")
		return
	else
	{
;		WinSet, Style, +0x40000000,  ahk_id %hk_id%
		capturelist .= hk_id . "-" . hk_result . "`n`r"
;		Gui, 1: Show
	}
}
return


^1::
Winset, Redraw, , ahk_id %GUI_id%
tmp_cl_1 =
tmp_cl_2 =
loop, parse, capturelist, `n, `r 
{
	if (A_LoopField = "")
		break
	StringSplit, tmp_cl_, A_LoopField, -,
	SendMessage, 0x0F, , , , ahk_id %tmp_cl_1% ; send WM_PAINT	
	Winset, Redraw, , ahk_id %tmp_cl_1%
;	WinHide, ahk_id %tmp_cl_1%
;	WinShow, ahk_id %tmp_cl_1%
}
;Winset, Redraw, , ahk_id %GUI_id%
Gui, 1: Restore
return


Set_Parent(Child_Handle, Parent_Handle) 
{
  
  Return DllCall( "SetParent", "uint", Child_Handle, "uint", Parent_Handle ) ; success = handle to previous parent, failure =null
}

IsOverTitleBar(x, y, hWnd)
{
   SendMessage, 0x84,, (x & 0xFFFF) | (y & 0xFFFF) << 16,, ahk_id %hWnd%
   if ErrorLevel in 2,3,8,9,20,21
      return true
   else
      return false
}

GuiClose:
tmp_cl_1 =
tmp_cl_2 =
loop, parse, capturelist, `n, `r 
{
	if (A_LoopField = "")
		break
	StringSplit, tmp_cl_, A_LoopField, -,
;	WinSet, Style, -0x40000000,  ahk_id %tmp_cl_1%
	Set_Parent(tmp_cl_1, tmp_cl_2)
}
ExitApp
return

googling for WS_CLIPCHILDREN i found this page: http://support.micro...b/112181/en-us/
it says:

NOTE: Microsoft recommends that you always include the WS_VISIBLE, WS_CLIPSIBLINGS, and WS_CLIPCHILDREN styles in the new value. This means the value of nVal would always be at least 0x16000000.

And exactly this did the trick.
code removed due to protest.
http://www.autohotke...pic.php?t=81795