PDA

View Full Version : [VB->C++] Mandare testo alla tastiera


AngeL)
22-08-2006, 17:29
ho visto in alcuni programmi, scritti probabilmente in vb, una funzione, che manda del testo alla tastiera.
mi spiego meglio:
c'è una textbox dove io scrivo qualunque cosa, e vicino ad essa un bottone.
se scrivo una frase a caso, premo il bottone e seleziono una pagina di word, vedo la tastiera scrivere da sola la frase che avevo scritto in precedenza.
non so se mi sono spiegato bene, ma spero di aver reso l'idea.
vorrei sapere se è possibile fare una cosa del genere anche in c++.
grazie in anticipo :)

71104
22-08-2006, 18:52
muovere magicamente i tasti della tastiera affinché scriva da sola? lo puoi fare solo con hardware dedicato, e probabilmente hai bisogno di contattare l'azienda produttrice per informazioni tecniche sulla gestione dell'hardware via software

AngeL)
22-08-2006, 19:32
non si muovono i tasti, ma compare la frase, come se l'avessi digitata io.

andbin
22-08-2006, 19:50
A dire il vero in Win32 esiste la funzione keybd_event() (e sui sistemi NT/2K/XP c'è SendInput()).
Permettono di "sintetizzare" la pressione dei tasti.

mynos79
22-08-2006, 23:42
In VB viene usata la funzione SendMessage oppure la KeySend per inviare un qualsiasi carattere o messaggio ad una qualsiasi applicazione tramite il suo hwnd (handle window) ...
Nel caso di passaggio di testo in Word (o altri applicativi) viene semplicemente caricato il componente OLE dell' applicazione nell' applicazione VB e poi si passa la stringa usando semplicemente gli oggetti offerti dal componente OLE.
Quindi sicuramente si può fare questa cosa anche in altri linguaggi ...

AngeL)
23-08-2006, 08:23
A dire il vero in Win32 esiste la funzione keybd_event() (e sui sistemi NT/2K/XP c'è SendInput()).
Permettono di "sintetizzare" la pressione dei tasti.
in quali headers sono dichiarate?

andbin
23-08-2006, 08:30
in quali headers sono dichiarate?EDIT: fisicamente sono nell'header Winuser.h ma si deve includere Windows.h

AngeL)
23-08-2006, 08:58
dove li trovo questi header?
io ho solo quelli normali (iostream, string...)

Marco Giunio Silano
23-08-2006, 09:08
dove li trovo questi header?
io ho solo quelli normali (iostream, string...)

#include <winuser.h>
#include <windows.h>

solitamente il compilatore (configurato di default) è in grado di trovarli. Altrimenti fai una bella ricerca, così ne trovi decine in decine di posti diversi ;) in sdk in ddk....

AngeL)
23-08-2006, 09:19
erano nella cartella include del borland :muro: :muro:
grazie mille metal gear solid :D
p.s. come uso SendInput()?
SendInput(testo) va bene?

andbin
23-08-2006, 09:28
erano nella cartella include del borland :muro: :muro:
grazie mille metal gear solid :D
p.s. come uso SendInput()?
SendInput(testo) va bene?No, è più complessa. Vedere su MSDN <qui> (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputfunctions/sendinput.asp).

AngeL)
23-08-2006, 09:30
vado a vedere.
grazie mille :)

edit: cosa sono quei parametri?

andbin
23-08-2006, 09:30
#include <winuser.h>
#include <windows.h>In genere non servirebbe includere winuser.h. MSDN dice: "Declared in Winuser.h, include Windows.h"

AngeL)
23-08-2006, 09:40
credo di aver capito...
in sendinput devo dare tra gli argomenti il puntatore a un array di struct di tipo input che a loro volta contengono struct di tipo mouseinput, keyboardinput o hardwareinput, che a loro volta sono formati da piccole strutture... vorrei non aver capito :D

andbin
23-08-2006, 09:53
credo di aver capito...
in sendinput devo dare tra gli argomenti il puntatore a un array di struct di tipo input che a loro volta contengono struct di tipo mouseinput, keyboardinput o hardwareinput, che a loro volta sono formati da piccole strutture... vorrei non aver capito :DÈ così, hai capito bene. Però si può fare una funzione che "wrappa" SendInput.

AngeL)
23-08-2006, 10:02
cosa significa "wrappare"?
esiste un verbo inglese ma non ricordo che significa :muro:

andbin
23-08-2006, 10:25
cosa significa "wrappare"?to wrap: avvolgere; imballare; coprire ;)

andbin
23-08-2006, 10:58
Ho scritto questo breve programma di prova:
#define STRICT
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

BOOL SendKeyboardText (LPSTR lpszText)
{
INT iLen, iIdx;
INPUT input;
SHORT code;
BYTE vk, flags;

iLen = lstrlen (lpszText);

input.type = INPUT_KEYBOARD;

for (iIdx = 0; iIdx < iLen; iIdx++)
{
code = VkKeyScan (lpszText[iIdx]);

vk = LOBYTE ((WORD) code);
flags = HIBYTE ((WORD) code);

if (vk != 0xFF)
{
if (flags & 1)
{
input.ki.wVk = VK_SHIFT;
input.ki.dwFlags = 0;
SendInput (1, &input, sizeof (INPUT));
}

input.ki.wVk = (WORD) vk;
input.ki.dwFlags = 0;
SendInput (1, &input, sizeof (INPUT));

input.ki.wVk = (WORD) vk;
input.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput (1, &input, sizeof (INPUT));

if (flags & 1)
{
input.ki.wVk = VK_SHIFT;
input.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput (1, &input, sizeof (INPUT));
}
}
}

return TRUE;
}

int main (void)
{
Sleep (4000);

SendKeyboardText ("Ciao, prova\r");

SendKeyboardText ("!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~");

return 0;
}
EDIT: Ho modificato/migliorato il codice

AngeL)
23-08-2006, 11:11
cosa sono questi?
#define STRICT
#define _WIN32_WINNT 0x0500

andbin
23-08-2006, 11:28
cosa sono questi?
#define STRICT
#define _WIN32_WINNT 0x0500STRICT indica agli include di Windows di definire i tipi (specialmente, ad esempio, gli handle) in modo particolare. È meglio se leggi <qui> (http://msdn.microsoft.com/library/en-us/vccore98/HTML/_core_windows..h_and_strict_type_checking.asp).
_WIN32_WINNT è una macro che consente (insieme all'altra WINVER) di abilitare le funzioni/costanti/strutture specifiche per i vari OS Microsoft. Anche in questo caso è meglio se leggi <qui> (https://msdn.microsoft.com/library/default.asp?url=/library/en-us/winprog/winprog/using_the_windows_headers.asp).

P.S.: ho modificato il codice del mio post sopra. Ora gestisce bene tutti i codici ASCII.

AngeL)
23-08-2006, 11:37
grazie per la spiegazione :)

edit: ah, un'altra cosa: la funzione SendKeyboardText() è standard o può essere modificata?

andbin
23-08-2006, 11:50
edit: ah, un'altra cosa: la funzione SendKeyboardText() è standard o può essere modificata?Standard??? L'ho fatta io. ;)
Sei libero ovviamente di modificarla come ti pare.

AngeL)
23-08-2006, 12:14
e cosa puo essere modificato?

p.s. sono riuscito a fare un programma con mouseinput, ma non ho capito ancora come funziona keyboardinput... ora studio un po il tuo codice :)

p.p.s. cosa sono DWORD, LPSTR, SHORT...? i tipi standard della lib di win?

andbin
23-08-2006, 13:07
e cosa puo essere modificato?Beh, dipende da cosa vuoi fare. L'ultima versione del codice che ho postato è in grado di inviare del testo ASCII (caratteri 32-126, di questi almeno sono sicuro).
Se vuoi fare qualcos'altro, spiega che vediamo. ;)

p.p.s. cosa sono DWORD, LPSTR, SHORT...? i tipi standard della lib di win?Sì esatto. Nel Platform SDK sono definiti un gran numero di tipi specifici.

EDIT: la lista completa la trovi <qui> (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winprog/winprog/windows_data_types.asp)

AngeL)
23-08-2006, 13:13
adesso sto provando a far accendere e spegnere la lucina di bloc num (0x90) ma non funziona :wtf:

il codice è
for(INT i=0;i<times;i++)//times è l'argomento della funzione Blink
{
input.ki.wVk=0x90;//bloc num
input.ki.wScan=1;//boh :D
input.ki.dwFlags=KEYEVENTF_KEYUP;//per rilasciare il tasto dopo averlo premuto
input.ki.time=0;//non so :D
sleep(500);
}

andbin
23-08-2006, 13:22
adesso sto provando a far accendere e spegnere la lucina di bloc num (0x90) ma non funziona :wtf:Io ho provato così e funziona:
keybd_event (VK_NUMLOCK, 0, 0, 0);
keybd_event (VK_NUMLOCK, 0, KEYEVENTF_KEYUP, 0);Adesso provo con la SendInput.

AngeL)
23-08-2006, 13:24
che cos'è keybd_event?

andbin
23-08-2006, 13:28
che cos'è keybd_event?L'avevo detto all'inizio del thread. È l'altra funzione per sintetizzare i tasti, che però è disponibile su tutti i sistemi Windows.

Ho provato e funziona anche con SendInput:
INPUT input;

ZeroMemory (&input, sizeof (input));
input.type = INPUT_KEYBOARD;

input.ki.wVk = VK_NUMLOCK;
input.ki.dwFlags = 0;
SendInput (1, &input, sizeof (INPUT));

input.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput (1, &input, sizeof (INPUT));

AngeL)
23-08-2006, 13:37
nel mio codice avevo dimenticato di fare sendinput... :muro::muro::muro:

AngeL)
23-08-2006, 14:08
ah, 1altra cosa: qual è il codice di bloc scorr?

andbin
23-08-2006, 14:13
ah, 1altra cosa: qual è il codice di bloc scorr?VK_SCROLL

La lista dei Virtual-Key Codes la trovi <qui> (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/virtualkeycodes.asp).

AngeL)
23-08-2006, 14:29
grazie :)

AngeL)
23-08-2006, 14:35
come faccio a rappresentare VK_UP, VK_DOWN, ecc in uno switch? ricordo dei numeri... tipo 72,75, ma non li ricordo.
qualcuno se li ricorda?

andbin
23-08-2006, 14:58
come faccio a rappresentare VK_UP, VK_DOWN, ecc in uno switch? ricordo dei numeri... tipo 72,75, ma non li ricordo.
qualcuno se li ricorda?switch (vkCode)
{
case VK_UP:
....
case VK_DOWN:
....
}Perché devi mettere dei numeri? ;)

AngeL)
23-08-2006, 15:15
pensavo non si potesse usare :)
che cos'è vkCode?vkcode è il nome della var che userò o è una parola riservata?

andbin
23-08-2006, 15:17
che cos'è vkCode?vkcode è il nome della var che useròEsatto, una tua variabile.

AngeL)
23-08-2006, 15:20
e come le assegno un valore?
usando getch?

Marco Giunio Silano
23-08-2006, 15:21
I programmatori si possono dividere in 2 categorie: quelli che hanno capito i puntatori e quelli che non li hanno capiti
:D :asd: perdonate l'ot...

AngeL)
23-08-2006, 15:27
I programmatori si possono dividere in 2 categorie: quelli che hanno capito i puntatori e quelli che non li hanno capiti.
so gia in quale mi trovo :cry:

AngeL)
23-08-2006, 15:29
stavo cercando di capire come funzionano x e y ma con questo codice il puntatore va a finire sempre in un angolo:
mov=getch();
switch(mov)
{
case 'w':
input.mi.dy--;
input.mi.dwFlags=MOUSEEVENTF_MOVE;
input.mi.time=0;
SendInput(1,&input,sizeof(INPUT));
break;
case 'a':
input.mi.dx--;
input.mi.dy;
input.mi.dwFlags=MOUSEEVENTF_MOVE;
input.mi.time=0;
SendInput(1,&input,sizeof(INPUT));
break;
case 's':
input.mi.dy--;
input.mi.dwFlags=MOUSEEVENTF_MOVE;
input.mi.time=0;
SendInput(1,&input,sizeof(INPUT));
break;
case 'd':
input.mi.dx++;
input.mi.dwFlags=MOUSEEVENTF_MOVE;
input.mi.time=0;
SendInput(1,&input,sizeof(INPUT));
break;
}

andbin
23-08-2006, 15:33
e come le assegno un valore?
usando getch?getch non restituisce un "virtual-key code" e non ha niente a che vedere con Windows.

AngeL)
23-08-2006, 15:34
e come faccio ad assegnare un vkcode a una variabile?

Marco Giunio Silano
23-08-2006, 15:40
so gia in quale mi trovo :cry:

Ma NO! non era per te, scusami se hai frainteso :mano: ! E che è la prima volta che leggo la firma di andbin e la cosa mi ha divertito.
Tutti abbiamo lacune e tutti abbiamo da imparare. Non c'è da vergognarsi. All'inizio si confonde sempre un po' tutto.
Non disturbo oltre. scusate l'intromissione.

AngeL)
23-08-2006, 15:42
Non disturbo oltre. scusate l'intromissione.
era una battuta... mica me la sono presa :)

sirbone72
24-08-2006, 09:15
e come faccio ad assegnare un vkcode a una variabile?
:confused: crei una variabile intera e le assegni il valore con un bel = . . . sempre che io abbia capito ciò che chiedi...