In primo luogo devi ottenere l'handle alla finestra che ha il focus, cosa non immediata dal momento che tale finestra apparterrà sicuramente ad un altro thread.
codice:
//Restituisce la finestra che ha correntemente il focus
HWND GetFocusEx()
{
GUITHREADINFO gti={0};
if(!GetGUIThreadInfo(GetWindowThreadProcessId(GetForegroundWindow(),NULL),>i))
return NULL;
return gti.hwndFocus;
}
Prima di ottenere il testo selezionato, bisogna assicurarsi che si tratti di una casella di testo standard.
codice:
bool IsStandardTextBox(HWND hWnd)
{
TCHAR buffer[64];
if(!GetClassName(hWnd,buffer,sizeof(buffer)))
return false;
return (_tcscmp(buffer,_T("Edit"))==0)||(_tcsstr(buffer,_T("RICHEDIT"))==buffer);
}
Quindi se ne potrà ottenere il contenuto e prendere solo la selezione con i messaggi WM_GETTEXT e EM_GETSEL (in questo stralcio di codice c'è anche la chiamata delle subroutine che ho appena mostrato; questa funzione verrebbe richiamata non appena viene intercettata la pressione di tasti).
codice:
bool InvertFocusedWndSelText() //I nomi delle funzioni non sono il mio forte...
{
HWND focusWnd;
TCHAR * buffer;
DWORD firstPos, lastPos;
unsigned int charNum;
//Ottiene l'handle della finestra con il focus
if((focusWnd=GetFocusEx())==NULL)
return false;
//Verifica se si tratta di una textbox standard
if(!IsStandardTextBox(focusWnd))
return false;
//Ottiene i limiti della selezione
SendMessage(focusWnd,EM_GETSEL,&firstPos,&lastPos);
if(lastPos-firstPos==0)
return false; //non c'è alcuna selezione
//Ottiene il numero di caratteri totali
charNum=(unsigned int)SendMessage(focusWnd,WM_GETTEXTLENGTH,0,0);
if(charNum==0)
return false;
//Alloca la memoria necessaria
//TODO: aggiungere controllo allocazione fallita o delegarlo al chiamante
buffer=new TCHAR[charNum+1];
//Ottiene la stringa contenuta nella textbox
if(SendMessage(focusWnd,WM_GETTEXT,charNum+1,buffer)==0)
{
delete [] buffer;
return false;
}
//Inverte il case
for(TCHAR * cchar=(buffer+firstPos);cchar<(buffer+lastPos);cchar++)
{
if(_istlower(*cchar))
*cchar=_totupper(*cchar);
else if(_istupper(*cchar))
*cchar=_totlower(*cchar);
}
//Rimette la stringa modificata nella textbox
if(!SendMessage(focusWnd,WM_SETTEXT,0,buffer))
{
delete [] buffer;
return false;
}
//Dealloca
delete [] buffer;
//Ok!
return true;
}
Quanto all'impostazione degli hotkey, ti rimando alla documentazione della funzione RegisterHotKey.
Questo approccio funziona solo con le textbox standard (ad esempio in un documento di Word non funzionerà).
Tra parentesi, non ho collaudato questo codice, per cui non ti garantisco niente.
---EDIT---
Vedo solo ora che la richiesta era per VB.NET/VB6...
Be', comunque le API da usare sono sempre quelle.