Page 1 of 1

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

Posted: Sat Nov 04, 2023 4:34 pm
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.

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

Posted: Sat Nov 04, 2023 10:13 pm
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

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

Posted: Sun Nov 05, 2023 1:03 am
by juergenkulow
Under Linux, underlining letters with & does not work at all. Image

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

Posted: Sun Nov 05, 2023 8:59 am
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

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

Posted: Sun Nov 05, 2023 7:19 pm
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.

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

Posted: Mon Nov 06, 2023 10:19 am
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 

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

Posted: Tue Jan 30, 2024 3:15 am
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

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

Posted: Tue Jan 30, 2024 7:16 am
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


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

Posted: Tue Jan 30, 2024 4:04 pm
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

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

Posted: Tue Jan 30, 2024 4:40 pm
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.

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

Posted: Tue Jan 30, 2024 5:11 pm
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.