First off, credits go to a friend...

Using the following:
http://thundervb.profitux.cz/go.php?adr=home

VB Code:
  1. 'Note double dereference because passing byref
  2. Public Function CheckBits(lngNumber As Long, lngTest As Long) As Boolean
  3.     '#asm'  mov eax,[esp+4]             ;Move pointer to lngNumber into eax
  4.     '#asm'  mov eax,[eax]               ;Move value of lngNumber into eax
  5.     '#asm'  mov ecx,[esp+8]
  6.     '#asm'  mov ecx,[ecx]
  7.     '#asm'  not eax
  8.     '#asm'  test eax,ecx                ;And the value of lngNumber with lngTest and effect SF, ZF, and PF
  9.     '#asm'  .IF !ZERO?                  ;Is the zero flag not set (bit set)
  10.     '#asm'      xor eax,eax             ;Return false
  11.     '#asm'  .ELSE
  12.     '#asm'      mov eax,-1              ;Return true
  13.     '#asm'  .ENDIF
  14.     '#asm'  ret 8
  15. End Function

However, he had to write a second one for those cases where Visual Basic's signed long can't hold a mask capable of checking every bit in an unsigned long. Work with file formats, you will understand why you need the speed of assembly and unsigned longs .

VB Code:
  1. Public Function CheckBitNumber(lngNumber As Long, lngBitNumber As Long) As Boolean
  2.     '#asm'  mov ecx,[esp+8]             ;Calculate 2^(lngBitNumber - 1) and place it in eax
  3.     '#asm'  mov cl,[ecx]
  4.     '#asm'  dec cl
  5.     '#asm'  mov eax,1
  6.     '#asm'  shl eax,cl
  7.    
  8.     '#asm'  mov ecx,[esp+4]             ;Move pointer to lngNumber into ecx
  9.     '#asm'  mov ecx,[ecx]               ;Move value of lngNumber into ecx
  10.  
  11.     '#asm'  test eax,ecx                ;And the value of lngNumber with lngTest and effect SF, ZF, and PF
  12.     '#asm'  .IF ZERO?                   ;Is the zero flag set (bit not set)
  13.     '#asm'      xor eax,eax             ;Return false
  14.     '#asm'  .ELSE
  15.     '#asm'      mov eax,-1              ;Return true
  16.     '#asm'  .ENDIF
  17.     '#asm'  ret 8
  18. End Function

Enjoy