Názvy kláves – Delphi – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Názvy kláves – Delphi – Fórum – Programujte.comNázvy kláves – Delphi – Fórum – Programujte.com

 

Sniper
~ Anonymní uživatel
215 příspěvků
28. 10. 2010   #1
-
0
-

Zdravím.
Takže mám následující problém:
Mám Virtual-Key Code nějaké klávesy (jakékoliv, nejde jen o písmena), a potřebuji uživateli zobrazit název této klávesy, např. "Ctrl", "Home", atd. . Zatím postupuji metodou že VK převedu na ScanCode pomocí API funkce MapVirtualKeyEx, a získaný ScanCode použiji do API funkce GetKeyNameText.
Až potud idylka. Jenže funkce MapVirtualKeyEx ignoruje jestli jde o levé nebo pravé klávesy (levý/pravý Alt atp.), a navíc klávesy jako šipky (VK_UP, VK_DOWN) nebo blok speciálních kláves (Home, Delete, ...) zvesela převede na scanCode kláves na numpadu. Takže při stisku PageUp se objeví "Num 9" atp. Podle dokumentace by měl jít ve MapVirtualKeyEx nastavit parametr uMapType na MAPVK_VK_TO_VSC_EX (4), což by to mělo řešit - ale to pochopitelně nefunguje (ve WinXP vůbec, ve vyšších Win sporadicky - nezkoušel jsem, ale podle komentářů co jsem měl tu čest vidět to nefunguje taky vůbec).
Takže já se ptám zkušenějších - jak docílit toho, abych mohl správně převést Virtual-Key Code na název klávesy bez toho abych na to musel vytvářet nějakou zvrácenou tabulku podle které bych to převáděl?
Dodávám že to píšu v Delphi 7, na Windows XP, a jsem amatér.

Předem děkuji za radu.

Nahlásit jako SPAM
IP: 90.179.201.–
liborb
~ Redaktor
+18
Guru
1. 11. 2010   #2
-
0
-
Nahlásit jako SPAM
IP: 78.80.52.–
Sniper
~ Anonymní uživatel
215 příspěvků
1. 11. 2010   #3
-
0
-

Samozřejmě jsem hledal, a danou stránku jsem také našel. Bohužel tohle je jenom částečné řešení.
Momentálně si pohrávám se strukturami v knihovnách kbd*.dll. Jenomže dokumentace k tomu je v C (aspoň myslím že je to C), a to já neumím. Většinu sice chápu a daří se mi dané struktury načítat (alespoň tedy pointery na ně), ale neumím převést "null terminated array" na delfácký array (jedině cyklem while, což mi přijde, mno, nic moc).
Takže zatím to vyřešené na 100% nemám.

Jedu asi takhle (je to jenom ukázka, skutečnej kód vypadá trochu jinak a je tam hromada nedodělků, jenom to testuju, a navíc jak jsem zmínil, jsem jenom amatér, tak mě za případný prasárny nekamenujte, jenom upozorněte):



const
LayoutsRegPath = '\System\CurrentControlSet\Control\Keyboard Layouts\';
RegLibValueName = 'Layout File';
ExportedFuncName = 'KbdLayerDescriptor';

TagKbdLayer = Record
pCharModifiers: Pointer;
pVkToWcharTable: Pointer; //ptr to Array of VK_TO_WCHAR_TABL
pDeadKey: Pointer;
pKeyNames: pointer; //ptr to Array of VSC_LPWSTR
pKeyNamesExt: Pointer; //ptr to Array of VSC_LPWSTR
pKeyNamesDead: ^PWideChar;
pusVSCtoVK: Pointer; //ptr to Array of Word
bMaxVSCtoVK: Byte;
pVSCtoVK_E0: Pointer; //ptr to Array of VSC_VK
pVSCtoVK_E1: Pointer; //ptr to Array of VSC_VK
fLocaleFlags: LongWord;
nLgMax: Byte;
cbLgEntry: Byte;
pLigature: Pointer;
dwType: LongWord;
dwSubType: LongWord;
end;
PTagKbdLayer = ^tagKbdLayer;

TKbdLayoutFunc = Function: PtagKbdLayer; stdcall;

var
KbdLayoutFunc: TKbdLayoutFunc;

Function GetSystemFolder: String;
const
CSIDL_SYSTEM = $0025;
var
Path: array[0..MAX_PATH] of Char;
begin
If SHGetSpecialFolderPath(0,Path,CSIDL_SYSTEM,False) then
begin
Result := IncludeTrailingPathDelimiter(Path);
end
else
begin
Result := '';
end;
end;

Function LoadLibraryFce: HModule;
var
Reg: TRegistry;
LibName: String;
LayoutName: String;
begin
Result := 0;
SetLength(LayoutName, KL_NAMELENGTH + 1);
If not GetKeyboardLayoutName(PChar(LayoutName)) then exit;
try
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
Reg.OpenKeyReadOnly(LayoutsRegPath + LayoutName);
LibName := Reg.ReadString(RegLibValueName);
finally
Reg.CloseKey;
Reg.Free;
end;
except
exit;
end;
Result := LoadLibrary(PAnsiChar(GetSystemFolder + LibName));
end;

Procedure GetKbdLayout;
var
LibHandle: HModule;
StructPoint: PtagKbdLayer;
begin
LibHandle := LoadLibraryFce;
If LibHandle = 0 then exit;
@KbdLayoutFunc := GetProcAddress(LibHandle,ExportedFuncName);
StructPoint := KbdLayoutFunc;

//...
//a dál už jenom pracuju se strukturama (StructPoint...) co jsem získal z dll knihovny.

Nahlásit jako SPAM
IP: 90.179.201.–
liborb
~ Redaktor
+18
Guru
2. 11. 2010   #4
-
0
-

No nevím ... než studovat struktury v dll, tak to bych snad udělal tu tabulku :) Ale podle vkusu každého soudruha :) A jenom poznámka ... jak jinak najít konec nulou ukončeného pole než v cyklu?

No a k tomu řešení ... pochopil jsem to tak, že to mapování umí "pojmenovat" v podstatě všechno až na ... a to jsou ty výjimky, které bych řešil ala ta odkazovaná stránka.

Nahlásit jako SPAM
IP: 78.80.52.–
Sniper
~ Anonymní uživatel
215 příspěvků
2. 11. 2010   #5
-
0
-

Asi takhle - ten program musí fungovat na různých klávesnicích (jazycích), takže tabulka nepřipadá v úvahu. A popravdě mě práce s dll na takovýhle úrovni nepřipadá nijak zvlášť složitá.
Ad. Array - mě nejde o nalezení konce (i když to s tím pochopitelně souvisí), ale o co nejjednodušší převedení na delfáckou Array (která má co jsem tak vyrozuměl trochu jinou strukturu v paměti).
To řešení - právě že to řeší i ty výjimky, a to tak že systémově. Problém zůstává jenom u pár "obskurních" kláves (NumLock, Pause/Break, přehazuje to Enter a NumEnter). Ale zatim nemám prostudovanou celou strukturu, tak snad to ještě vyřešim.

Každopádně každá pomoc je stále vítaná.

Nahlásit jako SPAM
IP: 90.179.201.–
liborb
~ Redaktor
+18
Guru
2. 11. 2010   #6
-
0
-

Proto se používají virtuální kódy, aby si nebyl závislý na jazyku nebo klávesnici. Jinak každá cesta, která vede k cíli, je správná, takže proč nebrat data z knihoven. A pokud nejsou stejné datové reprezentace, tak si je musíš načíst a programově upravit.

Nahlásit jako SPAM
IP: 195.189.143.–
liborb
~ Redaktor
+18
Guru
2. 11. 2010   #7
-
0
-

Proto se používají virtuální kódy, aby si nebyl závislý na jazyku nebo klávesnici. Jinak každá cesta, která vede k cíli, je správná, takže proč nebrat data z knihoven. A pokud nejsou stejné datové reprezentace, tak si je musíš načíst a programově upravit.

Nahlásit jako SPAM
IP: 195.189.143.–
Sniper
~ Anonymní uživatel
215 příspěvků
2. 11. 2010   #8
-
0
-

Zdá se že mi opravdu nezbude nic jiného než array převádět programově, ale to je fuk, to zvládám, jenom jsem doufal že je na to nějaký "fígl".
Jinak virtuální kódy samozřejmě používám, jenom holt potřebuju srozumitelně zobrazit jaké klávese to aktuálně odpovídá, a v tom API funkce zrovna neexcelují.

Nahlásit jako SPAM
IP: 90.179.201.–
liborb
~ Redaktor
+18
Guru
2. 11. 2010   #9
-
0
-

Ten problém jsem pochopil, jenom se neshodujeme na řešení. Mě by bylo bližší využít co API zvládá a zbytek přes jeden switch nebo tabulku. Dolování dat z knihoven už mi přijde více komplikované (nehledě na to - musí taková knihovna obsahovat vždy všechny klávesy?).

Nahlásit jako SPAM
IP: 195.189.143.–
Sniper
~ Anonymní uživatel
215 příspěvků
2. 11. 2010   #10
-
0
-

Já bych samozřejmě raději použil API, koneckonců dvě volání funkcí versus celej tenhle cirkus - dál asi netřeba rozvádět. Ale to co vyhazuje API skutečně není to pravé ořechové (prohození pomlčky, čárky a rovnítka, ...). Mě nejde jenom o dobrý pocit že to běží - ale program bude na 100% použit v cizině (včetně Asie), takže to potřebuji ošetřit maximálně systémově a pokud možno bez výjimek.
Jinak ta knihovna neobsahuje všechny klávesy, ale to co potřebuji tam je (převod VSC -> VK, VSC -> název klávesy).

Nahlásit jako SPAM
IP: 90.179.201.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 27 hostů

Podobná vlákna

Nazvy slozek do souboru — založil lamka

Dynamické názvy souborů — založil dragon124

Názvy proměnných apod. — založil Jan Sedlák

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý