5 Replies - 1290 Views - Last Post: 09 January 2013 - 10:49 AM Rate Topic: -----

#1 Sammdahamm  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 32
  • Joined: 14-February 12

WinAPI WM_KEYDOWN not being sent by editbox

Posted 09 January 2013 - 07:22 AM

Hey :)/>
I'm having a problem with catching inputs from the user. The intended effect is that each time the user presses the Tab key, the active focus of the program will be sent to the next control. Currently, when I press the tab key and no control is selected, the focus moves to the first control, which works fine:

case WM_KEYDOWN:
{
     if (toascii(LOWORD(wParam)) == toascii(9))
     {
         HWND SelectedControl;
         SelectedControl = GetFocus();



      if (SelectedControl == hwnd) //I use hwnd here because the default value when nothing is selected is the address
         {                         // of the main form
             SetFocus(hwndTxtUsername);
         }



This all works fine, and when I press tab for the first time, the hwndTxtUsername is selected, and the typing cursor appears. However, once the hwndTxtUsername is selected, it no longer recognises that the Tab key is being pressed (I conformed this by sending a message to cout when tab is pressed, which only outputs the first time tab is pressed)

if (SelectedControl == hwndTxtUsername)
            {
                SetFocus(hwndTxtPassword);
            }
            if (SelectedControl == hwndTxtPassword)
            {
                SetFocus(hwndCheckBox);
            }
            if (SelectedControl == hwndCheckBox)
            {
                SetFocus(hwndTxtUsername);
            }
        }
	    break;
	}


None of the above code executes once the focus of the program is in the first edit box. Also, when I click a button on the form which removes focus from the textbox, tab is once again recognised until it passes focus back to the text box.
I can only assumed that to prevent random hotkeys being pressed whilst typing in an editbox, the WM_KEYDOWN message isn't sent to the processor when focus is on an editbox? Can anyone think of a way around this?

Thanks in advance,
Sam

Is This A Good Question/Topic? 0
  • +

Replies To: WinAPI WM_KEYDOWN not being sent by editbox

#2 snoopy11  Icon User is online

  • Engineering ● Software
  • member icon

Reputation: 762
  • View blog
  • Posts: 2,214
  • Joined: 20-March 10

Re: WinAPI WM_KEYDOWN not being sent by editbox

Posted 09 January 2013 - 07:43 AM

Yes you can subclass the editbox

I used to have a snippet on DIC but it has vanished

I wil post later when I find the details

Snoopy.
Was This Post Helpful? 0
  • +
  • -

#3 Sammdahamm  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 32
  • Joined: 14-February 12

Re: WinAPI WM_KEYDOWN not being sent by editbox

Posted 09 January 2013 - 08:56 AM

Ah thanks that would be greatly appreciated :) If I'm honest I'd have no idea how to subclass an editbox, so further information would be very useful on how to do this :)
Was This Post Helpful? 0
  • +
  • -

#4 snoopy11  Icon User is online

  • Engineering ● Software
  • member icon

Reputation: 762
  • View blog
  • Posts: 2,214
  • Joined: 20-March 10

Re: WinAPI WM_KEYDOWN not being sent by editbox

Posted 09 January 2013 - 09:23 AM

Hi

code for this snippet as follows

#include <Windows.h>


#define IDC_EDIT 101
#define IDC_EDIT2 102
HWND EditBox;
HWND EditBox2;
WNDPROC wpOrigEditProc; 
WNDPROC wpOrigEditProc2; 
LRESULT APIENTRY EditSubclassProc(
    HWND hwnd, 
    UINT uMsg, 
    WPARAM wParam, 
    LPARAM lParam) ;
 
LRESULT APIENTRY EditSubclassProc2(
    HWND hwnd, 
    UINT uMsg, 
    WPARAM wParam, 
    LPARAM lParam) ;


/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
char szClassName[ ] = "CodeBlocksWindowsApp";

int WINAPI WinMain (HINSTANCE hThisInstance,
	HINSTANCE hPrevInstance,
	LPSTR lpszArgument,
	int nCmdShow)
{
	HWND hwnd;               /* This is the handle for our window */
	MSG messages;            /* Here messages to the application are saved */
	WNDCLASSEX wincl;        /* Data structure for the windowclass */

	/* The Window structure */
	wincl.hInstance = hThisInstance;
	wincl.lpszClassName = szClassName;
	wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
	wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
	wincl.cbSize = sizeof (WNDCLASSEX);

	/* Use default icon and mouse-pointer */
	wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
	wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
	wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
	wincl.lpszMenuName = NULL;                 /* No menu */
	wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
	wincl.cbWndExtra = 0;                      /* structure or the window instance */
	/* Use Windows's default colour as the background of the window */
	wincl.hbrBackground = (HBRUSH) GetStockObject(GRAY_BRUSH);

	/* Register the window class, and if it fails quit the program */
	if (!RegisterClassEx (&wincl))
		return 0;

	/* The class is registered, let's create the program*/
	hwnd = CreateWindowEx (
		0,                   /* Extended possibilites for variation */
		szClassName,         /* Classname */
		"Charting Demo Application.",       /* Title Text */
		WS_OVERLAPPEDWINDOW, /* default window */
		CW_USEDEFAULT,       /* Windows decides the position */
		CW_USEDEFAULT,       /* where the window ends up on the screen */
		600,                 /* The programs width */
		400,                 /* and height in pixels */
		HWND_DESKTOP,        /* The window is a child-window to desktop */
		NULL,                /* No menu */
		hThisInstance,       /* Program Instance handler */
		NULL                 /* No Window Creation data */
		);

	/* Make the window visible on the screen */
	ShowWindow (hwnd, nCmdShow);

	/* Run the message loop. It will run until GetMessage() returns 0 */
	while (GetMessage (&messages, NULL, 0, 0))
	{
		/* Translate virtual-key messages into character messages */
		TranslateMessage(&messages);
		/* Send message to WindowProcedure */
		DispatchMessage(&messages);
	}

	/* The program return-value is 0 - The value that PostQuitMessage() gave */
	return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{

	
	 
	
	

	switch (message)                  /* handle the messages */
	{
	case WM_CREATE:
		{
			

			EditBox = CreateWindowEx(NULL,"EDIT",TEXT(""),WS_VISIBLE|WS_CHILD|ES_LEFT,10,10,100,24,hwnd,(HMENU)IDC_EDIT,((LPCREATESTRUCT) lParam) -> hInstance,(LPVOID)NULL);
			EditBox2 = CreateWindowEx(NULL,"EDIT",TEXT(""),WS_VISIBLE|WS_CHILD|ES_LEFT,10,41,100,24,hwnd,(HMENU)IDC_EDIT2,((LPCREATESTRUCT) lParam) -> hInstance,(LPVOID)NULL);
			
			// Subclass the edit control. 
            wpOrigEditProc = (WNDPROC) SetWindowLong(EditBox, GWL_WNDPROC, (LONG) EditSubclassProc); 
			wpOrigEditProc2 = (WNDPROC) SetWindowLong(EditBox2, GWL_WNDPROC, (LONG) EditSubclassProc2); 

			SetFocus(EditBox);

			
			
			return 0;
		}

	


	


	case WM_DESTROY:
		PostQuitMessage (0); /* send a WM_QUIT to the message queue */
		
		break;
	default:                      /* for messages that we don't deal with */
		return DefWindowProc (hwnd, message, wParam, lParam);
	}

	return 0;
}

// Subclass procedure 
LRESULT APIENTRY EditSubclassProc(
    HWND hwnd, 
    UINT uMsg, 
    WPARAM wParam, 
    LPARAM lParam) 
{ 
    switch(uMsg)
	{
       case WM_GETDLGCODE:
               return (DLGC_WANTALLKEYS |
                       CallWindowProc( wpOrigEditProc, hwnd, uMsg,
                                      wParam, lParam));

             case WM_CHAR:
             //Process this message to avoid message beeps.
            if ((wParam == VK_RETURN) || (wParam == VK_TAB))
              return 0;
               else
              return (CallWindowProc( wpOrigEditProc, hwnd,
                                        uMsg, wParam, lParam));

          case WM_KEYDOWN:
               if ((wParam == VK_RETURN) || (wParam == VK_TAB)) {
                   SetFocus(EditBox2);
                 return FALSE;
               }
	}
	
    return CallWindowProc(wpOrigEditProc, hwnd, uMsg, 
        wParam, lParam); 
} 

LRESULT APIENTRY EditSubclassProc2(
    HWND hwnd, 
    UINT uMsg, 
    WPARAM wParam, 
    LPARAM lParam) 
{ 
    switch(uMsg)
	{
       case WM_GETDLGCODE:
               return (DLGC_WANTALLKEYS |
                       CallWindowProc( wpOrigEditProc2, hwnd, uMsg,
                                      wParam, lParam));

             case WM_CHAR:
             //Process this message to avoid message beeps.
            if ((wParam == VK_RETURN) || (wParam == VK_TAB))
              return 0;
               else
              return (CallWindowProc( wpOrigEditProc2, hwnd,
                                        uMsg, wParam, lParam));

          case WM_KEYDOWN:
               if ((wParam == VK_RETURN) || (wParam == VK_TAB)) {
                   SetFocus(EditBox);
                 return FALSE;
               }
	}
	
    return CallWindowProc(wpOrigEditProc2, hwnd, uMsg, 
        wParam, lParam); 
} 



This example has two edit controls tabbing or pressing the return key will switch between them

Best wishes

Snoopy

This post has been edited by snoopy11: 09 January 2013 - 09:24 AM

Was This Post Helpful? 0
  • +
  • -

#5 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3453
  • View blog
  • Posts: 10,659
  • Joined: 05-May 12

Re: WinAPI WM_KEYDOWN not being sent by editbox

Posted 09 January 2013 - 09:50 AM

The default behavior of the Edit and RichEdit controls is to switch focus from the current edit control to the next control in a dialog. Something is dramatically wrong if you need to do this manually.
Was This Post Helpful? 0
  • +
  • -

#6 snoopy11  Icon User is online

  • Engineering ● Software
  • member icon

Reputation: 762
  • View blog
  • Posts: 2,214
  • Joined: 20-March 10

Re: WinAPI WM_KEYDOWN not being sent by editbox

Posted 09 January 2013 - 10:49 AM

Hi Skydiver,

Yes for Dialogs this is true but for ordinary hwnds as far as I know it doesnt work after you type

There maybe a Windows Style or an ES that lets you but I dont know about it.

Anyway I prefer to subclass the editbox to catch the RETURN key, if you know what I mean.

Regards

Snoopy
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1