Thread: 2 child windows, top one not working

  1. #1
    Registered User
    Join Date
    Sep 2004
    Posts
    57

    2 child windows, top one not working

    I believe I have a fundamental misunderstanding about windows processing.

    I'm trying to create a piano keyboard on screen. I'm using child windows for the keys, with black key windows on top of the white key windows.

    This code has been simplified to just 1 white key and 1 black key.

    The problem: although the white and black key windows appear just fine on the screen (black on top of white), when I click on the left part of the black key, it is the white key that gets the click message.

    Why doesn't the message go to the black key callback processing?

    Thanks for any help.

    Code:
    // I'm using vc 7.00, command line, but gcc works too
    // compile and link with this:
    //cl %1.c /c
    //link %1.obj user32.lib gdi32.lib
    //---------------------------------------------------------------------------
    #include <windows.h>
    
    //--- local -----------------------------------------------------------------
    HWND     hwndMain;
    HWND     hwndWhiteKey;
    HWND     hwndBlackKey;
    HBRUSH   MW_bgColor;
    HBRUSH   WK_bgColor;
    HBRUSH   BK_bgColor;
    
    //---------------------------------------------------------------------------
    LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        switch(msg)
        {
            case WM_LBUTTONDOWN:
                MessageBox(hwnd,"Main WM_LBUTTONDOWN","", MB_OK);
                break;
            case WM_CLOSE:
                DestroyWindow(hwnd);
                break;
            case WM_DESTROY:
                PostQuitMessage(0);
                break;
            default:
                return DefWindowProc(hwnd, msg, wParam, lParam);
        }
        return 0;
    }
    
    //---------------------------------------------------------------------------
    LRESULT CALLBACK WhiteKeyWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        switch(msg)
        {
            case WM_LBUTTONDOWN:
                MessageBox(hwnd,"White Key WM_LBUTTONDOWN","", MB_OK);
                break;
            case WM_CLOSE:
                DestroyWindow(hwnd);
                break;
            case WM_DESTROY:
                PostQuitMessage(0);
                break;
            default:
                return DefWindowProc(hwnd, msg, wParam, lParam);
        }
        return 0;
    }
    
    //---------------------------------------------------------------------------
    LRESULT CALLBACK BlackKeyWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        switch(msg)
        {
            case WM_LBUTTONDOWN:
                MessageBox(hwnd,"Black Key WM_LBUTTONDOWN","", MB_OK);
                break;
            case WM_CLOSE:
                DestroyWindow(hwnd);
                break;
            case WM_DESTROY:
                PostQuitMessage(0);
                break;
            default:
                return DefWindowProc(hwnd, msg, wParam, lParam);
        }
        return 0;
    }
    
    //---------------------------------------------------------------------------
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
        LPSTR lpCmdLine, int nCmdShow)
    {
        WNDCLASSEX wc;
        MSG msg; 
    
        //--------------------------------------------------------------
        MW_bgColor = CreateSolidBrush(RGB(255, 0, 0));  // red
    
        //Step 1: Registering the Window Class
        wc.lpszClassName = "MainClass";
        wc.hInstance     = hInstance;
        wc.cbSize        = sizeof(WNDCLASSEX);
        wc.style         = 0;
        wc.cbClsExtra    = 0;
        wc.cbWndExtra    = 0;
        wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
        wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
        wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = MW_bgColor;
        wc.lpszMenuName  = NULL;
        wc.lpfnWndProc   = MainWndProc;
    
        if(!RegisterClassEx(&wc)) {
            MessageBox(NULL, "MWindow Registration Failed!", "Error!", MB_OK);
            exit(0);
        }
    
        // Step 2: Creating the Window
        hwndMain = CreateWindowEx(
            0,
            "MainClass",
            "PianoNotes",
            WS_OVERLAPPEDWINDOW,
            0, 0,
            600, 300,
            NULL, NULL, hInstance, NULL);
    
        if(hwndMain == NULL) {
            MessageBox(NULL, "MWindow Creation Failed!", "Error!", MB_OK);
            exit(0);
        }
    
    
        //--------------------------------------------------------------
        WK_bgColor = CreateSolidBrush(RGB(255,255,255));  // white
    
        //Step 1: Registering the Window Class
        wc.lpszClassName = "WhiteKeyClass";
        wc.hInstance     = hInstance;
        wc.cbSize        = sizeof(WNDCLASSEX);
        wc.style         = 0;
        wc.cbClsExtra    = 0;
        wc.cbWndExtra    = 0;
        wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
        wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
        wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = WK_bgColor;
        wc.lpszMenuName  = NULL;
        wc.lpfnWndProc   = WhiteKeyWndProc;
    
        if(!RegisterClassEx(&wc)) {
            MessageBox(NULL, "White Key Registration Failed!", "Error!", MB_OK);
            exit(0);
        }
    
        //--------------------------------------------------------------
        BK_bgColor = CreateSolidBrush(RGB(0,0,0));  // black
    
        //Step 1: Registering the Window Class
        wc.lpszClassName = "BlackKeyClass";
        wc.hInstance     = hInstance;
        wc.cbSize        = sizeof(WNDCLASSEX);
        wc.style         = 0;
        wc.cbClsExtra    = 0;
        wc.cbWndExtra    = 0;
        wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
        wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
        wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = BK_bgColor;
        wc.lpszMenuName  = NULL;
        wc.lpfnWndProc   = BlackKeyWndProc;
    
        if(!RegisterClassEx(&wc)) {
            MessageBox(NULL, "Black Key Registration Failed!", "Error!", MB_OK);
            exit(0);
        }
    
        //------ white ----------------
        hwndWhiteKey = CreateWindowEx(
            0,
            "WhiteKeyClass",
            "",
            WS_CHILD,
            10, 20,
            40, 100,
            hwndMain,
            NULL, hInstance, NULL);
        
        if(hwndWhiteKey == NULL) {
            MessageBox(NULL, "White Key Creation Failed!", "Error!", MB_OK);
            exit(0);
        }
    
        //------ black ----------------
        hwndBlackKey = CreateWindowEx(
            0,
            "BlackKeyClass",
            "",
            WS_CHILD,
            30,20,
            30, 70,
            hwndMain,
            NULL, hInstance, NULL);
        
        if(hwndBlackKey == NULL) {
            MessageBox(NULL, "Black Key Creation Failed!", "Error!", MB_OK);
            exit(0);
        }
                
    
        ShowWindow(hwndMain, nCmdShow);
        ShowWindow(hwndWhiteKey, SW_SHOW);
        ShowWindow(hwndBlackKey, SW_SHOW);
        UpdateWindow(hwndMain);
    
        while(GetMessage(&msg, NULL, 0, 0) > 0)
        { 
            TranslateMessage(&msg); 
            DispatchMessage(&msg); 
        } 
        return msg.wParam; 
    }

  2. #2
    Registered User Dante Shamest's Avatar
    Join Date
    Apr 2003
    Posts
    970
    1. Create the BLACK button first.
    2. Add WS_CLIPSIBLINGS when creating the WHITE button.

    Code:
        //------ black ----------------
        hwndBlackKey = CreateWindowEx(
            0,
            "BlackKeyClass",
            "",
            WS_CHILD,
            30,20,
            30, 70,
            hwndMain,
            NULL, hInstance, NULL);
        
        if(hwndBlackKey == NULL) {
            MessageBox(NULL, "Black Key Creation Failed!", "Error!", MB_OK);
            exit(0);
        }
                
        //------ white ----------------
        hwndWhiteKey = CreateWindowEx(
            0,
            "WhiteKeyClass",
            "",
            WS_CHILD|WS_CLIPSIBLINGS,
            10, 20,
            40, 100,
            hwndMain,
            NULL, hInstance, NULL);

  3. #3
    Registered User
    Join Date
    Sep 2004
    Posts
    57
    Yes, that worked!!

    Thanks, Dante!!

  4. #4
    Registered User Dante Shamest's Avatar
    Join Date
    Apr 2003
    Posts
    970
    You're welcome. I must commend you on providing enough information for me to compile and test your program.

    However, may I recommend that you draw your piano keys another way? Maybe by drawing the piano keys directly on the client area of the main window using GDI functions?

    Overlapping child windows is generally not a good idea, because you'll have to mess about with z-orders and clipping. And the more child windows that overlap, the harder it is to keep track of their z-orders. I'm speaking from experience, because I once tried to do something similar, and I spent alot of time debugging.

  5. #5
    Registered User
    Join Date
    Sep 2004
    Posts
    57
    Quote Originally Posted by Dante Shamest
    You're welcome. I must commend you on providing enough information for me to compile and test your program.

    However, may I recommend that you draw your piano keys another way? Maybe by drawing the piano keys directly on the client area of the main window using GDI functions?

    Overlapping child windows is generally not a good idea, because you'll have to mess about with z-orders and clipping. And the more child windows that overlap, the harder it is to keep track of their z-orders. I'm speaking from experience, because I once tried to do something similar, and I spent alot of time debugging.
    Oh, I see what you are saying.

    I had planned to create all black keys first, then all white keys.

    But, as I think you are pointing out, when a white key is pressed, it will pop on top of the black keys. Arggggh.

    I wonder if I can simply push any white key pressed back to lowest z order. hmmmm, I have some thinking and playing around to do.


    (One goal is to be able to change the color of any pressed key(s), which is why I am trying to use simple child windows. so far...)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Virtual keys
    By Arkanos in forum Windows Programming
    Replies: 4
    Last Post: 12-12-2005, 10:00 AM
  2. Menu Item Caption - /a for right aligned Accelerator?
    By JasonD in forum Windows Programming
    Replies: 6
    Last Post: 06-25-2003, 11:14 AM
  3. Changing bkgrnd color of Child windows
    By cMADsc in forum Windows Programming
    Replies: 11
    Last Post: 09-10-2002, 11:21 PM
  4. Function to resize child windows?
    By Clyde in forum Windows Programming
    Replies: 4
    Last Post: 05-28-2002, 08:33 PM
  5. Stack functions as arrays instead of node pointers
    By sballew in forum C Programming
    Replies: 8
    Last Post: 12-04-2001, 11:13 AM