@@ -25,7 +25,7 @@ void ConvertSelectedTextInActiveWindow(HKL hklSource, HKL hklTarget)
2525 }
2626
2727 // copy the selected text by simulating Ctrl-C
28- SendKeyCombo (VK_CONTROL , 'C' , FALSE);
28+ SendKeyCombo ('C' , TRUE, FALSE , FALSE);
2929
3030 // wait until copy operation completes and get the copied data from the clipboard
3131 // this loop has the nice side effect of setting copyOK to FALSE if there's no
@@ -67,7 +67,7 @@ void ConvertSelectedTextInActiveWindow(HKL hklSource, HKL hklTarget)
6767 if (SetClipboardText (targetText ))
6868 {
6969 // simulate Ctrl-V to paste the text, replacing the previous text
70- SendKeyCombo (VK_CONTROL , 'V' , FALSE);
70+ SendKeyCombo ('V' , TRUE, FALSE , FALSE);
7171
7272 // let the application complete pasting before putting the old data back on the clipboard
7373 Sleep (REMOTE_APP_WAIT );
@@ -334,22 +334,69 @@ BOOL SetClipboardText(const WCHAR* text)
334334}
335335
336336///////////////////////////////////////////////////////////////////////////////
337- // Simulates a key press in the active window
338- void SendKey (BYTE vk , BOOL extended )
337+ // Simulates a key combination (such as Ctrl+X) in the active window
338+ void SendKeyCombo (BYTE vk , BOOL ctrl , BOOL alt , BOOL shift )
339339{
340- keybd_event (vk , 0 , extended ? KEYEVENTF_EXTENDEDKEY : 0 , 0 );
341- keybd_event (vk , 0 , KEYEVENTF_KEYUP | (extended ? KEYEVENTF_EXTENDEDKEY : 0 ), 0 );
340+ BYTE vkModifiers [3 ] = { VK_CONTROL , VK_MENU , VK_SHIFT };
341+ BOOL bModRequested [3 ] = { ctrl != 0 , alt != 0 , shift != 0 };
342+ BOOL bModPressed [3 ];
343+ BOOL bKeyPressed ;
344+
345+ for (int i = 0 ; i < 3 ; i ++ )
346+ bModPressed [i ] = GetKeyState (vkModifiers [i ]) < 0 ;
347+
348+ bKeyPressed = GetKeyState (vk ) < 0 ;
349+
350+ for (int i = 0 ; i < 3 ; i ++ )
351+ {
352+ if (bModRequested [i ] != bModPressed [i ])
353+ keybd_event (vkModifiers [i ], 0 , bModPressed [i ] ? KEYEVENTF_KEYUP : 0 , 0 );
354+ }
355+
356+ if (!bKeyPressed )
357+ {
358+ keybd_event (vk , 0 , 0 , 0 );
359+ keybd_event (vk , 0 , KEYEVENTF_KEYUP , 0 );
360+ }
361+ else
362+ {
363+ keybd_event (vk , 0 , KEYEVENTF_KEYUP , 0 );
364+ keybd_event (vk , 0 , 0 , 0 );
365+ }
366+
367+ for (int i = 3 ; i >= 0 ; i -- )
368+ {
369+ if (bModRequested [i ] != bModPressed [i ])
370+ keybd_event (vkModifiers [i ], 0 , bModPressed [i ] ? 0 : KEYEVENTF_KEYUP , 0 );
371+ }
342372}
343373
344374///////////////////////////////////////////////////////////////////////////////
345- // Simulates a key combination (such as Ctrl+X) in the active window
346- void SendKeyCombo ( BYTE vkModifier , BYTE vk , BOOL extended )
375+ // Simulates Alt+Shift to change languages
376+ void SendAltShift ( )
347377{
348- BOOL modPressed = GetKeyState (vkModifier ) < 0 ;
349- if (!modPressed )
350- keybd_event (vkModifier , 0 , 0 , 0 );
351- keybd_event (vk , 0 , extended ? KEYEVENTF_EXTENDEDKEY : 0 , 0 );
352- keybd_event (vk , 0 , KEYEVENTF_KEYUP | (extended ? KEYEVENTF_EXTENDEDKEY : 0 ), 0 );
353- if (!modPressed )
354- keybd_event (vkModifier , 0 , KEYEVENTF_KEYUP , 0 );
378+ BYTE vkModifiers [3 ] = { VK_CONTROL , VK_MENU , VK_SHIFT };
379+ BOOL bModRequested [3 ] = { FALSE, TRUE, TRUE };
380+ BOOL bModPressed [3 ];
381+
382+ for (int i = 0 ; i < 3 ; i ++ )
383+ bModPressed [i ] = GetKeyState (vkModifiers [i ]) < 0 ;
384+
385+ for (int i = 0 ; i < 3 ; i ++ )
386+ {
387+ if (bModRequested [i ] != bModPressed [i ])
388+ keybd_event (vkModifiers [i ], 0 , bModPressed [i ] ? KEYEVENTF_KEYUP : 0 , 0 );
389+ }
390+
391+ if (bModRequested [2 ] && bModPressed [2 ])
392+ {
393+ keybd_event (vkModifiers [2 ], 0 , KEYEVENTF_KEYUP , 0 );
394+ keybd_event (vkModifiers [2 ], 0 , 0 , 0 );
395+ }
396+
397+ for (int i = 3 ; i >= 0 ; i -- )
398+ {
399+ if (bModRequested [i ] != bModPressed [i ])
400+ keybd_event (vkModifiers [i ], 0 , bModPressed [i ] ? 0 : KEYEVENTF_KEYUP , 0 );
401+ }
355402}
0 commit comments