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
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