2

Using Borland C++ Builder 2009

I screen-captured three buttons from a W7 Windows dialog and put them in a TImageList. I load the 3 variants in a TImage, when appropriate.

Image->Picture->Bitmap = NULL ; // Clear previous state
ImageList->GetBitmap(2, Image->Picture->Bitmap) ;

PS: Image->Transparent = True

On Windows 7 and Windows 10 this seems to work properly. BUT I just realized, only because the TForm the TImage is placed on has the exact same background color. (confirmed not to work after I changed the background to lime)

On Windows XP the button doesn't look so great. Since XP seems to have slightly different background color. Mind you, it's also clBtnFace

XP: XP . . . Windows 7: Windows 7

I have also experimented with setting BlendColor and DrawingStyle of the TImageList control, combined with Image->Transparent = true or false.

But I can't get it to work.

I captured the Image->Picture->Bitmap->Canvas->Pixels[0][0] value on W7 and put it in ImageList->BlendColor (ImageList->DrawingStyle = dsFocus or dsSelected) and so forth, without success.

I also have experimented with explicitly setting Image->Transparent = True again after a ImageList->GetBitmap(2, Image->Picture->Bitmap) and even tried

Image->Picture->Bitmap->TransparentColor =
Image->Picture->Bitmap->Canvas->Pixels[0][0]

without a noticeable effect.

Your thoughts ?

Ken White
  • 123,280
  • 14
  • 225
  • 444
Peter
  • 1,334
  • 12
  • 28
  • 1
    You need the original glyph, with the alpha channel. Screen cap after render is too late. – David Heffernan Dec 10 '15 at 07:01
  • Have you tried to modify your image by hand and insert one pixel of `clFuchsia` color in the upper left corner of the image? – Wodzu Dec 10 '15 at 07:17
  • @Wodzu It won't help because these images rely on partial alpha levels to look good – David Heffernan Dec 10 '15 at 07:50
  • 1
    Instead of capture the image from the screen you can try drawing the expand button using the [`DrawThemeBackground`](https://msdn.microsoft.com/en-us/library/bb773289(VS.85).aspx) method passing the `TDLG_EXPANDOBUTTON` part and one of the valid states (`TDLGEBS_NORMAL`, `TDLGEBS_HOVER`, `TDLGEBS_PRESSED`, etc) – RRUZ Dec 10 '15 at 17:26
  • I see ... thanks for the comments ! Any idea if this glyph can be found on a W7 system and where ? @RRUZ, seems to be limited to Vista and up and the issue I'm having is with XP – Peter Dec 10 '15 at 23:45
  • @Peter for XP try the `EBP_NORMALGROUPEXPAND` part like is shown here http://stackoverflow.com/questions/7264484/chevron-button-in-delphi-dialog-form – RRUZ Dec 11 '15 at 02:03
  • @RRUZ could you answer with a code example ? I'm confused as to what function to use, and what to pass to the function exactly ? Also how to show the different states (which is why I have 3 bitmaps, one for every state) – Peter Dec 11 '15 at 06:15

1 Answers1

4

How I said on my comment instead of capture the image from the screen you can try drawing the expand button using the DrawThemeBackground method passing the TDLG_EXPANDOBUTTON part and one of the valid states (TDLGEBS_NORMAL, TDLGEBS_HOVER, TDLGEBS_PRESSED, etc) . And for Windows XP you can use EBP_NORMALGROUPEXPAND part and one of these states (EBHC_NORMAL, EBHC_HOT, EBHC_PRESSED)

Check this sample which drawn the expando button in a TImage.

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "Vsstyle.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------


__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  Image1->Canvas->Brush->Color = clBtnFace;
  Image1->Canvas->FillRect(Image1->ClientRect);

  OSVERSIONINFO verwin;
  verwin.dwOSVersionInfoSize=sizeof(verwin);
  if (GetVersionEx(&verwin))
  {
    //Check  the Windows version
    if (verwin.dwMajorVersion >= 6) // is Vista at least?
    {
      HTHEME hTheme = OpenThemeData(Handle, VSCLASS_TASKDIALOG);
      if (hTheme)
      {
          SIZE s;
          //get the size of the  TDLG_EXPANDOBUTTON
          if (GetThemePartSize(hTheme, Image1->Canvas->Handle, TDLG_EXPANDOBUTTON, TDLGEBS_NORMAL, NULL, TS_TRUE, &s) == S_OK)
          {
              TRect pRect = Rect(0, 0, s.cx, s.cy);
              DrawThemeBackground(hTheme, Image1->Canvas->Handle, TDLG_EXPANDOBUTTON, TDLGEBS_NORMAL, &pRect, NULL);
           }
      }
    }
    else
    {
      HTHEME hTheme = OpenThemeData(Handle, VSCLASS_EXPLORERBAR);
      if (hTheme)
      {
          SIZE s;
          //get the size of the  EBP_NORMALGROUPEXPAND
          if (GetThemePartSize(hTheme, Image1->Canvas->Handle, EBP_NORMALGROUPEXPAND, EBHC_NORMAL, NULL, TS_TRUE, &s) == S_OK)
          {
              TRect pRect = Rect(0, 0, s.cx, s.cy);
              DrawThemeBackground(hTheme, Image1->Canvas->Handle, EBP_NORMALGROUPEXPAND, EBHC_NORMAL, &pRect, NULL);
           }
      }
    }
  }
}
Uli Gerhardt
  • 13,748
  • 1
  • 45
  • 83
RRUZ
  • 134,889
  • 20
  • 356
  • 483
  • Thanks !! I'm going to try this on Monday (can't right now, no access to my 'stuff'). Question, what size/dimensions should Image1 have ? Or doesn't it matter ? Other settings that are important ? Transparent ? Stretch ? ... – Peter Dec 12 '15 at 00:37
  • Just drop a TImage with the default values. – RRUZ Dec 12 '15 at 00:38
  • Making progress ! Thanks !! For completeness you may add that (at least for my Borland C++ Builder 2009) version you also need to include: `#include ` and add `UxTheme.lib` to the project ! Also, a link to where you get the image values from would be nice. I'm looking right now for the UP pointing version of the glyph, for my code ! – Peter Dec 14 '15 at 00:40
  • For the other states I found this: https://msdn.microsoft.com/en-us/library/windows/desktop/bb773210%28v=vs.85%29.aspx I have it working **very nicely** now ! Thanks for your help @RRUZ ! – Peter Dec 14 '15 at 01:40
  • PS. I **did** set `Image1->Transparent = true` to get the desired transparent effect (just for completeness) – Peter Dec 14 '15 at 02:09