Thread: Tabbing around :)

  1. #1
    * Death to Visual Basic * Devil Panther's Avatar
    Join Date
    Aug 2001
    Posts
    768

    Tabbing around :)

    in my main window i've created child windows as edit controls, but I can't move from one control to another using the TAB, how could this be done?


    thank you.
    "I don't suffer from insanity but enjoy every minute of it" - Edgar Allen Poe

    http://www.Bloodware.net - Developing free software for the community.

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981

  3. #3
    * Death to Visual Basic * Devil Panther's Avatar
    Join Date
    Aug 2001
    Posts
    768
    my problem is that instead of switching focus to the next control with WS_TAB is puts the tab char in the editbox...
    "I don't suffer from insanity but enjoy every minute of it" - Edgar Allen Poe

    http://www.Bloodware.net - Developing free software for the community.

  4. #4
    * Death to Visual Basic * Devil Panther's Avatar
    Join Date
    Aug 2001
    Posts
    768
    Well I took Codeplug's advice and wrote the next code, but still nothing, my problem is still:
    ...instead of switching focus to the next control with WS_TABSTOP is puts the tab char in the editbox...
    Code:
    case WM_CREATE:
                    CreateWindowEx(NULL, "Edit", "", WS_CHILD | WS_VISIBLE | WS_BORDER
                                   | WS_TABSTOP | ES_AUTOHSCROLL | ES_MULTILINE, 99, 81, 285, 40, hwnd,
                                   (HMENU)IDC_EDIT_FIRST, GetModuleHandle(NULL), NULL);
    
                    CreateWindowEx(NULL, "Edit", "", WS_CHILD | WS_VISIBLE | WS_BORDER
                                   | WS_TABSTOP | ES_AUTOHSCROLL | ES_MULTILINE, 99, 122, 370, 40, hwnd,
                                   (HMENU)IDC_EDIT_SECOND, GetModuleHandle(NULL), NULL);
                    break;
    
    case WM_CHAR:
                    if (LOWORD(wParam)==VK_TAB)
                       SetFocus(GetNextDlgTabItem(hwnd, NULL, FALSE));                
                    break;
    This works fine, as long an non of the editbox controls has the focus, becasue then the WM_CHAR doesn't recieve the message. Please Help.


    Thank you.
    "I don't suffer from insanity but enjoy every minute of it" - Edgar Allen Poe

    http://www.Bloodware.net - Developing free software for the community.

  5. #5
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Are you using IsDialogMessage in your 'main window' procedure as described in the section of the article Codeplug provided a link to?
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  6. #6
    * Death to Visual Basic * Devil Panther's Avatar
    Join Date
    Aug 2001
    Posts
    768
    No i am not.
    Also, I don't think I understand how the function works, and how can it help me.
    "I don't suffer from insanity but enjoy every minute of it" - Edgar Allen Poe

    http://www.Bloodware.net - Developing free software for the community.

  7. #7
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    That's what's actually responsible for default dialog message handling (like 'tabbing', assuming the WS_TABSTOP style bit is applied, that is).

    Put it in your message loop:
    Code:
    MSG msg;
    while (GetMessage(&msg,0,0,0)>0)
      {
      if (!IsDialogMessage(hwnd,&msg))
        {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
        }
      }
    Where hwnd is the handle of your window/dialog; GetActiveWindow can be useful here, too.

    I would strongly advise you to go back and re-read the article Codeplug initially and helpfully directed you to.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  8. #8
    * Death to Visual Basic * Devil Panther's Avatar
    Join Date
    Aug 2001
    Posts
    768
    I've added the code with the IsDialogMessage
    And now the Tab is no longer used as char in the editbox control, but nothing else happens.
    I've read The WS_GROUP Style section, and I am alittle confused, do I need to use WM_GETDLGCODE or the GetNextDlgTabItem, or should the Tabbing be done on it's own (on controls with the WS_TABSTOP style)
    "I don't suffer from insanity but enjoy every minute of it" - Edgar Allen Poe

    http://www.Bloodware.net - Developing free software for the community.

  9. #9
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Tabbing should be automatic - try to create a simple, minimalist example that replicates the problem and post the code for that, if necessary (sometimes by doing this you may see an error that you maybe missed in a larger project).
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  10. #10
    * Death to Visual Basic * Devil Panther's Avatar
    Join Date
    Aug 2001
    Posts
    768
    Well, when you're right you're right.
    I've wrote a simple example, and I've found the problem...

    1) The Editboxes contain the ES_MULTILINE style.
    So in the simple example, once i've removed the style the TABing worked just fine.

    So I guess the IsDialogMessage(hwnd, &Msg) creates a conflict that disables the ES_MULTILINE function.



    please help, it's killing me
    Last edited by Devil Panther; 07-01-2005 at 03:01 PM.
    "I don't suffer from insanity but enjoy every minute of it" - Edgar Allen Poe

    http://www.Bloodware.net - Developing free software for the community.

  11. #11
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Subclass the edit control(s) with the ES_MULTILINE style, handle the WM_KEYDOWN message and SetFocus with the window handle returned from GetNextDlgTabItem; something like:
    Code:
    LRESULT CALLBACK EditProc(HWND hwnd,....)
    {
    case WM_KEYDOWN:
      if (wParam==VK_TAB)
        {
        SetFocus(GetNextDlgTabItem(GetParent(hwnd), hwnd,0));
        }
      return 0;
      default:
        CallWindowProc(....);
    }
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  12. #12
    * Death to Visual Basic * Devil Panther's Avatar
    Join Date
    Aug 2001
    Posts
    768
    can you please explain this part
    Subclass the edit control(s)
    How do i use it?
    "I don't suffer from insanity but enjoy every minute of it" - Edgar Allen Poe

    http://www.Bloodware.net - Developing free software for the community.

  13. #13
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Subclassing simply replaces the existing window procedure with another you supply. This is done with SetWindowLongPtr using the GWLP_WNDPROC flag; you need to store the return value of the function call and use it with CallWindowProc (there's an example of subclassing at the foot of that page) in order to get default message processing.

    See also Safe subclassing in Win32.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  14. #14
    It's full of stars adrianxw's Avatar
    Join Date
    Aug 2001
    Posts
    4,829
    My standard subclassing example...
    Code:
    #include <windows.h>
    
    LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM);
    LRESULT CALLBACK NewEditProc(HWND, UINT, WPARAM, LPARAM);
    
    HINSTANCE hInst;
    WNDPROC OriginalEditProc;
    
    int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, 
                       LPSTR Args, int WinMode)
    {
        HWND hWnd;
        MSG Message;
        WNDCLASSEX Wcl;
    
        hInst = hThisInst;
        
        Wcl.cbSize = sizeof(WNDCLASSEX);    
        Wcl.hInstance = hThisInst;
        Wcl.lpszClassName = "Window";
        Wcl.lpfnWndProc = WindowFunc; 
        Wcl.style = 0;  
        Wcl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        Wcl.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
        Wcl.hCursor = LoadCursor(NULL, IDC_ARROW);
        Wcl.lpszMenuName = NULL; 
        Wcl.cbClsExtra = 0; 
        Wcl.cbWndExtra = 0;
        Wcl.hbrBackground = (HBRUSH) GetStockObject(LTGRAY_BRUSH); 
        
        if(!RegisterClassEx(&Wcl)) return 0;
        
        hWnd = CreateWindow(
            "Window", 
            "Window",
            WS_OVERLAPPEDWINDOW, 
            CW_USEDEFAULT, 
            CW_USEDEFAULT, 
            CW_USEDEFAULT, 
            CW_USEDEFAULT, 
            HWND_DESKTOP, 
            NULL, 
            hThisInst, 
            NULL 
            );
        
        ShowWindow(hWnd, WinMode);
        UpdateWindow(hWnd);
    
        while(GetMessage(&Message, NULL, 0, 0))
        {
            TranslateMessage(&Message); 
            DispatchMessage(&Message);
        }
        return Message.wParam;
    }
    
    LRESULT CALLBACK WindowFunc(HWND hWnd,UINT Message,WPARAM wParam,LPARAM lParam)
    {
        static HWND hEditBox;
        
        switch(Message)
        {
        case WM_CREATE:
            hEditBox = CreateWindowEx(0,
                                      "EDIT",
                                      NULL,
                                      WS_CHILD | WS_VISIBLE | WS_BORDER,
                                      10,
                                      10,
                                      300,
                                      20,
                                      hWnd,
                                      (HMENU) 500,
                                      hInst,
                                      NULL);
            OriginalEditProc = (WNDPROC) SetWindowLong(hEditBox,
                                                       GWL_WNDPROC,
                                                       (LONG) NewEditProc);
    
            SetFocus(hEditBox);
            break;
        case WM_DESTROY:
            SetWindowLong(hEditBox,
                          GWL_WNDPROC,
                          (LONG) OriginalEditProc);
            DestroyWindow(hEditBox);
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, Message, wParam, lParam);
        }
        return 0;
    }
    
    LRESULT CALLBACK NewEditProc(HWND hWnd,UINT Message,WPARAM wParam,LPARAM lParam)
    {
        const int TAB = '\x09';
        const int CR = '\x0d';
        const int ESC = '\x1b';
        
        if (Message == WM_CHAR)
        {
               if (wParam == TAB)
            {
                CallWindowProc(OriginalEditProc,
                               hWnd,
                               Message,
                               (WPARAM) '<',
                               lParam);
                CallWindowProc(OriginalEditProc,
                               hWnd,
                               Message,
                               (WPARAM) 'T',
                               lParam);
                CallWindowProc(OriginalEditProc,
                               hWnd,
                               Message,
                               (WPARAM) 'A',
                               lParam);
                CallWindowProc(OriginalEditProc,
                               hWnd,
                               Message,
                               (WPARAM) 'B',
                               lParam);
                CallWindowProc(OriginalEditProc,
                               hWnd,
                               Message,
                               (WPARAM) '>',
                               lParam);
                return 0;
            }
            else if (wParam == CR)
            {
                CallWindowProc(OriginalEditProc,
                               hWnd,
                               Message,
                               (WPARAM) '<',
                               lParam);
                CallWindowProc(OriginalEditProc,
                               hWnd,
                               Message,
                               (WPARAM) 'C',
                               lParam);
                CallWindowProc(OriginalEditProc,
                               hWnd,
                               Message,
                               (WPARAM) 'R',
                               lParam);
                CallWindowProc(OriginalEditProc,
                               hWnd,
                               Message,
                               (WPARAM) '>',
                               lParam);
                return 0;
            }
            else if (wParam == ESC)
            {
                CallWindowProc(OriginalEditProc,
                               hWnd,
                               Message,
                               (WPARAM) '<',
                               lParam);
                CallWindowProc(OriginalEditProc,
                               hWnd,
                               Message,
                               (WPARAM) 'E',
                               lParam);
                CallWindowProc(OriginalEditProc,
                               hWnd,
                               Message,
                               (WPARAM) 'S',
                               lParam);
                CallWindowProc(OriginalEditProc,
                               hWnd,
                               Message,
                               (WPARAM) 'C',
                               lParam);
                CallWindowProc(OriginalEditProc,
                               hWnd,
                               Message,
                               (WPARAM) '>',
                               lParam);
                return 0;
            }
        }
    
        return CallWindowProc(OriginalEditProc,
                              hWnd,
                              Message,
                              wParam,
                              lParam);
    }
    Wave upon wave of demented avengers march cheerfully out of obscurity unto the dream.

  15. #15
    * Death to Visual Basic * Devil Panther's Avatar
    Join Date
    Aug 2001
    Posts
    768
    In other words, you invade into the window's procedure do whatever you want and every else goes the way it should, am i right?
    "I don't suffer from insanity but enjoy every minute of it" - Edgar Allen Poe

    http://www.Bloodware.net - Developing free software for the community.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problems with an If loop..
    By Sedvan in forum C++ Programming
    Replies: 48
    Last Post: 01-29-2008, 01:03 PM
  2. ListBox, tabbing
    By ElastoManiac in forum Windows Programming
    Replies: 5
    Last Post: 12-03-2005, 04:26 PM
  3. Tabbing not working
    By Hunter2 in forum Windows Programming
    Replies: 5
    Last Post: 05-14-2004, 11:23 AM
  4. Tabbing through Edit Boxes (not MFC)
    By jdinger in forum Windows Programming
    Replies: 4
    Last Post: 03-24-2002, 04:50 PM
  5. Can't Implement Tabbing
    By Invincible in forum Windows Programming
    Replies: 10
    Last Post: 02-27-2002, 05:09 AM