Page 2 of 2 FirstFirst 12
Results 11 to 13 of 13

Thread: Rough Notes, and posts to be referenced from elsewhere, on VBA Windows API

  1. #11
    Fuhrer, Vierte Reich DocAElstein's Avatar
    Join Date
    Aug 2014
    Posts
    9,454
    Rep Power
    10
    This is page 2
    https://www.excelfox.com/forum/showt...dows-API/page2
    https://www.excelfox.com/forum/showthread.php/2989-Rough-Notes-and-posts-to-be-referenced-from-elsewhere-on-VBA-Windows-API/page2
    This is post #11 forum post24916
    https://www.excelfox.com/forum/showt...dows-API/page2
    https://www.excelfox.com/forum/showthread.php/2989-Rough-Notes-and-posts-to-be-referenced-from-elsewhere-on-VBA-Windows-API/page2
    This is post #11 forum post24916
    https://www.excelfox.com/forum/showt...ll=1#post24916
    https://www.excelfox.com/forum/showthread.php/2989-Rough-Notes-and-posts-to-be-referenced-from-elsewhere-on-VBA-Windows-API/page2
    https://www.excelfox.com/forum/showthread.php/2989-Rough-Notes-and-posts-to-be-referenced-from-elsewhere-on-VBA-Windows-API?p=24916&viewfull=1#post24916





    Some notes, codings etc. in support of some other posts
    https://eileenslounge.com/viewtopic....321979#p321979
    https://www.excelfox.com/forum/showt...ll=1#post24904


    Getting some windows identification info
    .

    Main coding courtesy of Dev Ashish, http://access.mvps.org/access/api/api0013.htm
    ( and https://eileenslounge.com/viewtopic....321978#p321978 )
    I did some minor adjustments, mostly in output to suit my own experiments


    Code:
    ' Original main Code Courtesy of Dev Ashish  http://access.mvps.org/access/api/api0013.htm  and  https://eileenslounge.com/viewtopic.php?p=321978#p321978
    '
    Private Declare Function apiGetClassName Lib "user32" Alias "GetClassNameA" (ByVal Hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
    Private Declare Function apiGetDesktopWindow Lib "user32" Alias "GetDesktopWindow" () As Long
    Private Declare Function apiGetWindow Lib "user32" Alias "GetWindow" (ByVal Hwnd As Long, ByVal wCmd As Long) As Long
    Private Declare Function apiGetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal Hwnd As Long, ByVal nIndex As Long) As Long
    Private Declare Function apiGetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal Hwnd As Long, ByVal lpString As String, ByVal aint As Long) As Long
    Private Declare Function FindWndNumber Lib "user32" Alias "FindWindowA" (Optional ByVal lpClassName As String, Optional ByVal lpWindowName As String) As Long
    Private Const mcGWCHILD = 5
    Private Const mcGWHWNDNEXT = 2
    Private Const mcGWLSTYLE = (-16)
    Private Const mcWSVISIBLE = &H10000000 '  Watch window gives  268435456 (even when no code is running)
    Private Const mconMAXLEN = 255
    
    Public Sub fEnumWindows()
    ' For worksheet output, not important for understanding the main coding
    Dim Ws As Worksheet: Set Ws = ThisWorkbook.Worksheets.Item(1)
    Dim Lc As Long, Lr As Long: Let Lc = Ws.Cells.Item(2, Ws.Columns.Count).End(xlToLeft).Column
     Let Ws.Cells.Item(1, Lc + 1) = CreateObject("WScript.Network").ComputerName & "      " & Format(Now(), "ddd,dd,mmm,yyyy")                  '  Environ$("computername")      Nigel Heffernan  https://stackoverflow.com/questions/3551055/how-to-get-name-of-the-computer-in-vba/10108951#10108951
     Let Ws.Cells.Item(2, Lc + 1) = "Hwnd": Let Ws.Cells.Item(2, Lc + 2) = "Class Name": Let Ws.Cells.Item(2, Lc + 3) = "Caption": Let Ws.Cells.Item(2, Lc + 4) = "Hwnd( Caption)": Let Ws.Cells.Item(2, Lc + 5) = "enum visible?"
    
    
    Dim lngx As Long, lngLen As Long, lngStyle As Long, strCaption As String
     Let lngx = apiGetDesktopWindow(): Debug.Print "Geted Desktop Window  " & lngx & " " & " CLass name " & fGetClassName(lngx)
     Let lngx = apiGetWindow(lngx, mcGWCHILD): Debug.Print "   First child to Desktop " & lngx & " CLass name " & fGetClassName(lngx) '   GW_CHILD = 5    The topmost of the given window's child windows. This has the same effect as using the GetTopWindow function, ... usually at the top of all the other children in the Z-order
        Do While Not lngx = 0 ' We are looping "equal level children", seperated not realy, just look seperate to us because of the seen to us z order
         Let strCaption = fGetCaption(lngx)
    '        If Len(strCaption) > 0 Then ' Those without a caption seem not important
             Let lngStyle = apiGetWindowLong(lngx, mcGWLSTYLE) '  apiGetWindowLong gets info,   GWL_STYLE  -16  retrieves the window styles
                ' For   enum visible windows only
    '            If lngStyle And mcWSVISIBLE Then   '
                 Let Lr = Ws.Cells.Item(Ws.Rows.Count, Lc + 1).End(xlUp).Row                                                    '  Handle             Class name          Caption
                    If lngStyle And mcWSVISIBLE Then
                     Let Ws.Cells.Item(Lr + 1, Lc + 5) = "enum visible " & lngStyle & " And " & mcWSVISIBLE
                    Else
                     'Let Ws.Cells.Item(Lr + 1, Lc + 5) = lngStyle & " And " & mcWSVISIBLE
                    End If
                 Let Ws.Cells.Item(Lr + 1, Lc + 6) = lngStyle: Ws.Cells.Item(Lr + 1, Lc + 7) = mcWSVISIBLE
                 Debug.Print FindWndNumber(lpClassName:=fGetClassName(lngx), lpWindowName:=vbNullString), fGetClassName(lngx); Tab(50); fGetCaption(lngx); Tab(100); FindWndNumber(lpClassName:=vbNullString, lpWindowName:=fGetCaption(lngx))
                 Let Ws.Cells.Item(Lr + 1, Lc + 1) = lngStyle & " " & FindWndNumber(lpClassName:=fGetClassName(lngx)): Let Ws.Cells.Item(Lr + 1, Lc + 2) = fGetClassName(lngx): Let Ws.Cells.Item(Lr + 1, Lc + 3) = fGetCaption(lngx): Let Ws.Cells.Item(Lr + 1, Lc + 4) = FindWndNumber(lpClassName:=vbNullString, lpWindowName:=fGetCaption(lngx))
    '            End If
    '        End If
         Let lngx = apiGetWindow(lngx, mcGWHWNDNEXT) '  GW_HWNDNEXT = 2   The window below the given window in the Z-order.
        Loop ' While Not lngx = 0  ' I am going through all the child windows of the desktop windows
    End Sub
    Private Function fGetCaption(Hwnd As Long) As String
    Dim strBuffer As String, intCount As Integer
     Let strBuffer = String$(Number:=255 - 1, Character:="0") ' "00000000000000000000000000000000..........000"
     Let intCount = apiGetWindowText(Hwnd:=Hwnd, lpString:=strBuffer, aint:=255) ' This makes  strBuffer  something like    *MSCTFIME UI 0000000000000000............000"
        If intCount > 0 Then Let fGetCaption = Left$(strBuffer, intCount)
    End Function
    Private Function fGetClassName(Hwnd As Long) As String
    Dim strBuffer As String, intCount As Integer
     Let strBuffer = String$(255 - 1, 0)
     Let intCount = apiGetClassName(Hwnd, strBuffer, mconMAXLEN)
        If intCount > 0 Then
         Let fGetClassName = Left$(strBuffer, intCount)
        End If
    End Function
    
    
    Last edited by DocAElstein; Yesterday at 02:35 AM.

  2. #12
    Fuhrer, Vierte Reich DocAElstein's Avatar
    Join Date
    Aug 2014
    Posts
    9,454
    Rep Power
    10

    If lngStyle And mcWSVISIBLE Then

    If lngStyle And mcWSVISIBLE Then
    Some notes, codings etc. in support of some other posts
    https://eileenslounge.com/viewtopic....321979#p321979 https://eileenslounge.com/viewtopic.php?f=30&t=41610
    https://www.excelfox.com/forum/showt...l=1#post249016


    Introduction
    A code line from the last post , If lngStyle And mcWSVISIBLE Then
    What’s going on? – Hans told me …. The number is looked at by VBA in its binary representation form, and each corresponding Bit at the same horizontal position for the two numbers is compared. This is referred to as bitwise AND of the binary representation of the numbers. If at any position both are 1 , then the result will be true…..


    It all started here:
    I had some strange results that I did not understand. It boiled down to some code lines such as this returning True
    If -1811939328 And 268435456 Then
    , whilst similar such as this returning False
    If -2046820352 And 268435456 Then

    So, because ExcelFox is the adult thinking man’s forum, we are going to have a good look at it.




    String like 0 1 representation of a number
    A couple of points to consider
    _(i) A string type representation of a lot of 0s and 1s is a good idea so that we don’t have problems with things like leading 0s vanishing when Excel or VBA messes with the format of a number we may write: In binary computer things the number will have typically some fixed character length, so we should not mess with that, or let Excel or VBA mess with it
    _(ii) The first Bit/first position is always reserved for the sign character, (which is 1 for a negative number, and that leads to the phenomena that Anding two negative numbers always results in a True, - it's an artefact of that the first digit is also included in the bitwise AND of the binary representation of the numbers.


    A simple function to get the string like binary 0s and 1s representation of a number.
    We decide on some length limit for the string. For now, based on an initial quick empirical look and guess, I will go for up to 30 powers of 2, ( (2 ^ N) = (2 ^ 30) ). I might change that later based on experience. A big one initially will hopefully catch numbers as big as we have. This means the string length will be 32 characters, as in the string like binary 0s and 1s representation we have (2 ^ 0) at the right, (2 ^ 30) at the left, and also an extra sign bit included to be the first left character.

    A simple function can be one that builds the string
    , first with a 0 or 1 depending on if the decimal number being converted is negative or positive
    , then we successively divide the number by (2 ^ N) where N goes from 30 to 0. If the result of the division results in 1 or 1 and a fraction more, we add** ( ** add as in including another character, not maths add ) a 1 to the string, and reduce the decimal number by that (2 ^ N) before moving to the next N. If the division resilts in less than 1, we add a 0, then move on to the next N
    Code:
    Sub TestNumberInBinary()
    Debug.Print NumberInBinary(9)         ' 00000000000000000000000000001001
    Debug.Print NumberInBinary(268435456) ' 00010000000000000000000000000000
    End Sub
    Public Function NumberInBinary(ByVal DecNumber As Long) As String
    Rem 1 A negative number in a computer binary representation has a  1  at the first character position
     Let NumberInBinary = IIf(DecNumber < 0, "1", "0")
    Rem 2  we successively divide the number by (2 ^ N) where N goes from 30 to 0. If the result of the division results in 1 or 1 and a fraction more, we add** ( ** add as in including another character, not maths add ) a 1 to the string, and reduce the decimal number by that (2 ^ N) before moving to the next N. If the division resilts in less than 1, we add a 0, then move on to the next N Divide the decimal number by 2 to the power of N, with N geting smaller. Every tine the resulting number is equal or bigger than 1  the binary bit would be 1 and the decimal number we reduce by that 2 to the N, and keep going
    Dim N As Long
        For N = 30 To 0 Step -1  '  30 seems to be the limit before something is too big
            If DecNumber / (2 ^ N) >= 1 Then
             Let NumberInBinary = NumberInBinary & "1"
             Let DecNumber = DecNumber - (2 ^ N)
            Else
             Let NumberInBinary = NumberInBinary & "0"
            End If
        Next N
    End Function

    A function to mimic the behaviour of the VBA And with numbers is very easy.
    Simply
    _ convert the two decimal numbers to a string in the form of the computer binary 0s and 1s representation, (using for example the function I did above)
    _ then starting from the left compare the characters in the corresponding position in the two strings. As soon as you get a 1 in both , you make the functions returned output as True and exit the function, otherwise the function returns false if you never get a pair of 1s

    Code:
    Public Function NumbersInVBAIf_And_Then(ByVal Dec1 As Long, Dec2 As Long) As Boolean
    Rem 1 the two decimal numbers to a string in the form of the computer binary 0s and 1s representation
    Dim Bin1 As String, Bin2 As String ' String representation helps prevent loosing leading 0's
     Let Bin1 = NumberInBinary(Dec1): Bin2 = NumberInBinary(Dec2)
    Rem 2 starting from the left compare the characters in the corresponding position in the two strings. As soon as you get a 1 in both , you make the functions returned output as True and exit the function, otherwise the function returns false if you never get a pair of 1s
    Dim TPwr As Long
        For TPwr = 1 To 32 Step 1
         If Mid(Bin1, TPwr, 1) = 1 And Mid(Bin2, TPwr, 1) = 1 Then Let NumbersInVBAIf_And_Then = True: Exit Function
        Next TPwr
    End Function
    Conclusions, Oh dear
    I thought it was too good to be true. It did tons of tests, my coding is sound, does what I think it should with all data extremes
    Doesn’t’ get the right bloody results though: Compare… as before, column D ( which effectively does what the main full codng does ) which gets the correct results.
    Based on everything so far, this is the test coding to get results in column E
    Code:
    Sub TryMyFuncsNumberInBinaryNumbersInVBAIf_And_Then()
    Range("E2:E20").Clear
    Dim Rw As Long, arrRws() As Variant: Let arrRws() = Range("A1:C20").Value
        For Rw = 2 To 20
         Let Range("E" & Rw) = NumbersInVBAIf_And_Then(arrRws(Rw, 2), arrRws(Rw, 3))
        Next Rw
    
    End Sub
    The results speak for themselves..
    https://i.postimg.cc/2jxYmcbH/Bollox.jpg
    Bollox.JPG




    Bollox
    Last edited by DocAElstein; Yesterday at 11:41 PM.

  3. #13
    Fuhrer, Vierte Reich DocAElstein's Avatar
    Join Date
    Aug 2014
    Posts
    9,454
    Rep Power
    10
    …. Continued from last post….

    Bollox, what went wrong
    It did not take long to find the problem. ..
    So I was following the simple logic like..
    A number 7 is somehow in computer binary a variation of
    Code:
                8 4 2 1
    0 0 0 0 0 0 0 1 1 1
    , and correspondingly -7 I was thinking , (and in a few places I was even seeing written)
    Code:
                8 4 2 1
    1 0 0 0 0 0 0 1 1 1
    It aint quite like that,
    Last edited by DocAElstein; Today at 12:13 AM.

Similar Threads

  1. Version Info using VBA and registry quirks
    By DocAElstein in forum Test Area
    Replies: 6
    Last Post: 10-23-2024, 01:50 PM
  2. ADS info via VBA 64bit
    By TML59 in forum Excel Help
    Replies: 9
    Last Post: 07-13-2024, 03:43 PM
  3. Replies: 26
    Last Post: 07-17-2013, 11:42 AM
  4. Info: different Value !
    By PcMax in forum Excel Help
    Replies: 2
    Last Post: 04-22-2012, 04:13 PM
  5. Version 2003 to 2007
    By PcMax in forum Excel Help
    Replies: 5
    Last Post: 11-23-2011, 07:52 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •