23. november 2000 - 12:04
Der er
7 kommentarer og
1 løsning
Scroll Lock, Global hot key, og toggle problem...
programeringsprog: MS. Visual C++.
Jeg skal bruge en Global hotkey til at fange et tryk på Scroll Lock. Dertil bruger jeg:
//---------------------------------
RegisterHotKey(\"bla bla\")
//---------------------------------
nu er mit problem at et tryk på Scroll Lock ikke må toggle statusen på Scroll Lock (ON OFF).
Det undersøges i programmets initialiserings fase om scroll Lock er ON eller OFF med:
//---------------------------------
SHORT keyState;
keyState = GetKeyState(VK_SCROLL);
scrollState = (keyState & 0x1);
//---------------------------------
lige efter registere jeg de globale hotkeys.
Grunden til dette er at det har vist sig at jeg ikke kan regne med \"GetKeyState\", efter Scroll Lock er registreret som global hotkey.
Nå men jeg modtager en WM_HOTKEY når scroll Lock bliver trykket ned.
Nu chekker jeg om scroll Lock er ON eller OFF på min \"scrollState\" (bool) var. hvis den er ON gør jeg følgende:
>>>>>>>>>>>
Sætter et flag der fortæller at jeg skal ignorere det næste tryk på Scroll Lock, samt opdatere scroll Lock \"scrollState\".
Jeg simulere nu et tryk Scroll Lock med:
//---------------------------------
keybd_event(VK_SCROLL, 0, 0, NULL);
keybd_event(VK_SCROLL, 0, KEYEVENTF_KEYUP,
NULL);
//---------------------------------
<<<<<<<<<<<<<<
hvis ikke gør jeg intet.
>>>>>>>>>>>>>>
Så langt så godt.
Alt dette virker som det skal :)
Problemet er når Scroll Lock bliver holdt nede... Nu kommer der nemlig en række WM_HOTKEY events som følge af tastens auto-repeat. For hver af disse kommer jeg uvilkårligt til at toggle \"scrollState\". men det skal jeg IKKE...
Jeg kan ikke benytte WM_KEYUP og WM_KEYDOWN da mit program ikke er i focus.. og WM_HOTKEY, har ingen oplysninger om repeaten.
Sammenfatning:
Jeg vil gerne kunne bruge Scroll Lock som en global hotkey, samtidig med at jeg skal kunne styre \"Scroll Lock\" status (lampen)
Hvordan gør jeg så???
23. november 2000 - 12:35
#1
Om du kan forhindere at Scrol Lock Lampen tænder tvivler jeg på ....
I steder for en global hotkey vil jeg anbefale dig at bruge et KeyBoardHook ...
Prøv at kigge på det her, og se om ikke det er den vej du skal :
#include <windows.h>
#define WIN32_LEAN_AND_MEAN
WNDCLASS WinClass;
HINSTANCE Inst;
HRGN hRegion;
HWND Handle;
MSG Msg;
HHOOK hookdata;
LRESULT CALLBACK KeyboardProc ( int code, WPARAM w, LPARAM l )
{
if ( code < 0 )
return CallNextHookEx ( hookdata, code, w, l ) ;
switch (w)
{
case VK_SCROLL:
do {/*loop*/}while (PeekMessage(&Msg, 0, 0, 0, PM_REMOVE));
if (GetKeyState(VK_SCROLL))
{
keybd_event(VK_SCROLL, 0, 0, NULL);
keybd_event(VK_SCROLL, 0, KEYEVENTF_KEYUP, NULL);
}
SetWindowText(Handle, \"Scroll Lock\");
break;
default:
return CallNextHookEx ( hookdata, code, w, l ) ;
}
return 1;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CREATE:
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
Inst = hInstance;
WinClass.style = CS_CLASSDC | CS_PARENTDC;
WinClass.lpfnWndProc = &WndProc;
WinClass.hInstance = Inst;
WinClass.hbrBackground = CreateSolidBrush(0xFFFFFF);
WinClass.lpszClassName = \"JB_KEY_WINDOW\";
WinClass.hCursor = LoadCursor(0, IDC_ARROW);
RegisterClass(&WinClass);
Handle = CreateWindowEx(WS_EX_WINDOWEDGE, \"JB_KEY_WINDOW\", \"\", WS_VISIBLE | WS_CAPTION|WS_SYSMENU, 363, 278, 350, 350, 0, 0, Inst, 0);
UpdateWindow(Handle);
hookdata = SetWindowsHookEx ( WH_KEYBOARD , &KeyboardProc, Inst, GetCurrentThreadId() ) ;
while(GetMessage(&Msg, 0, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
Jens B
23. november 2000 - 13:32
#2
Det lille program du der har lavet virker fint, hvis det har focus. Desværre har vores program ikke focus.. Hvis man skal bruge hook funktionen globalt skal der laves en DLL fil.
Dette har vi prøvet- men detsværre har det nogle andre uheldige side effekter som helst skulle ungås. Sideeffekterne er at der sker \"ting\" under screensavere og andre låsning af systemet, som betyder at hookfunktionen mister sin effekt.
Derfor ville vi benytte RegisterHotKey
Tak for ulejligheden
23. november 2000 - 14:02
#3
Jeg er klar over at et Globalt keyboard hook skal implemteres i en DLL. Grunden til at jeg ikke gjore det er at det er svært at vise her .....
Hvis du hooker globalt ind med Et keyboardHook, så er det den det sidst har sat hooket der får eventet først.
Hvis der er andre der hooker ind før dig får du alligevel ikke dit event udleveret før nogle andre har pillet ved det. Så du må forklare mig hvad der er af uheldige side efekter ved et globalt KeyBoardHook ....
Jens B
24. november 2000 - 09:35
#4
Nogle gange mister Hook funktionen sin funktionalitet uden vi helt er klar over hvorfor.... Men en sikker måde at provokere den frem er, manuelt låse sin computer (\"Lock Computer\" efter Alt-Ctrl-Del).
Det lyder rigtigt når du skriver at det er den funktion der sidst har hooket sig ind får eventet først... men det forklare ikke hvordan man kan forhindre at vores hook mister sin funktionalitet.