Button Images on XP Themed Buttons

S

SteveV

Gettting images to work with XP Themed buttons has always been a bit
of a pain but at least it was possible using MFC. It stands to reason
that anything you can do with MFC using API calls you should be able
to do using .NET and interop. I'm sure I'm doing something wrong but
for the life of me can't fiqure out what it might be. Here's what I'm
trying to do:

Using C++, assigning an image to a themed button required the folling
steps...

1.) Check if themes are supported by calling
::LoadLibrary(_T("UxTheme.dll")) and checking the returned HMODULE for
NULL;

2.) Check if themes are active by calling GetProcAddress(hModule,
"IsThemeActive") and using the returned pointer to call the
IsThemeActive function.



3.) Create a CImageList with 5 images to correspond to button states:

Image 0 = normal
Image 1 = mouse hover
Image 2 = button down
Image 3 = button disabled
Image 4 = button focus

4.) And lastly sending the button a message like so:


BUTTON_IMAGELIST BtnIL;
BtnIL.himl = pImageList->m_hImageList; // Handle to our image list
BtnIL.margin = CRect(0, 0, 0, 0); // margin around the icon
BtnIL.uAlign = BUTTON_IMAGELIST_ALIGN_CENTER; // Image alignment

::SendMessage
(
pBtn->GetSafeHwnd(), // handle to our button
BCM_SETIMAGELIST, // message ID
0, // not used, must be 0
(LPARAM)&BtnIL // pointer to our BUTTON_IMAGELIST structure
);


With that out of the way. Here's how I trying to accomplish the same
thing using .NET and interop (for the sake of brevity I've left out
the checking for theme support and themes enabled):


[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}


[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct BUTTON_IMAGELIST
{
public IntPtr hIml;
public RECT margin;
public uint uAlign;
}


[DllImport("User32.dll", CharSet=CharSet.Auto)]
public static extern uint SendMessage(IntPtr hWnd, int Msg, uint
wParam, IntPtr lParam);


const uint BUTTON_IMAGELIST_ALIGN_CENTER = 4;

....


public static bool SetXpButtonImage(IntPtr hButton, IntPtr hImgList)
{
if(hButton == IntPtr.Zero || hImgList == IntPtr.Zero)
return false;

Structs.RECT marginRect = new Win32.Structs.RECT();

marginRect.left = 0;
marginRect.right = 0;
marginRect.top = 0;
marginRect.bottom = 0;

Structs.BUTTON_IMAGELIST btnIL = new BUTTON_IMAGELIST();
btnIL.hIml = hImgList;
btnIL.margin = marginRect;
btnIL.uAlign = BUTTON_IMAGELIST_ALIGN_CENTER;

IntPtr mem = Marshal.AllocCoTaskMem(Marshal.SizeOf(btnIL));

try
{
Marshal.StructureToPtr(btnIL, mem, false);
uint result = User32Funcs.SendMessage(hButton,
(int)Enums.ButtonControlMsgs.BCM_GETIMAGELIST, (uint)0, (IntPtr)mem);
return result != 0;

}

catch
{
Marshal.FreeCoTaskMem(mem);
}

return false;
}

....


I call the function like so:

bool bResult = SetXpButtonImage(MoveDnBtn.Handle,
MoveDnBtnImageList.Handle);

and while eveything appears to do what it should the end result is NO
image on the button.

I have various the ImageList color depths and image formats noe of
which apear to make a difference. I'm running VS .NET 2003 /
Framework 1.1 and have enabled visual themes using a manifest file or
Application.EnableVisualStyles(). In both cases my controls show the
XP visual styles but button images are still missing.

Anyone have any thoughts?

Thanks -- Steve
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top