Solved

Programatically disable an accelerator key (then re-enable it later)

Posted on 2001-09-15
11
645 Views
Last Modified: 2013-11-20
Hi - I've got an accelerator defined so that a commonly used menu item is fired when the user presses the space bar.  At times, I'd like to disable it, then reenable it at a later point. How can I do this? The accelerator is defined under IDR_MAINFRAME.

Thanks,
Marcus
0
Comment
Question by:marcus78
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
11 Comments
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 6485531
why not use a simple flag that you put in the handler for the space bar being pressed.

eg pseudocode

OnSpacebar() // okay not a proper handler but you get the drift
{
  if (bProcess)
  {
    // do menu action
  }
}
0
 

Author Comment

by:marcus78
ID: 6486143
Hi - it's not quite a simple as that.  The accelerator is mapped to a function in my document class.  In one of my views, i have a list control where the user can edit some text.  The problem is that when i start editing the text, if i press the space bar, (to actually put a space in the text i'm typing), the handler in the document is fired before it gets to the view. so once the document handles it, even if i use the code below, the space character is stifled before it gets to the view. Hence, the space character won't show up.  So, if i can disable the accelerator when the user begins editing the item in the list control, the message won't get sent to the document.

At least, this is my take on it.  Can you think of anything else?

Thanks,
Marcus
0
 
LVL 2

Expert Comment

by:shilpa_Jb
ID: 6486659
Hi
why don't u try using Hook key methods where in u can provide ur own functionality and as well retain the standard feature. Try searching in MSDN for hook key's u will find some samples there.
Hope it helps u.
-shilpa
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:marcus78
ID: 6487541
Shilpa - Will do.  I'll try this out and get back to you.

Thanks!
0
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 6489605
how do you edit the text in a list control? - In my xperience a hook should be the last resort not the first
0
 
LVL 3

Expert Comment

by:krispols
ID: 6489768
you could also use pretranslate message
0
 
LVL 9

Accepted Solution

by:
ShaunWilde earned 50 total points
ID: 6490283
okay I have it handle the onbeginlabeledit and onendlabeledit messages and then manipualte the acceleartor table there

void CSpacebarView::OnBeginlabeledit(NMHDR* pNMHDR, LRESULT* pResult)
{
     LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
     // TODO: Add your control notification handler code here

    HACCEL haccelOld = ((CFrameWnd*)(AfxGetApp()->m_pMainWnd))->m_hAccelTable;

     // get accelerator data
     LPACCEL lpaccelNew;
     int cAccelerators = CopyAcceleratorTable(
          haccelOld, NULL, 0);

     lpaccelNew = (LPACCEL) LocalAlloc(LPTR,
          cAccelerators * sizeof(ACCEL));
     
     if (lpaccelNew != NULL)
     {
          CopyAcceleratorTable(haccelOld, lpaccelNew,
               cAccelerators);
     }
     
     // find our accelerator
     for (UINT i = 0; (i < (UINT) cAccelerators); i++)
     {
          if (lpaccelNew[i].cmd == ID_SPACE) // this is the ID of out handler
          {
               lpaccelNew[i].key = 0; // change its key to be 0
          }
     }
     
     // Create the new accelerator table, and
     // destroy the old one.
     
     DestroyAcceleratorTable(haccelOld);
     ((CFrameWnd*)(AfxGetApp()->m_pMainWnd))->m_hAccelTable = CreateAcceleratorTable(lpaccelNew,
          cAccelerators);
     
     LocalFree(lpaccelNew);  
           
     *pResult = 0;
}

void CSpacebarView::OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult)
{
     LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
     // TODO: Add your control notification handler code here
    HACCEL haccelOld = ((CFrameWnd*)(AfxGetApp()->m_pMainWnd))->m_hAccelTable;

     // get accelerator data
     LPACCEL lpaccelNew;
     
     int cAccelerators = CopyAcceleratorTable(
          haccelOld, NULL, 0);

     lpaccelNew = (LPACCEL) LocalAlloc(LPTR,
          cAccelerators * sizeof(ACCEL));
     
     if (lpaccelNew != NULL)
     {
          CopyAcceleratorTable(haccelOld, lpaccelNew,
               cAccelerators);
     }
     
     // find our key    
     for (UINT i = 0; (i < (UINT) cAccelerators); i++)
     {
          if (lpaccelNew[i].cmd == ID_SPACE) // thuis is the id of th handler
          {
               lpaccelNew[i].key = VK_SPACE;  // change it back to being VK_SPACE
          }
     }
     
     // Create the new accelerator table, and
     // destroy the old one.
     
     DestroyAcceleratorTable(haccelOld);
     ((CFrameWnd*)(AfxGetApp()->m_pMainWnd))->m_hAccelTable = CreateAcceleratorTable(lpaccelNew,
          cAccelerators);

     LocalFree(lpaccelNew);

     *pResult = 0;
}
 
0
 

Author Comment

by:marcus78
ID: 6490531
Shilpa - I agree with ShaunWilde - after reading about it some more, a hook seems rather much for this.

ShaunWilde - this sounds like what I'm looking for.  I'll give it a go, and get back to you soon.  Thanks!

Marcus
0
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 6490825
> I'll give it a go, and get back to you soon

the project I used to get this solution was an MFC SDI app with a ListView as the CView derived class
0
 

Author Comment

by:marcus78
ID: 6493504
ShaunWilde - That's exactly what I needed.  That solved my problem completly!

Thanks,
Marcus
0
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 6493633
okay :)
0

Featured Post

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Prevent this page from creating additional dialogs. 3 722
Change to event 1 129
how to use laptop or pad camera in vb.net windows application 2 107
Problem to App source 6 93
Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Are you ready to implement Active Directory best practices without reading 300+ pages? You're in luck. In this webinar hosted by Skyport Systems, you gain insight into Microsoft's latest comprehensive guide, with tips on the best and easiest way…

733 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question