Thread: Getting the array of bytes corresponding to a image of an icon

  1. #1
    Registered User
    Join Date
    Jul 2004
    Posts
    35

    Getting the array of bytes corresponding to a image of an icon

    I'm using the following procedure in order to get the small icon of an application window:
    Code:
    HICON GetWindowIcon
    (
        HWND  hwnd
    )
    {
        LRESULT lResult;
        HICON   hIcon;
        
        hIcon = NULL;
        
        lResult = SendMessageTimeout(hwnd, WM_GETICON, ICON_SMALL, 0, SMTO_ABORTIFHUNG|SMTO_BLOCK, 1000, (DWORD_PTR *)&hIcon);
        if (lResult==0) {
            hIcon = NULL;
        }
        
        if (hIcon == NULL) {
            hIcon = (HICON)GetClassLong(hwnd, GCL_HICONSM);
        }
        
        if (hIcon == NULL) {
            hIcon = LoadIcon(NULL, IDI_APPLICATION);
        }
        
        return hIcon;
    }
    Sometimes, with some application, SendMessageTimeout returns a hIcon which is different to NULL but the icon returned doesn't seem to be a small one, although I'm using the ICON_SMALL constant. Is it normal?

    I'm also using the following procedure in order to get the array of bytes corresponding to the icon image:
    Code:
    int GetIconBits
    (
        HICON hIcon,
        int   iIconSize,
        long* bits,
        int*  iIconBitsLength
    )
    {
        ICONINFO   iconInfo;
        HDC        dc;
        BITMAPINFO bmi;
        int        iBits;
        long       maskBits[4096];
        int        i;
        int        iMask;
        
        if(!GetIconInfo((HICON)hIcon, &iconInfo))
            return -1;
        
        if((dc = GetDC(NULL)) == NULL) {
            DeleteObject(iconInfo.hbmColor);
            DeleteObject(iconInfo.hbmMask);
            return -1;
        } 
        
        memset(&bmi, 0, sizeof(BITMAPINFO));
        bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bmi.bmiHeader.biWidth = iIconSize;
        bmi.bmiHeader.biHeight = -iIconSize;
        bmi.bmiHeader.biPlanes = 1;
        bmi.bmiHeader.biBitCount = 32;
        bmi.bmiHeader.biCompression = BI_RGB;
        
        iBits = iIconSize * iIconSize * 32 / 8;
        GetDIBits(dc, iconInfo.hbmColor, 0, iIconSize, bits, &bmi, DIB_RGB_COLORS);
        
        GetDIBits(dc, iconInfo.hbmMask, 0, iIconSize, maskBits, &bmi, DIB_RGB_COLORS);
        
        for(i = 0; i < iBits; i++) {
            bits[i] = bits[i] | ((maskBits[i] != 0) ? 0 : 0xff000000);
        }    
        
        (*iIconBitsLength) = iBits;
        
        ReleaseDC(NULL, dc);
        
        DeleteObject(iconInfo.hbmColor);
        DeleteObject(iconInfo.hbmMask);
        
        return 0;
    }
    There is a problem with 32-bit anti-aliased icons, which are typical in Windows XP. The images represented by the arrays of bytes returned by this procedure have a sort of dark area around. I guess this happens because the procedure doesn't handle correctly the mask information or something like that, I don't know. To tell the truth the procedure isn't mine, I've copied it. Does anybody know how I must treat the information return by the GetDIBits calls in order get a correct array of bytes representing the image?

    Finally, which is the real format of the array of bytes returned by this procedure? I mean, if I'm working with 32-bit icons, I need 8 bytes in order to represent each pixel. The image is supposed to be in a RGB format so, how are distributed the bytes? Is it something like this?
    Code:
    bits[0] bits[1] bits[2] bits[3] -> (0,0) pixel
    bits[4] bits[5] bits[6] bits[7] -> (0,1) pixel
    ...
    If this is correct, how are the RGB components mapped? Is it something like this?:
    Code:
      A       R       G      B
    bits[0] bits[1] bits[2] bits[3] -> (0,0) pixel
    bits[4] bits[5] bits[6] bits[7] -> (0,1) pixel
    ...
    Thanks for your help.

  2. #2
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    I's not 100% sure on this, but...

    Code:
        A             R           G            B
    bits[0-7]     bits[8-15]   bits[16-23] bits[24-31] -> (0,0) pixel
    bits[32-39]   bits[40-47]  bits[48-55] bits[56-63] -> (1,0) pixel
    etc

  3. #3
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    AFAIK the second image is a mask. This is monochrome (B&W). You may therefore need to use the BI_BITFIELDS flag for the mask image.

    more info here
    http://www.gdgsoft.com/gconvert/help...Is_An_Icon.htm
    some here
    http://support.microsoft.com/kb/q94326/

    I use BYTE arrays not long arrays.

    I would also try a call to GetObject() with a BITMAP struct on each icon.

    BITMAP bmp;
    GetObject(iconInfo.hbmColor, sizeof(BITMAP), (LPSTR)&bmp);

    and check that the image is 32bit ect.

    I also draw the image into the hdc I send into the GetDIBits() call but now I wonder why.
    "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

  4. #4
    Registered User
    Join Date
    Jul 2004
    Posts
    35
    Many thanks for your answer.

    So it seems I have to do something with the mask in order to get a correct image, but I don't know what do! Do you know how I have to mix mask and byte colors so that the resulting image is good?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 16
    Last Post: 05-29-2009, 07:25 PM
  2. concatenating 2 bytes of an array
    By davo666 in forum C Programming
    Replies: 1
    Last Post: 02-28-2009, 07:37 AM
  3. image to array
    By elninio in forum C++ Programming
    Replies: 3
    Last Post: 06-02-2008, 07:43 AM
  4. 1-D array
    By jack999 in forum C++ Programming
    Replies: 24
    Last Post: 05-12-2006, 07:01 PM
  5. Merge sort please
    By vasanth in forum C Programming
    Replies: 2
    Last Post: 11-09-2003, 12:09 PM