Canvas keydown

Just starting out? Need help? Post your questions and find answers here.
Polo
Addict
Addict
Posts: 2422
Joined: Tue May 06, 2003 5:07 pm
Location: UK

Canvas keydown

Post by Polo »

Hello,

The CanvasGadget won't return the correct character after a keydown, only the key pushed - which is useless imho.
we've got a workaround on windows to return the character, and I'm building one for MacOS.
The code below does what I want (i.e. it accepts capital letters), but doesn't take all characters.
For instance "é" returns -114.
changing to unsigned word in the callback won't return the correct character.

Anybody has an idea?

Code: Select all

ImportC ""
      NewControlUserPaneKeyDownUPP.l(*userRoutine)
      SetControlData ( ControlRef.l, ControlPartCode.l, inTagName.l, inSize.l,*inData)
EndImport

    #kControlEntireControl = 0
    #kControlUserPaneKeyDownProcTag = 1801812324

    ProcedureC MacCanvasCallback(ControlRef.l, key.w, char.w, modifiers.w)
      MessageRequester("",Str(key)+" "+Str(char)+" "+Str(modifiers))
    EndProcedure

    canvascallback.i = NewControlUserPaneKeyDownUPP(@MacCanvasCallback())
    SetControlData(GadgetID(canvas), #kControlEntireControl,#kControlUserPaneKeyDownProcTag,SizeOf(Integer),@canvascallback)

Thanks!
Gaetan
User avatar
TomS
Enthusiast
Enthusiast
Posts: 342
Joined: Sun Mar 18, 2007 2:26 pm
Location: Munich, Germany

Re: Canvas keydown

Post by TomS »

The character is never returned. Only the key.
This is always the case.
é = 221 + 69
Since ´ is a "dead key" (must always be followed by another key) this is not a problem.

Code: Select all

If OpenWindow(0, 0, 0, 220, 220, "CanvasGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	
	StringGadget(2, 10, 190, 200, 20, "StringGadget")	
	CanvasGadget(1, 10, 10, 200, 170, #PB_Canvas_Keyboard)
	
	
	Repeat
		Event = WaitWindowEvent()
		
		Select Event
			Case #PB_Event_Gadget 
				If EventGadget() = 1 
					If EventType()=#PB_EventType_KeyDown
						
						Select GetGadgetAttribute(1,#PB_Canvas_Key ) 
							Case 221
								apostrophe_right = 1
								
							Case 69	;#PB_Shortcut_E		
								
								If apostrophe_right = 1
									StartDrawing(CanvasOutput(1))
									Box(0,0,200,170,$FFFFFF)
									DrawText(5, 5, "é", 0, $FFFFFF)
									StopDrawing()
									apostrophe_right = 0
								Else 
									StartDrawing(CanvasOutput(1))
									Box(0,0,200,170,$FFFFFF)
									DrawText(5, 5, "e", 0, $FFFFFF)
									StopDrawing()
									apostrophe_right = 0
								EndIf 
								
						EndSelect 
						
						
					EndIf 
				EndIf 
				
				
				
		EndSelect 
		
	Until Event = #PB_Event_CloseWindow
EndIf 
Polo
Addict
Addict
Posts: 2422
Joined: Tue May 06, 2003 5:07 pm
Location: UK

Re: Canvas keydown

Post by Polo »

On a french keyboard, "é" is on the key "2" for instance.
And as you can see in my example, the callback does return the key and the character - only it doesn't work for accents, unfortunately, unlike the workaround with the Windows callback.
User avatar
TomS
Enthusiast
Enthusiast
Posts: 342
Joined: Sun Mar 18, 2007 2:26 pm
Location: Munich, Germany

Re: Canvas keydown

Post by TomS »

I see.
So on your keyboard my code doesn't work at all.

I can't get your code to work
---------------------------
PureBasic - Linker error
---------------------------
POLINK: error: Unresolved external symbol '_NewControlUserPaneKeyDownUPP'.

POLINK: error: Unresolved external symbol '_SetControlData'.

POLINK: fatal error: 2 unresolved external(s).


---------------------------
OK
---------------------------

Code: Select all

ImportC ""
	NewControlUserPaneKeyDownUPP.l(*userRoutine)
	SetControlData ( ControlRef.l, ControlPartCode.l, inTagName.l, inSize.l,*inData)
EndImport

#kControlEntireControl = 0
#kControlUserPaneKeyDownProcTag = 1801812324

ProcedureC MacCanvasCallback(ControlRef.l, key.w, char.w, modifiers.w)
	MessageRequester("",Str(key)+" "+Str(char)+" "+Str(modifiers))
EndProcedure


canvascallback.i = NewControlUserPaneKeyDownUPP(@MacCanvasCallback())


hWnd = OpenWindow(#PB_Any, 0, 0, 400, 400, "Fenster", #PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)
CanvasGadget(0,0,0,400,400,#PB_Canvas_Keyboard)


SetControlData(GadgetID(0), #kControlEntireControl,#kControlUserPaneKeyDownProcTag,SizeOf(Integer),@canvascallback)

Repeat
	event = WaitWindowEvent(20)
	
Until event = #PB_Event_CloseWindow
End
Polo
Addict
Addict
Posts: 2422
Joined: Tue May 06, 2003 5:07 pm
Location: UK

Re: Canvas keydown

Post by Polo »

Doesn't work on MacOS, right?

Try :

Code: Select all

    ImportC "/System/Library/Frameworks/Carbon.framework/Carbon"
User avatar
TomS
Enthusiast
Enthusiast
Posts: 342
Joined: Sun Mar 18, 2007 2:26 pm
Location: Munich, Germany

Re: Canvas keydown

Post by TomS »

No. Windows 7, 32bit
PB 4.6 b3
User avatar
STARGÅTE
Addict
Addict
Posts: 2235
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: Canvas keydown

Post by STARGÅTE »

i use this for get the right character:

Code: Select all

OpenWindow(0, 0, 0, 400, 300, "", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)

#PB_Event_Character = #WM_CHAR

Repeat
	Select WaitWindowEvent()
		Case #PB_Event_CloseWindow
			End
		Case #PB_Event_Character
			Debug Chr(EventwParam())
	EndSelect
ForEver
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
User avatar
TomS
Enthusiast
Enthusiast
Posts: 342
Joined: Sun Mar 18, 2007 2:26 pm
Location: Munich, Germany

Re: Canvas keydown

Post by TomS »

Awesome, Stargate.
Polo
Addict
Addict
Posts: 2422
Joined: Tue May 06, 2003 5:07 pm
Location: UK

Re: Canvas keydown

Post by Polo »

Great, though my problem is on MacOS only ;)
User avatar
Shardik
Addict
Addict
Posts: 2060
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Canvas keydown

Post by Shardik »

Polo wrote:Hello,

The CanvasGadget won't return the correct character after a keydown, only the key pushed - which is useless imho.
we've got a workaround on windows to return the character, and I'm building one for MacOS.
The code below does what I want (i.e. it accepts capital letters), but doesn't take all characters.
For instance "é" returns -114.
changing to unsigned word in the callback won't return the correct character.

Anybody has an idea?
I have taken TomS' code example and replaced the MacCanvasCallback with this code:

Code: Select all

ProcedureC MacCanvasCallback(ControlRef.l, key.w, char.w, modifiers.w)
  If char & $FF00
    Select char & $FF
      Case $8E
        Debug "é"
      Case $8F
        Debug "è"
      Case $90
        Debug "ê"
    EndSelect
  Else
    Debug Chr(char)
  EndIf
EndProcedure
On my German Mac keyboard the character "é" is displayed without problems.
You simply have to test whether the first byte of the word in char is $FF and in that
case you have to evaluate the second byte and convert it to your wanted character.
Probably my example won't work for you directly on your French keyboard and
you have to find out the correct value of the second byte to translate it to é... :wink:
Polo
Addict
Addict
Posts: 2422
Joined: Tue May 06, 2003 5:07 pm
Location: UK

Re: Canvas keydown

Post by Polo »

Thanks Shardik!
Strange Mac doesn't return the correct characters though, there are many more that shall not work correctly (ù, ç, à, ë, ï, ...) :cry:
Polo
Addict
Addict
Posts: 2422
Joined: Tue May 06, 2003 5:07 pm
Location: UK

Re: Canvas keydown

Post by Polo »

... and this is not just me on the canvas gadget, when i type on the key "^" on my french keyboard, it displays "NUL" in PB IDE - and displays "NUL ê" if i type "^" and then "e".
Weird :)
User avatar
Shardik
Addict
Addict
Posts: 2060
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Canvas keydown

Post by Shardik »

Polo wrote:... and this is not just me on the canvas gadget, when i type on the key "^" on my french keyboard, it displays "NUL" in PB IDE - and displays "NUL ê" if i type "^" and then "e".
Weird :)
If I examine the character code generated for pressing the dead key
accent aigu in a CanvasGadget on my German Mac keyboard, I obtain
the value $00. The PB IDE doesn't catch that dead key and incorrectly
displays NUL before correctly displaying the character é... :wink:

But please try the following example without any API calls. It displays
the following special language characters without any problems on a
German Mac keyboard (although it doesn't work without OS specific
adaptions on Windows or Linux and I doubt that it will work on your
French keyboard without modifications but it might well give you the
idea for a possible alternative solution):

Image

Code: Select all

OpenWindow(0, 100, 100, 400, 100, "Display pressed key")

CanvasGadget(0, 3, 3, WindowWidth(0) - 6, WindowHeight(0) - 46, #PB_Canvas_Keyboard | #PB_Canvas_DrawFocus)
TextGadget(1, 2, WindowHeight(0) - 40, WindowWidth(0) - 4, 38, "", #PB_Text_Border | #PB_Text_Center)
SetGadgetFont(1, LoadFont(0, "Arial", 32))
SetActiveGadget(0)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventType() = #PB_EventType_KeyDown
        ShiftKey = 0
        
        If GetGadgetAttribute(0, #PB_Canvas_Modifiers) & #PB_Canvas_Shift
          ShiftKey = $20
        EndIf
        
        CharCode = GetGadgetAttribute(0, #PB_Canvas_Key)
        
        If CharCode = 0
          If ShiftKey = 0
            AccentGrave = #False
          Else
            AccentGrave = #True
          EndIf
        EndIf
        
        If FindString("Éé", Chr(CharCode))
          If AccentGrave
            CharCode - 1
          EndIf
        EndIf

        If CharCode <> 0
          InputString$ + Chr(CharCode ! ShiftKey)
          SetGadgetText(1, InputString$)
        EndIf
      EndIf
  EndSelect
ForEver
Polo
Addict
Addict
Posts: 2422
Joined: Tue May 06, 2003 5:07 pm
Location: UK

Re: Canvas keydown

Post by Polo »

With your code I get some of the accentued characters (éèçàùê) and some not (ëä...) but cannot get the numbers working then (on a french keyboard you get a number by pressing shift plus the number key).
Unfortunately this workaround won't work on all keyboards :cry:
Post Reply