unit DKeyMonMain; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Define, Vcl.StdCtrls, KeyMonDLL, Vcl.ExtCtrls, VirtualTrees, System.Generics.Collections, Vcl.Buttons; type PKeyMonEnt = ^TKeyMonEnt; TKeyMonEnt = record sPName, sData: String; end; TDlgKeyMon = class(TForm) mmLog: TMemo; Splitter1: TSplitter; vtList: TVirtualStringTree; Splitter2: TSplitter; pnClient: TPanel; mmInput: TMemo; pnClientTop: TPanel; btnRefresh: TSpeedButton; btnTrans: TSpeedButton; procedure vtListGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer); procedure vtListFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode); procedure vtListGetHint(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle; var HintText: string); procedure vtListGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string); procedure vtListFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex); procedure btnRefreshClick(Sender: TObject); procedure btnTransClick(Sender: TObject); private { Private declarations } KeyMonDll_: TKeyMonDLL; DcKEnt_: TDictionary; pRecentEnt_: PKeyMonEnt; bTrans_: Boolean; public { Public declarations } Constructor Create(aOwner: TComponent); override; Destructor Destroy; override; procedure process_WM_CATCHKEY_NOTIFY(var msg: TMessage); Message WM_CATCHKEY_NOTIFY; end; var DlgKeyMon: TDlgKeyMon; implementation uses Tocsg.Keyboard, Tocsg.Path, Tocsg.Shell, Tocsg.Process, Tocsg.VTUtil, DefineKeyMon, Tocsg.WndUtil, Tocsg.Trace, Tocsg.PCRE, Tocsg.Safe, Tocsg.Strings; {$R *.dfm} var _sInput: String = ''; Constructor TDlgKeyMon.Create(aOwner: TComponent); begin Inherited Create(aOwner); Caption := APP_NAME; bTrans_ := false; pRecentEnt_ := nil; KeyMonDll_ := TKeyMonDLL.Create(Handle, MAP_FILENAME_KM, GetRunExePathDir + DLL_KEYMON); if KeyMonDll_.LastError <> ERROR_SUCCESS then begin MessageBox(Handle, PChar(Format('DLL ·Îµå ½ÇÆÐ. Error = %d', [KeyMonDll_.LastError])), APP_NAME, MB_ICONSTOP or MB_OK); Close; end; DcKEnt_ := TDictionary.Create; mmLog.Clear; end; Destructor TDlgKeyMon.Destroy; begin FreeAndNil(DcKEnt_); FreeAndNil(KeyMonDll_); Inherited; end; procedure TDlgKeyMon.btnTransClick(Sender: TObject); begin if not bTrans_ then begin mmInput.Text := EngStrToHanStr(mmInput.Text, true); bTrans_ := true; end else btnRefresh.Click; end; procedure TDlgKeyMon.btnRefreshClick(Sender: TObject); begin if pRecentEnt_ <> nil then mmInput.Text := pRecentEnt_.sData; bTrans_ := false; end; function GetProcessPIDFromWndHandle(hWndHandle: THandle): DWORD; begin Result := 0; GetWindowThreadProcessId(hWndHandle, Result); end; procedure TDlgKeyMon.process_WM_CATCHKEY_NOTIFY(var msg: TMessage); const RUN_NOTEPAD = 'apahwkd'; RUN_CALC = 'rPtksrl'; var ShiftState: TShiftState; sPName: String; nLen: Integer; h: HWND; pData: PKeyMonEnt; begin msg.Result := 0; ShiftState := KeyDataToShiftState(0); if GetKeyState(VK_LMENU) < 0 then Include(ShiftState, ssAlt); if (ssShift in ShiftState) and (ssAlt in ShiftState) and (ssCtrl in ShiftState) then begin case msg.WParam of 67 : ExecutePath('calc.exe'); // C 77 : ExecutePath('notepad.exe'); // M end; end; _sInput := _sInput + Char(msg.WParam); nLen := Length(_sInput); if nLen >= 7 then begin if CompareText(Copy(_sInput, nLen - 6, 7), RUN_NOTEPAD) = 0 then begin ExecutePath('notepad.exe'); _sInput := ''; end else if CompareText(Copy(_sInput, nLen - 6, 7), RUN_CALC) = 0 then begin ExecutePath('calc.exe'); _sInput := ''; end; if nLen > 10 then Delete(_sInput, 1, nLen - 10); end; mmLog.Lines.Add(Format('%s - KeyCode = %d', [GetInputKeyToStr(msg.WParam), msg.WParam])); h := GetForegroundWindow; if h <> 0 then begin sPName := GetProcessNameByPid(GetProcessPIDFromWndHandle(h)); if sPName <> '' then begin if (msg.WParam = VK_RETURN) and not (ssCtrl in ShiftState) then begin if CompareText('kakaotalk.exe', sPName) = 0 then begin // msg.Result := 100; // Â÷´Ü var hc := GetWndChildClass(h, 'RICHEDIT50W'); if hc <> 0 then begin var sInput := GetEditText(hc); var sOut := sInput; TTgTrace.T('kakaotalk.exe input : ' + sInput); var sSchTxt := '((?<=\b)|(?<=\D))01[016789][ ]?[-]?[ -]?[- ]?[ ]?[\s]?[.]?[^0][\d]{2,3}[ ]?[-]?[ -]?[- ]?[ ]?[\s]?[.]?[\d]{3,4}((?=\b)|(?=\D))|'+ '((?<=\b)|(?<=\D))[0]([2]|([3][1-3])|([4][1-4])|([5][1-5])|([6][12347]))-\d{3,4}-\d{4}((?=\b)|(?=\D))|((?<=\b)|(?<=\D))01[016789]-[\d]{3,4}-[\d]'+ '{4}((?=\b)|(?=\D))'; var sFound: String; var nHits := TTgPcre.GetMatchValues(sOut, sSchTxt, sFound); if nHits > 0 then begin sFound := RemoveOverlapWords(sFound); var StrList: TStringList; Guard(StrList, TStringList.Create); SplitString(sFound, ',', StrList); var i: Integer; for i := 0 to StrList.Count - 1 do sOut := StringReplace(sOut, StrList[i], '{ÇÚµåÆù¹øÈ£}', [rfReplaceAll]); sOut := sOut + #13#10#13#10 + '------------------------------' + #13#10'°³ÀÎÁ¤º¸°¡ °ËÃâµÇ¾ú½À´Ï´Ù.'; end; sOut := StringReplace(sOut, 'º´½Å', '**', [rfReplaceAll]); sOut := StringReplace(sOut, '°³»õ³¢', '***', [rfReplaceAll]); SetEditText(hc, sOut); end; end; end; if not DcKEnt_.ContainsKey(sPName) then begin pData := VT_AddChildData(vtList); pData.sPName := sPName; pData.sData := ''; DcKEnt_.Add(sPName, pData); end else pData := DcKEnt_[sPName]; pData.sData := pData.sData + GetInputKeyToStr(msg.WParam); if msg.WParam = 13 then pData.sData := pData.sData + #13#10; end; end; end; procedure TDlgKeyMon.vtListFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex); begin if Node = nil then exit; pRecentEnt_ := Sender.GetNodeData(Node); ASSERT(pRecentEnt_ <> nil); btnRefresh.Click; end; procedure TDlgKeyMon.vtListFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode); var pData: PKeyMonEnt; begin pData := Sender.GetNodeData(Node); Finalize(pData^); end; procedure TDlgKeyMon.vtListGetHint(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle; var HintText: string); begin HintText := vtList.Text[Node, Column]; end; procedure TDlgKeyMon.vtListGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer); begin NodeDataSize := SizeOf(TKeyMonEnt); end; procedure TDlgKeyMon.vtListGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string); var pData: PKeyMonEnt; begin pData := Sender.GetNodeData(Node); case Column of 0 : CellText := IntToStr(Node.Index + 1); 1 : CellText := pData.sPName; 2 : CellText := IntToStr(Length(pData.sData)); end; end; end.