733 lines
20 KiB
Plaintext
733 lines
20 KiB
Plaintext
{*******************************************************}
|
|
{ }
|
|
{ Tocsg.Keyboard }
|
|
{ }
|
|
{ Copyright (C) 2022 sunk }
|
|
{ }
|
|
{*******************************************************}
|
|
|
|
unit Tocsg.Keyboard;
|
|
|
|
interface
|
|
|
|
uses
|
|
Winapi.Windows, System.Classes, System.SysUtils;
|
|
|
|
function IsCapsLockOn: Boolean;
|
|
function IsNumLockOn: Boolean;
|
|
function IsScrollLockOn: Boolean;
|
|
function GetInputKeyToStr(nInput: Integer): String; inline;
|
|
|
|
function EngCharToHanChar(const cEng: Char): Char;
|
|
function EngStrToHanStr(const sEng: String; bIgnoreSPKey: Boolean = false): String;
|
|
|
|
procedure DeleteSPKey(var sContexts: String);
|
|
|
|
function ConvHotkeyToStr(dwHotkey: DWORD): String;
|
|
|
|
procedure PressKeys(const sPress: String; bCtrl: Boolean = false);
|
|
procedure PressKey(const dwCode: DWORD);
|
|
|
|
function IsWinKeyDown: Boolean;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Vcl.Forms;
|
|
|
|
const
|
|
ChoSung : WideString = 'ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ';
|
|
JungSung : WideString = 'ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ';
|
|
JongSung : WideString = ' ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ';
|
|
|
|
function IsCapsLockOn: Boolean;
|
|
begin
|
|
Result := GetKeyState(VK_CAPITAL) = 1;
|
|
end;
|
|
|
|
function IsNumLockOn: Boolean;
|
|
begin
|
|
Result := GetKeyState(VK_NUMLOCK) = 1;
|
|
end;
|
|
|
|
function IsScrollLockOn: Boolean;
|
|
begin
|
|
Result := GetKeyState(VK_SCROLL) = 1;
|
|
end;
|
|
|
|
function GetInputKeyToStr(nInput: Integer): String;
|
|
var
|
|
ShiftState: TShiftState;
|
|
begin
|
|
ShiftState := KeyDataToShiftState(0);
|
|
if GetKeyState(VK_LMENU) < 0 then
|
|
Include(ShiftState, ssAlt);
|
|
|
|
// 단순 캐스팅으로 뭘 쳤는지 알수 없는 것들은 아래처럼 처리한다.
|
|
case nInput of
|
|
8 : Result := '[Back Space]';
|
|
9 : Result := '[Tab]';
|
|
13 : Result := '[Enter]';
|
|
19 : Result := '[Pause]';
|
|
21 : Result := '[HanYoung]';
|
|
22 : Result := '[Hangul]';
|
|
23,
|
|
25 : Result := '[Hanja]';
|
|
27 : Result := '[Esc]';
|
|
32 : Result := ' ';
|
|
33 : Result := '[Page Up]';
|
|
34 : Result := '[Page Down]';
|
|
35 : Result := '[End]';
|
|
36 : Result := '[Home]';
|
|
37 : Result := '[Left]';
|
|
38 : Result := '[Up]';
|
|
39 : Result := '[Right]';
|
|
40 : Result := '[Down]';
|
|
44 : Result := '[Print Screen]';
|
|
45 : Result := '[Insert]';
|
|
46 : Result := '[Delete]';
|
|
91 : Result := '[Win Right]';
|
|
92 : Result := '[Win Left]';
|
|
93 : Result := '[Win Menu]';
|
|
96 : Result := '[Num 0]';
|
|
97 : Result := '[Num 1]';
|
|
98 : Result := '[Num 2]';
|
|
99 : Result := '[Num 3]';
|
|
100 : Result := '[Num 4]';
|
|
101 : Result := '[Num 5]';
|
|
102 : Result := '[Num 6]';
|
|
103 : Result := '[Num 7]';
|
|
104 : Result := '[Num 8]';
|
|
105 : Result := '[Num 9]';
|
|
106 : Result := '*';
|
|
107 : Result := '+';
|
|
109 : Result := '-';
|
|
110 : Result := '[. Del]';
|
|
111 : Result := '/';
|
|
112 : Result := '[F1]';
|
|
113 : Result := '[F2]';
|
|
114 : Result := '[F3]';
|
|
115 : Result := '[F4]';
|
|
116 : Result := '[F5]';
|
|
117 : Result := '[F6]';
|
|
118 : Result := '[F7]';
|
|
119 : Result := '[F8]';
|
|
120 : Result := '[F9]';
|
|
121 : Result := '[F10]';
|
|
122 : Result := '[F11]';
|
|
123 : Result := '[F12]';
|
|
144 : Result := '[Num Lock]';
|
|
145 : Result := '[Scroll Lock]';
|
|
186 :
|
|
if ssShift in ShiftState then
|
|
Result := ':'
|
|
else
|
|
Result := ';';
|
|
187 :
|
|
if ssShift in ShiftState then
|
|
Result := '+'
|
|
else
|
|
Result := '=';
|
|
188 :
|
|
if ssShift in ShiftState then
|
|
Result := '<'
|
|
else
|
|
Result := ',';
|
|
189 :
|
|
if ssShift in ShiftState then
|
|
Result := '_'
|
|
else
|
|
Result := '-';
|
|
190 :
|
|
if ssShift in ShiftState then
|
|
Result := '>'
|
|
else
|
|
Result := '.';
|
|
191 :
|
|
if ssShift in ShiftState then
|
|
Result := '?'
|
|
else
|
|
Result := '/';
|
|
192 :
|
|
if ssShift in ShiftState then
|
|
Result := '~'
|
|
else
|
|
Result := '`';
|
|
219 :
|
|
if ssShift in ShiftState then
|
|
Result := '{'
|
|
else
|
|
Result := '"["';
|
|
220 :
|
|
if ssShift in ShiftState then
|
|
Result := '|'
|
|
else
|
|
Result := '\';
|
|
221 :
|
|
if ssShift in ShiftState then
|
|
Result := '}'
|
|
else
|
|
Result := '"]"';
|
|
222 :
|
|
if ssShift in ShiftState then
|
|
Result := '"'
|
|
else
|
|
Result := '''';
|
|
48..57 :
|
|
if ssShift in ShiftState then
|
|
begin
|
|
case nInput of
|
|
48 : Result := ')';
|
|
49 : Result := '!';
|
|
50 : Result := '@';
|
|
51 : Result := '#';
|
|
52 : Result := '$';
|
|
53 : Result := '%';
|
|
54 : Result := '^';
|
|
55 : Result := '&';
|
|
56 : Result := '*';
|
|
57 : Result := '(';
|
|
end;
|
|
end else
|
|
Result := IntToStr(nInput - 48); // 숫자 0 ~ 9
|
|
65..90 :
|
|
begin
|
|
if GetKeyState(VK_CAPITAL) = 0 then
|
|
begin
|
|
if ssShift in ShiftState then
|
|
Result := Char(nInput)
|
|
else
|
|
Result := Char(nInput + 32);
|
|
end else
|
|
if ssShift in ShiftState then
|
|
Result := Char(nInput + 32)
|
|
else
|
|
Result := Char(nInput);
|
|
end;
|
|
end;
|
|
|
|
if ssAlt in ShiftState then
|
|
Result := '[Alt]+' + Result;
|
|
|
|
if ssCtrl in ShiftState then
|
|
Result := '[Ctrl]+' + Result;
|
|
|
|
if ssShift in ShiftState then
|
|
Result := '[Shift]+' + Result;
|
|
end;
|
|
|
|
function GetChoSungIdx(const cJaso: Char): WORD;
|
|
begin
|
|
Result := Pos(cJaso, ChoSung);
|
|
end;
|
|
|
|
function GetJungSungIdx(const cJaso: Char): WORD;
|
|
begin
|
|
Result := Pos(cJaso, JungSung);
|
|
end;
|
|
|
|
function GetJongSungIdx(const cJaso: Char): WORD;
|
|
begin
|
|
Result := Pos(cJaso, JongSung);
|
|
end;
|
|
|
|
function EngCharToHanChar(const cEng: Char): Char;
|
|
begin
|
|
Result := cEng;
|
|
case cEng of
|
|
'A',
|
|
'a' : Result := 'ㅁ';
|
|
'B',
|
|
'b' : Result := 'ㅠ';
|
|
'C',
|
|
'c' : Result := 'ㅊ';
|
|
'D',
|
|
'd' : Result := 'ㅇ';
|
|
'e' : Result := 'ㄷ';
|
|
'F',
|
|
'f' : Result := 'ㄹ';
|
|
'G',
|
|
'g' : Result := 'ㅎ';
|
|
'H',
|
|
'h' : Result := 'ㅗ';
|
|
'I',
|
|
'i' : Result := 'ㅑ';
|
|
'J',
|
|
'j' : Result := 'ㅓ';
|
|
'K',
|
|
'k' : Result := 'ㅏ';
|
|
'L',
|
|
'l' : Result := 'ㅣ';
|
|
'M',
|
|
'm' : Result := 'ㅡ';
|
|
'N',
|
|
'n' : Result := 'ㅜ';
|
|
'o' : Result := 'ㅐ';
|
|
'p' : Result := 'ㅔ';
|
|
'q' : Result := 'ㅂ';
|
|
'r' : Result := 'ㄱ';
|
|
'S',
|
|
's' : Result := 'ㄴ';
|
|
't' : Result := 'ㅅ';
|
|
'U',
|
|
'u' : Result := 'ㅕ';
|
|
'V',
|
|
'v' : Result := 'ㅍ';
|
|
'w' : Result := 'ㅈ';
|
|
'X',
|
|
'x' : Result := 'ㅌ';
|
|
'Y',
|
|
'y' : Result := 'ㅛ';
|
|
'Z',
|
|
'z' : Result := 'ㅋ';
|
|
|
|
'R' : Result := 'ㄲ';
|
|
'E' : Result := 'ㄸ';
|
|
'Q' : Result := 'ㅃ';
|
|
'T' : Result := 'ㅆ';
|
|
'W' : Result := 'ㅉ';
|
|
|
|
'O' : Result := 'ㅒ';
|
|
'P' : Result := 'ㅖ';
|
|
end;
|
|
end;
|
|
|
|
function EngStrToHanStr(const sEng: String; bIgnoreSPKey: Boolean = false): String;
|
|
const
|
|
STEP_CHOSUNG = 0;
|
|
STEP_JUNGSUNG = 1;
|
|
STEP_JUNGSUNG2 = 2;
|
|
STEP_JONGSUNG = 3;
|
|
STEP_JONGSUNG2 = 4;
|
|
|
|
RESULT_SUCCESS = 0;
|
|
RESULT_FAIL = 1;
|
|
RESULT_RETRY = 2;
|
|
RESULT_ADD_RETRY = 3;
|
|
|
|
var
|
|
i, nLen,
|
|
nStep: Integer;
|
|
wCombine,
|
|
wJasoTemp,
|
|
wCombineTemp: WORD;
|
|
cJaso,
|
|
cNextJaso: Char;
|
|
bFilterSP: Boolean;
|
|
|
|
function ProcessCombine: Integer;
|
|
var
|
|
wTemp: WORD;
|
|
Label LB_EXIT_STEP_JUNGSUNG2;
|
|
Label LB_EXIT_STEP_JONGSUNG2;
|
|
begin
|
|
Result := RESULT_FAIL;
|
|
|
|
case nStep of
|
|
STEP_CHOSUNG :
|
|
begin
|
|
wTemp := GetChoSungIdx(cJaso);
|
|
if wTemp > 0 then
|
|
begin
|
|
Result := RESULT_SUCCESS;
|
|
wCombineTemp := wTemp;
|
|
nStep := STEP_JUNGSUNG;
|
|
end;
|
|
end;
|
|
STEP_JUNGSUNG :
|
|
begin
|
|
wTemp := GetJungSungIdx(cJaso);
|
|
if wTemp > 0 then
|
|
begin
|
|
wCombine := ((wCombineTemp - 1) * 21 * 28) + $AC00;
|
|
Result := RESULT_SUCCESS;
|
|
case wTemp of
|
|
9, // ㅗ
|
|
14, // ㅜ
|
|
19 : // ㅡ
|
|
begin
|
|
wCombineTemp := wTemp;
|
|
nStep := STEP_JUNGSUNG2;
|
|
end;
|
|
else begin
|
|
Inc(wCombine, (wTemp-1) * 28);
|
|
nStep := STEP_JONGSUNG;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
STEP_JUNGSUNG2 :
|
|
begin
|
|
nStep := STEP_JONGSUNG;
|
|
// ㅘ, ㅚ, ㅙ, ㅞ,ㅟ... 등등을 처리해 준다 13_1216 16:37:29 sunk
|
|
wJasoTemp := GetJungSungIdx(cJaso);
|
|
case wJasoTemp of
|
|
1 : // ㅏ
|
|
case wCombineTemp of
|
|
9 : Inc(wCombine, (10-1) * 28); // ㅘ
|
|
14 : Goto LB_EXIT_STEP_JUNGSUNG2;
|
|
19 : Goto LB_EXIT_STEP_JUNGSUNG2;
|
|
end;
|
|
2 : // ㅐ
|
|
case wCombineTemp of
|
|
9 : Inc(wCombine, (11-1) * 28); // ㅙ
|
|
14 : Goto LB_EXIT_STEP_JUNGSUNG2;
|
|
19 : Goto LB_EXIT_STEP_JUNGSUNG2;
|
|
end;
|
|
5 :
|
|
case wCombineTemp of
|
|
9 : Goto LB_EXIT_STEP_JUNGSUNG2;
|
|
14 : Inc(wCombine, (15-1) * 28); // ㅝ
|
|
19 : Goto LB_EXIT_STEP_JUNGSUNG2;
|
|
end;
|
|
6 : // ㅔ
|
|
case wCombineTemp of
|
|
9 : Goto LB_EXIT_STEP_JUNGSUNG2;
|
|
14 : Inc(wCombine, (16-1) * 28); // ㅞ
|
|
19 : Goto LB_EXIT_STEP_JUNGSUNG2;
|
|
end;
|
|
21 : // ㅣ
|
|
case wCombineTemp of
|
|
9 : Inc(wCombine, (12-1) * 28); // ㅚ
|
|
14 : Inc(wCombine, (17-1) * 28); // ㅟ
|
|
19 : Inc(wCombine, (20-1) * 28); // ㅢ
|
|
end;
|
|
else Goto LB_EXIT_STEP_JUNGSUNG2;
|
|
end;
|
|
Result := RESULT_SUCCESS;
|
|
exit;
|
|
|
|
LB_EXIT_STEP_JUNGSUNG2 :
|
|
Inc(wCombine, (wCombineTemp-1) * 28);
|
|
Result := RESULT_RETRY;
|
|
end;
|
|
STEP_JONGSUNG :
|
|
begin
|
|
if cJaso = ' ' then
|
|
exit;
|
|
|
|
if (cNextJaso <> #0) and
|
|
(GetJungSungIdx(EngCharToHanChar(cNextJaso)) > 0) then
|
|
begin
|
|
// 종성처리 부분이지만 다음 부분이 중성이면
|
|
// 종성처리 하지 않고 초성처리부터 조합하도록 넘긴다 13_1216 16:38:03 sunk
|
|
nStep := STEP_CHOSUNG;
|
|
Result := RESULT_ADD_RETRY;
|
|
exit;
|
|
end;
|
|
|
|
wTemp := GetJongSungIdx(cJaso);
|
|
if wTemp > 0 then
|
|
begin
|
|
Result := RESULT_SUCCESS;
|
|
case wTemp of
|
|
2, // ㄱ
|
|
5, // ㄴ
|
|
9, // ㄹ
|
|
18 : // ㅂ
|
|
begin
|
|
wCombineTemp := wTemp;
|
|
nStep := STEP_JONGSUNG2;
|
|
end;
|
|
else begin
|
|
Inc(wCombine, wTemp-1);
|
|
nStep := STEP_CHOSUNG;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
STEP_JONGSUNG2 :
|
|
if ((cNextJaso <> #0) and
|
|
(GetJungSungIdx(EngCharToHanChar(cNextJaso)) > 0)) or
|
|
(GetJungSungIdx(cJaso) > 0) then
|
|
begin
|
|
Inc(wCombine, wCombineTemp-1);
|
|
nStep := STEP_CHOSUNG;
|
|
Result := RESULT_ADD_RETRY;
|
|
end else begin
|
|
// 종성처리 - ㄳ ㄵ ㄶ ㄺ... 등등을 처리해준다.
|
|
nStep := STEP_CHOSUNG;
|
|
wJasoTemp := GetJongSungIdx(cJaso);
|
|
case wJasoTemp of
|
|
2 : // ㄱ
|
|
case wCombineTemp of
|
|
2 : Goto LB_EXIT_STEP_JONGSUNG2; // ㄱㄱ
|
|
5 : Goto LB_EXIT_STEP_JONGSUNG2; // ㄴㄱ
|
|
9 : Inc(wCombine, 10-1); // ㄹㄱ
|
|
18 : Goto LB_EXIT_STEP_JONGSUNG2; // ㅂㄱ
|
|
end;
|
|
17 : // ㅁ
|
|
case wCombineTemp of
|
|
2 : Goto LB_EXIT_STEP_JONGSUNG2; // ㄱㅁ
|
|
5 : Goto LB_EXIT_STEP_JONGSUNG2; // ㄴㅁ
|
|
9 : Inc(wCombine, 11-1); // ㄹㅁ
|
|
18 : Goto LB_EXIT_STEP_JONGSUNG2; // ㅂㅁ
|
|
end;
|
|
18 : // ㅂ
|
|
case wCombineTemp of
|
|
2 : Goto LB_EXIT_STEP_JONGSUNG2; // ㄱㅂ
|
|
5 : Goto LB_EXIT_STEP_JONGSUNG2; // ㄴㅂ
|
|
9 : Inc(wCombine, 12-1); // ㄹㅂ
|
|
18 : Goto LB_EXIT_STEP_JONGSUNG2; // ㅂㅂ
|
|
end;
|
|
20 : // ㅅ
|
|
case wCombineTemp of
|
|
2 : Inc(wCombine, 4-1); // ㄱㅅ
|
|
5 : Goto LB_EXIT_STEP_JONGSUNG2; // ㄴㅅ
|
|
9 : Inc(wCombine, 13-1); // ㄹㅅ
|
|
18 : Inc(wCombine, 19-1); // ㅂㅅ
|
|
end;
|
|
23 : // ㅈ
|
|
case wCombineTemp of
|
|
2 : Goto LB_EXIT_STEP_JONGSUNG2; // ㄱㅈ
|
|
5 : Inc(wCombine, 6-1); // ㄴㅈ
|
|
9 : Goto LB_EXIT_STEP_JONGSUNG2; // ㄹㅈ
|
|
18 : Goto LB_EXIT_STEP_JONGSUNG2; // ㅂㅈ
|
|
end;
|
|
26 : // ㅌ
|
|
case wCombineTemp of
|
|
2 : Goto LB_EXIT_STEP_JONGSUNG2; // ㄱㅌ
|
|
5 : Goto LB_EXIT_STEP_JONGSUNG2; // ㄴㅌ
|
|
9 : Inc(wCombine, 14-1); // ㄹㅌ
|
|
18 : Goto LB_EXIT_STEP_JONGSUNG2; // ㅂㅌ
|
|
end;
|
|
27 : // ㅍ
|
|
case wCombineTemp of
|
|
2 : Goto LB_EXIT_STEP_JONGSUNG2; // ㄱㅍ
|
|
5 : Goto LB_EXIT_STEP_JONGSUNG2; // ㄴㅍ
|
|
9 : Inc(wCombine, 15-1); // ㄹㅍ
|
|
18 : Goto LB_EXIT_STEP_JONGSUNG2; // ㅂㅍ
|
|
end;
|
|
28 : // ㅎ
|
|
case wCombineTemp of
|
|
2 : Goto LB_EXIT_STEP_JONGSUNG2; // ㄱㅎ
|
|
5 : Inc(wCombine, 7-1); // ㄴㅎ
|
|
9 : Inc(wCombine, 16-1); // ㄹㅎ
|
|
18 : Goto LB_EXIT_STEP_JONGSUNG2; // ㅂㅎ
|
|
end;
|
|
else Goto LB_EXIT_STEP_JONGSUNG2;
|
|
end;
|
|
Result := RESULT_SUCCESS;
|
|
exit;
|
|
|
|
LB_EXIT_STEP_JONGSUNG2 :
|
|
Inc(wCombine, wCombineTemp-1);
|
|
Result := RESULT_ADD_RETRY;
|
|
end;
|
|
else ASSERT(false);
|
|
end;
|
|
end;
|
|
|
|
procedure ProcessAfterCombine;
|
|
begin
|
|
// 특수키 제외 시키는 부분에서도 필요해서 따로 뺌 13_1217 16:25:27 sunk
|
|
case nStep of
|
|
STEP_JUNGSUNG : Result := Result + ChoSung[wCombineTemp]; // 중성 조합시기에 끝났다면 초성찍고 마무리 13_1217 13:42:40 sunk
|
|
STEP_JUNGSUNG2 :
|
|
begin
|
|
Inc(wCombine, (wCombineTemp-1) * 28);
|
|
Result := Result + Char(wCombine);
|
|
end;
|
|
STEP_JONGSUNG2 :
|
|
begin
|
|
Inc(wCombine, wCombineTemp-1);
|
|
Result := Result + Char(wCombine);
|
|
end;
|
|
else
|
|
if wCombine <> 0 then
|
|
Result := Result + Char(wCombine); // 조합중인거 있다면 포함시켜서 마무리 13_1217 13:43:31 sunk
|
|
end;
|
|
wCombine := 0;
|
|
nStep := STEP_CHOSUNG;
|
|
end;
|
|
|
|
begin
|
|
Result := '';
|
|
bFilterSP := false;
|
|
nStep := 0;
|
|
nLen := Length(sEng);
|
|
wCombine := 0;
|
|
i := 1;
|
|
|
|
while i <= nLen do
|
|
begin
|
|
cJaso := EngCharToHanChar(sEng[i]);
|
|
if (i+1) <= nLen then
|
|
cNextJaso := EngCharToHanChar(sEng[i+1])
|
|
else
|
|
cNextJaso := #0;
|
|
|
|
if bIgnoreSPKey and not bFilterSP and (cJaso = '[') and (cNextJaso <> '"') then
|
|
begin
|
|
ProcessAfterCombine;
|
|
|
|
bFilterSP := true;
|
|
Result := Result + sEng[i];
|
|
Inc(i);
|
|
continue;
|
|
end else
|
|
if bIgnoreSPKey and bFilterSP and (cJaso <> '"') and (cNextJaso = ']') then
|
|
begin
|
|
bFilterSP := false;
|
|
Result := Result + sEng[i] + sEng[i+1];
|
|
Inc(i, 2);
|
|
continue;
|
|
end else
|
|
if bFilterSP then
|
|
begin
|
|
Result := Result + sEng[i];
|
|
Inc(i);
|
|
continue;
|
|
end;
|
|
|
|
case ProcessCombine of
|
|
RESULT_SUCCESS :
|
|
case nStep of
|
|
STEP_CHOSUNG :
|
|
begin
|
|
Result := Result + Char(wCombine);
|
|
wCombine := 0;
|
|
end;
|
|
end;
|
|
RESULT_FAIL :
|
|
if nStep <> STEP_CHOSUNG then
|
|
begin
|
|
if nStep = STEP_JUNGSUNG then
|
|
begin
|
|
Result := Result + ChoSung[wCombineTemp];
|
|
nStep := STEP_CHOSUNG;
|
|
continue;
|
|
end else
|
|
if wCombine <> 0 then
|
|
begin
|
|
Result := Result + Char(wCombine) + cJaso;
|
|
end else
|
|
Result := Result + cJaso;
|
|
wCombine := 0;
|
|
nStep := STEP_CHOSUNG;
|
|
end else
|
|
Result := Result + cJaso;
|
|
RESULT_RETRY : continue;
|
|
RESULT_ADD_RETRY :
|
|
begin
|
|
Result := Result + Char(wCombine);
|
|
wCombine := 0;
|
|
continue;
|
|
end;
|
|
end;
|
|
Inc(i);
|
|
end;
|
|
|
|
// 조합 도중 끝났을때 마무리
|
|
ProcessAfterCombine;
|
|
end;
|
|
|
|
// [Shift], [Ctrl] ... 이렇게 [ ]에 감싼건 다 없애준다. 13_1217 15:19:14 sunk
|
|
procedure DeleteSPKey(var sContexts: String);
|
|
var
|
|
i, nDelBegin: Integer;
|
|
cOne, cTwo: Char;
|
|
begin
|
|
sContexts := StringReplace(sContexts, ']+', ']', [rfReplaceAll]);
|
|
i := Length(sContexts);
|
|
nDelBegin := 0;
|
|
while i > 0 do
|
|
begin
|
|
cOne := sContexts[i];
|
|
if (i-1) > 0 then
|
|
cTwo := sContexts[i-1]
|
|
else
|
|
cTwo := #0;
|
|
|
|
if (nDelBegin = 0) and (cOne = ']') and (cTwo <> '"') then
|
|
begin
|
|
nDelBegin := i;
|
|
end else
|
|
if (nDelBegin > 0) and (cTwo = '[') and (cOne <> '"') then
|
|
begin
|
|
Delete(sContexts, i-1, nDelBegin - i + 2);
|
|
Dec(i);
|
|
nDelBegin := 0;
|
|
end;
|
|
|
|
Dec(i);
|
|
end;
|
|
end;
|
|
|
|
function ConvHotkeyToStr(dwHotkey: DWORD): String;
|
|
var
|
|
nHk: Integer;
|
|
arrChar: array [0..1] of Char;
|
|
begin
|
|
Result := '';
|
|
ZeroMemory(@arrChar, SizeOf(arrChar));
|
|
try
|
|
if dwHotkey = 0 then
|
|
exit;
|
|
|
|
if (dwHotkey and $FF) >= $70 then // F1 - F24
|
|
begin
|
|
if ((dwHotkey and $FF) >= $90) then
|
|
begin
|
|
case dwHotKey and $FF of
|
|
$90 : Result := 'Num Lock';
|
|
$91 : Result := 'Scroll Lock';
|
|
end;
|
|
end else begin
|
|
nHk := ((dwHotkey and $FF) - $70) + 1;
|
|
Result := 'F' + IntToStr(nHk);
|
|
end;
|
|
end else begin
|
|
Result := GetInputKeyToStr(dwHotKey and $FF);
|
|
end;
|
|
|
|
// if (Result <> '') and ((dwHotKey and $700) > 0) then
|
|
// Result := ' + ' + Result;
|
|
|
|
// 아래 순서는 일부러 이렇게 함 17_1011 15:29:21 sunk
|
|
if ((dwHotKey and $400) > 0) then
|
|
Result := 'Alt + ' + Result;
|
|
if ((dwHotKey and $100) > 0) then
|
|
Result := 'Shift + ' + Result;
|
|
if ((dwHotKey and $200) > 0) then
|
|
Result := 'Ctrl + ' + Result;
|
|
finally
|
|
if Result = '' then
|
|
Result := 'None';
|
|
end;
|
|
end;
|
|
|
|
procedure PressKeys(const sPress: String; bCtrl: Boolean = false);
|
|
var
|
|
i: Integer;
|
|
u: Byte;
|
|
begin
|
|
if bCtrl then
|
|
keybd_event(VK_CONTROL, 0, 0, 0);
|
|
try
|
|
for i := 1 to Length(sPress) do
|
|
begin
|
|
u := Byte(sPress[i]);
|
|
|
|
keybd_event(u, MapVirtualKey(u, 0),0, 0);
|
|
keybd_event(u, MapVirtualKey(u, 0), KEYEVENTF_KEYUP, 0);
|
|
end;
|
|
finally
|
|
if bCtrl then
|
|
keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
|
|
end;
|
|
end;
|
|
|
|
procedure PressKey(const dwCode: DWORD);
|
|
begin
|
|
keybd_event(dwCode, 0, 0, 0);
|
|
keybd_event(dwCode, 0, KEYEVENTF_KEYUP, 0);
|
|
end;
|
|
|
|
function IsWinKeyDown: Boolean;
|
|
begin
|
|
Result := (GetKeyState(VK_LWIN) and $8000 <> 0) or (GetKeyState(VK_RWIN) and $8000 <> 0);
|
|
end;
|
|
|
|
end.
|