Sign in to follow this  
qzole

UpdateLayeredWindow, strange bug?

Recommended Posts

Hi all I was frustrated over UpdateLayeredWindow for days, becasue I simply couldn't get it working, I was just about to post it on forums, so I made a minimum code, and finally it worked, after that I modified the original code, and well it does work, but I really don't get why :S (or is it, why didn't it worked until now...). Here is the modified code:
#define WINVER 0x0500

#include <windows.h>

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
char szClassName[ ] = "CodeBlocksWindowsApp";

HDC hDcScreen;
HDC hDcMem;
HBITMAP hBitm;
BITMAP bitmap;



int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nFunsterStil)
{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = NULL;                 /* Have a private DC */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default color as the background of the window */
    //wincl.hbrBackground = (HBRUSH) GetStockObject( BLACK_BRUSH );
    wincl.hbrBackground = CreateHatchBrush( HS_CROSS, RGB( 255, 0, 255 ) );

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           WS_EX_LAYERED,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "Code::Blocks Template Windows App",       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           300,                 /* The programs width */
           300,                 /* and height in pixels */
           NULL,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );

    /* Make the window visible on the screen */

    hBitm = (HBITMAP) ::LoadImage( NULL, "proba.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
    if ( 0 == hBitm )
        return 1;

    HDC dc = GetDC(NULL);
    hDcMem = CreateCompatibleDC(dc);
    HBITMAP hOldBitmap = (HBITMAP) SelectObject(hDcMem, hBitm);
    GetObject(hBitm, sizeof(bitmap), &bitmap);
    SIZE size = { bitmap.bmWidth, bitmap.bmHeight };
    POINT ppsrc = { 0, 0 };
    BLENDFUNCTION pblend = { AC_SRC_OVER, 0, 255, NULL };
    //BitBlt(GetDC(hwnd), 0,0,300,300, hDcMem, 0,0, SRCCOPY);
    if ( 0 == UpdateLayeredWindow(hwnd, dc, &ppsrc, &size, hDcMem, &ppsrc, 0, &pblend, ULW_ALPHA ) )
          MessageBox(hwnd, "You still suck", "Bye!", MB_OK | MB_ICONERROR);
      else
          MessageBox(hwnd, "You don't suck", "Weee!", MB_OK | MB_ICONINFORMATION);

    ShowWindow (hwnd, SW_SHOW);


    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}




void skinning(HWND hwnd){
    HDC dc = GetDC(NULL);
    hDcMem = CreateCompatibleDC(dc);
    HBITMAP hOldBitmap = (HBITMAP) SelectObject(hDcMem, hBitm);
    SIZE size = { bitmap.bmWidth, bitmap.bmHeight };
    POINT ppsrc = { 0, 0 };
    BLENDFUNCTION pblend = { AC_SRC_OVER, 0, 255, NULL };
    //BitBlt(GetDC(hwnd), 0,0,300,300, hDcMem, 0,0, SRCCOPY);
    if ( 0 == UpdateLayeredWindow(hwnd, dc, &ppsrc, &size, hDcMem, &ppsrc, 0, &pblend, ULW_ALPHA ) )
        MessageBox(hwnd, "You still suck", "Bye!", MB_OK | MB_ICONERROR);
    else
        MessageBox(hwnd, "You don't suck", "Weee!", MB_OK | MB_ICONINFORMATION);
    //SetLayeredWindowAttributes(hwnd, RGB(255,0,255), 150, LWA_ALPHA);
}



/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{

    switch (message)                  /* handle the messages */
    {
        case WM_CREATE:
            skinning(hwnd);
            break;
        case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        case WM_PAINT:
            PAINTSTRUCT ps;
            BeginPaint(hwnd, &ps);
            skinning(hwnd);
            EndPaint(hwnd, &ps);
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}




As you see there are two UpdateLayeredWindow calls, the first one returns an error, the second succedes. If I delete the first one, the second one will fail. If I delete the first one, but copy it underneath the second one (even several times) all will fail. I would like some help with this bacause it bothers me, that I don't know why does this happen, and I defenetly don't want to have this kind of error, when the code gets larger. Thank you in advance Q. Edit: Some lines were commented wich shouldn't have been [Edited by - qzole on February 20, 2008 8:53:14 AM]

Share this post


Link to post
Share on other sites
Ok, I was a bit tired yesterday night, but now I see, what was wrong, simply I call the skin function in WM_CREATE, but at that point I did not load the image file in. So actually I need the first UpdateLayeredWindow call.

On the other hand, I wanted to try to be able to write out the error, so I tried out the code, but Code::Blocks doesn't have strsafe.h, so I just used this (Didn't really get what did StringCchPrintf wanted to do)


if ( 0 == UpdateLayeredWindow(hwnd, dc, &ppsrc, &size, hDcMem, &ppsrc, 0, &pblend, ULW_ALPHA ) ){
LPVOID lpMsgBuf;
DWORD dw = GetLastError();
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM , NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL );
MessageBox(NULL, (LPCTSTR)lpMsgBuf, TEXT("Error"), MB_OK);
}
else
MessageBox(hwnd, "You don't suck", "Weee!", MB_OK | MB_ICONINFORMATION);



But it writes out that "The operation compleated successfully" Do you think that is normal?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this