Office System

The Office Developer Blog (by Luiz Cláudio C. V. Rocha - São Paulo, Brazil)

VB6 - SendKeys no Windows Vista

Ao rodar um código bastante simples, que transforma Enter em Tab, recebi a mensagem de erro "Permission Denied":

Private Sub Form_KeyPress(KeyAscii As Integer)
If KeyAscii = vbKeyReturn Then
   KeyAscii = 0
   SendKeys "{TAB}"
   End If
End Sub

Demorei um pouco a entender o problema, mas enfim cheguei à coclusão que se tratava de uma regra de segurança do Windows Vista.

Para contorná-la, devemos recorrer a APIs do Windows para enviar teclas (o que, aliás, é uma boa prática independentemente da versão do Windows).

A função SendKeys pode ser substituída por esta:

Option Explicit

Private Const KEYEVENTF_KEYUP = &H2
Private Const INPUT_KEYBOARD = 1

Private Type KEYBDINPUT
wVk As Integer
wScan As Integer
dwFlags As Long
time As Long
dwExtraInfo As Long
End Type

Private Type GENERALINPUT
dwType As Long
xi(0 To 23) As Byte
End Type

Private Declare Function SendInput Lib "user32.dll" (ByVal nInputs As Long, pInputs As GENERALINPUT, ByVal cbSize As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)

Public Function SendKeysA(ByVal vKey As Integer, Optional booDown As Boolean = False)
Dim GInput(0) As GENERALINPUT
Dim KInput As KEYBDINPUT
KInput.wVk = vKey
If Not booDown Then
    KInput.dwFlags = KEYEVENTF_KEYUP
End If
GInput(0).dwType = INPUT_KEYBOARD
CopyMemory GInput(0).xi(0), KInput, Len(KInput)
Call SendInput(1, GInput(0), Len(GInput(0)))
End Function

Comments

Everton said:

Otimo cara, consegui resolver o problema de permission denied, pois se tratava exatamente no bloqueio dos cóidgo SenkKey que o Vb jah tem por padrao, a declaração dessas apis funcionariam perfeitamente. Obrigado.

# April 3, 2007 2:40 PM

guillermo javier lozano cuadra said:

gracias, pero ¿como funciona?, no puedo ejecutarla

saludos

gjlozano99@hotmail.com

# June 22, 2007 7:56 PM

Fernanda Macan said:

Olá Luiz Cláudio,

Tive o mesmo problema e substitui a função Sendkeys pela SendkeysA. O código ficou assim:

Private Sub NomeOp_AfterUpdate()

'SendKeys "{TAB}", True

SendKeysA 9, True

End Sub

Não funcionou. A tecla TAB não foi acionada. O mesmo ocorre com a tecla F2 ou F4.

Você sabe me dizer o que está errado ?

# August 22, 2007 6:40 AM

Alexandre Macedo said:

Sorry, but I cannot understood. Could you send me a exemple / form.

Tks in advance.

Desculpe, mas eu não consegui entender. Voce poderia me enviar um exemplo.

Agradeço desde já.

Email: amottinha@hotmail.com

# October 26, 2007 7:46 AM

Alone said:

Achei muito boa sua soluçao só nao conseguir fazer funcionar o cod q vc passou, estou tendo esse problema aqui com o windows vista

# October 31, 2007 2:56 PM

francisco said:

SHOW

funcionou perfeitamente

segue abaixo exemplo de meu teste

'Codigo do Modulo

Private Const KEYEVENTF_KEYUP = &H2

Private Const INPUT_KEYBOARD = 1

Private Type KEYBDINPUT

   wVk As Integer

   wScan As Integer

   dwFlags As Long

   time As Long

   dwExtraInfo As Long

End Type

Private Type GENERALINPUT

   dwType As Long

   xi(0 To 23) As Byte

End Type

Public Declare Function SendInput Lib "user32.dll" (ByVal nInputs As Long, pInputs As GENERALINPUT, ByVal cbSize As Long) As Long

Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)

Public Function SendKeysA(ByVal vKey As Integer, Optional booDown As Boolean = False)

   Dim GInput(0) As GENERALINPUT

   Dim KInput As KEYBDINPUT

   KInput.wVk = vKey

   If Not booDown Then

       KInput.dwFlags = KEYEVENTF_KEYUP

   End If

   GInput(0).dwType = INPUT_KEYBOARD

   CopyMemory GInput(0).xi(0), KInput, Len(KInput)

   Call SendInput(1, GInput(0), Len(GInput(0)))

End Function

'Codigo do form

'o keypreview do form deve esta true

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)

   Select Case KeyCode

       Case 13:

           '*** Campo  se pressionado (ENTER)      

           SendKeysA vbKeyTab, True        

       Case 27:

            'Fecha Form  se pressionado (ESC)          

            Unload Me

       Case 38:

           'Volta Campo similar   (SHIFT + TAB)

           SendKeysA vbKeyShift, True

           SendKeysA vbKeyTab, True

           SendKeysA vbKeyShift, False

       Case 40:

           '*** Campo se pressionado (SETA ACIMA)

            SendKeysA vbKeyTab, True

   End Select

End Sub

'f.r.c.junior@hotmail.com

# January 11, 2008 5:51 PM
Leave a Comment

(required) 

(required) 

(optional)

(required)