trancexx Posted January 29, 2009 Share Posted January 29, 2009 I'm having troubles understanding some special situations that I encounterd recently and that are closly related to function DllCall() and types used whith DllCall() function.For example one call to function MessageBox from user32.dll. There shouldn't be any unknown things there:MSDN description:int MessageBox( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType );Autoit:DllCall("user32.dll", "int", "MessageBox", "hwnd", 0, "str", "Text", "str", "Title", "dword", 48)SmOke_N suggested that it could be done like this and in fact that it's the more proper way of diong the call (he demonstrated on function FindWindowEx):DllCall("user32.dll", "int", "MessageBox", "hwnd", 0, "ptr", "Text", "ptr", "Title", "dword", 48)If you run it you will see that it's obviously not a proper way.Another way is to create structures and use pointers to them in DllCall():$sTitle = "Title" $tTitle = DllStructCreate("char[" & StringLen($sTitle) + 1 & "]") DllStructSetData($tTitle, 1, $sTitle) $sText = "Text" $tText = DllStructCreate("char[" & StringLen($sText) + 1 & "]") DllStructSetData($tText, 1, $sText) DllCall("user32.dll", "int", "MessageBox", "hwnd", 0, "ptr", DllStructGetPtr($tText), "ptr", DllStructGetPtr($tTitle), "dword", 48)Of course there could be any combination of two methods:$sTitle = "Title" $tTitle = DllStructCreate("char[" & StringLen($sTitle) + 1 & "]") DllStructSetData($tTitle, 1, $sTitle) DllCall("user32.dll", "int", "MessageBox", "hwnd", 0, "str", "Text", "ptr", DllStructGetPtr($tTitle), "dword", 48)... and the other way arround.What can be concluded so far? - "str", "string" will create pointer to null-terminated string in calls- "ptr", $pointer will do the same thing if structure is oversized by 1 to make string null-terminated. Not oversizing is bad because pointer is not pointing to null-terminated string:$sTitle = "Title" $tTitle = DllStructCreate("char[" & StringLen($sTitle) & "]") DllStructSetData($tTitle, 1, $sTitle) $sText = "Text" $tText = DllStructCreate("char[" & StringLen($sText) & "]") DllStructSetData($tText, 1, $sText) DllCall("user32.dll", "int", "MessageBox", "hwnd", 0, "ptr", DllStructGetPtr($tText), "ptr", DllStructGetPtr($tTitle), "dword", 48)Btw, truncation of largely oversized char buffer is done by default and pointer to that will be pointer to null-terminated string.That all looks logical but then there were this mentioned function FindWindowEx from user32.dll.Something is wrong there, at least I cannot comprehend it. Situation there is that "ptr", $pointer works and "str", "string" is not working.Will make new post (double-post, hate that) because this one is getting too large to follow. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
trancexx Posted January 29, 2009 Author Share Posted January 29, 2009 First to go back and to mention the secial case when NULL pointer could be required in functions."str", "" is not the same as "ptr", 0 as I was noted by one member of stuff here. First is pointer to empty string. Pointer to something. Latter is null-pointer, pointer to nothing (to say it that way). There is a great difference.OK, function is FindWindowEx from user32.dll. MSDN says:HWND FindWindowEx( HWND hwndParent, HWND hwndChildAfter, LPCTSTR lpszClass, LPCTSTR lpszWindow );What is different here? When you look to what is in code tags, almost nothing is different. The difference is in description of parameters. You can find that here. That last parameter LPCTSTR lpszWindow can be either pointer to null-terminated string or NULL.Since "str", "..." cannot produce NULL, only pointer to empty string in best case, to get the most of this function it would be better to use pointers. But... and this is what confuses me, and to show what is it I will repost working SmOke_N code:expandcollapse popuphideStartButton() Sleep(2000) showStartButton() Func hideStartButton() ;This Function Hides the Start Button Local Const $_SW_HIDE = 0 Local $h_parent = _FindWindow("Shell_TrayWnd") If @error Then Return SetError(1, 0, 0) Local $h_child = _FindWindowEx("Button", "", $h_parent) If @error Then Return SetError(2, 0, 0) If _ShowWindow($h_child, $_SW_HIDE) Then Return SetError(0, 0, 1) Return SetError(3, 0, 0) EndFunc Func showStartButton() ;This Function Shows the Start Button Local Const $_SW_SHOW = 5 Local $h_parent = _FindWindow("Shell_TrayWnd") If @error Then Return SetError(1, 0, 0) Local $h_child = _FindWindowEx("Button", "", $h_parent) If @error Then Return SetError(2, 0, 0) If _ShowWindow($h_child, $_SW_SHOW) Then Return SetError(0, 0, 1) Return SetError(3, 0, 0) EndFunc Func _FindWindow($s_class, $s_title = "") Local $t_class = DllStructCreate("char[" & StringLen($s_class) + 1 & "]") DllStructSetData($t_class, 1, $s_class) Local $t_title = DllStructCreate("char[" & StringLen($s_title) + 1 & "]") DllStructSetData($t_title, 1, $s_title) Local $h_wnd = DllCall("user32.dll", "hwnd", "FindWindow", _ "ptr", DllStructGetPtr($t_class), _ "ptr", DllStructGetPtr($s_title)) If Not $h_wnd[0] Then Return SetError(1, 0, 0) Return $h_wnd[0] EndFunc Func _FindWindowEx($s_class, $s_title = "", $h_parent = 0, $h_child = 0) Local $t_class = DllStructCreate("char[" & StringLen($s_class) + 1 & "]") DllStructSetData($t_class, 1, $s_class) Local $t_title = DllStructCreate("char[" & StringLen($s_title) + 1 & "]") DllStructSetData($t_title, 1, $s_title) Local $h_wnd = DllCall("user32.dll", "hwnd", "FindWindowEx", _ "hwnd", $h_parent, _ "hwnd", $h_child, _ "ptr", DllStructGetPtr($t_class), _ "ptr", DllStructGetPtr($s_title)) If Not $h_wnd[0] Then Return SetError(1, 0, 0) Return $h_wnd[0] EndFunc Func _ShowWindow($h_wnd, $i_flag) Local $a_ret = DllCall("user32.dll", "int", "ShowWindow", "hwnd", $h_wnd, "int", $i_flag) Return ($a_ret[0] <> 0) EndFuncThat script will hide start button on XP for two seconds.It's done with pointers and all works well. That code will never produce NULL pointer to pass to function call because all structures are by 1 larger then lenght of strings that fills them.For example, empty string:$sString = "" $tString = DllStructCreate("char[" & StringLen($sString) + 1 & "]") DllStructSetData($tString, 1, $sString) ConsoleWrite(DllStructGetPtr($tString, 1) & @CRLF)My question is, why that script works and this one isn't?expandcollapse popuphideStartButton() Sleep(2000) showStartButton() Func hideStartButton() ;This Function Hides the Start Button Local Const $_SW_HIDE = 0 Local $h_parent = _FindWindow("Shell_TrayWnd") If @error Then Return SetError(1, 0, 0) Local $h_child = _FindWindowEx("Button", "", $h_parent) If @error Then Return SetError(2, 0, 0) If _ShowWindow($h_child, $_SW_HIDE) Then Return SetError(0, 0, 1) Return SetError(3, 0, 0) EndFunc Func showStartButton() ;This Function Shows the Start Button Local Const $_SW_SHOW = 5 Local $h_parent = _FindWindow("Shell_TrayWnd") If @error Then Return SetError(1, 0, 0) Local $h_child = _FindWindowEx("Button", "", $h_parent) If @error Then Return SetError(2, 0, 0) If _ShowWindow($h_child, $_SW_SHOW) Then Return SetError(0, 0, 1) Return SetError(3, 0, 0) EndFunc Func _FindWindow($s_class, $s_title = "") Local $h_wnd = DllCall("user32.dll", "hwnd", "FindWindow", _ "str", $s_class, _ "str", $s_title) If Not $h_wnd[0] Then Return SetError(1, 0, 0) Return $h_wnd[0] EndFunc Func _FindWindowEx($s_class, $s_title = "", $h_parent = 0, $h_child = 0) Local $h_wnd = DllCall("user32.dll", "hwnd", "FindWindowEx", _ "hwnd", $h_parent, _ "hwnd", $h_child, _ "str", $s_class, _ "str", $s_title) If Not $h_wnd[0] Then Return SetError(1, 0, 0) Return $h_wnd[0] EndFunc Func _ShowWindow($h_wnd, $i_flag) Local $a_ret = DllCall("user32.dll", "int", "ShowWindow", "hwnd", $h_wnd, "int", $i_flag) Return ($a_ret[0] <> 0) EndFuncIf someone would care to explain it to me I would be deeply gratified. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
Solution trancexx Posted January 30, 2009 Author Solution Share Posted January 30, 2009 (edited) The only difference between those two scripts is data types used in function DllCall().One is "ptr" and pointer to buffer with null terminated string and the other is "str" and string.At least I thought so till about 30 minutes ago. SmOke_N made a mistake there. His passing pointers to strings (literaly) thus creating "ptr", 0 situation and that's why it appears that his code is working as it should be.I guess not wanting to answer is also an answer (this person will know what I mean). Thanks again.Knowing this, function _WinAPI_FindWindow() from WinAPI.au3 looks like it could be written maybe to be more complete. At least description of parameters should be modified. Currently is, for example:$WindowName - A string that specifies the window name. If this parameter is blank, all window names match.Not if blank and never in its current form. Edited January 30, 2009 by trancexx ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted January 30, 2009 Moderators Share Posted January 30, 2009 The only difference between those two scripts is data types used in function DllCall().One is "ptr" and pointer to buffer with null terminated string and the other is "str" and string.At least I thought so till about 30 minutes ago. SmOke_N made a mistake there. His passing pointers to strings (literaly) thus creating "ptr", 0 situation and that's why it appears that his code is working as it should be.I guess not wanting to answer is also an answer (this person will know what I mean). Thanks again.Knowing this, function _WinAPI_FindWindow() from WinAPI.au3 looks like it could be written maybe to be more complete. At least description of parameters should be modified. Currently is, for example:$WindowName - A string that specifies the window name. If this parameter is blank, all window names match.Not if blank and never in its current form.I didn't make a mistake doing that, you may want to read what the options were for those two parameters I passed a null string ptr to.I'm not sure what you mean by "not wanting to answer" and or if that was directed to me, I don't read every single post... Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
trancexx Posted January 30, 2009 Author Share Posted January 30, 2009 I didn't make a mistake doing that, you may want to read what the options were for those two parameters I passed a null string ptr to. I'm not sure what you mean by "not wanting to answer" and or if that was directed to me, I don't read every single post...Thing is that if one of you guys (green, red, blue) make a statement, not opinion (well... you know what I mean) here on forum I expect it to be true. So if you or anyone mentioned say for example: "This is true... this is true tooo,... this is not", I would expect first thing to be true, second also and third not. Otherwise too much energy is wasted on things that shouldn't be wasted on. I'm sorry but that's the way I percept things. Burden is on you guys and you took it by your own free will. Code posted by colored users is almost a fact (to me, that is). You made a mistake in your code. This how (will stick to FindWindowEx function): Func _FindWindowEx($s_class, $s_title = "", $h_parent = 0, $h_child = 0) Local $t_class = DllStructCreate("char[" & StringLen($s_class) + 1 & "]") DllStructSetData($t_class, 1, $s_class) Local $t_title = DllStructCreate("char[" & StringLen($s_title) + 1 & "]") DllStructSetData($t_title, 1, $s_title) Local $h_wnd = DllCall("user32.dll", "hwnd", "FindWindowEx", _ "hwnd", $h_parent, _ "hwnd", $h_child, _ "ptr", DllStructGetPtr($t_class), _ "ptr", DllStructGetPtr($s_title)) If Not $h_wnd[0] Then Return SetError(1, 0, 0) Return $h_wnd[0] EndFunc You are creating structure named $t_title. Why? What is the use for it in your code? There isn't any because there's no pointer to that. On the other hand you are making pointer to $s_title. Pointer to something that is not dll structure. The result of that is raising error and DllStructGetPtr() returning 0. Respond to that is success of FindWindowEx funcion (sounds bizar) since it's provided by NULL ("ptr", 0) Do you still think there's no mistake? So, I guess, everyone makes mistakes, you here, PaulIA in description of _WinAPI_FindWindow() in WinAPI.au3, PsaltyDS the other day with $SystemPowerInformation structure (wrong data types, signed - unsigned) etc... Morteza's code was as correct as yours (he is having array issue) only thing is that the last parameter in his FindWindowEx function should have been "str", "start". - "not wanting to answer" was not about you. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted January 30, 2009 Moderators Share Posted January 30, 2009 lpszWindow [in] Pointer to a null-terminated string that specifies the window name (the window's title). If this parameter is NULL, all window names match.So, if I actually pass a window title, it will be convert it to the null-terminated pointer that MSDN specifically indicates there. If I pass a blank string, it will convert it to a null-terminated pointer. When you say someone is wrong. Please be sure they are. Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
trancexx Posted January 31, 2009 Author Share Posted January 31, 2009 So, if I actually pass a window title, it will be convert it to the null-terminated pointer that MSDN specifically indicates there. If I pass a blank string, it will convert it to a null-terminated pointer.When you say someone is wrong. Please be sure they are."str", "string" is pointer to null-terminated string "string""str", "" is pointer to null-terminated empty string"ptr", 0 is NULL ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now