SetLayeredWindowAttributes

This is a discussion on SetLayeredWindowAttributes within the Windows Programming forums, part of the Platform Specific Boards category; Trying to set a window's opacity, but the compiler gives this: [Linker error] undefined reference to `SetLayeredWindowAttributes'. I included User32.lib ...

  1. #1
    HelpingYouHelpUsHelpUsAll
    Join Date
    Dec 2007
    Location
    In your nightmares
    Posts
    223

    SetLayeredWindowAttributes

    Trying to set a window's opacity, but the compiler gives this: [Linker error] undefined reference to `SetLayeredWindowAttributes'. I included User32.lib (libuser32.a using Dev-C++) like msdn said to, but I still got the error. Next I tried downloading the lib from the site I got pdh.def off. Still no luck. Looking in the def file: no wonder - It made no reference to the function. Where is this function referenced? Is it even in user32 or is msdn wrong? Edit: Is this a new function that was only introduced in the latest version of user32.dll? Also, has anyone ever got a semi-transparent window working in Dev-C++?
    Last edited by P4R4N01D; 06-14-2008 at 03:59 AM. Reason: Fix some mistakes... sorry
    long time no C; //seige
    You miss 100% of the people you don't C;
    Code:
    if (language != LANG_C && language != LANG_CPP)
        drown(language);

  2. #2
    Registered User
    Join Date
    May 2008
    Location
    Kentucky
    Posts
    13
    First make sure it is in the lib file. If you have grep do something like:

    grep -i setlayeredwindowattributes *.lib

    from your lib directory. If you don't have grep you could open the user32.lib file in an editor that handles binary files and search for "setlayeredwindowattributes."

    Dale L

  3. #3
    Registered User
    Join Date
    Mar 2005
    Location
    Juneda
    Posts
    287
    "...Where is this function referenced?..."

    as far as I know it isn't referenced, you have to declare yourself.

    you should load user32.dll to get the function:
    Code:
    hUser32=GetModuleHandle(TEXT("USER32.DLL"));

    now prototype the function, get it from the module loaded and check it:
    Code:
    typedef int (WINAPI *lpfnSetLayeredWindowAttributes) (HWND , COLORREF , BYTE , DWORD );
    lpfnSetLayeredWindowAttributes slwa_function;
    if(!(slwa_function=(lpfnSetLayeredWindowAttributes)GetProcAddress(hUser32,"SetLayeredWindowAttributes")))
    {/*error*/}

    prepare the control or the window to be transparent:
    Code:
    SetWindowLong(hwnds,GWL_EXSTYLE,GetWindowLong(hwnd,GWL_EXSTYLE)|0x00080000);
    /*
    of course you can set a definition (if you haven't it in the used headers), to make a more readable code
    #define WS_EX_LAYERED 0x00080000
    */

    you've got it, just select a transparent color and apply:
    Code:
    COLORREF ctransparent=RGB(128,128,128);
    slwa_function(hwnd,ctransparent,0,1);
    Tha function gets 4 args: the handle to the target control, the color, the opacity (0->invisible, 255->visible), and an action. the action is LWA_COLORKEY or LWA_ALPHA, the first sets to transparent the specifyed color, and the second applies the alpha transparency to the color, just play a bit with them.


    "...Also, has anyone ever got a semi-transparent window working in Dev-C++?..."
    Yes, use the alpha semi transparency instead of use the hole color transparency



    Hope that helps.
    Niara

  4. #4
    Registered User
    Join Date
    Mar 2007
    Posts
    142
    I have an application that has to work on Win98 and Me as well as on XP/Vista so I can't just call SetLayeredWindowAttributes() because it would crash on Win9x.

    Here is the code that should work in any compiler and on every version of Windows:

    Code:
    #ifndef WS_EX_LAYERED
    #define  WS_EX_LAYERED  0x00080000
    #endif
    
    // Prototype for Win2000/XP API: SetLayeredWindowAttributes
    typedef BOOL (WINAPI * SLWAProc)(HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
    
    #ifndef LWA_COLORKEY
    #define  LWA_COLORKEY            0x00000001
    #define  LWA_ALPHA               0x00000002
    
    #define  ULW_COLORKEY            0x00000001
    #define  ULW_ALPHA               0x00000002
    #define  ULW_OPAQUE              0x00000004
    #endif
    
    static SLWAProc pSLWA = NULL;
    
    BOOL SetWindowTransparency (HWND hwnd, int percent)
    {
       static short beenHere = FALSE;
       
       HMODULE  hUser32;
    
       if (!pSLWA && !beenHere)  {
          beenHere = TRUE;
          hUser32 = GetModuleHandle ("USER32.DLL");
    
          pSLWA = (SLWAProc)GetProcAddress(hUser32, (char *)"SetLayeredWindowAttributes");
    
       }
       
       if (!pSLWA)
          return (FALSE);  // No support for translucent windows!
    
       SetWindowLong (hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
    
       return (pSLWA(hwnd, 0, (BYTE)((255 * percent) / 100), LWA_ALPHA));   // percent% alpha
    }
    
    BOOL RemoveWindowTransparency (HWND hwnd)
    {
       SetWindowLong (hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED);
       
       RedrawWindow (hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
    
       return (TRUE);
    }

  5. #5
    HelpingYouHelpUsHelpUsAll
    Join Date
    Dec 2007
    Location
    In your nightmares
    Posts
    223
    I have got the following in WM_INITDIALOG, and I don't get any warnings or errors about it. The problem is that it doesn't seem to do anything. slwa_function succeeds in getting the address of the function and returns a non-zero value when it is called (I debugged this to confirm). Note that SEEMsgBox simply brings up a message box (I use it for debugging, easier to pass one param rather than 5).
    Code:
    HMODULE hUser32;
    hUser32 = GetModuleHandle(TEXT("USER32.DLL"));
    typedef int (WINAPI *lpfnSetLayeredWindowAttributes) (HWND , COLORREF , BYTE , DWORD );
    lpfnSetLayeredWindowAttributes slwa_function;
    
    if(!(slwa_function=(lpfnSetLayeredWindowAttributes)GetProcAddress(hUser32,"SetLayeredWindowAttributes")))
                SEEMsgBox("ERROR CALLING SETLAYEREDWINDOW");
             
    // Set WS_EX_LAYERED on this window
    SetWindowLong(hwndDlg, GWL_EXSTYLE, GetWindowLong(hwndDlg, GWL_EXSTYLE) | WS_EX_LAYERED);
    // Change opacity of window
    slwa_function(hwndDlg, 0,(255 * 50) / 100, LWA_ALPHA);
    open the user32.lib file in an editor that handles binary files and search for "setlayeredwindowattributes."
    The closest thing is SetLayeredWin. As i thought, it definitely is not in libuser32. Great suggestion to use ifndef and endif though.
    long time no C; //seige
    You miss 100% of the people you don't C;
    Code:
    if (language != LANG_C && language != LANG_CPP)
        drown(language);

  6. #6
    Registered User
    Join Date
    Mar 2007
    Posts
    142
    I have got the following in WM_INITDIALOG, ...
    Well, maybe the Dialog Manager calls later SetWindowLong (hwnd, GWL_EXSTYLE,... with its own idea how dialog should be set up. I forgot if WM_INITDIALOG is called before or after WM_CREATE (and WM_CREATE for dialogs is handled by dialog manager) because I gave up on dialogs - all my windows are windows, some of them are just modal in nature.

    Anyway, if GetProcAddress() returns something, than it's got to be the real thing. Move your SetWindowLong (hwnd, GWL_EXSTYLE,... someplace else.

    Here is how I'm doing it and it works fine:

    Code:
    hwnd = CreateWindowEx (...);
                               
    if (hwnd)  {
    
       if (.... some conditions ...)
          SetWindowTransparency (hwnd, transPercent);
    
       ShowWindow (hwnd, SW_SHOWNORMAL);
       UpdateWindow (hwnd);
    }

  7. #7
    Registered User
    Join Date
    Mar 2005
    Location
    Juneda
    Posts
    287
    a comment, don't do it inside the main procedure, do it after the window creation on the winmain, but before you show/update window:

    Code:
    typedef int (WINAPI *lpfnSetLayeredWindowAttributes) (HWND , COLORREF , BYTE , DWORD );
    lpfnSetLayeredWindowAttributes slwa_function;
    
    int WINAPI WinMain (HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR cmdl,int cmds)
    {
    HWND hwnd;
    MSG msg;
    WNDCLASSEX wc;
    HMODULE hUser32;
    
    InitCommonControls();
    wc.hInstance = hInstance;
    wc.lpszClassName = "classname";
    wc.lpfnWndProc = procedimentPrincipal;
    wc.style = CS_DBLCLKS;
    wc.cbSize = sizeof (WNDCLASSEX);
    wc.hIcon = LoadIcon(hInstance,"ICONA");
    wc.hIconSm = LoadIcon (hInstance,"ICONA");
    wc.hCursor = LoadCursor (NULL,IDC_ARROW);
    wc.lpszMenuName = "menu";
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hbrBackground =(HBRUSH)GetStockObject(WHITE_BRUSH);
    
    if(!RegisterClassEx(&wc)) {return 0;}
    
    hwnd=CreateWindowEx(WS_EX_CLIENTEDGE,"classname","",WS_OVERLAPPEDWINDOW,0,0,100,100,NULL,NULL,hInstance,NULL);
    
    hUser32=GetModuleHandle(TEXT("USER32.DLL"));
    if(!(slwa_function=(lpfnSetLayeredWindowAttributes)GetProcAddress(hUser32,"SetLayeredWindowAttributes")))
        {
        MessageBox(hwnd,"error","Error",MB_OK);
        return 0;
        }
    else
        {
    SetWindowLong(hwnd,GWL_EXSTYLE,GetWindowLong(hwnd,GWL_EXSTYLE)|WS_EX_LAYERED);
        slwa_function(hwnd,0xffffff,0,1);//white color transparent
        }
    
    ShowWindow(hwnd,SW_SHOW);
    UpdateWindow(hwnd);
    while(TRUE==GetMessage(&msg,NULL,0,0))
        {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
        }
    return msg.wParam;
    }
    In that sample, as the background color is the same as the transparent, if you run it over the desktop you'll se the desktop through the window. Also you can search on the net for some splash window (i think that on codeguru there's a sample about that).

    Niara

  8. #8
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,059
    Also, has anyone ever got a semi-transparent window working in Dev-C++?
    Well, I don't normally use Dev-C++ but I converted a MS compilable tidbit to Dev-C++ and it appears to work:

    Code:
    #define IDD_TOOLBAR 1000
    #define IDC_TRANSPARENCY 2000
    #define IDC_ENDIT 3000
    Code:
    #include <windows.h>
    #include "resource.h"
    
    IDD_TOOLBAR DIALOGEX 0, 0, 98, 52
    STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION
    EXSTYLE WS_EX_TOOLWINDOW
    CAPTION "My Transparent Dialog"
    FONT 8, "MS Sans Serif"
    BEGIN
        PUSHBUTTON      "&Toggle Transparent",IDC_TRANSPARENCY,7,7,84,14
        PUSHBUTTON      "&Exit",IDC_ENDIT,7,31,84,14
    END
    Code:
    #pragma comment( lib, "user32.lib" ) 
    #include <windows.h>
    #include "resource.h"
    
    #define WS_EX_LAYERED 0x00080000L
    #define LWA_ALPHA 2
    
    BOOL bToggleTransparency = TRUE;
    
    typedef BOOL (WINAPI* SLWA)(HWND, COLORREF, BYTE, DWORD);
    SLWA SetLayeredWindowAttributes = 0;
    LRESULT CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
    HINSTANCE hInstance;
    
    int main(void)
    {
        HMODULE hDLL = GetModuleHandle("USER32.DLL");
        SetLayeredWindowAttributes = (SLWA)GetProcAddress(hDLL, "SetLayeredWindowAttributes");
        if( SetLayeredWindowAttributes == NULL)
            MessageBox(NULL, "SetLayeredWindowAttributes is NULL VALUE", " ",MB_OK);
        DialogBox(hInstance,
            MAKEINTRESOURCE(IDD_TOOLBAR),
            NULL,
            (DLGPROC) DlgProc);
        return 0;
    }
    
    LRESULT CALLBACK DlgProc(HWND hWndDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
    {
        switch(Msg)
        {
            case WM_INITDIALOG:
                {
                    DWORD dwStyle = GetWindowLong(hWndDlg, GWL_EXSTYLE);
                    dwStyle = dwStyle | WS_EX_LAYERED;
                    SetWindowLong(hWndDlg, GWL_EXSTYLE, dwStyle);
                    SetLayeredWindowAttributes(hWndDlg, 0, (255 * 70) / 100, LWA_ALPHA);
                    return TRUE;
                }
            case WM_COMMAND:
                switch(wParam)
                {
                    case IDC_TRANSPARENCY:
                        {
                            if(bToggleTransparency)
                                SetLayeredWindowAttributes(hWndDlg, 0, (255 * 70) / 100, LWA_ALPHA);
                            else
                                SetLayeredWindowAttributes(hWndDlg, 0, 255, LWA_ALPHA);
                            bToggleTransparency = !bToggleTransparency;
                            break;
                        }
                    case IDC_ENDIT:
                        EndDialog(hWndDlg, 0);
                        return TRUE;
                }
                break;
        }
        return FALSE;
    }

  9. #9
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,587
    Don't remember to unload the dll before the program exits!
    You shouldn't need to use this method to call the function, though. All functions should be callable without the need of dynamic dll loading. Though I don't know what the problem is nor can I test it now...
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21