Avatar billede dyrby Nybegynder
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å???





Avatar billede borrisholt Novice
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
Avatar billede dyrby Nybegynder
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
Avatar billede borrisholt Novice
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
Avatar billede dyrby Nybegynder
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.
Avatar billede borrisholt Novice
24. november 2000 - 11:40 #5
Alt-Ctrl-Del kan du ikke blokere andet end i win 95/98

Men hvordan man får hooket sat igen efter \"Lock Computer\" ved jeg ikke men det kan jeg da forske lidt i .....

Jens B

Avatar billede lbs Nybegynder
25. november 2000 - 04:37 #6
det gør du bare ikke

Det er langt ude og jeg forstår windows folkene helt og holdent hvis de har syntes der ikke var grund til at bygge plads til den slags ind.
Avatar billede dyrby Nybegynder
25. november 2000 - 15:10 #7
>>lbs
Hvad er det præcist du harmer over?? Skal det ikke kunne lade sig gøre at lave en hook funktion som kan bruges også selvom man har startet f.eks. \"task manager\" ved hjælp af: Alt-Ctrl-Del? eller bare at man fortryder at have trykket Alt-Ctrl-Del og derfor vælger cancel?
Hvad er det præcist logikken i at man så ikke har mulighed for at sætte hook funktionen igen?
Avatar billede dyrby Nybegynder
11. december 2000 - 14:01 #8
Jeg lukker spørgsmålet... men er der nogen der pludseliig kommer på en løsning, finder vi ud at få pointene uddelt alligevel:) Glædelig jul!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester