• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 812
  • Last Modified:

keyboard accelerators problem

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
luchoware
Asked:
luchoware
  • 5
  • 4
1 Solution
 
DanRollinsCommented:
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
 
DanRollinsCommented:
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
 
luchowareAuthor Commented:
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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
DanRollinsCommented:
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
 
DanRollinsCommented:
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
 
luchowareAuthor Commented:
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
 
DanRollinsCommented:
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
 
luchowareAuthor Commented:
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
 
luchowareAuthor Commented:
thank kou for your help !

:-)
0
 
_Logan_Commented:
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

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

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.

  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now