Sign in to follow this  
Followers 0
EvAsion

DWM Thumbnail APIs for Vista - wheres my error?

9 posts in this topic

Just started doing dllcall so i am unable to spot what i am doing wrong. I'm not sure if i'm on the right track, this is basically guess work.

see: http://msdn2.microsoft.com/en-us/library/a...541(VS.85).aspx

Const $DWM_TNP_RECTDESTINATION = 0x00000001
Const $DWM_TNP_RECTSOURCE = 0x00000002
Const $DWM_TNP_OPACITY = 0x00000004
Const $DWM_TNP_VISIBLE = 0x00000008
Const $DWM_TNP_SOURCECLIENTAREAONLY = 0x00000010
GUICreate("Meh")
Guisetstate(@SW_SHOWNOACTIVATE)
opt("WinTitleMatchMode",2)
$hwnd = WinGetHandle("")
$destwin = WinGetHandle("Meh")
$size = WinGetClientSize("")
$Struct = DllStructCreate("dword;ptr;ptr;byte;int;int")
If @error then msgbox(0,"",@error)
msgbox(0,"","here")
$StructDest = DllStructCreate("long;long;long;long")
If @error then msgbox(0,"",@error)
$StructSource = DllStructCreate("long;long;long;long")
If @error then msgbox(0,"",@error)
DllStructSetData($StructDest,1,"0")
DllStructSetData($StructDest,2,"0")
DllStructSetData($StructDest,3,"100")
DllStructSetData($StructDest,4,"100")
DllStructSetData($StructSource,1,"0")
DllStructSetData($StructSource,2,"0")
DllStructSetData($StructSource,3,$size[0])
DllStructSetData($StructSource,4,$size[1])
DllStructSetData($Struct,1,BitOr($DWM_TNP_RECTDESTINATION,$DWM_TNP_VISIBLE,$DWM_TNP_SOURCECLIENTAREAONLY))
DllStructSetData($Struct,2,DllStructGetPtr($StructDest))
DllStructSetData($Struct,3,"0")
DllStructSetData($Struct,4,"255")
DllStructSetData($Struct,5,"1")
DllStructSetData($Struct,6,"0")
$StructSiz = DllStructCreate("long;long")
DllStructSetData($Struct,1,"100")
DllStructSetData($Struct,2,"100")
;Exit
DllCall("dwmapi.dll","int","DwmRegisterThumbnail","hwnd",$destwin,"hwnd",$hwnd,"int","0","int","0","ptr",DllStructGetPtr($StructSiz))
msgbox(0,"",@error)
DllCall("dwmapi.dll","int","DwmUpdateThumbnailProperties","int","0","ptr",DllStructGetPtr($Struct))
msgbox(0,"",@error)

Share this post


Link to post
Share on other sites



I don't have Vista, but from what gather in MSDN...

DwmUpdateThumbnailProperties

says

"Parameters

hThumbnailId

The DWM thumbnail to be updated. NULL, invalid, or thumbnails owned by other process will result in an HRESULT of E_INVALIDARG."

And that's exactly what you are doing in your last DllCall, specifying NULL for first param, which would make the function fail in any case.

Also, DwmRegisterThumbnail (which would give you a hThumbnailId), looks like it takes 3 params - "hwnd", "hwnd", and "ptr" (or "hwnd*", so you could get returned value from returned array[3]). In your code 5 are specified for whatever reason.


"be smart, drink your wine"

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

I don't have Vista, but from what gather in MSDN...

DwmUpdateThumbnailProperties

says

"Parameters

hThumbnailId

The DWM thumbnail to be updated. NULL, invalid, or thumbnails owned by other process will result in an HRESULT of E_INVALIDARG."

And that's exactly what you are doing in your last DllCall, specifying NULL for first param, which would make the function fail in any case.

Also, DwmRegisterThumbnail (which would give you a hThumbnailId), looks like it takes 3 params - "hwnd", "hwnd", and "ptr" (or "hwnd*", so you could get returned value from returned array[3]). In your code 5 are specified for whatever reason.

Oh yes i now understand what "[out]" means.. i feel dumbish. so something closer to this?

Const $DWM_TNP_RECTDESTINATION = 0x00000001
Const $DWM_TNP_RECTSOURCE = 0x00000002
Const $DWM_TNP_OPACITY = 0x00000004
Const $DWM_TNP_VISIBLE = 0x00000008
Const $DWM_TNP_SOURCECLIENTAREAONLY = 0x00000010
GUICreate("Meh")
Guisetstate(@SW_SHOWNOACTIVATE)
opt("WinTitleMatchMode",2)
$hwnd = WinGetHandle("")
$destwin = WinGetHandle("Meh")
$size = WinGetClientSize("")
$Struct = DllStructCreate("dword;ptr;ptr;byte;int;int")
If @error then msgbox(0,"",@error)
$StructDest = DllStructCreate("long;long;long;long")
If @error then msgbox(0,"",@error)
$StructSource = DllStructCreate("long;long;long;long")
If @error then msgbox(0,"",@error)
DllStructSetData($StructDest,1,"0")
DllStructSetData($StructDest,2,"0")
DllStructSetData($StructDest,3,"100")
DllStructSetData($StructDest,4,"100")
DllStructSetData($StructSource,1,"0")
DllStructSetData($StructSource,2,"0")
DllStructSetData($StructSource,3,$size[0])
DllStructSetData($StructSource,4,$size[1])
DllStructSetData($Struct,1,BitOr($DWM_TNP_RECTDESTINATION,$DWM_TNP_VISIBLE,$DWM_TNP_SOURCECLIENTAREAONLY))
DllStructSetData($Struct,2,DllStructGetPtr($StructDest))
DllStructSetData($Struct,3,"0")
DllStructSetData($Struct,4,"255")
DllStructSetData($Struct,5,"1")
DllStructSetData($Struct,6,"0")
$StructSiz = DllStructCreate("long;long")
DllStructSetData($StructSiz,1,"100")
DllStructSetData($StructSiz,2,"100")
;Exit
$dll = DllOpen("dwmapi.dll")
$call = DllCall($dll,"int","DwmRegisterThumbnail","hwnd",$destwin,"hwnd*",$hwnd,"ptr","0");,"ptr",DllStructGetPtr($StructSiz),"int","0");"int","0","ptr",DllStructGetPtr($StructSiz))
$call2 = DllCall($dll,"int","DwmUpdateThumbnailProperties","ptr",$call[3],"ptr",DllStructGetPtr($Struct))
sleep(4000)
DllClose($dll)

edit: changes slightly

Edited by EvAsion

Share this post


Link to post
Share on other sites

$dll = DllOpen("dwmapi.dll")

$call = DllCall($dll,"int","DwmRegisterThumbnail", "hwnd",$destwin, "hwnd",$hwnd, "hwnd*",0);

$call2 = DllCall($dll,"int","DwmUpdateThumbnailProperties", "hwnd",$call[3], "ptr",DllStructGetPtr($Struct))

DllClose($dll)


"be smart, drink your wine"

Share this post


Link to post
Share on other sites

$dll = DllOpen("dwmapi.dll")

$call = DllCall($dll,"int","DwmRegisterThumbnail", "hwnd",$destwin, "hwnd",$hwnd, "hwnd*",0);

$call2 = DllCall($dll,"int","DwmUpdateThumbnailProperties", "hwnd",$call[3], "ptr",DllStructGetPtr($Struct))

DllClose($dll)

Well, doesn't seem to be working so i may have made an error when creating the structures or something, i'll have a closer look, by the way did i do the "rect"'s correctly? I just guessed that i would have to create another structure for the rect's and use it as a pointer.

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

by the way did i do the "rect"'s correctly? I just guessed that i would have to create another structure for the rect's and use it as a pointer.

That's correct.

I just have a general comment on the way you use quotes in DllStructSetData.

Lets say you have defined some $element of some structure as "byte", and then have, lets say, DllStructSetData($struct, $element, "255").

A value in quotes is a string. "255" is not an integer 255, but a string of 3 chars. Now, DllCall and DllStruct... functions are nice enough (maybe) and let you get away with it, but I'm not sure that all AutoIt built-in functions are that nice, and most UDFs certainly aren't, so it's not a healthy practice.

Also, check the returns from DllCalls (and perhaps other functions too), that will give you some clue to what and where went wrong.

Edited by Siao

"be smart, drink your wine"

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

That's correct.

I just have a general comment on the way you use quotes in DllStructSetData.

Lets say you have defined some $element of some structure as "byte", and then have, lets say, DllStructSetData($struct, $element, "255").

A value in quotes is a string. "255" is not an integer 255, but a string of 3 chars. Now, DllCall and DllStruct... functions are nice enough (maybe) and let you get away with it, but I'm not sure that all AutoIt built-in functions are that nice, and most UDFs certainly aren't, so it's not a healthy practice.

Also, check the returns from DllCalls (and perhaps other functions too), that will give you some clue to what and where went wrong.

Thanks for the tip, and all your help in general. I have uncovered that the first dllcall isn't returning a valid hwnd and i don't know why of course. any ideas?

Const $DWM_TNP_RECTDESTINATION = 0x00000001
Const $DWM_TNP_RECTSOURCE = 0x00000002
Const $DWM_TNP_OPACITY = 0x00000004
Const $DWM_TNP_VISIBLE = 0x00000008
Const $DWM_TNP_SOURCECLIENTAREAONLY = 0x00000010
opt("WinTitleMatchMode",2)
$hwnd = WinGetHandle("Windows Media Player")
GUICreate("Meh")
Guisetstate()
$destwin = WinGetHandle("Meh")

$Struct = DllStructCreate("dword;ptr;ptr;ubyte;int;int")
If @error then msgbox(0,"",@error)
$StructDest = DllStructCreate("long;long;long;long")
If @error then msgbox(0,"",@error)
$StructSource = DllStructCreate("long;long;long;long")
If @error then msgbox(0,"",@error)
DllStructSetData($StructDest,1,"0")
DllStructSetData($StructDest,2,"50")
DllStructSetData($StructDest,3,"100")
DllStructSetData($StructDest,4,"150")
DllStructSetData($Struct,1,BitOr($DWM_TNP_RECTDESTINATION,$DWM_TNP_VISIBLE,$DWM_TNP_SOURCECLIENTAREAONLY))
DllStructSetData($Struct,2,DllStructGetPtr($StructDest))
DllStructSetData($Struct,3,DllStructGetPtr($StructSource))
DllStructSetData($Struct,4,255)
DllStructSetData($Struct,5,"1")
DllStructSetData($Struct,6,"1")
$dll = DllOpen("dwmapi.dll")
$call = DllCall($dll,"int","DwmRegisterThumbnail", "hwnd",$destwin, "hwnd",$hwnd, "hwnd*",0)
If @error then msgbox(0,"",@error)
msgbox(0,"",$call[3])
$call2 = DllCall($dll,"int","DwmUpdateThumbnailProperties", "hwnd",$call[3], "ptr",DllStructGetPtr($Struct))
If @error then msgbox(0,"",@error)
DllClose($dll)
sleep(5000)
Edited by EvAsion

Share this post


Link to post
Share on other sites

Well, if the DwmRegisterThumbnail call doesn't return proper thumbnail handle, it should return something, such as an error code.

What is $call[0]?

Also check the window handles you pass to that function.


"be smart, drink your wine"

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Well, if the DwmRegisterThumbnail call doesn't return proper thumbnail handle, it should return something, such as an error code.

What is $call[0]?

Also check the window handles you pass to that function.

$call[0] = -2147024809 and the window handles seem ok.

Edit: $call[3] = 0x00000000 incase you were interested

Edit2: Those were when calling a gui from another autoit application, if using gui from the current autoit script the result becomes $call[0] = 0 and $call[3] = 0x00000001

Edited by EvAsion

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0