Search code examples
winapimagnification-api

Why is my capture window code not working?


I am newbie to winapi. I have seen an example to capture desktop excluding some windows at codeproject

There a child window is created and it is captured.

hwndMag = CreateWindow(WC_MAGNIFIER, TEXT("MagnifierWindow"), 
        WS_CHILD | MS_SHOWMAGNIFIEDCURSOR | WS_VISIBLE,
        0, 0, m_ScreenX, m_ScreenY, 
        hostDlg->GetSafeHwnd(), NULL, hInstance, NULL ); 

Instead of creating a child window, I want to create a parent window.

I have tried with this code.

hwndMag = CreateWindow(WC_MAGNIFIER, TEXT("MagnifierWindow"), 
         MS_SHOWMAGNIFIEDCURSOR | WS_VISIBLE,
        0, 0, m_ScreenX, m_ScreenY, 
        NULL , NULL, hInstance, NULL ); 

A new window is visible with black screen. And even when I click the capture button the window is stucked.

Why is this happening and How can I make that work with a new parent window?

Thanks


Solution

  • The magnifier window should be a child window. It therefore needs a host parent window. The example code on MSDN shows how to do it:

    BOOL CreateMagnifier(HINSTANCE hInstance)
    {
       // Register the host window class.
        WNDCLASSEX wcex = {};
        wcex.cbSize = sizeof(WNDCLASSEX); 
        wcex.style          = 0;
        wcex.lpfnWndProc    = HostWndProc;
        wcex.hInstance      = hInstance;
        wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground  = (HBRUSH)(1 + COLOR_BTNFACE);
        wcex.lpszClassName  = WindowClassName;
        
        if (RegisterClassEx(&wcex) == 0)
            return FALSE;
    
        // Create the host window. 
        hwndHost = CreateWindowEx(WS_EX_TOPMOST | WS_EX_LAYERED | WS_EX_TRANSPARENT, 
            WindowClassName, WindowTitle, 
            WS_CLIPCHILDREN,
            0, 0, 0, 0,
            NULL, NULL, hInstance, NULL);
        if (!hwndHost)
        {
            return FALSE;
        }
    
        // Make the window opaque.
        SetLayeredWindowAttributes(hwndHost, 0, 255, LWA_ALPHA);
    
        // Create a magnifier control that fills the client area.
        hwndMag = CreateWindow(WC_MAGNIFIER, TEXT("MagnifierWindow"), 
            WS_CHILD | MS_SHOWMAGNIFIEDCURSOR | WS_VISIBLE,
            0, 0, 
            LENS_WIDTH, 
            LENS_HEIGHT, 
            hwndHost, NULL, hInstance, NULL );
        if (!hwndMag)
        {
            return FALSE;
        }
    
        return TRUE;
    }
    

    This same documentation also says:

    The magnifier control must be hosted in a window created with the WS_EX_LAYERED extended style. After creating the host window, call SetLayeredWindowAttributes to set the opacity of the host window. The host window is typically set to full opacity to prevent the underlying screen content from showing though. The following example shows how to set the host window to full opacity:

    SetLayeredWindowAttributes(hwndHost, NULL, 255, LWA_ALPHA);
    

    If you apply the WS_EX_TRANSPARENT style to the host window, mouse clicks are passed to whatever object is behind the host window at the location of the mouse cursor. Be aware that, because the host window does not process mouse clicks, the user will not be able to move or resize the magnification window by using the mouse.

    The MSDN example above illustrates this. And the CodeProject article that you link to also adheres to these rules. You must do likewise.