PB 6.03: attaching a shortcut to a gadget with & nonfunctional

Just starting out? Need help? Post your questions and find answers here.
Quin
Addict
Addict
Posts: 1124
Joined: Thu Mar 31, 2022 7:03 pm
Location: Colorado, United States
Contact:

PB 6.03: attaching a shortcut to a gadget with & nonfunctional

Post by Quin »

To reproduce, run the following code, and try to press alt+f for first, alt+t for toggle, etc. At least to my screen reader, NVDA, the keys are read out as having the shortcuts attached (e.g. "First button alt+f"), but the shortcuts don't actually work. This applies to more than just buttons (StringGadgets with an associated TextGadget(), for example, also have the same problem), but buttons were just the easiest example.

Code: Select all

EnableExplicit

OpenWindow(0, 0, 0, 222, 200, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(0, 10, 10, 200, 20, "&First")
ButtonGadget(1, 10, 40, 200, 20, "&Second")
ButtonGadget(2, 10, 70, 200, 20, "&Third")
ButtonGadget(3, 10, 100, 200, 60, "&Fourth")
ButtonGadget(4, 10, 170, 200, 20, "&Toggle Button", #PB_Button_Toggle)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
This isn't super new, pretty sure I also at least saw it on PB 6.02 but am not completely sure when it started.
infratec
Always Here
Always Here
Posts: 7577
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: PB 6.03: attaching a shortcut to a gadget with & nonfunctional

Post by infratec »

Hm ...
there is no automatic fuctionality for Alt functions when you underscore a letter.
Even as MenuItem you have to do it by yourself.

Code: Select all

EnableExplicit

OpenWindow(0, 0, 0, 222, 200, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(0, 10, 10, 200, 20, "&First")
AddKeyboardShortcut(0, #PB_Shortcut_Alt + #PB_Shortcut_F, 0)
ButtonGadget(1, 10, 40, 200, 20, "&Second")
AddKeyboardShortcut(0, #PB_Shortcut_Alt + #PB_Shortcut_S, 1)
ButtonGadget(2, 10, 70, 200, 20, "&Third")
AddKeyboardShortcut(0, #PB_Shortcut_Alt + #PB_Shortcut_T, 2)
ButtonGadget(3, 10, 100, 200, 60, "F&ourth")
AddKeyboardShortcut(0, #PB_Shortcut_Alt + #PB_Shortcut_O, 3)
ButtonGadget(4, 10, 170, 200, 20, "To&ggle Button", #PB_Button_Toggle)
AddKeyboardShortcut(0, #PB_Shortcut_Alt + #PB_Shortcut_G, 4)
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Menu
      Debug EventMenu()
      Select EventMenu()
        Case 4
          SetGadgetState(4, Bool(Not GetGadgetState(4)))
      EndSelect
  EndSelect
ForEver
juergenkulow
Enthusiast
Enthusiast
Posts: 581
Joined: Wed Sep 25, 2019 10:18 am

[No Bug]Re: PB 6.03: attaching a shortcut to a gadget with & nonfunctional

Post by juergenkulow »

Under Linux, underlining letters with & does not work at all. Image
Quin
Addict
Addict
Posts: 1124
Joined: Thu Mar 31, 2022 7:03 pm
Location: Colorado, United States
Contact:

Re: PB 6.03: attaching a shortcut to a gadget with & nonfunctional

Post by Quin »

I'm fairly certain this is the default in virtually every framework. WPF, Win32, wxWidgets, etc. If the behavior never existed, it should, it's extremely universal.
infratec wrote: Sat Nov 04, 2023 10:13 pm Hm ...
there is no automatic fuctionality for Alt functions when you underscore a letter.
Even as MenuItem you have to do it by yourself.

Code: Select all

EnableExplicit

OpenWindow(0, 0, 0, 222, 200, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(0, 10, 10, 200, 20, "&First")
AddKeyboardShortcut(0, #PB_Shortcut_Alt + #PB_Shortcut_F, 0)
ButtonGadget(1, 10, 40, 200, 20, "&Second")
AddKeyboardShortcut(0, #PB_Shortcut_Alt + #PB_Shortcut_S, 1)
ButtonGadget(2, 10, 70, 200, 20, "&Third")
AddKeyboardShortcut(0, #PB_Shortcut_Alt + #PB_Shortcut_T, 2)
ButtonGadget(3, 10, 100, 200, 60, "F&ourth")
AddKeyboardShortcut(0, #PB_Shortcut_Alt + #PB_Shortcut_O, 3)
ButtonGadget(4, 10, 170, 200, 20, "To&ggle Button", #PB_Button_Toggle)
AddKeyboardShortcut(0, #PB_Shortcut_Alt + #PB_Shortcut_G, 4)
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Menu
      Debug EventMenu()
      Select EventMenu()
        Case 4
          SetGadgetState(4, Bool(Not GetGadgetState(4)))
      EndSelect
  EndSelect
ForEver
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [No Bug]Re: PB 6.03: attaching a shortcut to a gadget with & nonfunctional

Post by Shardik »

juergenkulow wrote: Sun Nov 05, 2023 1:03 am Under Linux, underlining letters with & does not work at all.
It also works under Linux - kind of. Instead of the ampersand character "&" you have to use the underline character "_" in Linux. 13 years ago debashisde asked in this thread how to display underlined shortcut characters on a button and I posted this cross-platform example for Linux and Windows. But when testing it again on my now current Linux Mint 21.2 x64, it seemingly didn't work. Until I discovered that you have to press the <Alt> key for at least 300 ms until the underscore character is displayed. The shortcut key combination <Alt> + <A> is working at once without having to wait 300 milliseconds.

This is one of the many weird design decisions the GTK developers have chosen. Take a look into this 9 year old thread and see Emmanuele Bassi's (one of the main developers of GTK) arguments for closing this thread 3 years ago:
Mnemonics work regardless of whether they are visible or not. The "press Alt to show mnemonics" is a tool to learn what those mnemonics are, until you don't need to see them any more.
We don't have any plans on making the timeout configurable, nor to add back the setting to make the mnemonic always visible.
juergenkulow
Enthusiast
Enthusiast
Posts: 581
Joined: Wed Sep 25, 2019 10:18 am

Re: PB 6.03: attaching a shortcut to a gadget with & nonfunctional

Post by juergenkulow »

Code: Select all

; Button Menu: Try to press Key 1  
Enumeration ButtonKeys : #noAction=0 : #Key1=1 : #Key2 : #Key3 : #Key4 : #Key5  : EndEnumeration
Procedure ButtonMenu12345()
  Protected Action,Event 
  OpenWindow(0, 0, 0, 222, 200, "ButtonMenu12345", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  AddKeyboardShortcut(0,#PB_Shortcut_1,#Key1)
  AddKeyboardShortcut(0,#PB_Shortcut_2,#Key2)
  AddKeyboardShortcut(0,#PB_Shortcut_3,#Key3)
  AddKeyboardShortcut(0,#PB_Shortcut_4,#Key4)
  AddKeyboardShortcut(0,#PB_Shortcut_5,#Key5)
  
  ButtonGadget(1, 10, 10, 200, 20, "First Key 1")  
  ButtonGadget(2, 10, 40, 200, 20, "Second Key 2")
  ButtonGadget(3, 10, 70, 200, 20, "Third Key 3")
  ButtonGadget(4, 10, 100, 200, 60, "Fourth Key 4")
  ButtonGadget(5, 10, 170, 200, 20, "Toggle Button Key 5", #PB_Button_Toggle)
  Action=#noAction
  Repeat 
    Event=WaitWindowEvent(1)
    If Event=#PB_Event_Gadget
      Action=EventGadget()
    ElseIf Event= #PB_Event_Menu
      Action=EventMenu() 
    EndIf   
  Until Event = #PB_Event_CloseWindow Or Action<>#noAction
  CloseWindow(0)
  Debug "Action:"+Str(Action)
  
  ProcedureReturn Action  
EndProcedure

End ButtonMenu12345() ;  returns the exitcode Action, see ProgramExitCode()

Code: Select all

; Run Program ButtonMenu12345
Program=RunProgram("/tmp/a.out","","", #PB_Program_Open | #PB_Program_Read ) ; Please adjust the file name.
If Program 
  While ProgramRunning(Program) :  Wend 
  Debug ProgramExitCode(Program)
EndIf 
Quin
Addict
Addict
Posts: 1124
Joined: Thu Mar 31, 2022 7:03 pm
Location: Colorado, United States
Contact:

Re: PB 6.03: attaching a shortcut to a gadget with & nonfunctional

Post by Quin »

Just wrote a tiny C program to test this using the raw Win32 API, and it would appear that I was wrong. Even though my screen reader, NVDA, considers any underlined letter to be an accelerator, that appears to be quite wrong. Here's the code, just for reference:

Code: Select all

#include <windows.h>

void OnButtonClick(HWND hwnd) {
	MessageBox(hwnd, "Button Clicked!", "Message", MB_OK | MB_ICONINFORMATION);
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
	switch (message) {
		case WM_COMMAND:
			if (LOWORD(wParam) == IDOK) {
				OnButtonClick(hwnd);
			}
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			return DefWindowProc(hwnd, message, wParam, lParam);
	}
	return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	WNDCLASS wc = { 0 };
	wc.lpfnWndProc = WndProc;
	wc.hInstance = hInstance;
	wc.lpszClassName = "AltKeyTest";
	RegisterClass(&wc);
	HWND hwnd = CreateWindow("AltKeyTest", "Test", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 400, 200, NULL, NULL, hInstance, NULL);
	CreateWindow("BUTTON", "&OK", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 150, 70, 80, 30, hwnd, (HMENU)IDOK, hInstance, NULL);
	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}
Has anyone explored using an accelerator table with PB? https://learn.microsoft.com/en-us/windo ... tor-tables
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: PB 6.03: attaching a shortcut to a gadget with & nonfunctional

Post by RASHAD »

Hi
For Windows
Run Accelerators Keys for Windows [ Underscore char ]

Code: Select all

OpenWindow(0, 0, 0, 222, 200, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(0, 10, 10, 200, 24, "&First")
ButtonGadget(1, 10, 40, 200, 24, "&Second")
ButtonGadget(2, 10, 70, 200, 24, "&Third")
ButtonGadget(3, 10, 100, 200, 60, "&Fourth")
ButtonGadget(4, 10, 170, 200, 24, "&Toggle Button", #PB_Button_Toggle)
SendMessage_(WindowID(0), #WM_UPDATEUISTATE, $30002,0)
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
      
    Case #WM_SYSKEYDOWN 
      key = EventwParam()
      Select key
        Case 70
          Debug "Button 0 selected"
        Case 83
          Debug "Button 1 selected"
        Case 84
          Debug "Button 2 selected"
      EndSelect      
  EndSelect
Until Quit = 1

Egypt my love
GoodNPlenty
Enthusiast
Enthusiast
Posts: 112
Joined: Wed May 13, 2009 8:38 am
Location: Arizona, USA

Re: PB 6.03: attaching a shortcut to a gadget with & nonfunctional

Post by GoodNPlenty »

Since EventwParam() will be eventually deprecated a SetWindowCallback() example below.

Code: Select all

Procedure WinCallback(hWnd, uMsg, WParam, LParam) 
  
  Select uMsg
    Case #WM_SYSKEYDOWN 
      Select WParam
        Case 70
          Debug "First Selected"
        Case 83
          Debug "Second Selected"
        Case 84
          Debug "Third Selected"
        Case 79
          Debug "Fourth Selected"
        Case 71
          Debug "Toggle Button Selected"
      EndSelect      
  EndSelect          
  
  ProcedureReturn #PB_ProcessPureBasicEvents 
EndProcedure 

If OpenWindow(0, 0, 0, 222, 200, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ButtonGadget(0, 10, 10, 200, 24, "&First")
  ButtonGadget(1, 10, 40, 200, 24, "&Second")
  ButtonGadget(2, 10, 70, 200, 24, "&Third")
  ButtonGadget(3, 10, 100, 200, 60, "F&ourth")
  ButtonGadget(4, 10, 170, 200, 24, "To&ggle Button", #PB_Button_Toggle)
  SendMessage_(WindowID(0), #WM_UPDATEUISTATE, $30002,0)
  
  SetWindowCallback(@WinCallback(), 0)
    
  Repeat 
    Select WaitWindowEvent() 
      Case #PB_Event_CloseWindow 
        End 
    EndSelect 
  ForEver 
EndIf
Fred
Administrator
Administrator
Posts: 18161
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: PB 6.03: attaching a shortcut to a gadget with & nonfunctional

Post by Fred »

Quin wrote: Tue Jan 30, 2024 3:15 am Just wrote a tiny C program to test this using the raw Win32 API, and it would appear that I was wrong. Even though my screen reader, NVDA, considers any underlined letter to be an accelerator, that appears to be quite wrong. Here's the code, just for reference:

Code: Select all

#include <windows.h>

void OnButtonClick(HWND hwnd) {
	MessageBox(hwnd, "Button Clicked!", "Message", MB_OK | MB_ICONINFORMATION);
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
	switch (message) {
		case WM_COMMAND:
			if (LOWORD(wParam) == IDOK) {
				OnButtonClick(hwnd);
			}
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			return DefWindowProc(hwnd, message, wParam, lParam);
	}
	return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	WNDCLASS wc = { 0 };
	wc.lpfnWndProc = WndProc;
	wc.hInstance = hInstance;
	wc.lpszClassName = "AltKeyTest";
	RegisterClass(&wc);
	HWND hwnd = CreateWindow("AltKeyTest", "Test", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 400, 200, NULL, NULL, hInstance, NULL);
	CreateWindow("BUTTON", "&OK", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 150, 70, 80, 30, hwnd, (HMENU)IDOK, hInstance, NULL);
	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}
Has anyone explored using an accelerator table with PB? https://learn.microsoft.com/en-us/windo ... tor-tables
You should use DefDlgProc() instead of DefWindowProc() to handle keyboard shortcut and more. PB doesn't do that because all window are not dialog in PB. I might add a flag to the window creation to enable this.
Quin
Addict
Addict
Posts: 1124
Joined: Thu Mar 31, 2022 7:03 pm
Location: Colorado, United States
Contact:

Re: PB 6.03: attaching a shortcut to a gadget with & nonfunctional

Post by Quin »

Please do, that would be incredible! :)
Fred wrote: Tue Jan 30, 2024 4:40 pm
Quin wrote: Tue Jan 30, 2024 3:15 am Just wrote a tiny C program to test this using the raw Win32 API, and it would appear that I was wrong. Even though my screen reader, NVDA, considers any underlined letter to be an accelerator, that appears to be quite wrong. Here's the code, just for reference:

Code: Select all

#include <windows.h>

void OnButtonClick(HWND hwnd) {
	MessageBox(hwnd, "Button Clicked!", "Message", MB_OK | MB_ICONINFORMATION);
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
	switch (message) {
		case WM_COMMAND:
			if (LOWORD(wParam) == IDOK) {
				OnButtonClick(hwnd);
			}
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			return DefWindowProc(hwnd, message, wParam, lParam);
	}
	return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	WNDCLASS wc = { 0 };
	wc.lpfnWndProc = WndProc;
	wc.hInstance = hInstance;
	wc.lpszClassName = "AltKeyTest";
	RegisterClass(&wc);
	HWND hwnd = CreateWindow("AltKeyTest", "Test", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 400, 200, NULL, NULL, hInstance, NULL);
	CreateWindow("BUTTON", "&OK", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 150, 70, 80, 30, hwnd, (HMENU)IDOK, hInstance, NULL);
	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}
Has anyone explored using an accelerator table with PB? https://learn.microsoft.com/en-us/windo ... tor-tables
You should use DefDlgProc() instead of DefWindowProc() to handle keyboard shortcut and more. PB doesn't do that because all window are not dialog in PB. I might add a flag to the window creation to enable this.
Post Reply