• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 346
  • Last Modified:

Drawing a highlighted bitmap

I want to draw a highlighted bitmap like
the explorer when you select a item (with icon).
Does anyone knows how can i do that?
0
bugroger
Asked:
bugroger
1 Solution
 
ginsonicCommented:
Can you give me more details , please?
0
 
DragonSlayerCommented:
listening...
0
 
bugrogerAuthor Commented:
more details:

ex.
 When you click on an exe-file in the explorer
 the text changed to clHighlightText/clhighlight
 and the icon from the exe-file will be displayed
 darker.


 How can I "convert" a normal icon/bitmap to such
 a "darker" icon/bitmap?


0
Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

 
bugrogerAuthor Commented:
I found the ImgList_DrawEx function.

With this function you can draw a "selcected Bitmap".
So you can write a function which convert a Bitmap to
a "darker" bitmap.


0
 
Slick812Commented:
hello bugroger, here is some code that I used to TRY to simulate the Icon hilighting used in windows explorer windows. This uses a PatBlt with the dwRop set to $A000C9, which might be undocumented, it is a pixel blending dwRop operation. I never got an exact match for the windows highlighting operation, but this was close enough for me to use as a visual image highlighting method.

private
bmp: TBitmap;


procedure TForm1.FormCreate(Sender: TObject);
var
i, k, Dot: Integer;
begin
{this creates a 8x8 bitmap for your Brush, I put it in create because I used this bmp many, many times}
bmp:= TBitmap.Create;
  With bmp Do
  Begin
  width := 8;
  height:= 8;
  PixelFormat := pf24Bit;
  Dot := 0;
  for i:= 0 to 7 do
  begin
    for k:= 0 to 7 do
    if ((k+ Dot) mod 2) <> 0 then
    canvas.Pixels[k,i] := clSilver
    else
    canvas.Pixels[k,i] := GetSysColor(COLOR_HIGHLIGHT)};
{if you don't need the same color highlight as windows, you can try clGray here or your own color}
    Inc(Dot)
  end;
    End;

end;

procedure TForm1.Button_HiLiteClick(Sender: TObject);
var
FirstPic: TBitmap;
begin
if OpenpictureDialog1.Execute then
  begin
  FirstPic := TBitmap.Create;
  FirstPic.LoadFromFile(OpenpictureDialog1.FileName);
{if the bitmap is not 24 Bit then colors will be blocky}
  FirstPic.PixelFormat := pf24bit;
{set brush bitmap to the one you created}
  FirstPic.Canvas.Brush.Bitmap := bmp;

{you can try FirstPic.Canvas.Brush.Color := clHighlight ,
 and you don't need the bmp or bitmap brush at all,
but this didn't look close enough to the windows highlight for me}

{this will blend the FirstPic with the bmp brush, and then it's ready to use}
  PatBlt(FirstPic.Canvas.Handle, 0, 0, FirstPic.Width, FirstPic.Height, $A000C9);
  Canvas.Draw(0,0,FirstPic); // use bitmap
  FirstPic.Free;
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
bmp.Free;
end;

- - - - - - - - - - - - - - - - - - - - - -
there must be an undocumented dwRop for the windows highlighting operation, but I couldn't find it.
0
 
Slick812Commented:
correction, I should have put this

for k:= 0 to 7 do
    if ((k+ Dot) mod 2) <> 0 then
    canvas.Pixels[k,i] := $00AAAAAA
    else
    canvas.Pixels[k,i] := clHightLight;
0
 
bugrogerAuthor Commented:
I have written my own function to highlight a bitmap.
I have used ALPHA-BLENDING to realized that.

NewRed    = Rs*Sr+Rd*Dr
NewGreen  = Gs*Sg+Gd*Dg
NewBlue   = Bs*Sb+Bd*Db
NewFactor = As*Sa+Ad*Da

  Rs=FactorSourceRed    | Sr=SourceRed     |
  Rd=FactorDestRed      | Dr=DestRed

  Gs=FactorSourceGreen  | Sg=SourceGreen   |
  Gd=FactorDestGreen    | Dg=DestGreen
     
  Bs=FactorSourceBlue   | Sb=SourceBlue    |
  Bd=FactorDestBlue     | Db=DestBlue

  As=FactorSourceFactor | Sa=SourceFactor  |
  Ad=FactorDestFactor   | Da=DestFactor


//Alpha 0.0 - 1.0
Procedure BlendWithColor(Src, Dest : TBitmap; BlendColor : TColor; Alpha : Real);
TYPE
 TRGB = record
         r, g, b, PALType : Byte;
        end;
 TpRGB = packed record
          b, g, r : Byte;
         end;

VAR
 BlendColorChannels : TRGB;
 DestRGBPixel       : ^TpRGB;
 SrcRGBPixel        : ^TpRGB;
 y, x               : Integer;
 SourceColorFaktor  : real;

Begin
 //Set BitPerPixel -> 24Bit
 Src.PixelFormat  := pf24Bit;
 Dest.PixelFormat := pf24Bit;
 Dest.Width       := Src.Width;
 Dest.Height      := Src.Height;


 //Get RGB-Channels from Color
 BlendColorChannels := TRGB(BlendColor);
 IF BlendColorChannels.PalType = 128 then
  BlendColorChannels := TRGB(GetSysColor((BlendColor AND $0000FFFF)));

 //Get SourceColorFaktor
 SourceColorFaktor := 1.0 - Alpha;

 //Get all Pixels
 For y := 0 to Dest.Height -1 do
 Begin
  //Get Pixel
  SrcRGBPixel  := Src.ScanLine[y];
  DestRGBPixel := Dest.ScanLine[y];
  For x := 0 to Dest.Width -1 do
  Begin
   DestRGBPixel.r := Round(SourceColorFaktor * SrcRGBPixel.r  + Alpha * BlendColorChannels.r);
   DestRGBPixel.g := Round(SourceColorFaktor * SrcRGBPixel.g  + Alpha * BlendColorChannels.g);
   DestRGBPixel.b := Round(SourceColorFaktor * SrcRGBPixel.b  + Alpha * BlendColorChannels.b);
 
   //Set Pointer to next Pixel
   Inc(DestRGBPixel);
   Inc(SrcRGBPixel);
  End;
 End;
End;
0
 
Slick812Commented:
well bugroger, I like your code and it works real good, but its not an exact match for the windows icon highlighting effect, at least not on my puters. I got very close results with the alpha set to  .61 - I added a line to help the highlighted look with dark colors

For x := 0 to Dest.Width -1 do
 Begin
  if SrcRGBPixel.r + SrcRGBPixel.g + SrcRGBPixel.b < 64 then
  begin
  DestRGBPixel.r := SrcRGBPixel.r;
  DestRGBPixel.g := SrcRGBPixel.g;
  DestRGBPixel.b := SrcRGBPixel.b;
  end else
  begin
  DestRGBPixel.r := Round(SourceColorFaktor * SrcRGBPixel.r  + Alpha * BlendColorChannels.r);
  DestRGBPixel.g := Round(SourceColorFaktor * SrcRGBPixel.g  + Alpha * BlendColorChannels.g);
  DestRGBPixel.b := Round(SourceColorFaktor * SrcRGBPixel.b  + Alpha * BlendColorChannels.b);
  end;
  //Set Pointer to next Pixel
  Inc(DestRGBPixel);
  Inc(SrcRGBPixel);
 End;

- - - - - - -
good work
0
 
bugrogerAuthor Commented:
Here is my new code to get an exact match
for the "windows icon highlighting effect."

I have used ROUND(INT(......))...

 For y := 0 to Dest.Height -1 do
 Begin
  //Get Pixel
  SrcRGBPixel  := Src.ScanLine[y];
  DestRGBPixel := Dest.ScanLine[y];
  For x := 0 to Dest.Width -1 do
  Begin

    DestRGBPixel.r := ROUND(INT(SourceColorFaktor *     SrcRGBPixel.r  + BlendingColorFaktor *        BlendColorChannels.r));
    DestRGBPixel.g := ROUND(INT(SourceColorFaktor *      SrcRGBPixel.g  + BlendingColorFaktor *       BlendColorChannels.g));
    DestRGBPixel.b := ROUND(INT(SourceColorFaktor * SrcRGBPixel.b  + BlendingColorFaktor * BlendColorChannels.b));

   //Set Pointer to next Pixel
   Inc(DestRGBPixel);
   Inc(SrcRGBPixel);
  End;
 
0
 
Slick812Commented:
this looks like a match for me
 - - - - - -

var
Dot: Integer;

Dot := 0;
For x := 0 to Dest.Width -1 do
 Begin
  if ((x+ Dot) mod 2) = 0 then
  begin
  DestRGBPixel.r := Round(0.38 * SrcRGBPixel.r  + 0.4 * BlendColorChannels.r);
  DestRGBPixel.g := Round(0.38 * SrcRGBPixel.g  + 0.4 * BlendColorChannels.g);
  DestRGBPixel.b := Round(0.38 * SrcRGBPixel.b  + 0.4 * BlendColorChannels.b);
  end else
  begin
  DestRGBPixel.r := Round(0.38 * SrcRGBPixel.r  + 0.62 * BlendColorChannels.r);
  DestRGBPixel.g := Round(0.38 * SrcRGBPixel.g  + 0.62 * BlendColorChannels.g);
  DestRGBPixel.b := Round(0.38 * SrcRGBPixel.b  + 0.62 * BlendColorChannels.b);
  end;
  //Set Pointer to next Pixel
  Inc(DestRGBPixel);
  Inc(SrcRGBPixel);

 End;
 Inc(Dot);
End;
0
 
edeyCommented:
Actually, if you look very carefully at a "selected" icon you can see that it's just had a mask drawn over it like this:

* * * * * * * *
 * * * * * * *
* * * * * * * *
 * * * * * * *
* * * * * * * *
 * * * * * * *
* * * * * * * *

where the spaces are transparent & the *'s are dark blue.  You could (if you've already got the "checkerboard" mask) do this with a couple of blts:

bmp.canvas.copyMode := cmMergeCopy;
bmp.canvas.draw(0,0,mask_bmp);
bmp.canvas.copymode := cmMergePaint;
bmp.canvas.draw(0,0,mask_bmp);


GL
Mike
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now