Solved

keyboard accelerators problem

Posted on 2002-07-07
10
802 Views
Last Modified: 2010-05-18
hello everybody !

I have a problem to add keyboard accelerators to my WIN32 (no MFC) application. I did all the API documentation said but does not work !!

here is an extract of the code i am using in the main function of the application:


//******************************************

ACCEL tabla[2]; // array for store accelerator info
HACCEL h_tabla; // handle for accelerator table

// load accelerator info
tabla[0].fVirt = FVIRTKEY;
tabla[0].key = VK_F5;
tabla[0].cmd = 1001;

tabla[1].fVirt = FVIRTKEY;
tabla[1].key = VK_F6;
tabla[1].cmd = 2001;

// create accelerator table
h_tabla = CreateAcceleratorTable(tabla,2);


while (GetMessage(&msg, (HWND) NULL, 0, 0)) {
 
    if (!TranslateAccelerator(hwndMain, h_tabla,&msg)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

//*******************************

when i press F5 or F6 nothing happen, through i capture de WM_COMMAND message. i try to do this using the function "LoadAccelerators" and an accelerator table resource and worked OK !! so the problem is with the run-time way, isn't  it? and i need to do it with out resources !!

thank you !

:-)
0
Comment
Question by:luchoware
[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
  • 5
  • 4
10 Comments
 
LVL 49

Expert Comment

by:DanRollins
ID: 7137227
From MSDN:
If an accelerator has the same identifier as a menu item and the menu item is grayed or disabled, the accelerator is disabled and does not generate a WM_COMMAND or WM_SYSCOMMAND message. Also, an accelerator does not generate a command message if the corresponding window is minimized.

Also, have you verified that h_tabla is not NULL -- that is, that CreateAcceleratorTable API fn succeeded?

-- Dan
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7137235
Also check your message cracking technique.  The WPARAM will not exactly match the command IDs.  

Also from MSDN:
To differentiate the message that this function sends from messages sent by menus or controls, the high-order word of the wParam parameter of the WM_COMMAND or WM_SYSCOMMAND message contains the value 1.

-- Dan
0
 

Author Comment

by:luchoware
ID: 7139145
hi dan !

 y read your sugestions but

1) h_tabla is not NULL

2) the message cracking technique is ok, because when i use a resource keyboard accelerators everything works fine
the problem is with the run-time way !


here is the entire program (do not worry is small)

// *********************
#include <windows.h>

LRESULT APIENTRY MainWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);

HINSTANCE g_hInst;

HWND testwin;

HMENU principal;

HICON d;

HACCEL h_hotkey;

ACCEL hotkey[2];

// ***************** WINMAIN ****************************

int APIENTRY WinMain(HINSTANCE hInst,HINSTANCE hPrev,LPSTR line,int CmdShow) {

g_hInst = hInst;
MSG msg;
WNDCLASS wc;

wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = NULL;
wc.hInstance = hInst;
wc.hIcon = NULL; //LoadIcon(hInst,MAKEINTRESOURCE(IDI_ICON1));
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.lpfnWndProc = (WNDPROC)MainWndProc;
wc.lpszClassName = "jlb";
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW;

RegisterClass(&wc);

testwin = CreateWindowEx(WS_EX_CLIENTEDGE,"jlb","YaSP SOFTWARE 2002",WS_OVERLAPPEDWINDOW,0,0,800,600,0,0,hInst,0);

hotkey[0].fVirt = FVIRTKEY;
hotkey[0].key = VK_F1;
hotkey[0].cmd = 1001;

hotkey[1].fVirt = FVIRTKEY;
hotkey[1].key = VK_F2;
hotkey[1].cmd = 1002;

// if i use the nect line everithing works ok !!
// h_hotkey = LoadAccelerators(hInst,MAKEINTRESOURCE(1));

/* here is the resource script for the accelerators

luciano ACCELERATORS
{
VK_F1, 1001, VIRTKEY
VK_F2, 1002, VIRTKEY
}

*/

h_hotkey = CreateAcceleratorTable(&(hotkey[0]),2);

if (h_hotkey == NULL) return 0;

ShowWindow(testwin,SW_SHOWMAXIMIZED);
UpdateWindow(testwin);

while(GetMessage(&msg,0,0,0)) {
if (! TranslateAccelerator(msg.hwnd,h_hotkey,&msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

return msg.wParam;
}

// ***************** WINMAIN ****************************


// ***************** PROC ****************************

LRESULT APIENTRY MainWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam){
HDC dc;
PAINTSTRUCT ps;
HBRUSH pincel,pincel2;
RECT area;
int divi;

MENUITEMINFO itmenu;

HMENU hMenu;

char teclado[KL_NAMELENGTH];

switch(msg) {

case WM_PAINT: {

pincel = CreateSolidBrush(RGB(110, 0, 255));
pincel2 = CreateSolidBrush(RGB(255, 255, 255));
dc = BeginPaint(hwnd, &ps);

GetClientRect(hwnd, &(ps.rcPaint));

divi = ps.rcPaint.bottom / 3;
area = ps.rcPaint;
area.bottom = divi;
FillRect(dc, &area , pincel);
area.top = divi;
area.bottom = divi * 2;
FillRect(dc, &area, pincel2);
area.top = divi*2;
area.bottom = divi * 3;
FillRect(dc, &area, pincel);
EndPaint(hwnd, &ps);

}

break;

case WM_DESTROY: {
DestroyAcceleratorTable(h_hotkey);
DestroyMenu(principal);
PostQuitMessage(0);
}
break;

case WM_CREATE:{
principal = CreateMenu();

// OPCIONES DEL MENU PRINCIPAL

itmenu.cbSize = sizeof(MENUITEMINFO);

itmenu.fMask = MIIM_DATA | MIIM_ID | MIIM_STATE | MIIM_TYPE ;
itmenu.fType = MFT_STRING;
itmenu.fState = MFS_ENABLED;
itmenu.wID = 1001;
itmenu.dwTypeData = "Opcisn &Uno";
itmenu.cch = 10;
InsertMenuItem(principal,0,true,&itmenu);


itmenu.fMask = MIIM_DATA | MIIM_ID | MIIM_STATE | MIIM_TYPE ;
itmenu.fType = MFT_STRING;
itmenu.fState = MFS_ENABLED;
itmenu.wID = 1002;
itmenu.dwTypeData = "Opcisn &Dos";
itmenu.cch = 11;
InsertMenuItem(principal,2,true,&itmenu);

// FIN OPCIONES DEL MENU PRINCIPAL

SetMenu(hwnd,principal);

}
break;

case WM_COMMAND: {

switch(LOWORD(wParam)) { // SWITCH BOTONES

case 1001: {
GetKeyboardLayoutName(teclado);
MessageBox(hwnd,teclado,"AVISO",MB_OK);
}
break;

case 1002: {
MessageBeep(MB_OK);
MessageBox(hwnd,"OPCISN DOS","AVISO",MB_OK);

}
break;
} // SWITCH BOTONES

}
break;

default: return DefWindowProc(hwnd,msg,wParam,lParam);
}
return 0;
}


//***********
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!

 
LVL 49

Expert Comment

by:DanRollins
ID: 7139235
There is a SERIOUS ERROR in your program!  Every time I press F5 or F6, nothing happens AT ALL.  But when I press the Help key (F1) or if I accidentlly brush the F2 key, your program display a critical error message like:

        AVISO
        000000409
or
        AVISO
        OPCION DOS

This is obviously a bug in the Win32 API.  I suggest that you call Bill Gates at his home phone number.

-- Dan
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7139486
Oops.  My mistake.  I meant to say:
In your program, you are setting the hot keys as F1 and F2.  If you want it to take action on F5 and F6, change it as follows.  Modify the lines that read:
        hotkey[0].fVirt = FVIRTKEY;
        hotkey[0].key = VK_F1;
        hotkey[0].cmd = 1001;
        hotkey[1].fVirt = FVIRTKEY;
        hotkey[1].key = VK_F2;
        hotkey[1].cmd = 1002;
change them so that they read:
        hotkey[0].fVirt = FVIRTKEY;
        hotkey[0].key = VK_F5; //<<<<--- change this
        hotkey[0].cmd = 1001;
        hotkey[1].fVirt = FVIRTKEY;
        hotkey[1].key = VK_F6;  //<<<<--- change this
        hotkey[1].cmd = 1002;

That will certainly fix the problem.
-- Dan
0
 

Author Comment

by:luchoware
ID: 7142340
jajajaja good joke !!!

" There is a SERIOUS ERROR in your program!  Every time I press F5 or F6, nothing happens AT ALL.  But when I press the Help key (F1) or if I accidentlly brush the F2 key, your program display a critical error message like:....."

if you read the program the hotkey are F1 and F2 (not F5 and F6, there was in the first message sent)

but compiling my program with borland C++ 5.01 no action takes pressing F1 or F2 !!



0
 
LVL 49

Accepted Solution

by:
DanRollins earned 200 total points
ID: 7142742
It works first time with VC++.  

If you are writing a 16-bit app, then the line:
    switch( LOWORD(wParam) )
will cause problems.  

You must place a breakpoint on that line and examine the value of wParam when you press F1.  Report here with the tale of what happens when you do that.   And get a real compiler.

-- Dan
0
 

Author Comment

by:luchoware
ID: 7158312
hi again DAN !!

 i can not understand what is happening here !! after 2 weeks i got Visual C++ and compile my program, and guess wath !! IT WORKED !!

but with borland does not work, and i am writing a 32 bit application !!

:-)
0
 

Author Comment

by:luchoware
ID: 7158320
thank kou for your help !

:-)
0
 

Expert Comment

by:_Logan_
ID: 7245646
might be a little late to post, but why don't you use MingW and Dev-C++?

http://www.bloodshed.net/dev/devcpp.html
0

Featured Post

Secure Your Active Directory - April 20, 2017

Active Directory plays a critical role in your company’s IT infrastructure and keeping it secure in today’s hacker-infested world is a must.
Microsoft published 300+ pages of guidance, but who has the time, money, and resources to implement? Register now to find an easier way.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Setting nameservers after res_init fails doing res_query 2 119
max float value 3 59
Need some help with mailto 16 33
Coding for the first time 9 67
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

749 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