1 Attachment(s)
VBA Input Pop up Boxes: Application.InputBox Method versus VBA.InputBox Function [Solved]
VBA Input Pop up Boxes: Application.InputBox Method versus VBA.InputBox Function
Hi
Recently I have been trying to revise my knowledge of various ways to get simple user interaction with simple Pop ups. ( Later I will go into the “custom route” and learn about UserForms )
I started at a fairly ignorant level of knowledge and I thought the notes that I made for myself could be useful for someone learning about these things, so I am sharing them here. I have noticed some problems / Bug “features” , so I might try to extend the notes later to try to share an alternative semi – self made solution using the available collection of supplied with Windows small additional programs ( API, User 32 dll stuff ) that can also be accessed in a “user customerised” way in VBA.
But Initially , I am talking about these two things:
https://msdn.microsoft.com/en-us/vba...x-method-excel
https://msdn.microsoft.com/en-us/lib...ffice.11).aspx
https://msdn.microsoft.com/en-us/vba...utbox-function
https://powerspreadsheets.com/excel-vba-inputbox/ )
Bug Features
The comparison of these two similar things is complicated by various Bugs in Application.InputBox . Often when one gets caught out for the first time by such a Bug , then one learns of the two similar alternatives available in VBA to get an Input Pop up Box
I have never quite got a clear understanding or definition of the difference between a Method and a Function in these things. However in this case that is probably the key to understanding the difference.
My conclusion at the end is that the Application.InputBox Method is something of an abortion, and I hope to give later a simple alternative to one of its most popular uses, that of returning the range object of a selection made by the user in a worksheet.
Preparations Some preliminary stuff. ( Help File )
To help test check and understand the differences it is necessary to do some preliminary stuff which due to other Microsoft Bug features may not work. :( Never mind.
Follow the following instructions. You need to get a “working” Microsoft help type Window to pop up. If you cannot get it to work then never mind: It just means that you will have to forgo on a demo of one of the features.
So, here we go… Prepare a new File, or use a spare one. Important is that you save it as .xls, not .xlsm. It would be useful if you have access to two Excel versions:
Excel 2003 or earlier
and
Excel 2007 or later.
If not, no worries – you will just have to forgo on a few other experiments.
Having got a File saved somewhere ( it does not matter where it is saved ), then download this file:
https://app.box.com/s/bx2pkvtemsppscz60rd6f430wm89c6fj This is a “.chm Microsoft Help file” It has the name _ AnyFileName.chm
Important is to save it in the same folder as your file. Try and open that file
either
_1 directly, if your browser gives you the option, example for Google Chrome: GetOpen_1_2.JPG https://imgur.com/gRjn0HJ https://i.postimg.cc/3wt0t6PP/Open-d...-help-file.jpg
Or
_2 by double clicking on the file in Windows Explorer https://i.postimg.cc/cHmmdXtW/Double...s-Explorer.jpg GetOpen_1_2.JPG https://imgur.com/gRjn0HJ
_3 Or another typical short cut way you know to open a file, etc.
Or
_3 Use this code
Code:
Sub HelpGetItUp_3()
Application.Help HelpFile:=ThisWorkbook.Path & "\AnyFileName.chm", HelpContextID:=2
End Sub
Click on the Help Button, You should see this:
HelpGetUpBollox.JPG https://imgur.com/KdKOYWr https://i.postimg.cc/tT7Zwkb7/Help-B...-Input-Box.jpg
If that does not work… you could try to sort it out based on the information here: https://www.excelforum.com/excel-new...ml#post4827566
If you can not get that to work, then no worries – you will just have to forgo on a few other experiments.
InputBox Method and Function. Method or Function
I think loosely a Function is defined as some sort of process, Sub code , set of instructions or some pre defined way of doing something. In normal life a Method is just another word for that. In programming the word Method might loosely be described as a Function “within” an Object and/ or a Function “using” things in an object. There lies the crux of the difference.
So if there is any truth to that last explanation, then the basic or more fundamental or more “lower level” of the two things can thought of as being the….
Input Box Function.
This returns a string of what the user types into the Pop up box which should come up when you use a code of this form:
Dim strReturned As String
_ Let strReturned = InputBox(Prompt:="Type Something in", Title:="MyBox", Default:="Something", xpos:=100, ypos:=100, HelpFile:=ThisWorkbook.Path & "\AnyFileName.chm", Context:=2)
A code like that should give something like this:
InputBoxFunctionWithHelpButton.JPG https://imgur.com/htritBi https://i.postimg.cc/tgqVtym3/Type-s...-Input-Box.jpg https://i.postimg.cc/tTny1qxR/Input-Box-Something.jpg
As far as I know all is well understood and works with the VBA InputBox Function.
One thing worth having a quick play around with at this stage is those x y positional numbers
It should result in the box coming up in different places. In the next post I have a demo code, and the first short part, Rem 1 , has those code lines. So.. open your .xls file in Excel, hit Alt+F11 to get into the VB Editor, paste in that code into the large Code window, then run the code, preferably in Debug Mode, F8, for this initial selection. Then you can hit the stop button ( VBEditorStopButton.JPG https://imgur.com/0o8Ojqm https://i.postimg.cc/rwCrrzgy/Stop-Button-VB-Editor.jpg ), edit those positional number values, the re run the code.
_._______________________
For Input Box Function When that is showing, you do not have any chance to select anywhere in the spreadsheet. You simply have to enter a string value into the Pop up Input Box Input Bar. The technical term here is along the lines of “The VBA InputBox Function is always Model” . In English that means you can’t do anything else in the worksheet until you either close the pop up Input Box or Hit the OK Button. Effectively the Excel Window is “hung up”, or “control is passed” to the Pop up Box
This is perhaps a very important point , particularly in discussions of the difference in the two
Application Input Method
From now on it is a bit of a complicated mess because of Bug features.
The basic idea is that within the object that is the current instance of the (Excel in this case ) object ( known loosely as the “Application” ) that the VBA InputBox Function is used somehow. That is to say , one might imply that the Application Input Method somehow uses the VBA InputBox Function “within it”, that is to say it is using for it data / information from the Application object.
I doubt anyone knows much better then that description for sure.
And I question whether there is any truth at all to that.
Clearly who ever “invented” it doesn’t know what is going on. If he or she did, then it might work consistently or the Bug features which have been around for about 10 years might have been fixed. I only have Excel 2003, 2007 and 2010. As far as I can see the Bug features started at Excel 2007 for the Positional arguments, and are still there in Excel 2010. If anyone following this and trying the experiments on a more recent version can add anything here then that would be welcome.
But the Help option arguments do not appear to work in any version for the Application.Input Box Method. So probably the Application Input Method was flaky right from the start and got worse as time went on.
Very briefly for now, and just as a quick approximate statement: The difference in the two things is that the Method has an extra last optional argument and if that is included then what is actually done is a bit more complicated ( I would suggest it is a mess actually – hence someone messed up and that causes the Bug features ).
Before we go full out in using the Application Input Method, consider the following that is often seen in Microsoft documentation:
……. that Application.InputBox calls the InputBox method; InputBox with no object qualifier calls the InputBox function.
I don’t think this makes any sense, or at least it is very unclear.
One reasonable interpretation is that the box that comes up probably does not have a lot to do with the VBA InputBox Function once the last optional argument of type is given. Or visa versa, a reasonable interpretation of that might reasonably be that without the extra last optional Type:= argument then effectively the InputBox function is done.
A short bit of experimenting suggest however that in any situation ( that is to say any argument selection used, even the minimum of just the first ( only not optional ) Prompt:= ) , something significantly different is going on with the Application.InputBox Method compared to the VBA InputBox Function.
Regardless of whether the last argument, Type:= , is given or not, clearly what happens is significantly different in the case of Application.InputBox Method compared to VBA InputBox Function
I did some experimenting, and my observations are that for any options combination you have, with Application.InputBox Method , an additional possibility to add data other than just entering into the Box input bar: You can select the spreadsheet: Although the code that fires up the Application.InputBox Method “waits” , it is possible to make a selection in the spreadsheet. (The Application.InputBox is "Non-Modal"). If a selection is made then the address is shown in the absolute column letter and row number notation ( Like $A$1:$B$6 etc.. ) appears automatically in the pop up box input bar. It would appear that some coding determines what to return based on the area selected and the Type:= . ( If no Type:= is given the default type is taken as Text (a string), ( but as noted, the Application.InputBox Method does not then simply work as if it were the VBA InputBox Function )
A full code is given in the next post in which a section, Rem 3 , loops through types allowing an input for each type to be made. ( As is standard for the Application.InputBox Method you can make an entry by typing into the pop up box input bar, or make a spreadsheet selecting in which case the pop up box input bar is automatically filled with the selection address in the absolute column letter and row number notation.
Note that for the case of a returned range object, there will not be an error in assigning the returned thing to a variant ( Let Var = , or Var =) , ( rather than a more conventional in this case of Setting it to a range object) , as this is a typical case where VBA returns the default property of .Value from the range object. However the code has to do a bit of juggling about for this return and in the case of an Array return in order to show those values in a single displayable String
After selecting OK , a message box attempts to show what is actually returned from the Application.InputBox Method.
( If you have any difficulties with the help optional arguments_...
HelpFile:=ThisWorkbook.Path & "\AnyFileName.chm", Context:=2
or
HelpFile:=ThisWorkbook.Path & "\AnyFileName.chm", HelpContextID:=2
-…. Then if you cannot get the workarounds ( https://www.excelforum.com/excel-new...ml#post4827566 ) to work then simply remove them and ignore the help stuff )
_.______________
My guess is that there is a messy routine full of bug features which looks initially
either
at what is inputted by the user in the Input Box Input Bar,
or
if a selection is made by the user in a worksheet, the address is placed into the Input box, and a note is made of the actual range object that is referred to by the selection.
Thereafter an attempt is made to give a Type correct return. Depending on exactly what is inputted, this may or may not be accepted. This last point is reasonable I think.
As example: if type Number is specified in the options ( ____, Type:=1 ) _ ‘ Number ) then
an error occurs if a string is inputted or if a cell is referenced which has a string in it. A reference to an empty cell will result in _ 0 _ for this case. This is consistent with assigning a Number variable to the .Value of a range object.
If no string is entered into the Input Box Input Bar then Application.InputBox Method issues a pop up warning that an incorrect entry has been made. You are able then to correct this by adding a correct entry. It is not clear from this exactly what process then follows, but clearly it is a bit different to the user worksheet area selection case.
For all but the Type:= range and Type:= array , and Type:= formula, a multi cell selection results in just the top left cell being considered.
A full listing of what happens for different entries for each type would take a book. I might do that later. For now it is probably best to experiment with the code for the thing you are trying to do and variations thereof. Better still, don’t use the Application.InputBox Method as it is too flaky / full with bug features.
In the over next post I may try some alternatives, but not yet the UserForm. For now I am interested in the more standard/ simpler alternatives.
Demo code in next post and a few other places possibly: ( https://www.excelforum.com/developme...ml#post4829620
https://pastebin.com/58U8eagx )
References in the next post also.
Pop Up User InputBox with range selection alternative with API User 32 dll Programs
Pop Up User InputBox with range selection alternative with API User 32 dll Programs
The major 2 differences of interst to us here, between the ( VBA ) InputBox Function and the ( Application ( Excel ) ) InputBox Method were seen to be that
Rem1_a) The InputBox Method has the ability to make a Worksheet range selection whilst the Pop up box is active
_b) The InputBox Method is flaky, aka Bug features
_b)(i) Microsoft “Help” doesn’t work
Rem2_b)(ii) the positional arguments don’t work in Excel 2007+
Some attempt will be made to explain some Windows API User 32 dll Programs background ideas to make a simple Pop Up to come close to realising a Pop Up User InputBox with range selection.
Part a) Worksheet range selection whilst the Pop up box is active, ( and _b)(i) Microsoft “Help” )
Manipulating “Windows”.
It would appear the word “Windows” is a name for a programming idea which might result in something we “see” as what we conceive as Windows. Manipulating of the actual “Windows” seems the key to pseudo “making my own” InputBox with range selection.
Doing this in any language is a task for a computer genius, and in Visual Basic the documentation is very sparse. But “API User 32 dll Programs” would appear to make this possible. I can only attempt to get a working solution with a very light-minded fecile understanding.
It would appear that direct linked libraries (dll) are available to run as and when required, hence the wording of direct link: They are used as an efficient means to organise Microsoft’s software generally allowing different Applications to share smaller programs which are shipped as standard with the Microsoft Windows Operating system. They are however also available to programmers , programming the applications.
API , “API Calls”
The things discussed in the last section gets bundled up in an imprecise intimidating term API, for Application Programming interface. They are usually contained in a Folder with a name similar to User 32.
Another seemingly intimidating phrase is “API call”. You may hear the term “I am using API calls”. It just means usually that you are using those things and related “Windows” concept
Here’s a “API Calls” “thing” that I am getting familiar with using for now.
Function thing __ SetWindowsHooksExample AliAs SetWindowsHookExA
This is one of the Library programs that can be used. I have been told by some professionals that in actual fact these Library programs are organised in a similar way to the Libraries that one can pseudo Import by “checking a reference” in the list of available to VBA code libraries. However by some subtlety that they are not sure about they cannot be used in a code in the way of through declaring ( Dim ing ) them and then after assigning a variable using that variable to “get at” the various Methods / Functions inside them.
In place of the normal declaring ( Dim ing ) that would be within a routine, in the case of the Library programs being used here, you must do a sort of initial globial type Declaration. For this thing that I am intending to use, it looks like
Code:
Private Declare Function SetWindowsHookExample Lib "user32" Alias "SetWindowsHookExA" (ByVal Hooktype As Long, ByVal lokprocedureAddress As Long, Optional ByVal hmod As Long, Optional ByVal dwThreadId As Long) As Long
Declareing Declare Type Functions
You don’t always need the AliAs bit in these things. ( It just means _ this Lib "user32" _ Ali As ¬_ “that” _ (that is the Microsoft name , this is any name that I choose to use) ). Occasionally something can only be done to the AliAs where numbers and variable used to refer to things are concerned. It is subtle general point in computing that you might get problems when a number is used to refer to something that might take or give a number at some point. But you might need to do that, so having an intermediate word is a workaround for that so that the number is set to a word which is then related to a word that might be being referred to or returning a number.
Function = Word
Word = 873248
So the Function can be referred to by a number indirectly, --- occasionally this may not be possible directly, --- Function =837547 might error for subtle computer reasons.
It seems to do no harm to use an AliAs when you don’t need it and it helps to make a code prettier.
( Per PM request, Just as a comparison, I did no AliAs for one of the other things that I am using, so you can easily work out the syntax difference ( Function GetCurrentThreadId Lib "kernel32" () As Long ) http://www.excelfox.com/forum/showth...0478#post10478 )
Once Declared you can think of them to a first approximation as a function written in a code module in the Folder on your computer with the name something like “User32” or “User32dll” or similar. You then use them to a very crude approximation as you would any conventional function that you may have made and which is typically in a VBA code module, like pseudo
_ x = SetWindowsHookExample( 3 , y , _..__…… etc )
For use in a normal code you can use Private or Pubic. As in convectional VBA Functions Pubic will not confine the use of the function to the macro module in which it is in.
For a class code module, such as a worksheet code module ( To get there, right click the worksheet's tab and select View Code ), these Declare type functions must be Private
Owned “Windows”, and/ or z order.
It is well above my knowledge to explain all concepts here, and as noted some things will have to be read as “on the tin” or in other words its faecile value.
A Pop up is apparently always the one on top of to be seen ( “above on the screen “z axis” “ , - as a approximation the z axis is in the direction looking at it ) of the Window to which they belong and they always “belong”” to a parent window… well maybe something is not quite clear there…
It is not always clear what “z option” does what, and even professionals sometimes seem to choose it from trial and error .
But anyway these are two things that will need to be taken into the equation… or rather the “API calls” that I do..
Hooking a “Window” to Handle it ..Computer Bollox terminology.
I have needed to get some terms undefined correctly. Words like Handle and Hook are computer terms similar to the word Bollox in normal language and can be used alone or in conjunction with other words to have some meaning possibly in the context in which they are used but cannot have any precise meaning. Defining them as some computer bollox to do with handling and identifying Windows is a useful way to understand these terms.
Some handle bollox will need to be taken into the equation… or rather the “API calls” that I do..
Some published literature even supports my somewhat naive and critical resume, saying the words can mean a number of things. In our case the handle can be thought a number identifying a Window. A Hook can be thought of as hook or trip trap placed in some run or chain of events cause shuddering or jerking off of a procedure. This is related to the idea os Sub Classing of a window discussed below as a possible solution to the second _b)(ii) the positional arguments
MsgBox Pop up.
At the time of writing this I have not figured out or found any InputBox API . I have found and got working some Message Box API’s . So for now I will look at Message Boxes Pop Ups in API calls. To make a better 1 to 1 type equivalent to my attempt and a InputBox method, some InputBox API would have been better, but for the specific requirement of making a range object selection, my attempt and the InputBox method work similarly. The non modelness is an important simularity
Handleing of the MsgBox Pop up
The code in the following post attempts to put some clarity, as far as I am able, on what the handle of the MsgBox, or rather on what the handle of the API User32 Windows dll MessageBoxA Function might be about.
I am able to find A “handle to a Window” that allows me to make the API User32 Windows dll MessageBoxA appear to work as the Standard VBA MsgBox, but with the extra feature of non modalability.
In all other cases of either a successfully found handle number ( to which it belongs is not clear to me ) or an unsuccessful found handle number ( hWnd is then 0 as returned from FindWind___ ), I appear to have a “non modal” Pop up box, in which case I have the possibility to make a spreadsheet selection with the Pop Up, popped up
Some further reading has suggested that the unsuccessful found handle number returns a specific type of Long Null and contradictorily to some other literature suggests that this pop up must not have a owner window. There may be some more subtle points to it, but for now the use of the special symbol for a Long Null _ &H0 _ would suggest that the major part of the solution can be reduced to a simplified code lines such as in '2e) This will do then
Pop Up Window Positioning with API WindowsHook
https://www.excelfox.com/forum/showt...ll=1#post10471
Part _Rem2_b)(ii) the positional arguments
Although, the important feature of the spreadsheet selection possibility whilst the Pop Up is up has been realised, ( and also another issue, the Microsoft “Help” appears to work ) , the position and size is somehow in someway coming to a default value, there is no position or size option
I am guessing that possibly it is not sized as such and that there are predetermined rules for an owned “Window”. There size is possibly predetermined from some pre determined “Window” that does not generally have the resize option , although positioning is somehow possible..
The feature of controlling the size was an option in both the Application InputBox Method and the InputBox Function. In the case of the InputBox Method it appeared to broken from Excel 2007+
I am not particularly interested in sizing and positioning after the event as I want a fairly fundamental Pop up for simple user input.
It turns out that this requires some very complicated processes.
It requires a full understanding of “Window”s. I can only attempt a very short very light-minded fecile overview. That will be discussed in the next posts: in Brief:
Sub Classing / Redefining a “Window”
As is generally the case with “Window” Functions, A window belongs to a class. The Dynamic Linked Libraries concept allow the small programs in the with windows shipped typically in the User32 Folder programs to be called up / used at runtime, rather than a fixed set of instructions copied or and/ or used as such at some point. This allows for a modification of the class, known as Sub classing.
This means that it is possible to modify / add to the “Window” Function and so pseudo create a customised dll. It does not necessarily mean that a “Window” Function or a used User32 Folder program is directly Sub classes , but it just happens to be in our case as we are intending to mess about with the MessageBoxA ( or MessageBoxTimeoutA )
Trigger Events Codes in Windows programs
If you are familiar with Event triggered codes in VBA then the way to do this you can consider as similar idea:
You can arrange that a used “Window” Function is modified as it is used.
Similar in the way that a Worksheet_change code is triggered as something happens, you must arrange that a VBA Function is triggered when a Windows “event” occurs. At this point the concept gets a bit vague and I doubt many people really understand anymore how it really works. A good name for the VBA Function might be Function WinSubWinCls_JerkBackOffHooKterd.
This VBA Function will itself be a pseudo “Window” Function and “hung” or hooked on a chain of events. Because of the dynamic / volatile nature of the stuff, things will have a habit of going on forever if they not “unhooked” such that a procedure will have to be designed to unhook itself. This will mean that generally this event triggered type code will only work once. A simple solution to make the solution work in a code for any number of message boxes would be use a simple routine which does two things, like pseudo
Sub()
' A) Hook the pseudo Windows Sub Class Function WinSubWinCls_JerkBackOffHooKterd
' B) Call the MessageBoxA
End
***The actual form of this will be close to these pseudo codings. It will be explained a bit more in detail later..
Code:
Sub HookAPIssinUserDLL_MsgBoxThenDropIt()
' A) HOOK Hook the pseudo Windows Sub Class Function WinSubWinCls_JerkBackOffHooKerd
Let hHookTrapCrapNumber = SetWindowsHooksExample(5, AddressOf WinSubWinCls_JerkBackOffHooKterd, 0, GetCurrentThreadId) ' (5-pull before flush, somehow arranges that the function gets called ,
' B) Call the MessageBoxA
APIssinUserDLL_MsgBox(hWnd:=&H0, Prompt:="Yes, or No to ReCheck, Cancel for help ", Title:="Selection Check: Address is " & Rsel.Address & " Value is """ & Valyou & """", Buts:=vbYesNoCancel) ' ' Pseudo Non Modal Message Box
End Sub
Or
Code:
Sub HookAPIssinUserDLL_MsgBoxThenDropIt()
' a) HOOK Hook the pseudo Windows Sub Class Function WinSubWinCls_JerkBackOffHooKerd
Dim BookMarkClassTeachMeWind As Long: Let BookMarkClassTeachMeWind = 5
Let hHookTrapCrapNumber = SetWindowsHooksExample(BookMarkClassTeachMeWind, AddressOf HoldYaBackCalledYaBackClapTrap, 0, GetCurrentThreadId) ' (5-pull before flush, somehow arranges that the function gets called ,
' b) Call the MessageBoxA
APIssinUserDLL_MsgBox &H0, "Select Range", "MutsNuts AkaApi working ApplicationPromptToRangeInputBox", vbOKOnly ' Pseudo Non Modal
End Sub
' B) Call the MessageBoxA
This is simply our
Code:
__ APIssinUserDLL_MsgBox(hWnd:=&H0, Prompt:="Yes, or No to ReCheck, Cancel for help ", Title:="Selection Check: " & RngSel.Address, Buts:=vbYesNoCancel) ' Pseudo Non Modal MsgBox
We need now to find the solutions to two things, I will try to give them a identifying “handle”
HOOK _ ' A) Hook the pseudo Windows Sub Class Function WinSubWinCls_JerkBackOffHooKterd
and then
PROC _ we need the ( VBA in this case ) Function/ Sub Procedure in that we will be hanging, / dangling on, a chain of events / effectively making a Windows Sub Class. I am calling this:
Function WinSubWinCls_JerkBackOffHooKterd.
Sub Classing Windows aka in English: One way to mess about and modify the underlying Windows processes within a VBA code to get extra and novel solutions
The following I will repeat a few times as it is a seemingly complicated way of doing stuff, and a bit off a *** “chicken and egg” thing to try and explain. It is very difficult to start anywhere, as you usually need to go back and forth constantly when explaining the underlying concepts. This is reflected in the very complicated interrelated processes and interactions going on in a final solution
I will do my best to explain it in some sort of logical order. In parallel to the last two issues we have
HOOK_ Setting a hook
The Hook bollox word in this situation can be thought of as
_(i) lots of hooks on a lot of different things / events that might happen. Alternatively a cyber robot keeping his beady eyes on lot of different things / events that might happen
PROC _(ii) Some process / procedure / Function or similar that would be done on if any of the hooks are aroused. This (ii) may sometimes be referred to in literature as the hook procedure
Refs:
Microsoft Windows Features : types, states, size, and position : https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx
User 32 API VBA Function list :
Dan Appleman “Visual Basic Programmer’s Guide to the Win32 API”
https://www.excelforum.com/excel-pro...rary-list.html
Getting some Messsaga Box API Call’s working:
http://www.eileenslounge.com/viewtopic.php?f=18&t=28885
https://www.excelforum.com/excel-pro...dll-stuff.html
http://www.vbforums.com/showthread.php?329373-MsgBoxEx-Extended-Message-Box[/url]
https://eileenslounge.com/viewtopic....321874#p321874
Microsoft help (argument options): http://www.excelfox.com/forum/showth...0467#post10467
Pop Up Window Positioning with API WindowsHook "User32” dll User Inpfuts Plop up stuff
Sub Classing Windows aka in English: One way to mess about and modify the underlying Windows processes within a VBA code to get extra and novel solutions
“First Part HOOK” Setting a hook
The Hook bollox word in this situation can be thought of as
_(i) lots of hooks on a lot of different things / events that might happen. Alternatively a cyber robot keeping his beady eyes on lot of different things / events that might happen
There is an API program available for this is
Code:
Private Declare Function SetWindowsHookExample Lib "user32" Alias "SetWindowsHookExA" (ByVal Hooktype As Long, ByVal lokprocedureAddress As Long, Optional ByVal hmod As Long, Optional ByVal dwThreadId As Long) As Long ' https://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx
Setting a Windows Hook
The way this particular API Function, SetWindowsHookExA , works must have been deliberately designed to confuse in my opinion. I say this in particular because of the returned Long number is probably better considered as one of the functions arguments to be passed in some hidden process or procedure or instructions written on a bookmark or written on the class defining notes of , many bookmarks
Very approximately and simply put: This code line _..
SetWindowsHookExample(5, AddressOf HoldYaBackCalledYaBackClapTrap, 0, GetCurrentThreadId)
_.. is “responsible” or “organises” to a large extent how and when the Function ( PROC hook procedure )which is discussed in the next post is called
This code line might give the impression that there are 5 arguments type parameters to it.
SetWindowsHookExample(5, AddressOf HoldYaBackCalledYaBackClapTrap, 0, GetCurrentThreadId)
To see pseudo all the arguments you must consider that code line in the full used form
hHookTrapCrapNumber = SetWindowsHookExample(5, AddressOf HoldYaBackCalledYaBackClapTrap, 0, GetCurrentThreadId)
Pseudo we have, or rather Declareation makes more sense to me
Code:
Declare Function SetWindowsHooksExample Lib "user32" Alias "SetWindowsHookExA" (ByVal hHookTrapCrapNumber As Long, ByVal Hooktype As Long, ByVal lokprocedureAddress As Long, Optional ByVal hmod As Long, Optional ByVal dwThreadId As Long) As Long
, in other words to look in a code like this:
SetWindowsHooksExample(hHookTrapCrapNumber , 5, AddressOf HoldYaBackCalledYaBackClapTrap, 0, GetCurrentThreadId)
It probably should have been. But never mind. But because of this daft way of putting the hHookTrapCrapNumber as the Function’s return, I must have a global variable for my hHookTrapCrapNumber so that I can get later at it in the hook procedure Function WinSubWinCls_JerkBackOffHooKterd
Here an attempt to explain those arguments in English:
(… my HoldYaBackCalledYaBackClapTrap or WinSubWinCls_JerkBackOffHooKterd is my hook Procedure .. just to remind )
hHookTrapCrapNumber : This has the computer bollox word hook in it, so no one quite knows how to define it.. it can be thought of as a number of a Window in this case. But not in classic “seen Window”. In this case it is more of a number to identify a bookmark or class of , many bookmarks. Alternatively it is the name of our cyber Robot who could be called a Microsoft Windows program. He may or may not be residing in the User 32 Folder.
5 : lets call this a Type of a hook a Handled or set trap point , ( or in English think of it as defining/ making a book mark type to be put in a book / books, that is / are likely to be going to be read at some later point in time_ 5 is the one that is defined or set to be fired by most stuff to do with window manipulations, as well as some other more advanced stuff that goes on. Alternatively this could be selecting the class of bookmark for those that will be placed in a few places by the API Function SetWindowsHookExA
The number 5 is what we want. But we have mentioned that for subtle computer reasons it is generally a good idea to have and use a variable holding this number rather than direct number. It is also helpful in our particular case as we will see that another option defining number sent to out hook procedure could be 5 , and we test for that later. So just to avoid confusion I use a variable _ BookMarkClassTeachMeWind = 5
AddressOf : This is called an Operator. An Operator is a computer word which in normal English means “some Bollox or other”. This stores in some secret place a number used to identify where to find the WinSubWinCls_JerkBackOffHooKterd
So you had better have a WinSubWinCls_JerkBackOffHooKterd or you will get a compile error when running a code with the AddressOf WinSubWinCls_JerkBackOffHooKterd inside the (arguments, , , ) section of the use of the dll / User32 Function
0 : Think of this as one of two radio buttons. The other one is the second argument , AddressOf WinSubWinCls_JerkBackOffHooKterd . The arguments are a bit similar. It was probably just done in two rather than one to confuse and intimidate me and my kind. So it is set to 0 as the other one is more like how and where my “hook” Procedure Bollox is
GetCurrentThreadId : The Thread is what is going on, I expect that means in this case my VBA. My computer might do something else with or without me knowing. Most things going on will have a Thread number. When used in my code, Function GetCurrentThreadId will return an identifying number referring to the Excel instance that that code line is in.
_.____
Where are we?
At this point, that is to say on completion of this code line, we can think of many Bookmarks having been placed. Think of an idea of a Windows form which we built a class Form for, and may have many open instances of it. It is difficult to find any better description of the situation. Whatever instances or “things” are hooked in place, they are waiting like a trap waiting to be tripped
There could be a few things that might trigger them off. The purpose of doing all this is to trigger it off when our Message Box Pops up. There is no guarantee that other things going on as a result of out message box coming up may not also trigger one or more of the things. In fact, experiments by me have shown that typically 4 times a bookmark “hook” is triggered before the event that I actually want does the triggering.
We need to try and arrange that we react appropriately to the required trigger.
Some selection is possible and this will be a applied in the PROC hook procedure.
In addition the possibility of a reacting to a false trigger in a program generally is minimised by putting the MessageBoxA call immediately after the call if the API SetWindowsHookExA function, as is the case in our Sub Procedure, Sub HookAPIssinUserDLL_MsgBoxThenDropIt().
Code:
Sub HookAPIssinUserDLL_MsgBoxThenDropIt()
' a) HOOK Hook the pseudo Windows Sub Class Function WinSubWinCls_JerkBackOffHooKerd
Dim BookMarkClassTeachMeWind As Long: Let BookMarkClassTeachMeWind = 5
Let hHookTrapCrapNumber = SetWindowsHooksExample(BookMarkClassTeachMeWind, AddressOf WinSubWinCls_JerkBackOffHooKterd , 0, GetCurrentThreadId) ' (5-pull before flush, somehow arranges that the function gets called ,
' b) Call the MessageBoxA
APIssinUserDLL_MsgBox &H0, "Select Range", "MutsNuts AkaApi working ApplicationPromptToRangeInputBox", vbOKOnly ' Pseudo Non Modal
End Sub
So at this point in the discussions we are ready to consider and write our PROC hook procedure such that it will do what we want it to do after this code line is done
_ MsgBox &H0, "Select Range", "MutsNuts AkaApi working ApplicationPromptToRangeInputBox", vbOKOnly ' Pseudo Non Modal
So at this point in our descriptions we have got as far as having and possibly understanding a VBA Sub Procedure, Sub HookAPIssinUserDLL_MsgBoxThenDropIt().
The significance of this is that in a code we will be able to
_ Call HookAPIssinUserDLL_MsgBoxThenDropIt()
This will have the effect of doing the necessary to arrange that then the_..
_ MsgBox &H0, "Select Range", "MutsNuts AkaApi working ApplicationPromptToRangeInputBox", vbOKOnly ' Pseudo Non Modal
_..riggers off the PROC hook procedure, which I am going to call
Function HoldYaBackCalledYaBackClapTrap(!!!argumentssended !!! )
Or rather some triggered happening takes place and somewhere towards the end of this happening my HoldYaBackCalledYaBackClapTrap(!!!argumentssended !!! ) is passed / sended some arguments and set off running
“Triggered happening” of………
Bookmark Procedure or
Hidden Microsoft triggered code or
What is trigger set to do / !!!arguments send.. , , !!! or
Microsoft CBTProc callback function ( https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx )
This Procedure should not be confused with my, still to be written, Function HoldYaBackCalledYaBackClapTrap(!!!argumentssended, , !!! ……) or maybe in a way of thinking it is. I am not too sure.
In any case some happening has taken place and the referenced article is related to this Happening. This particular happening rather than any other is done by virtue of us selecting the option of 5 when setting the hook ( BookMarkClassTeachMeWind = 5 --- SetWindowsHooksExample(BookMarkClassTeachMeWind, , __)
or
SetWindowsHooksExample( 5 , , __) )
The important information from the Microsoft article is the information regarding three parameters that I have indicated by !!!arguments send..!!!
Somehow what the CBTProc callback function does is to “hold” these arguments for our Function HoldYaBackCalledYaBackClapTrap(!!!argumentssended, , !!! …… .
So it is going to be important to write a Function in that three parameter argument signature line form. It seems as though that article describes some “skeleton” structure that I must adhere to in the Function design.
It is important also to use a Function rather than a Sub routine: I do not think that I need to concern myself with this returned value. But I need to make my structure support this. I think. ( ..it crashes my Excel if I do a Sub routine ! )
Summary of so far..
This post summarised the main and pseudo Calling codes. At least it does in terms of the API bollox part of it.
I say pseudo Calling because the main purpose of the codes is to “Call” my “ “Hook” Procedure “ Function, the Function to be set up in the next post as the Function HoldYaBackCalledYaBackClapTrap “ “Hook” Procedure “
But the main strange unusual characteristic of the code concepts is that there is no conventional Call code line
The whole point of what is difficult to understand is that the codes have done the stuff necessary so that when the last main bit of the code is done, ( APIssinUserDLL_MsgBox ___ ) the event that then occurs will trigger / fire the Function HoldYaBackCalledYaBackClapTrap.
With hindsight is not difficult to understand and say in plain English:
If _…
_..you just had the last main code bit of this sort of form:_..
APIssinUserDLL_MsgBox &H0, "Select Range", "MutsNuts AkaApi working ApplicationPromptToRangeInputBox", vbOKOnly
_... then a message box pops up. That is all there is to it.
_.. But, … because of all the hooking bollox, when that Message box starts to come up, or when the chain of events waggles in anticipation, then that triggers/ fires the Function HoldYaBackCalledYaBackClapTrap
Final Function --- Function HoldYaBackCalledYaBackClapTrap( , , ) As Long ' --- PROC Hook Procedure
Some conclusions from experiments on various codes types.
Two main ‘_- observations
‘_- Stopping the function.
I have done a number of experiments, as briefly explained at the end of the last post.
Some important observations:
It seems that my “hook procedure” function will potentially be triggered indefinitely. Possibly this is reasonable. It is further reasonable that the simple API Function call already discussed is needed to stop the function being triggered once my function has done its main purpose:
Here an Ali -As-‘d version of this code line:
UnHookWindowsHookCodEx hHookTrapCrapNumber
The corresponding Declare line for that would be
Private Declare Function UnHookWindowsHookCodEx Lib "user32" Alias "UnhookWindowsHookEx" (ByVal hHookTrapCrapNumber As Long) As Long
‘_- Doing the Pop up window sizing and positioning ( API User32 dll program SetWindowPos)
Originally the issue for which my Hook procedure Function was required was the _ Part _b)(ii) the positional arguments _ .
The API Function which appears to have been used in Visual Basic and VBA codes in similar issues to this is the
SetWindowPos ( https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx ). This looks potentially very useful as it can change_..
_..all three positional co ordinates, horizontal (x), vertical (y), and the “z axis” “Z order”. ( The last z coordinate can be thought of to a first approximation as the axis looking onto the screen, the “top z” then being the window “seen” above all others ).
_.. also, as a bonus, it can also be used to change the seen Window width and height.
The syntax in a code line use of this function is pseudo like
_ SetWindowPosition _ WindowIdentifyinghandle, zorder , x , y , width , height , zFurtherInfo
The two z__ options are not too intuitive, and even some computer Professionals make an inspired guess for them based on a partial understanding of the documentation. The rest of the argument parameters are as “written on the can” _ x , y , width , height ( “says the tin”.. https://www.excelforum.com/excel-pro...ml#post4831198 )
From the experiments with use of this I was concerned about a seemingly unnecessary recursion process that seemed to set in. I also observed this in published Functions which were intended to do something similar.
My final Hook procedure Function differs therefore slightly in any I have seen so far in that it a globinal variable, GlobinalCntChopsLog, is used to keep track of the times that my Hook procedure Function is run. The constant jerking back and forth of the function, repeating, presumably by the “Bookmarks” reacting seemingly indefinitely is actually needed. As noted in the previous post we will do some selection to hopefully pick out the correct “event”, that is to say the appropriate event in the chain of events in which the “popping up” of our message box is included. But I am not sure if the extra recursion runs of copies of my function are necessary or desired. - The required action appears to be done on the first use of the SetWindowPosition . However a usage seems itself to trigger the function. I am assuming this is a recursion process so that another copy of my function is made and that is run. It does not, however, go into stack overflow. Consistently at the 29th recursion, it would appear that the recursion stops and each copy function is ended one after the other. ( A guess is that the stack might be limited somehow to 30 ). For my codes this resulted in a total of 6+29=35 runs: My function jerked itself off 5 times until a condition I set to hopefully find the event I was wanting to be caught was satisfied. So on the 6th run the SetWindowPosition code line was done. Experimenting on that showed that at this point all was done and OK as regards the positioning. A further 29 copy runs of the function appeared to be done, suggesting that the SetWindowPosition code line was responsible somehow for this. ( Example of this test code with output Log is shown here: http://www.excelfox.com/forum/showth...0478#post10478 )
Logic of my final Hook procedure Function
At the outset of the function, my gobinial variable is increased by 1. This intended to keep count of the copy number of the Function being run. It will therefore be reduced by 1 at the end of the function. Therefore, should a recursion run take place, ( that is to say a copy of the function is made and run ) , then the gobinial variable will hold the value of 2. A test for that will be made. This is tested for and If a value of 2 is found Then the “hook is released” and the function ended.
When my function is no in a recursion run, that is to say GlobinalCntChopsLog is not equal to 2 then the code proceeds as follows:
The value of the first argument lMsg at the incoming signature line _..
_ Function HoldYaBackCalledYaBackClapTrapRuc(ByVal lMsg As Long, ByVal wParam As Long, ByVal lParam As Long ).
_.. is investigated
This is done for the following reason:
As explained in the lost few posts, one result of the “hook” being “hanged” is that when one of our “bookmarks” is “triggered”, then some coding ( possibly the Microsoft CBTProc callback function ( https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx ) ) is responsible for passing information into the three arguments of my Hook procedure Function. ( Possibly this coding itself is responsible for all the other “placing of bookmarks” etc.. previously discussed ).
The first argument defines the type of “event” that has done the triggering. ( Remember we mentioned previously that it is an unfortunate co incidence that the number of 5 is what we are looking for here.. This was also the number which we needed to stipulate in the setting of the hook code line, hHookTrapCrapNumber = SetWindowsHooksExample(5, AddressOf , …….. ). That had a different meaning so should not be confused with the current 5 under discussion. )
The value of 5 specifies that the system is about to activate a window.
So If lMsg = 5 Then the code line_..
_ SetWindowPosition(wParam, 0, 10, 50, 400, 150, 40)
_.. is carried out.
_ wParam ________ is the passed windows identifying number for my Message box
10, 50, 400, 150 ___ are the horizontal and vertical size and positions
_ , 0 , _ , _ , _ , 40 __ The two numbers 0 and 40 are chosen after a bit of intuitive guessing based on the previous given Microsoft references. The end effect is to have the window seen as dominantly as wanted. They are likely to be based to some extent on experimenting in a particular requirement.
( As a function, the SetWindowPos is designed to return a value. In this usage I have not experienced problems using it as a Sub routine Call _..
_ Call SetWindowPosition( , , , , , , )
_.. but to be on the safe side I have used it as a Function returning its return in a Boolean variable, Booloks )
_.__________________
All the ground has been covered and explained as far as I am able to give finally a Pop Up User pseudo InputBox with range selection alternative with API User 32 dll Programs.
The next post will give a Summarised working full codes solution.
Pop Up User pseudo InputBox with range selection alternative with API User 32 dll Programs
Pop Up User pseudo InputBox with range selection alternative with API User 32 dll Programs.
This is a summary final working codes solution to allow a user to use a simple Pop up ( non UserForm ) to make an Excel range object selection.
This solution allows you to make a spreadsheet selection whilst the Pop Up is up.
The Standard stuff currently available
The VBA Message Box and VBA Input Box Functions are Modal, in other words you cannot do anything to the spreadsheet when they are up.
The Application Input Box Method should allow you to do this when you choose the last option as , Type:=8. It does allow you to do this, but a couple of things are broken:
_ The ability to position the Pop up ( appears to be broken since Excel 2007 )
_ The Microsoft help function does not appear to me to work in Excel 2003 2007 2010. I do not know if it ever worked for the Application Input Box Method
My Solution
This solution overcomes these problems, which is the main reason I did it, especially because of the first problem. It also has a few extra things that might be useful
_ You can choose the size of the Pop up ( width , height )
_ You can adjust the “z” things… I am not too clear on these options but in simple terms it means that you arrange how it appears in terms of the order of what windows you see, how and in which priority you see it, what windows are “under” or “above” it to see etc..
_ A simple change of the ByRef to ByVal in the signature line of a Called routine ( Sub HangAHookToCatchAPIssinUserDLL_MsgBoxThenBringThat MsgBoxUp(By___ ) allows you to change the value of a range object to that of the selection, but the original range object will not change, that is to say its address remains as before the selection. That could give you an extra option in how you select and move around in a spreadsheet.
All codes should be copied to the same code module.
The first sections Rem 1 and Rem 2 makes the necessary API programme available and declares (Dim’s) a couple of related globial variables. This section will need to go at the top of a code module.
Rem 1 is straight forward and makes available a pseudo Non Modal message box.
Rem 2 is a bit more complicated and makes available a few API program things needed to mess about with Windows dimensions when they come up.
Code:
Option Explicit ' “Window"s is a name for a programming idea which might result in something we “see” as what we conceive as Windows. Manipulating of the actual “Windows” seems the key to pseudo “making my own” InputBox with range selection. Direct linked libraries (dll) are available to run as and when required, hence the wording of direct link: They are used as an efficient means to organise Microsoft’s software generally allowing different Applications to share smaller programs which are shipped as standard with the Microsoft Windows Operating system. They are however also available to programmers , programming the applications. They are usually contained in Folder with name similar to User 32. "API calls”: just means usually that you are using those things and related “Windows” concept-all gets gets bundled up in imprecise intimidating term API, for Application Programming interface
Rem 1 Pseudo Non Modal MsgBox, MessageBoxA API Standard Non Standard Stuff, More Fundamentally complicated UnWRap it and.. "Pseudo Non Modal MsgBox" --- A valid handle, hWnd, other than the Excel spreadsheet window ( Private Declare Function FindWndNumber Lib "user32" Alias "FindWindowA" (Optional ByVal lpClassName As String, Optional ByVal lpWindowName As String) As Long --- hWndParent = FindWndNumber(lpClassName:="XLMAIN", lpWindowName:=vbNullString) ), or even no ( Null ) hWnd results in a pseudo Non Modal MsgBox http://www.excelfox.com/forum/showthread.php/2227-VBA-Input-Pop-up-Boxes-Application-InputBox-Method-versus-VBA-InputBox-Function?p=10476#post10470 http://www.tek-tips.com/faqs.cfm?fid=4699
Private Declare Function APIssinUserDLL_MsgBox Lib "user32" Alias "MessageBoxA" (Optional ByVal hWnd As Long, Optional ByVal Prompt As String, Optional ByVal Title As String, Optional ByVal Buts As Long) As Long '
'_- ==== The above is all I need to do so that writing APIssinUserDLL_MsgBox in any code in this code module will do something very similar to the VBA MsgBox. The main difference is that when it is up, I can still scroll up and down in my Excel Spreadsheet and also select a range.
Rem 2_b)(ii) == To set/change The positional arguments "Sub Classing a "Window"" As is generally the case with “Window” Functions, A window belongs to a class. The Dynamic Linked Libraries concept allow the small programs in the with windows shipped typically in the User32 Folder programs to be called up / used at runtime, rather than a fixed set of instructions copied or and/ or used as such at some point. This allows for a modification of the class, known as Sub classing. This means that it is possible to modify / add to the “Window” Function and so pseudo create a customised ddl. It does not necessarily mean that a “Window” Function or a used User32 Folder program is directly Sub classes , but it just happens to be in our case as we are intending to mess about with the MessageBoxA ( or MessageBoxTimeoutA ) You can arrange that a used “Window” Function is modified as it is used.
' The next four line will tie something on my chain for when you pull it. Similar in the way that a Worksheet_change code is triggered as something happens, you must arrange that a VBA Function is triggered when a Windows “event” occurs. At this point the concept gets a bit vague and I doubt many people really understand anymore how it really works. A good name for the VBA Function might be Function WinSubWinCls_JerkBackOffHooKterd. This VBA Function will itself be a pseudo “Window” Function and “hung” or hooked on a chain of events. Because of the dynamic / volatile nature of the stuff, things will have a habit of going on forever if they not “unhooked” such that a procedure will have to be designed to unhook itself.
https://www.youtube.com/channel/UCnxwq2aGJRbjOo_MO54oaHA
https://eileenslounge.com/viewtopic.php?f=27&t=35521&p=276185#p276185
https://eileenslounge.com/viewtopic.php?p=276185#p276185
https://eileenslounge.com/viewtopic.php?p=276185#p276185
https://eileenslounge.com/viewtopic.php?p=276673#p276673
https://eileenslounge.com/viewtopic.php?p=276751#p276751
https://eileenslounge.com/viewtopic.php?p=276754#p276754
https://eileenslounge.com/viewtopic.php?f=30&t=35100&p=274367#p274367
https://eileenslounge.com/viewtopic.php?p=274368#p274368
https://eileenslounge.com/viewtopic.php?p=274370#p274370
https://eileenslounge.com/viewtopic.php?p=274578#p274578
https://eileenslounge.com/viewtopic.php?p=274577#p274577
https://eileenslounge.com/viewtopic.php?p=274474#p274474
https://eileenslounge.com/viewtopic.php?p=274579#p274579
https://www.excelfox.com/forum/showthread.php/261-Scrolling-Marquee-text-on-Userform?p=864&viewfull=1#post864
https://www.youtube.com/channel/UCnxwq2aGJRbjOo_MO54oaHA