ByVal and ByRef behaviour, and general varied argument behaviour, in windows API Declare lines and VBA winapi codings

User avatar
DocAElstein
5StarLounger
Posts: 773
Joined: 18 Jan 2022, 15:59
Location: An Englishman, illegally re-routing rivers, in Hof, Beautiful Bavaria. Rule, Britannia!

ByVal and ByRef behaviour, and general varied argument behaviour, in windows API Declare lines and VBA winapi codings

Post by DocAElstein »

Hi
Before I start my question, this first code snippet bit is just to make it clear "where I am coming from" in my understanding so far in arguments to do with VB VBA function type things….
So I think I understand what is going on in this simple normal VBA snippet

Code: Select all

 Sub ByValByRefSimpleVBAFunctions()
Dim StrBuffa As String
 Let StrBuffa = "the original text" 
Call TakeValue(StrBuffa) ' Take the value in  StrBuffa  into  Sub TakeValue(ByVal Tecst As String)
MsgBox StrBuffa
Call TakeVariable(StrBuffa)  ' ' A bit like Taking the variable,  StrBuffa,  into  Sub TakeVariable(ByRef Tecst As String)
MsgBox StrBuffa
End Sub
Sub TakeValue(ByVal Tecst As String)
 Let Tecst = "a new value"
End Sub
Sub TakeVariable(ByRef Tecst As String)
 Let Tecst = "a new value"
End Sub 
If you run the routine, then the first MsgBox tells you that you (still) have the original text in a variable, StrBuffa, and the second MsgBox tells you that you have a new value in that variable.
A simple laymen explanation is that in the first Call I put a value in a local variable in the second routine, Sub TakeValue, and/so there is no way in that second subroutine to change the value in StrBuffa
In the second Call I am arranging that I am referring to the variable StrBuffa within the routine Sub TakeVariable, so I can and do change its value, which is then what the second message box tells me. A simple layman way to think of that is that in the third and final routine, Sub TakeVariable, I take the variable, not just its value. I realise that is not technically so correct.
(Many of us will know this latter ByRef way is a way to effectively get more values returned from a routine, since variables likeStrBuffa can be thought of as a Buffer to take values assigned in the Called routine)

OK, so far mostly so good, I think.

Coming from that way of thinking I am getting a bit confused and puzzled wondering what is going on with ByVal and ByRef behaviour in windows API Declare lines and associated VBA winapi code lines. I am thinking that some informed insight into what is going on might help get quicker clued up on this VBA windows API stuff

I have seen a few similar quirks, here is just one example. But it is a good one to try and get some help on, since I am using the SendMessageA twice in a couple of slightly different ways. The quirks involve the last two arguments, which I am wondering if they can be thought of as a couple of buckets to chuck anything into that no one could quite figure out how to order them in some meaningful way: Even places with usually good descriptions give up on these and say…… Specifies additional message-specific information. ….. which is about as useful as a chocolate Teapot


So I was experimenting/ researching API stuff. I got a simple text file opened using Notepad on my desktop, TextFile.txt with 4 characters in it
a vbCr
VbLf b

, and for the greater glory of mankind, I got a Spy, and dragged him into the text file text area , which seemed to be showing me the text in some weird abstract caption way

I have got that text out into a string variable in a few VBA winapi ways, including the first coding here , which was cobbled together from bits and pieces found on the internet, and I was confident it would work. But Don’t run that one, as it crashes , - the second two "cured" ones under it are OK
The first two declare lines and the first two lines in the main sub are OK, tried and tested many times now, - the second code line is "taking a step down in the tree" from the code line above (because in VBA/ VB winapi we do not have tools to get directly at a windows handle)
Problems come in from the SendMessagA declare line, and/ or in line 2 and 5 in the main Sub TextAPI()

I got a clue to the cures because, if you copy that SendMessagA Declare line from around the internet you notice that the last argument often gets left unqualified, (by unqualified I mean has no ByVal or ByRef, even if the other 3 arguments usually do have.) I figure it is ByRef by default, but it seems perhaps, or perhaps sometimes, not to be)

Now, I know approximately what goes on here, or should go on, if and when the coding does not error, (partly out of hindsight after curing the crashing, and partly by internet research): The variable Biffa seems to be working similar, when considering the ByRef case to the variable StrBuffa in my simple VBA coding above
But if you add ByRef to the last argument in the SendMessagA Declare line, then it still crashes, ( as expected perhaps as I assumed the default was ByRef)
The weird things is that the problem is cured if you either
_Cure 1(i) add ByVal to the last argument in the SendMessagA Declare line, but then also: _1(ii) Somehow related is something, a similar phenomena that I have seen before: I must now change in line 3, the last 0 to 0&
or
_Cure 2 I can forget _1(i) and _1(ii), and instead make just one change, by adding a ByVal at line 5

I know the simple answer is that ByVal and ByRef behaviour in windows API Declare lines is different, but I am guessing that the basic idea behind what ByVal and ByRef are doing is perhaps similar?, or maybe not?, so if anyone has a more enlightening explanation to the behaviour , it might give some valuable insights into learning about these winapi things.

Initially it seems confusing to me as it seems that how a Declare line, the call line and perhaps some other associated code lines work can be very varied. For example an identical code line can get a needed argument value in one situation and then in another situation it sometimes somehow passes some instructions defining how something is done.

My answer, which I assume is wrong, is that no one could figure out a more ordered logical well organised interface so the nearest looking combination of Declare line, call line and associated coding is used as an enigma type coding that sets off some particular back end coding to do something?



Coding is also in uploaded excel file, in module SendMessageA_capturetxt. You need the text file open ( or you can open it with shell execute API if you feel the desire)

Alan
You do not have the required permissions to view the files attached to this post.
Last edited by DocAElstein on 02 Jan 2025, 14:13, edited 1 time in total.
Regards , Ālan , DocÆlstein :england: , :germany:

User avatar
SpeakEasy
5StarLounger
Posts: 742
Joined: 27 Jun 2021, 10:46

Re: ByVal and ByRef behaviour, and general varied argument behaviour, in windows API Declare lines and VBA winapi coding

Post by SpeakEasy »

This will tell you more low-level info than you will probably ever need to know about VB strings

Weirdly, it isn't particularly explicit about why calling an API function with a ByRef string generally ends in a crash. Specifically, and once you have read the article this should make a little more sense, the issue is that with a vb string ByRef passes a pointer to a pointer in to the function, but the API, which knows nothing of BSTRs, assumes it is a pointer to an LPSTR (or LPWSTR). Treating a pointer as a string leads to chaos, and generally a crash.

User avatar
DocAElstein
5StarLounger
Posts: 773
Joined: 18 Jan 2022, 15:59
Location: An Englishman, illegally re-routing rivers, in Hof, Beautiful Bavaria. Rule, Britannia!

Re: ByVal and ByRef behaviour, and general varied argument behaviour, in windows API Declare lines and VBA winapi coding

Post by DocAElstein »

SpeakEasy wrote:
03 Dec 2024, 15:08
This ....
Thanks, good to have an archive copy of something from Microsoft that might be useful. The author seems slightly critical of Microsoft documentation impreciseness, which is encouraging….
…. Day one: I am about an eighth of the way through it, making notes and translations into Ucode-E* as I go along
( * Ucode-E: Understandable English ).
I have not so much else to do for a few days apart from chopping big trees down illegally and putting them in other places with pretty lights on them, so I will read it all carefully and report back next week, if I survive…. ( with some pics of my trees if nothing else…. )
Regards , Ālan , DocÆlstein :england: , :germany:

User avatar
SpeakEasy
5StarLounger
Posts: 742
Joined: 27 Jun 2021, 10:46

Re: ByVal and ByRef behaviour, and general varied argument behaviour, in windows API Declare lines and VBA winapi coding

Post by SpeakEasy »

>good to have an archive copy of something from Microsoft

It's an extract from a great book; if you are interested in Win32 API programming (and much of what is going on under the covers) from VBA it is definitely worth trying to get hold of a copy.

User avatar
DocAElstein
5StarLounger
Posts: 773
Joined: 18 Jan 2022, 15:59
Location: An Englishman, illegally re-routing rivers, in Hof, Beautiful Bavaria. Rule, Britannia!

Re: ByVal and ByRef behaviour, and general varied argument behaviour, in windows API Declare lines and VBA winapi coding

Post by DocAElstein »

I recognise the cover of that book, it might be one of the 100 VB books I collected a few years back. But I don’t feel like searching through and cleaning the dust off those just yet, - I was planning to make a book shelf behind where I might sit when I make videos and use all those books as decoration.
It looks very cheap currently on eBay, and a few other places. I will get another to hang on one of my trees for Xmas
Regards , Ālan , DocÆlstein :england: , :germany: