Page 1 of 2
Using ActiveX Control
Posted: Tue Mar 09, 2010 11:28 pm
by univeda
I try to embed a rdp-client activex-control (mstscax) into my purebasic-app.
Code: Select all
IncludePath "inc\"
XIncludeFile "COMatePLUS.pbi"
Define.COMateObject rdpObject
If OpenWindow(0, 0, 0, 600, 600, "rdpObject", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget)
rdpObject = Comate_CreateActiveXControl(0, 0, 600, 600, "mstscax.mstscax")
If rdpObject
rdpObject\SetProperty("DisconnectedText = 'Verbindung wurde getrennt.'")
rdpObject\SetProperty("ConnectingText = 'Verbindung wird aufgebaut. Bitte warten...'")
rdpObject\SetProperty("Server = 'my_server_hostname'")
rdpObject\SetProperty("Domain = 'my_server_logondomain")
rdpObject\SetProperty("UserName = 'my_username'")
rdpObject\SetProperty("AdvancedSettings2.ClearTextPassword = 'my_password'")
rdpObject\Invoke("Connect()")
While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
CloseWindow(0)
rdpObject\Release()
Else
MessageRequester("rdpObject", "Couldn't create the ActiveX object!")
EndIf
EndIf
This works fine, so far. But the password is not transfered to the rdpObject.
Code: Select all
rdpObject\SetProperty("AdvancedSettings2.ClearTextPassword = 'my_password'")
I'm using this property in other languages like AutoIt and C# without problems.
Anyone with experience in using this kind of ActiveX-Control with PB?
Re: Using ActiveX Control
Posted: Wed Mar 10, 2010 12:39 am
by Kiffi
univeda wrote:Code: Select all
rdpObject\SetProperty("AdvancedSettings2.ClearTextPassword = 'my_password'")
try this:
Code: Select all
rdpObject\SetProperty("AdvancedSettings2\ClearTextPassword = 'my_password'")
(replace the point with a backslash)
Greetings ... Kiffi
Re: Using ActiveX Control
Posted: Wed Mar 10, 2010 8:30 pm
by univeda
Thanks, Kiffi. This made the job! Works perfect.
Re: Using ActiveX Control
Posted: Mon Mar 15, 2010 8:49 am
by univeda
After fixing the password-problem (thanks, kiffi), there is another one:
When i move my Windows with the embedded rdp-activeX-Control, some parts of the rdp-desktop disappear. It looks like some kind of clipping error. I realized this program already in autoIt, but how can i adapt this code to purebasic?
Code: Select all
modify the styles of the child controls to match those set by the offical client application
; this prevents clipping problems
Const $WS_EX_NOPARENTNOTIFY = 0x4
Const $WS_EX_NOINHERITLAYOUT = 0x100000
$hUIContainerClassStyle = BitOR($WS_CHILD, $WS_CLIPCHILDREN, $WS_CLIPSIBLINGS, $WS_VISIBLE) ; 0x56000000
$hUIContainerClassStyleEx = BitOR($WS_EX_NOINHERITLAYOUT, $WS_EX_NOPARENTNOTIFY) ; 0x00100004
$hUIMainClassStyle = BitOR($WS_CHILD, $WS_CLIPCHILDREN, $WS_CLIPSIBLINGS, $WS_SYSMENU, $WS_VISIBLE) ; 0x56080000
$hUIMainClassStyleEx = 0x0
$hATLStyle = BitOR($WS_CHILD, $WS_CLIPCHILDREN, $WS_CLIPSIBLINGS, $WS_VISIBLE) ; 0x56000000
$hATLStyleEx = 0x0
;$guiStyle = BitOR($WS_BORDER, $WS_CAPTION, $WS_CLIPCHILDREN, $WS_CLIPSIBLINGS, $WS_DLGFRAME, $WS_GROUP, $WS_MAXIMIZE, $WS_MAXIMIZEBOX, $WS_MINIMIZEBOX, $WS_SYSMENU, $WS_TABSTOP, $WS_THICKFRAME, $WS_VISIBLE) ; 0x17CF0100
$guiStyle = BitOR($WS_CAPTION, $WS_CLIPCHILDREN, $WS_CLIPSIBLINGS, $WS_GROUP, $WS_MINIMIZEBOX, $WS_SYSMENU, $WS_TABSTOP, $WS_VISIBLE) ; 0x17CF0100
$guiStyleEx = $WS_EX_WINDOWEDGE ; 0x00000100
_SetStyle($hUIContainerClass, $hUIContainerClassStyle, $hUIContainerClassStyleEx)
_SetStyle($hUIMainClass, $hUIMainClassStyle, $hUIMainClassStyleEx)
_SetStyle($hATL, $hATLStyle, $hATLStyleEx)
_SetStyle($GUI, $guiStyle, $guiStyleEx)
$aStyle = GUIGetStyle()
GUISetStyle(BitAND($aStyle[0], BitNOT($WS_MAXIMIZEBOX)))
Is there an easy way to prevent clipping problems with activex-controls?
Re: Using ActiveX Control
Posted: Mon Mar 15, 2010 11:08 am
by srod
ComatePLUS automatically applies the #WS_CLIPCHILDREN style to ActiveX containers. Perhaps it is this which is causing the problems?
Try and find the following line (in the COMate_CreateActiveXControl() function) and commenting it out - see if that makes any difference?
Code: Select all
SetWindowLongPtr_(hWnd, #GWL_STYLE, GetWindowLongPtr_(hWnd, #GWL_STYLE)|#WS_CLIPCHILDREN)
Re: Using ActiveX Control
Posted: Mon Mar 15, 2010 2:09 pm
by univeda
I tried your hint but it looks like it's getting even worse.
Here is my sample code:
Code: Select all
IncludePath "inc\"
XIncludeFile "COMatePLUS.pbi"
Define.COMateObject RdpObject
Define Server.s = "your_server_ip_or_name"
Define Domain.s = "server_logon_domain"
Define UserName.s = "your_username"
Define Password.s = "your_password"
Define RdpWidth.i = 800
Define RdpHeight.i = 600
Define ColorDepth.i = 16
If OpenWindow(0, 0, 0, RdpWidth, RdpHeight, "Extended Terminal Services Client - " + Server, #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget)
RdpObject = Comate_CreateActiveXControl(0, 0, RdpWidth, RdpHeight, "mstscax.mstscax")
If RdpObject
RdpObject\SetProperty("DisconnectedText = 'Verbindung wurde getrennt.'")
RdpObject\SetProperty("ConnectingText = 'Verbindung wird aufgebaut. Bitte warten...'")
RdpObject\SetProperty("Server = '" + Server + "'")
RdpObject\SetProperty("Domain = '" + Domain + "'")
RdpObject\SetProperty("UserName = '" + UserName + "'")
RdpObject\SetProperty("AdvancedSettings2\ClearTextPassword = '" + Password + "'")
RdpObject\SetProperty("DesktopWidth = '" + Str(RdpWidth) + "'")
RdpObject\SetProperty("DesktopHeight = '" + Str(RdpHeight) + "'")
RdpObject\SetProperty("ColorDepth = '" + Str(ColorDepth) + "'")
RdpObject\Invoke("Connect()")
While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
CloseWindow(0)
RdpObject\Release()
Else
MessageRequester("ExTSC", "ActiveX Control konnte nicht erstellt werden!")
EndIf
EndIf
Can you try this code and confirm my problem? You just have to move the window around (outside the local desktop) or minimize it.
Thanks
Michael
Re: Using ActiveX Control
Posted: Mon Mar 15, 2010 2:14 pm
by srod
I have no server to connect to so all I get is the disconnected text. With that, everything looks fine.
Re: Using ActiveX Control
Posted: Mon Mar 15, 2010 2:27 pm
by srod
The COMateClass_GetContainerhWnd() function will allow you to retrieve the hWnd of the ATL container. You can use this to set any styles as you see fit (through SetWindowLongPtr_() etc.) Perhaps setting the styles along the lines of those in your code above will do the trick?
Re: Using ActiveX Control
Posted: Mon Mar 15, 2010 2:49 pm
by univeda
I tried to produce the error with my autoIt-Code:
Code: Select all
; modify the styles of the child controls to match those set by the offical client application
; this prevents clipping problems
Const $WS_EX_NOPARENTNOTIFY = 0x4
Const $WS_EX_NOINHERITLAYOUT = 0x100000
$hUIContainerClassStyle = BitOR($WS_CHILD, $WS_CLIPCHILDREN, $WS_CLIPSIBLINGS, $WS_VISIBLE) ; 0x56000000
$hUIContainerClassStyleEx = BitOR($WS_EX_NOINHERITLAYOUT, $WS_EX_NOPARENTNOTIFY) ; 0x00100004
$hUIMainClassStyle = BitOR($WS_CHILD, $WS_CLIPCHILDREN, $WS_CLIPSIBLINGS, $WS_SYSMENU, $WS_VISIBLE) ; 0x56080000
$hUIMainClassStyleEx = 0x0
$hATLStyle = BitOR($WS_CHILD, $WS_CLIPCHILDREN, $WS_CLIPSIBLINGS, $WS_VISIBLE) ; 0x56000000
$hATLStyleEx = 0x0
;$guiStyle = BitOR($WS_BORDER, $WS_CAPTION, $WS_CLIPCHILDREN, $WS_CLIPSIBLINGS, $WS_DLGFRAME, $WS_GROUP, $WS_MAXIMIZE, $WS_MAXIMIZEBOX, $WS_MINIMIZEBOX, $WS_SYSMENU, $WS_TABSTOP, $WS_THICKFRAME, $WS_VISIBLE) ; 0x17CF0100
$guiStyle = BitOR($WS_CAPTION, $WS_CLIPCHILDREN, $WS_CLIPSIBLINGS, $WS_GROUP, $WS_MINIMIZEBOX, $WS_SYSMENU, $WS_TABSTOP, $WS_VISIBLE) ; 0x17CF0100
$guiStyleEx = $WS_EX_WINDOWEDGE ; 0x00000100
_SetStyle($hUIContainerClass, $hUIContainerClassStyle, $hUIContainerClassStyleEx)
_SetStyle($hUIMainClass, $hUIMainClassStyle, $hUIMainClassStyleEx)
_SetStyle($hATL, $hATLStyle, $hATLStyleEx)
_SetStyle($GUI, $guiStyle, $guiStyleEx)
$aStyle = GUIGetStyle()
GUISetStyle(BitAND($aStyle[0], BitNOT($WS_MAXIMIZEBOX)))
Func _SetStyle($hwnd, $style, $exstyle)
DllCall("user32.dll", "long", "SetWindowLong", "hwnd", $hwnd, "int", -16, "long", $style)
DllCall("user32.dll", "long", "SetWindowLong", "hwnd", $hwnd, "int", -20, "long", $exstyle)
EndFunc ;==>_SetStyle
When i disable the function _SetStyle the clipping error appears:
Code: Select all
Func _SetStyle($hwnd, $style, $exstyle)
;DllCall("user32.dll", "long", "SetWindowLong", "hwnd", $hwnd, "int", -16, "long", $style)
;DllCall("user32.dll", "long", "SetWindowLong", "hwnd", $hwnd, "int", -20, "long", $exstyle)
EndFunc ;==>_SetStyle
[/code]
Can you show me how to set the styles in my pb-code like i my autoIt-Script does?
Re: Using ActiveX Control
Posted: Mon Mar 15, 2010 2:58 pm
by srod
Not exactly because I do not know which windows/controls you are directing the function calls at?
You can change the window and extended window styles for your ActiveX container using something like :
Code: Select all
hWnd = RdpObject\GetContainerhWnd()
SetWindowLongPtr_(hWnd, #GWL_STYLE, myStyle)
SetWindowLongPtr_(hWnd, #GWL_EXSTYLE, myExStyle)
myStyle and myExStyle would be appropriate combinations of window styles (e.g. #WS_CLIPSIBLINGS...) and extended window styles (e.g. #WS_EX_CLIENTEDGE...) etc.
Re: Using ActiveX Control
Posted: Mon Mar 15, 2010 5:11 pm
by univeda
I now have tried this:
Code: Select all
#WS_EX_NOPARENTNOTIFY = $4
#WS_EX_NOINHERITLAYOUT = $100000
If OpenWindow(0, 0, 0, RdpWidth, RdpHeight, "Extended Terminal Services Client - " + Server, #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget)
RdpObject = Comate_CreateActiveXControl(0, 0, RdpWidth, RdpHeight, "mstscax.mstscax")
If RdpObject
RdpObject\SetProperty("DisconnectedText = 'Verbindung wurde getrennt.'")
RdpObject\SetProperty("ConnectingText = 'Verbindung wird aufgebaut. Bitte warten...'")
RdpObject\SetProperty("Server = '" + Server + "'")
RdpObject\SetProperty("Domain = '" + Domain + "'")
RdpObject\SetProperty("UserName = '" + UserName + "'")
RdpObject\SetProperty("AdvancedSettings2\ClearTextPassword = '" + Password + "'")
RdpObject\SetProperty("DesktopWidth = '" + Str(RdpWidth) + "'")
RdpObject\SetProperty("DesktopHeight = '" + Str(RdpHeight) + "'")
RdpObject\SetProperty("ColorDepth = '" + Str(ColorDepth) + "'")
RdpObject\Invoke("Connect()")
hWnd = RdpObject\GetContainerhWnd()
SetWindowLongPtr_(hWnd, #GWL_STYLE, #WS_CHILD | #WS_CLIPCHILDREN | #WS_CLIPSIBLINGS | #WS_VISIBLE)
SetWindowLongPtr_(hWnd, #GWL_EXSTYLE, #WS_EX_NOINHERITLAYOUT | #WS_EX_NOPARENTNOTIFY)
While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
CloseWindow(0)
RdpObject\Release()
Else
MessageRequester("ExTSC", "ActiveX Control konnte nicht erstellt werden!")
EndIf
EndIf
The clipping-error still occurs.
But as you can see in my autoIt-Code there are also styles for the MainClass and the ATLClass:
Code: Select all
$hUIContainerClass = ControlGetHandle($GUI, "", "[CLASS:UIContainerClass]")
$hUIMainClass = ControlGetHandle($GUI, "", "[CLASS:UIMainClass]")
$hATL = ControlGetHandle($GUI, "", "[CLASS:" & $sATLClass & "]")
$hUIContainerClassStyle = BitOR($WS_CHILD, $WS_CLIPCHILDREN, $WS_CLIPSIBLINGS, $WS_VISIBLE) ; 0x56000000
$hUIContainerClassStyleEx = BitOR($WS_EX_NOINHERITLAYOUT, $WS_EX_NOPARENTNOTIFY) ; 0x00100004
$hUIMainClassStyle = BitOR($WS_CHILD, $WS_CLIPCHILDREN, $WS_CLIPSIBLINGS, $WS_SYSMENU, $WS_VISIBLE) ; 0x56080000
$hUIMainClassStyleEx = 0x0
$hATLStyle = BitOR($WS_CHILD, $WS_CLIPCHILDREN, $WS_CLIPSIBLINGS, $WS_VISIBLE) ; 0x56000000
$hATLStyleEx = 0x0
How can i set the style for the MainClass and the ATLClass as i did for the ContainerClass?
Re: Using ActiveX Control
Posted: Mon Mar 15, 2010 7:58 pm
by srod
Try the following and apply the styles (with SetWindowLonPtr_()) as appropriate :
Code: Select all
hUIContainerClass = RdpObject\GetContainerhWnd()
hUIMainClass = GetParent_(hUIContainerClass)
hATL = FindWindowEx_(hUIContainerClass, 0, 0, 0)
You may need to switch hUIContainerClass and hATL.
Re: Using ActiveX Control
Posted: Mon Mar 15, 2010 10:51 pm
by univeda
Thanks srod for your help. This is my working solution:
Code: Select all
IncludePath "inc\"
XIncludeFile "COMatePLUS.pbi"
Global.COMateObject RdpObject
Define Server.s = "your_servername_or_ipaddress"
Define Domain.s = "your_logon_domain"
Define UserName.s = "your_username"
Define Password.s = "your_password"
Define RdpWidth.i = 800
Define RdpHeight.i = 600
Define ColorDepth.i = 16
Enumeration
#WIN_MAIN
EndEnumeration
Declare SetStyles(COMateObject, hWnd)
#WS_EX_NOPARENTNOTIFY = $4
#WS_EX_NOINHERITLAYOUT = $100000
If OpenWindow(#WIN_MAIN, 10, 10, RdpWidth, RdpHeight, "Extended Terminal Services Client - " + Server, #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget)
RdpObject = Comate_CreateActiveXControl(5, 5, RdpWidth, RdpHeight, "mstscax.mstscax")
If RdpObject
RdpObject\SetProperty("DisconnectedText = 'Verbindung wurde getrennt.'")
RdpObject\SetProperty("ConnectingText = 'Verbindung wird aufgebaut. Bitte warten...'")
RdpObject\SetProperty("Server = '" + Server + "'")
RdpObject\SetProperty("Domain = '" + Domain + "'")
RdpObject\SetProperty("UserName = '" + UserName + "'")
RdpObject\SetProperty("AdvancedSettings2\ClearTextPassword = '" + Password + "'")
RdpObject\SetProperty("DesktopWidth = '" + Str(RdpWidth) + "'")
RdpObject\SetProperty("DesktopHeight = '" + Str(RdpHeight) + "'")
RdpObject\SetProperty("ColorDepth = '" + Str(ColorDepth) + "'")
RdpObject\Invoke("Connect()")
SetStyles(RdpObject, #WIN_MAIN)
While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
CloseWindow(#WIN_MAIN)
RdpObject\Release()
Else
MessageRequester("ExTSC", "ActiveX Control konnte nicht erstellt werden!")
EndIf
EndIf
Procedure SetStyles(COMateObject, hWnd)
;this prevents clipping problems
;ContainerClass
hUIContainerClass = RdpObject\GetContainerhWnd()
SetWindowLongPtr_(hUIContainerClass, #GWL_STYLE, #WS_CHILD | #WS_CLIPCHILDREN | #WS_CLIPSIBLINGS | #WS_VISIBLE)
SetWindowLongPtr_(hUIContainerClass, #GWL_EXSTYLE, #WS_EX_NOINHERITLAYOUT | #WS_EX_NOPARENTNOTIFY)
;MainClass
hUIMainClass = GetParent_(hUIContainerClass)
SetWindowLongPtr_(hUIMainClass, #GWL_STYLE, #WS_CHILD | #WS_CLIPCHILDREN | #WS_CLIPSIBLINGS | #WS_SYSMENU | #WS_VISIBLE)
SetWindowLongPtr_(hUIMainClass, #GWL_EXSTYLE, $0)
;ATL
hATL = FindWindowEx_(hUIContainerClass, 0, 0, 0)
SetWindowLongPtr_(hATL, #GWL_STYLE, #WS_CHILD | #WS_CLIPCHILDREN | #WS_CLIPSIBLINGS | #WS_VISIBLE)
SetWindowLongPtr_(hATL, #GWL_EXSTYLE, $0)
;Window
hWnd = WindowID(#WIN_MAIN)
SetWindowLongPtr_(hWnd, #GWL_STYLE, #WS_CAPTION | #WS_CLIPCHILDREN | #WS_CLIPSIBLINGS | #WS_GROUP | #WS_MINIMIZEBOX | #WS_SYSMENU | #WS_TABSTOP | #WS_VISIBLE)
SetWindowLongPtr_(hWnd, #GWL_EXSTYLE, #WS_EX_WINDOWEDGE)
EndProcedure
Again, thank you very much!
Re: Using ActiveX Control
Posted: Mon Mar 15, 2010 11:52 pm
by srod
You have some redundancy/repetion here in that hUIMainClass and WindowID(#WinMain) refer to the same window.
Re: Using ActiveX Control
Posted: Tue Mar 16, 2010 8:36 am
by univeda
srod wrote:You have some redundancy/repetion here in that hUIMainClass and WindowID(#WinMain) refer to the same window.
You mean that huiMainClass and #WIN_MAIN is the same? Sorry did not get what you mean.