C++ School Assignment? Project Due Tomorrow? Chat LIVE With A Programming Expert!

Welcome to Dream.In.Code
Become a C++ Expert!

Join 307,175 C++ Programmers for FREE! Get instant access to thousands of C++ experts, tutorials, code snippets, and more! There are 1,564 people online right now. Registration is fast and FREE... Join Now!




Keyboard Shortcuts without a Menu

 
Reply to this topicStart new topic

> Keyboard Shortcuts without a Menu, Complete with wxWidgets example (applicable to other languages/toolkit

gabehabe
Group Icon



post 11 Sep, 2009 - 01:26 PM
Post #1


Been a while since I wrote one of these. smile.gif

Okay, so... creating keyboard shortcuts in a wxWidgets application, without adding billions of menu items. It's actually a very simple process, which can be applied to most, if not all, languages and UI developments. All we really need to do is design keyboard events for our main application, the main thing being checking for modifier keys. (Such as Ctrl, Alt, etc)

This tutorial is gonna be fairly short since it's quite a simple concept. But it's nice to know, and seems to be quite a common topic in all languages and UI toolkits.

But in this tutorial, my example is going to be wxWidgets based. If you're not familiar with wxWidgets, you might want to read the short series of tutorials I wrote to get acquainted with the toolkit:
Part I - setting up wxWidgets
Part II - familiarising yourself with wxWidgets
Part III - create a notepad application in wxWidgets (events tutorial)

So to start off, I'm gonna throw a load of code under your nose. It's only the basic layout for a simple application:
cpp
// basic setup code, I'll fly past this. If you're not familiar, check out this tutorial:
// http://www.dreamincode.net/forums/showtopic66948.htm

#include <wx/wx.h>

class app : public wxApp {
public:
virtual bool OnInit();
private:
wxTextCtrl* txt;
wxCheckBox* chk;

void key_shortcut(wxKeyEvent&);
DECLARE_EVENT_TABLE()
};

// if you're not familiar with events, check out this tutorial:
// http://www.dreamincode.net/forums/showtopic67058.htm

BEGIN_EVENT_TABLE(app, wxApp)
EVT_KEY_DOWN(app::key_shortcut)
END_EVENT_TABLE()

IMPLEMENT_APP(app)

bool app::OnInit() {
wxFrame* win = new wxFrame(NULL, wxID_ANY, wxT("Keyboard Shortcuts, No Menu!"), wxDefaultPosition, wxSize(250, 125));
win->Show(true);

this->txt = new wxTextCtrl(win, wxID_ANY, wxT("Press Ctrl+G to append text to me"), wxPoint(0,0), wxSize(250, 50), wxTE_MULTILINE);
this->chk = new wxCheckBox(win, wxID_ANY, wxT("Press Ctrl+Left to toggle me."), wxPoint(0, 55), wxDefaultSize);

return true;
}

There shouldn't really be anything new here, if you've followed all the tutorials I mentioned above. We simply create our App class which inherits from wxApp, give it a couple of inputs, and initialise it. We also IMPLEMENT_APP it, which basically tells wxWidgets that it's our "main" in the program.

The text control will have "Press Ctrl+G to append text to me" when initialised, and the checkbox will have a label which reads "Press Ctrl+Left to toggle me."

Right, onto the event. The bulk of this tutorial is gonna be how to use the wxKeyEvent to check for modifier keys, etc. I've only used two objects to keep the code short and sweet. You could of course do this with as many as you wish. It's fast, effective, and easy to implement.

First off, we're going to open up our function:
CODE
void app::key_shortcut(wxKeyEvent& e) {
Simple enough.
The next part could be laid out in a number of ways, since we could use multiple ifs, or a nested switch. Since I'm only using Ctrl shortcuts, I'll use an if statement to check if the control key is being held. (This is known as a modifier key)
CODE
if(e.GetModifiers() == wxMOD_CONTROL) {
As you can see, we're checking if the control key is being held down. For information on other modifiers, click here.

The next thing we need is a switch, to check for the key being pressed along with the control key. To do this, we need to call GetKeyCode() of our wxKeyEvent.
CODE
        switch(e.GetKeyCode()) {
            case 'G': // can return the upper ASCII value of a key
                // do whatever you like for a Ctrl+G event here!
                this->txt->AppendText(wxT(" gabehabe ftw!"));
                break;
            case WXK_LEFT: // we also have special keycodes for non-ascii values.
                // get a full list of special keycodes here:
                // http://docs.wxwidgets.org/stable/wx_keycodes.html
                this->chk->SetValue(!this->chk->GetValue());
                break;
            default: // do nothing
                break;
        }
And finally, all we need to do is close off our if statement and function:
CODE

    } // end if
} // end function

And that's all there is to creating keyboard shortcuts without a menu! smile.gif

Like I said, it's a rather simple concept, but certainly something worth knowing.

As always, here's the complete code in a block, complete with lots of comments:
CODE
// basic setup code, I'll fly past this. If you're not familiar, check out this tutorial:
// http://www.dreamincode.net/forums/showtopic66948.htm

#include <wx/wx.h>

class app : public wxApp {
    public:
        virtual bool OnInit();
    private:
        wxTextCtrl* txt;
        wxCheckBox* chk;

        void key_shortcut(wxKeyEvent&);
        DECLARE_EVENT_TABLE()
};

// if you're not familiar with events, check out this tutorial:
// http://www.dreamincode.net/forums/showtopic67058.htm

BEGIN_EVENT_TABLE(app, wxApp)
    EVT_KEY_DOWN(app::key_shortcut)
END_EVENT_TABLE()

IMPLEMENT_APP(app)

bool app::OnInit() {
    wxFrame* win = new wxFrame(NULL, wxID_ANY, wxT("Keyboard Shortcuts, No Menu!"), wxDefaultPosition, wxSize(250, 125));
    win->Show(true);

    this->txt = new wxTextCtrl(win, wxID_ANY, wxT("Press Ctrl+G to append text to me"), wxPoint(0,0), wxSize(250, 50), wxTE_MULTILINE);
    this->chk = new wxCheckBox(win, wxID_ANY, wxT("Press Ctrl+Left to toggle me."), wxPoint(0, 55), wxDefaultSize);

    return true;
}

// this is the method I'll be focusing on. The key_shortcut event which we create
// to do fancy stuff without adding billions of menu items

void app::key_shortcut(wxKeyEvent& e) {
    // of course, it doesn't have to be the control key. You can use others:
    // http://docs.wxwidgets.org/stable/wx_wxkeyevent.html
    if(e.GetModifiers() == wxMOD_CONTROL) {
        switch(e.GetKeyCode()) {
            case 'G': // can return the upper ASCII value of a key
                // do whatever you like for a Ctrl+G event here!
                this->txt->AppendText(wxT(" gabehabe ftw!"));
                break;
            case WXK_LEFT: // we also have special keycodes for non-ascii values.
                // get a full list of special keycodes here:
                // http://docs.wxwidgets.org/stable/wx_keycodes.html
                this->chk->SetValue(!this->chk->GetValue());
                break;
            default: // do nothing
                break;
        }
    }
}


The result is this rather crude looking user interface:
Attached Image
Go to the top of the page
+Quote Post


Register to Make This Ad Go Away!


Reply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 


Lo-Fi Version Time is now: 11/21/09 07:15PM

Live C++ Help!

Be Social

Dream.In.Code RSS Feed Dream.In.Code LinkedIn Group Follow Us On Twitter Fan Us On Facebook

C++ Tutorials

Reference Sheets

C++ Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month