Page 1 of 2

Hotkey gadgets would be nice!

Posted: Tue Aug 22, 2006 10:23 pm
by Fluid Byte
Indeed! :!:

Posted: Wed Aug 23, 2006 12:54 am
by srod
I could guess, but what exactly would a hotkey gadget do?

Posted: Wed Aug 23, 2006 9:15 am
by Trond
Like, it shows the hotkey combination you press. Word has one.

Posted: Wed Aug 23, 2006 3:10 pm
by Fluid Byte

Posted: Wed Aug 23, 2006 8:27 pm
by netmaestro
Yes, I agree, I think it would be nice to have this! While the team is working on it, in the meantime here's a little example of how you can "do it yourself". Run this program, set a hotkey and then test it by minimizing the window and then pressing your hotkey combination. If all goes well, your window will be restored when you hit the hotkey:

Code: Select all

#HotKeyGadget = 99 ; or whatever, just remember this is a #gadget so don't reuse it

Procedure ShowMsg(a,b,c,d,e) 
  If c = 0 
    SetGadgetText(1, "HOTKEY IS SET") 
  ElseIf c=1 
    SetGadgetText(1, "HOTKEY IS PRESSED") 
  EndIf 
  Delay(1000) 
  SetGadgetText(1, "") 
EndProcedure 

OpenWindow(0,0,0,320,200,"Hotkey Test",#PB_Window_SystemMenu | #PB_Window_ScreenCentered |#PB_Window_MinimizeGadget) 
CreateGadgetList(WindowID(0)) ; without this you'd want to do InitCommonControls_()
ButtonGadget(0, 220,10, 80, 20, "Set") 
TextGadget(1, 100, 60, 200, 20, "") 

hwndHot = CreateWindowEx_(0,"msctls_hotkey32","",#WS_CHILD|#WS_VISIBLE,10,10,200,20,WindowID(0),#HotkeyGadget,GetModuleHandle_(0),0)                      
SetFocus_(hwndHot) 

Repeat 
  ev = WaitWindowEvent() 
  Select ev 
    Case #WM_SYSCOMMAND
      If EventwParam() = #SC_HOTKEY
        timeSetEvent_(10,10,@ShowMsg(),1,#TIME_ONESHOT)
      EndIf
    Case #PB_Event_Gadget 
      Select EventGadget() 
        Case 0
          wHotkey.w  
           ; Retrieve the hot key (virtual key code And modifiers) 
          wHotkey = SendMessage_(hwndHot, #HKM_GETHOTKEY, 0, 0) 
          ; Use the result As wParam For WM_SETHOTKEY. 
          If SendMessage_(WindowID(0), #WM_SETHOTKEY, wHotkey, 0) 
            timeSetEvent_(10,10,@ShowMsg(),0,#TIME_ONESHOT) 
          EndIf 
      EndSelect 
   EndSelect 
Until ev=#WM_CLOSE 

Posted: Thu Mar 05, 2009 10:04 pm
by Michael Vogel
Cool code, netmaestro - thanks!

But - typically for me :roll: - I have some questions...

...is there also a possibility to check combinations including the Windows key (#VK_MOD)?
...how I can use the same font for the hotkey control gadget like in all other gadgets?

And, can the value assigned to the variable wHotkey be used to register a hotkey?

Thanks,
Michael

Posted: Mon Apr 13, 2009 1:22 pm
by PB
> While the team is working on it

:lol: +1

Seriously: is there a way to make this gadget not be bold?

Posted: Mon Apr 13, 2009 2:08 pm
by netmaestro
@PB: Yes, just stick this line in the code below the CreateWindowEx:

Code: Select all

SendMessage_(hwndHot,#WM_SETFONT,GetStockObject_(#DEFAULT_GUI_FONT),0)

Posted: Thu Jul 23, 2009 11:38 am
by PB
Two more questions for netmaestro's example:

(1) Is there a way to get the text of the control as a string?
(2) Is there a way to color the background and text of it?

Thanks for any help.

Posted: Thu Jul 23, 2009 1:47 pm
by netmaestro
As to the color, I'm not sure. Still thinking for now. As to retrieving the text, I don't think there's a simple way. It isn't as easy as sending WM_GETTEXT or GetWindowText_() but you can parse the return value of HKM_GETHOTKEY and go from there:

Code: Select all

#HotKeyGadget = 99 ; or whatever, just remember this is a #gadget so don't reuse it 

Procedure ShowMsg(a,b,c,d,e) 
  If c = 0 
    SetGadgetText(1, "HOTKEY IS SET") 
  ElseIf c=1 
    SetGadgetText(1, "HOTKEY IS PRESSED") 
  EndIf 
  Delay(1000) 
  SetGadgetText(1, "") 
EndProcedure 

Procedure$ GetHotkeyText(hotkeycontrol) 
  Protected locale, hotkey.w, key, key$, mod$, ctrl$, shift$, alt$, result$ 
  locale = GetKeyboardLayout_(GetCurrentThreadId_()) 
  hotkey.w = SendMessage_(hotkeycontrol, #HKM_GETHOTKEY, 0, 0) 
  key$ = Space(100) 
  ; Virtual key 
  key = MapVirtualKeyEx_(hotkey&$FF,0,locale)<<16 
  If hotkey>>8 & #HOTKEYF_EXT 
    key | (1<<24) ; Set the extended key bit 
  EndIf 
  GetKeyNameText_(key, @key$, 100) 
  ; Modifier(s) 
  ctrl$ = Space(100) : shift$ = Space(100) : alt$ = Space(100) 
  GetKeyNameText_(MapVirtualKeyEx_(#VK_CONTROL,0,locale)<<16, @ctrl$,  100) : ctrl$  + " + " 
  GetKeyNameText_(MapVirtualKeyEx_(#VK_SHIFT,  0,locale)<<16, @shift$, 100) : shift$ + " + " 
  GetKeyNameText_(MapVirtualKeyEx_(#VK_MENU,   0,locale)<<16, @alt$,   100) : alt$   + " + " 
  
  mod$ = "" 
  If hotkey>>8 & #HOTKEYF_CONTROL : mod$ + ctrl$  : EndIf 
  If hotkey>>8 & #HOTKEYF_SHIFT   : mod$ + shift$ : EndIf 
  If hotkey>>8 & #HOTKEYF_ALT     : mod$ + alt$   : EndIf 
  ; Output string 
  result$ = mod$+key$ 
  If result$ = "" : result$ = "None" : EndIf 
  ProcedureReturn result$ 
EndProcedure 

OpenWindow(0,0,0,320,200,"Hotkey Test",#PB_Window_SystemMenu | #PB_Window_ScreenCentered |#PB_Window_MinimizeGadget) 

ButtonGadget(0, 220,10, 80, 20, "Set") 
TextGadget(1, 100, 60, 200, 20, "") 
TextGadget(2, 70,140,80,20, "Hotkey Text:") 
TextGadget(3, 150,140,140,20,"") 

hwndHot = CreateWindowEx_(0,"msctls_hotkey32","",#WS_CHILD|#WS_VISIBLE,10,10,200,20,WindowID(0),#HotkeyGadget,GetModuleHandle_(0),0)                      
SetFocus_(hwndHot) 

txt$ = GetHotkeyText(hwndhot) 
SetGadgetText(3, txt$) 

Repeat 
  ev = WaitWindowEvent() 
  Select ev 
    Case #WM_SYSCOMMAND 
      If EventwParam() = #SC_HOTKEY 
        timeSetEvent_(10,10,@ShowMsg(),1,#TIME_ONESHOT) 
      EndIf 
    Case #PB_Event_Gadget 
      Select EventGadget() 
        Case 0 
          ; Retrieve the hot key (virtual key code And modifiers) 
          wHotkey.w = SendMessage_(hwndHot, #HKM_GETHOTKEY, 0, 0) 
          ; Use the result As wParam For WM_SETHOTKEY. 
          If SendMessage_(WindowID(0), #WM_SETHOTKEY, wHotkey, 0) 
            ; Retrieve the contents of the control in text form 
            txt$ = GetHotkeyText(hwndhot) 
            If txt$ <> "None" 
              timeSetEvent_(10,10,@ShowMsg(),0,#TIME_ONESHOT) 
            EndIf 
            SetGadgetText(3, txt$) 
          EndIf 
          SetFocus_(hwndHot) 
      EndSelect 
   EndSelect 
Until ev=#PB_Event_CloseWindow 
Should be fine for ascii or unicode. Tested with English and German locales, no problems found.

Posted: Thu Jul 23, 2009 9:28 pm
by PB
Thanks netmaestro; I did try #WM_GETTEXT and GetWindowText_() but had
no luck either. But with your amended code, I ran into this problem: Num 6?

Image

Posted: Thu Jul 23, 2009 10:37 pm
by netmaestro
You're right, I forgot to set the extended key bit in the created lParam so that GetKeyNameText_() can distinguish between nums and arrows. Please accept my apologies, posted code is modified and should work now.

Posted: Fri Jul 24, 2009 10:08 am
by PB
No need to apologise. I'm just glad you're able to help. Will look at it later.

Posted: Fri Jul 24, 2009 11:17 am
by Michael Vogel
Michael Vogel wrote:...is there also a possibility to check combinations including the Windows key (#VK_MOD)?
...how I can use the same font for the hotkey control gadget like in all other gadgets?
:roll:

Posted: Fri Jul 24, 2009 1:32 pm
by netmaestro
For the font just look up a few posts... :wink: