c++winapitabbing

Tab through Edit boxes doesn't work C++


Well hello,

I have a problem and I didn't find any solution to this by searching; basically I want to make a simple login where you can switch through the controls ( username, password, login button ) with tabbing.

The only thing happening when pressing TAB is that it just completely selects the text from the current edit box.

Here's my code:

HWND g_hLogin1, g_hLogin2, g_hLogin3;
#define ID_BUTTON_LOGIN     201

    LRESULT CALLBACK LoginProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
    {
        switch( uMsg )
        {
            case WM_CREATE:
            {
                g_hLogin1 = CreateWindow( "EDIT", "", WS_CHILD | WS_VISIBLE | WS_BORDER, 50, 40, 200, 20, hWnd, 0, 0, 0 );
                g_hLogin2 = CreateWindow( "EDIT", "", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_PASSWORD, 50, 80, 200, 20, hWnd, 0, 0, 0 );
                g_hLogin3 = CreateWindow( "BUTTON", "Login", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 100, 120, 100, 22, hWnd, (HMENU)ID_BUTTON_LOGIN, 0, 0 );

                HFONT font = CreateFont( 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Arial" );
                SendMessage( g_hLogin1, WM_SETFONT, (WPARAM)font, 0 );
                SendMessage( g_hLogin2, WM_SETFONT, (WPARAM)font, 0 );
                SendMessage( g_hLogin3, WM_SETFONT, (WPARAM)font, 0 );

                break;
            }

            case WM_DESTROY:
            {
                PostQuitMessage( 0 );
                return 0;
            }

case WM_KEYDOWN:
        {
            if( wParam == VK_TAB )
            {
                HWND hNext = GetWindow( hWnd, GW_HWNDNEXT );

                if( !hNext )
                    hNext = GetWindow( hWnd, GW_HWNDLAST );

                SendMessage( hNext, EM_SETSEL, (WPARAM)0, (LPARAM)-1 );
                SetFocus( hNext );
            }

            break;
        }

            case WM_PAINT:
            {
                PAINTSTRUCT ps;
                HDC hDC = BeginPaint( hWnd, &ps );

                HFONT font = CreateFont( 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Arial" );
                SelectObject( hDC, font );

                RECT rc[] =
                {
                    { 50, 22, 0, 0 },
                    { 50, 62, 0, 0 }
                };

                DrawText( hDC, "Username:", -1, &rc[ 0 ], DT_NOCLIP );
                DrawText( hDC, "Password:", -1, &rc[ 1 ], DT_NOCLIP );

                EndPaint( hWnd, &ps );

                break;
            }

            case WM_COMMAND:
            {
                if( LOWORD( wParam ) == ID_BUTTON_LOGIN )
                {
                    int len1 = GetWindowTextLength( g_hLogin1 );
                    int len2 = GetWindowTextLength( g_hLogin2 );

                    char* username = new char[ len1 + 1 ];
                    char* password = new char[ len2 + 1 ];

                    GetWindowText( g_hLogin1, username, len1 + 1 );
                    GetWindowText( g_hLogin2, password, len2 + 1 );

                    if( g_pServer->Login( username, password ) )
                    {
                        ShowWindow( g_hLogin, SW_HIDE );
                        ShowWindow( g_hMainWnd, SW_SHOW );
                    }
                }

                break;
            }

            default:
                return DefWindowProc( hWnd, uMsg, wParam, lParam );
        }

        return DefWindowProc( hWnd, uMsg, wParam, lParam );
    }

bool SetupClass( HINSTANCE hInstance, char* szClassName, WNDPROC wndProc )
{
    WNDCLASSEX wc = { 0 };
    wc.cbClsExtra = 0;
    wc.cbSize = sizeof( WNDCLASSEX );
    wc.cbWndExtra = 0;
    wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wc.hCursor = LoadCursor( 0, IDC_ARROW );
    wc.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_ICON1 ) );
    wc.hIconSm = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_ICON1 ) );
    wc.hInstance = hInstance;
    wc.lpfnWndProc = wndProc;
    wc.lpszClassName = szClassName;
    wc.lpszMenuName = "";
    wc.style = CS_HREDRAW | CS_VREDRAW;

    return RegisterClassEx( &wc );
}

int APIENTRY WinMain( HINSTANCE hThis, HINSTANCE hPrev, LPSTR lpCmd, int iCmd )
{
    if( !SetupClass( hThis, "zcfw001", LoginProc ) )
        return 1;

    g_hLogin = CreateWindowEx( WS_EX_CONTROLPARENT, "zcfw001", "Login", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 300, 200, 0, 0, hThis, 0 );

    if( !g_hLogin )
        return 1;

    ShowWindow( g_hLogin, SW_SHOW );

    MSG msg;
    while( 1 )
    {
        if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )
        {
            if( msg.message == WM_QUIT )
                break;

            if( !IsDialogMessage( g_hLogin, &msg ) )
            {
                TranslateMessage( &msg );
                DispatchMessage( &msg );
            }
        }
    }

    return msg.wParam;
}

Solution

  • You should use WS_TABSTOP style to make tab stops working.