1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Keyboard wxWidgets sample
4 // Author: Vadim Zeitlin
5 // Modified by: Marcin Wojdyr
8 // Copyright: (c) 2002 Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
21 #ifndef wxHAS_IMAGES_IN_RESOURCES
22 #include "../sample.xpm"
25 // Define a new frame type: this is going to be our main frame
26 class MyFrame
: public wxFrame
29 MyFrame(const wxString
& title
);
33 void OnQuit(wxCommandEvent
& WXUNUSED(event
)) { Close(true); }
34 void OnAbout(wxCommandEvent
& event
);
36 void OnUseTextCtrl(wxCommandEvent
& event
);
38 void OnTestAccelA(wxCommandEvent
& WXUNUSED(event
))
39 { m_logText
->AppendText("Test accelerator \"A\" used.\n"); }
40 void OnTestAccelCtrlA(wxCommandEvent
& WXUNUSED(event
))
41 { m_logText
->AppendText("Test accelerator \"Ctrl-A\" used.\n"); }
42 void OnTestAccelEsc(wxCommandEvent
& WXUNUSED(event
))
43 { m_logText
->AppendText("Test accelerator \"Esc\" used.\n"); }
45 void OnClear(wxCommandEvent
& WXUNUSED(event
)) { m_logText
->Clear(); }
46 void OnSkipDown(wxCommandEvent
& event
) { m_skipDown
= event
.IsChecked(); }
47 void OnSkipHook(wxCommandEvent
& event
) { m_skipHook
= event
.IsChecked(); }
49 void OnKeyDown(wxKeyEvent
& event
)
51 LogEvent("KeyDown", event
);
55 void OnKeyUp(wxKeyEvent
& event
) { LogEvent("KeyUp", event
); }
56 void OnChar(wxKeyEvent
& event
) { LogEvent("Char", event
); }
57 void OnCharHook(wxKeyEvent
& event
)
59 // The logged messages can be confusing if the input window doesn't
60 // have focus so warn about this.
61 if ( !m_inputWin
->HasFocus() )
63 m_logText
->SetDefaultStyle(*wxRED
);
64 m_logText
->AppendText("WARNING: focus is not on input window, "
65 "non-hook events won't be logged.\n");
66 m_logText
->SetDefaultStyle(wxTextAttr());
69 LogEvent("Hook", event
);
74 void OnPaintInputWin(wxPaintEvent
& event
);
76 void LogEvent(const wxString
& name
, wxKeyEvent
& event
);
78 // Set m_inputWin to either a new wxWindow or new wxTextCtrl.
79 void DoCreateInputWindow(bool text
);
81 wxTextCtrl
*m_logText
;
88 // Define a new application type, each program should derive a class from wxApp
89 class MyApp
: public wxApp
92 // 'Main program' equivalent: the program execution "starts" here
95 // create the main application window
96 new MyFrame("Keyboard wxWidgets App");
98 // If we returned false here, the application would exit immediately.
103 // Create a new application object: this macro will allow wxWidgets to create
104 // the application object during program execution (it's better than using a
105 // static object for many reasons) and also declares the accessor function
106 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
111 // ============================================================================
113 // ============================================================================
116 MyFrame::MyFrame(const wxString
& title
)
117 : wxFrame(NULL
, wxID_ANY
, title
),
122 SetIcon(wxICON(sample
));
124 // IDs for menu items
128 ClearID
= wxID_CLEAR
,
138 wxMenu
*menuFile
= new wxMenu
;
140 menuFile
->Append(ClearID
, "&Clear log\tCtrl-L");
141 menuFile
->AppendSeparator();
143 menuFile
->Append(TestAccelA
, "Test accelerator &1\tA");
144 menuFile
->Append(TestAccelCtrlA
, "Test accelerator &2\tCtrl-A");
145 menuFile
->Append(TestAccelEsc
, "Test accelerator &3\tEsc");
146 menuFile
->AppendSeparator();
148 menuFile
->AppendCheckItem(SkipHook
, "Skip CHAR_HOOK event",
149 "Not skipping this event disables both KEY_DOWN and CHAR events"
151 menuFile
->Check(SkipHook
, true);
152 menuFile
->AppendCheckItem(SkipDown
, "Skip KEY_DOWN event",
153 "Not skipping this event disables CHAR event generation"
155 menuFile
->Check(SkipDown
, true);
156 menuFile
->AppendSeparator();
158 menuFile
->AppendCheckItem(UseTextCtrl
, "Use &text control\tCtrl-T",
159 "Use wxTextCtrl or a simple wxWindow for input window"
161 menuFile
->AppendSeparator();
163 menuFile
->Append(QuitID
, "E&xit\tAlt-X", "Quit this program");
165 // the "About" item should be in the help menu
166 wxMenu
*menuHelp
= new wxMenu
;
167 menuHelp
->Append(wxID_ABOUT
, "&About\tF1", "Show about dialog");
169 // now append the freshly created menu to the menu bar...
170 wxMenuBar
*menuBar
= new wxMenuBar();
171 menuBar
->Append(menuFile
, "&File");
172 menuBar
->Append(menuHelp
, "&Help");
174 // ... and attach this menu bar to the frame
177 DoCreateInputWindow(false /* simple window initially */);
179 wxTextCtrl
*headerText
= new wxTextCtrl(this, wxID_ANY
, "",
180 wxDefaultPosition
, wxDefaultSize
,
182 headerText
->SetValue(
183 " event key KeyCode mod UnicodeKey "
184 " RawKeyCode RawKeyFlags Position");
187 m_logText
= new wxTextCtrl(this, wxID_ANY
, "",
188 wxDefaultPosition
, wxDefaultSize
,
189 wxTE_MULTILINE
|wxTE_READONLY
|wxTE_RICH
|wxHSCROLL
);
191 // set monospace font to have output in nice columns
192 wxFont
font(10, wxFONTFAMILY_TELETYPE
,
193 wxFONTSTYLE_NORMAL
, wxFONTWEIGHT_NORMAL
);
194 headerText
->SetFont(font
);
195 m_logText
->SetFont(font
);
198 wxBoxSizer
*sizer
= new wxBoxSizer(wxVERTICAL
);
199 sizer
->Add(m_inputWin
, wxSizerFlags().Expand());
200 sizer
->Add(headerText
, wxSizerFlags().Expand());
201 sizer
->Add(m_logText
, wxSizerFlags(1).Expand());
202 SetSizerAndFit(sizer
);
204 // set size and position on screen
208 // connect menu event handlers
210 Connect(QuitID
, wxEVT_COMMAND_MENU_SELECTED
,
211 wxCommandEventHandler(MyFrame::OnQuit
));
213 Connect(wxID_ABOUT
, wxEVT_COMMAND_MENU_SELECTED
,
214 wxCommandEventHandler(MyFrame::OnAbout
));
216 Connect(ClearID
, wxEVT_COMMAND_MENU_SELECTED
,
217 wxCommandEventHandler(MyFrame::OnClear
));
219 Connect(SkipHook
, wxEVT_COMMAND_MENU_SELECTED
,
220 wxCommandEventHandler(MyFrame::OnSkipHook
));
221 Connect(SkipDown
, wxEVT_COMMAND_MENU_SELECTED
,
222 wxCommandEventHandler(MyFrame::OnSkipDown
));
224 Connect(UseTextCtrl
, wxEVT_COMMAND_MENU_SELECTED
,
225 wxCommandEventHandler(MyFrame::OnUseTextCtrl
));
227 Connect(TestAccelA
, wxEVT_COMMAND_MENU_SELECTED
,
228 wxCommandEventHandler(MyFrame::OnTestAccelA
));
230 Connect(TestAccelCtrlA
, wxEVT_COMMAND_MENU_SELECTED
,
231 wxCommandEventHandler(MyFrame::OnTestAccelCtrlA
));
233 Connect(TestAccelEsc
, wxEVT_COMMAND_MENU_SELECTED
,
234 wxCommandEventHandler(MyFrame::OnTestAccelEsc
));
236 // notice that we don't connect OnCharHook() to the input window, unlike
237 // the usual key events this one is propagated upwards
238 Connect(wxEVT_CHAR_HOOK
, wxKeyEventHandler(MyFrame::OnCharHook
));
240 // status bar is useful for showing the menu items help strings
243 // and show itself (the frames, unlike simple controls, are not shown when
244 // created initially)
250 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
252 wxMessageBox("Demonstrates keyboard event processing in wxWidgets\n"
253 "(c) 2002 Vadim Zeitlin\n"
254 "(c) 2008 Marcin Wojdyr",
255 "About wxWidgets Keyboard Sample",
256 wxOK
| wxICON_INFORMATION
, this);
259 void MyFrame::DoCreateInputWindow(bool text
)
261 wxWindow
* const oldWin
= m_inputWin
;
263 m_inputWin
= text
? new wxTextCtrl(this, wxID_ANY
, "Press keys here",
264 wxDefaultPosition
, wxSize(-1, 50),
266 : new wxWindow(this, wxID_ANY
,
267 wxDefaultPosition
, wxSize(-1, 50),
269 m_inputWin
->SetBackgroundColour(*wxBLUE
);
270 m_inputWin
->SetForegroundColour(*wxWHITE
);
272 // connect event handlers for the blue input window
273 m_inputWin
->Connect(wxEVT_KEY_DOWN
, wxKeyEventHandler(MyFrame::OnKeyDown
),
275 m_inputWin
->Connect(wxEVT_KEY_UP
, wxKeyEventHandler(MyFrame::OnKeyUp
),
277 m_inputWin
->Connect(wxEVT_CHAR
, wxKeyEventHandler(MyFrame::OnChar
),
282 m_inputWin
->Connect(wxEVT_PAINT
,
283 wxPaintEventHandler(MyFrame::OnPaintInputWin
),
289 GetSizer()->Replace(oldWin
, m_inputWin
);
295 void MyFrame::OnUseTextCtrl(wxCommandEvent
& event
)
297 DoCreateInputWindow(event
.IsChecked());
300 void MyFrame::OnPaintInputWin(wxPaintEvent
& WXUNUSED(event
))
302 wxPaintDC
dc(m_inputWin
);
303 dc
.SetTextForeground(*wxWHITE
);
304 wxFont
font(*wxSWISS_FONT
);
305 font
.SetWeight(wxFONTWEIGHT_BOLD
);
306 font
.SetPointSize(font
.GetPointSize() + 2);
309 dc
.DrawLabel("Press keys here",
310 m_inputWin
->GetClientRect(), wxALIGN_CENTER
);
314 // helper function that returns textual description of wx virtual keycode
315 const char* GetVirtualKeyCodeName(int keycode
)
320 case WXK_##x: return #x;
409 WXK_(NUMPAD_PAGEDOWN
)
415 WXK_(NUMPAD_MULTIPLY
)
417 WXK_(NUMPAD_SEPARATOR
)
418 WXK_(NUMPAD_SUBTRACT
)
434 // helper function that returns textual description of key in the event
435 wxString
GetKeyName(const wxKeyEvent
&event
)
437 int keycode
= event
.GetKeyCode();
438 const char* virt
= GetVirtualKeyCodeName(keycode
);
441 if ( keycode
> 0 && keycode
< 32 )
442 return wxString::Format("Ctrl-%c", (unsigned char)('A' + keycode
- 1));
443 if ( keycode
>= 32 && keycode
< 128 )
444 return wxString::Format("'%c'", (unsigned char)keycode
);
447 int uc
= event
.GetUnicodeKey();
448 if ( uc
!= WXK_NONE
)
449 return wxString::Format("'%c'", uc
);
456 void MyFrame::LogEvent(const wxString
& name
, wxKeyEvent
& event
)
459 // event key_name KeyCode modifiers Unicode raw_code raw_flags pos
460 msg
.Printf("%7s %15s %5d %c%c%c%c"
466 #ifdef wxHAS_RAW_KEY_CODES
476 event
.ControlDown() ? 'C' : '-',
477 event
.AltDown() ? 'A' : '-',
478 event
.ShiftDown() ? 'S' : '-',
479 event
.MetaDown() ? 'M' : '-'
481 , event
.GetUnicodeKey()
482 , event
.GetUnicodeKey()
484 #ifdef wxHAS_RAW_KEY_CODES
485 , (unsigned long) event
.GetRawKeyCode()
486 , (unsigned long) event
.GetRawKeyFlags()
492 m_logText
->AppendText(msg
);