Thread: Child Windows and Messages

  1. #1
    Registered User
    Join Date
    Sep 2001
    Posts
    16

    Question Child Windows and Messages

    Below is my main message loop. I have created an Edit window as a child window of the main window. All I want to do is to be able to catch the keystrokes of the edit window (child window), but I cannot seem to figure out where to place the WM_KEYDOWN case. I have used spy++ to see the messages, and I know the WM_KEYDOWN, WM_CHAR, and WM_KEYUP messages are being fired, but I do not know where to put my message catcher. Please help me! Thanks!


    LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
    {
    static HWND hwndEdit;
    char buffer[20];
    switch(iMsg)
    {
    case WM_CREATE:
    {
    hwndEdit = CreateWindow(TEXT("edit"), NULL, WS_CHILD | ES_WANTRETURN | WS_VISIBLE |
    ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL, 0, 0, 0, 0,
    hWnd, NULL, pWin->hInstance, NULL);
    break;
    }

    case WM_SETFOCUS:
    SetFocus (hwndEdit);
    return 0;

    case WM_SIZE:
    MoveWindow(hwndEdit, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
    return 0;

    case WM_COMMAND:
    {
    //SetWindowText(hWnd, _itoa(LOWORD(wParam), buffer, 10));
    switch (LOWORD(wParam))
    {
    case VK_RETURN:
    //MessageBox(NULL, _itoa(LOWORD(wParam), buffer, 10), TEXT("Command"), MB_OK);
    break;
    }

    return 0;
    }

    case WM_KEYDOWN:
    {
    SetWindowText(hWnd, TEXT("Sucker"));

    switch (wParam)
    {
    case VK_RETURN:
    MessageBox(NULL, _itoa(LOWORD(wParam), buffer, 10), TEXT("Command"), MB_OK);
    break;
    }
    }

    case WM_CHAR:
    {
    SetWindowText(hWnd, TEXT("Loser"));

    // switch (wParam)
    // {
    // case VK_RETURN:
    // MessageBox(NULL, _itoa(LOWORD(wParam), buffer, 10), TEXT("Command"), MB_OK);
    // break;
    // }
    }

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

    EndPaint(hWnd, &ps);
    break;
    }

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


    return DefWindowProc(hWnd, iMsg, wParam, lParam);

    }

  2. #2
    Registered User sean345's Avatar
    Join Date
    Mar 2002
    Posts
    346
    To capture the messages like WM_KEYDOWN being sent to the edit control you must subclass the edit control. Try doing a board search on this because a few months ago I did a similiar subclass of an edit.

    - Sean
    If cities were built like software is built, the first woodpecker to come along would level civilization.
    Black Frog Studios

  3. #3
    Registered User
    Join Date
    Sep 2001
    Posts
    16
    I tried to subclass the edit control, and i can't even get my edit control to appear on the screen. I was just trying the minimum to see how it would work, and it just doesnt seem to work. What am I doing wrong? There is the header file that I made:

    #include <afxwin.h>

    class myEdit : public CEdit
    {
    public:
    myEdit();
    virtual ~myEdit();

    };

    Is there anything else that I need to do do subclass that control? I was just going to use all of CEdit's builtin functions, so I did not override them.

  4. #4
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Assuming CEdit is an mfc class, just use the class wizard thingy with msvc to insert any message handler you need.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  5. #5
    Registered User
    Join Date
    Sep 2001
    Posts
    16
    I tried that, and I didn't really want to use MFC. The little wizard thingy I dont really like, I want to have complete control over my code. I cannot stand generated code.

  6. #6
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    You cannot see the window because you sized it to zero

    In the main message loop, you can check if a WM_KEYDOWN message or WM_CHAR message is generated. If so, SendMessage right then and there to the child.

    By subclassing what is meant is not C++ classes, but the act of setting one of several internal data structures of a given window using GetWindowLong(HWND hwnd, int which) and SetWindowLong(HWND hwnd, int which, long what). The variable GWL_USERDATA is typically used for the 'which' parameter, and the HWND or a pointer to a class instance for the 'what' parameter for the second function.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  7. #7
    Registered User
    Join Date
    Sep 2001
    Posts
    16
    I change the size of my window in WM_SIZE, that way if the user resizes the window, the entire window will be resized as well.

    When I check for WM_KEYDOWN or WM_CHAR in the main message loop, they are never getting called. I don't know how to trap them or catch them. Why are they not getting to my main message loop?

    How would you use the GetWindowLong() and SetWindowLong()?

  8. #8
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    As sean345 suggested earlier, search the windows board as there have been numerous examples/discussions of windows subclassing before (ie using GetWindowLong() and SetWindowLong() ).
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  9. #9
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    while(GetMessage(&messages, NULL, 0, 0) > 0)
    {
    DispatchMessage(&messages);

    TranslateMessage(&messages);

    if(messages.message == WM_KEYDOWN)
    SendMessage(hEdit, messages.message, messages.wParam, messages.lParam);
    }
    }


    Does it look something like that?

  10. #10
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    When you create a child window you should cast the HMENU param as the control ID (not NULL). Use 30,000 + to avoid any conflicts with the resouce editor (or check its last int ID allocation in resource.h).

    ie
    Code:
    #define     IDC_EDIT_1      30001
    hwndEdit = CreateWindow(TEXT("edit"), NULL, 
    WS_CHILD | ES_WANTRETURN | WS_VISIBLE | ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL,
     0, 0, 0, 0, hWnd, (HMENU)IDC_EDIT_1, pWin->hInstance, NULL);
    then you can use IDC_EDIT_1 as a case in the WM_COMMAND switch and look for EN_CHANGE msg's.

    ie
    Code:
    case IDC_EDIT_1:
       if (EN_CHANGE == HIWORD(wParam))
           GetDlgItemText(hWndEdit, IDC_EDIT_1, sBuffer, sizeof(sBuffer) );
    //edited to try and make it more readable
    Last edited by novacain; 09-05-2002 at 01:34 AM.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  11. #11
    Registered User
    Join Date
    Sep 2001
    Posts
    16

    Talking

    Thanks for all of your help!! I looked again for the GetWindowLong() and SetWindowLong() posts on the board, and I found an example with code of what I needed to do!

    DefEditProc = (WNDPROC)GetWindowLong(hwndEdit, GWL_WNDPROC);
    SetWindowLong(hwndEdit, GWL_WNDPROC, (LONG)EditProc);



    LRESULT CALLBACK EditProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
    {
    char lpszBuffer[20];

    switch(message)
    {
    case WM_COMMAND:
    {
    case WM_KEYDOWN:
    switch(wParam)
    {
    case VK_RETURN:
    {
    SetWindowText(pWin->hWnd, "Here");
    break;
    }

    default:
    {
    SetWindowText(pWin->hWnd, "Socket Example");
    break;
    }
    }
    }


    default: //Send all messages not processed to default edit proc
    return CallWindowProc(DefEditProc,hWnd,message,
    wParam,lParam);
    }
    }

    This works exactly as I wanted it to!! Thanks for all of your help!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Sending windows messages
    By Ideswa in forum Windows Programming
    Replies: 2
    Last Post: 03-02-2006, 01:27 PM
  2. input/output
    By dogbert234 in forum Windows Programming
    Replies: 11
    Last Post: 01-26-2005, 06:57 AM
  3. Messages from child windows with MFC
    By Gravedigga in forum Windows Programming
    Replies: 7
    Last Post: 08-13-2004, 03:54 AM
  4. Receiving messages from child of a child.
    By Sindol in forum Windows Programming
    Replies: 3
    Last Post: 01-26-2002, 07:58 AM