Solved

Drawing a highlighted bitmap

Posted on 2001-06-04
11
330 Views
Last Modified: 2013-12-03
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
Comment
Question by:bugroger
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
11 Comments
 
LVL 9

Expert Comment

by:ginsonic
ID: 6154938
Can you give me more details , please?
0
 
LVL 14

Expert Comment

by:DragonSlayer
ID: 6155284
listening...
0
 
LVL 2

Author Comment

by:bugroger
ID: 6155371
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 2

Author Comment

by:bugroger
ID: 6155811
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
 
LVL 34

Expert Comment

by:Slick812
ID: 6157531
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
 
LVL 34

Expert Comment

by:Slick812
ID: 6158116
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
 
LVL 2

Author Comment

by:bugroger
ID: 6158859
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
 
LVL 34

Expert Comment

by:Slick812
ID: 6162005
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
 
LVL 2

Author Comment

by:bugroger
ID: 6162936
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
 
LVL 34

Accepted Solution

by:
Slick812 earned 100 total points
ID: 6165783
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
 
LVL 6

Expert Comment

by:edey
ID: 6484042
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

Featured Post

On Demand Webinar: Networking for the Cloud Era

Ready to improve network connectivity? Watch this webinar to learn how SD-WANs and a one-click instant connect tool can boost provisions, deployment, and management of your cloud connection.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…

695 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question