Solved

get a copy of the win2k/xp cursor with shadow

Posted on 2003-11-28
11
509 Views
Last Modified: 2010-04-05
There's all sorts of ways to get the cursor image.
e.g. this draws the cursor onto a bitmap:
DrawIcon(Bmp.Canvas.Handle, offx, offy, hCursor);

Q.
With D5/6, where can the shadow from win2k, xp be found?
So that (I am presuming) it can be blended on first.

Regards
Steve
0
Comment
Question by:SteveWaite
[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
  • 5
  • 5
11 Comments
 
LVL 2

Assisted Solution

by:TheLeader
TheLeader earned 200 total points
ID: 9841530
The shadow is stored in the ICO file as an alpha layer.  This format ICO file was introduced in Win2K.
but in xp well try to make a search in msdn
0
 
LVL 3

Author Comment

by:SteveWaite
ID: 9843659
Many thanks for that,
I too have read that, but so far I have been unable to obtain this 32bit icon.
This is a 500pt Q after all :-)

Actually re-reading my Q, perhaps I should have said where can the icon be found, such that I can obtain a bitmap of the shadow?
I do know the rudimentary stuff about it and I only posted here after lots of searching.

Any help is greatly appreciated.

Regards
Steve

0
 
LVL 34

Expert Comment

by:Slick812
ID: 9847348
The 32 bit Icons and Cursors shadow is a "Blending" effect that the system does by reading the BitMask bitmap for Black pixels I think, ,  and the Alpha Chanel of the 32 bit color bitmap (at least in Win XP), There is no "Bitmap" for the shadow or other blending effects, since cursors and Icons are two bitmaps , a color and a black and white "Mask" bitmap which defines the transparent and inverse color areas (and the blending areas in win XP using a 32 bit icon)
0
Independent Software Vendors: 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 3

Author Comment

by:SteveWaite
ID: 9847557
hi Slick, I do know all that though, but I was thinking along the lines that the alpha layer of some 32 bit icon contained the values of the actual shadow being shown, which I was hoping to make a mask for and blend on a background. I have done a computed shadow cast of my own from the actual cursor mask bitmap but I thought the actual shadow data was gettable from somewhere and could avoid complications. I've tried a lot of stuff and I'm beginning to think i'ts not kept anywhere other than the original resource of custom cursors.

I'm just wondering if there is a little more to this story...

Thanks guys..
0
 
LVL 34

Expert Comment

by:Slick812
ID: 9852395
I am busy right now so I do not have time to code and test, maybe tomorrow, I think the DrawIconEx will do the blending and shadow for Icons and cursors, there may be a Flag to NOT do the Blending and shadow, but I don't remember right now, I can look at my code tomorrow, but if I remember right the AlphaBlend function can do all of that reading of the alpha chanel and then blend it according to the value there to another bitmap, so you just set the TBlendFunction record with certain flags and you will get the alpha chanel read and blend, I think this is the way the system does the Icon and cursor blend. . .  As far as reading the alpha chanel values, you can do a scanline and get the non-Color byte of the color Cardinal value and use that for a blend amount value. . . I did a IconToFile thing where I had to convert 32 bit blended Icons to 24 bit non blended Icons, you can look at the code for that at

http://www.angelfire.com/hi5/delphizeus/saveicons.html

and the code is in the Icon32To24File function

I'll try and look for the alpha blend thing tommorow, You might try the DrawIconEx thing
0
 
LVL 3

Author Comment

by:SteveWaite
ID: 9853904
I'm off to check that out right away, I appreciate your help.
0
 
LVL 34

Accepted Solution

by:
Slick812 earned 300 total points
ID: 9877195
Seems like I should have looked into the system mouse Cursor drawing more, I thought is was like the system Icon drawing, but it is not. I did not have any luck getting a shadow on a cursor draw, The cursors may not use any alpha channel info to do the shadow drawing (unlike the Icons). So I had to create a 32 bit bitmap and draw the cursor mask bitmap on it and the scanline this 32 bit bitmap to add alpha channel info for the AlphaBlend function to use.

here's some code for a button click that simulates the cursor shadow drawing, the shadow does not exactly match the cursor shadow of the XP cursor, but I don't have time to try and get the scanline to exactly match, you can add some fade out in the downward direction to match it more better, if you want. This looks very much like it -


procedure TMainForm1.sbut_CursorShadowClick(Sender: TObject);
type
  TaryCard = Array[byte] of Cardinal;
  ParyCard = ^TaryCard;

var
IconInfo: TIconInfo;
hCursor, maskDC, x, y, Start: Integer;
ShadowBmp: TBitmap;
ParyCar1: ParyCard;
Blend1: TBlendFunction;
begin
hCursor := LoadCursor(0,IDC_ARROW);
DrawIconEx(Canvas.handle,20,20, hCursor, 0, 0, 0, 0, DI_NORMAL);
if not GetIconInfo(hCursor, IconInfo) then
  begin
  ShowMessage('Failure to Get Cursor Info');
  Exit;
  end;
ShadowBmp := TBitmap.Create;
ShadowBmp.PixelFormat := pf32bit;
ShadowBmp.Width := 32;
ShadowBmp.Height := 32;
try
  maskDC := CreateCompatibleDC(0);
  SelectObject(maskDC, IconInfo.hbmMask);
  BitBlt(ShadowBmp.Canvas.Handle, 0, 0, 32, 32, maskDC,
              0,0, SRCCOPY);
  DeleteDC(maskDC);

  finally
  DeleteObject(IconInfo.hbmMask);
  DeleteObject(IconInfo.hbmColor);
  end;

for y := 0 to 31 do
  begin
  // scanline through the ShadowBmp to change black pixels to alpha byte blend values
  ParyCar1 := ShadowBmp.ScanLine[y];
  Start := 0;
  for x := 31 downto 0 do
  begin
  if ParyCar1[x] and $FFFFFF = 0 then // black pixel color
    begin
    if Start = 0 then // Start moves the Blend value higher to the left
      begin
      if x < 29 then
      ParyCar1[x+3] := $0D000000; // the high byte $0D is set to the amount of Blend
      if x < 30 then
      ParyCar1[x+2] := $10000000;  // the Color value in it 3 low bytes are set to zero black
      if x < 31 then
      ParyCar1[x+1] := $18000000;
      ParyCar1[x] := $26000000;
      end else
      ParyCar1[x] := $35000000;
      Inc(Start);
      end else
      if Start > 0 then // to the left of the black mask pixels
          begin
          ParyCar1[x] := $0D000000;
          ParyCar1[x+1] := $10000000;
          Start := 0;
          end else
        ParyCar1[x] := 0; // change all white to black without any alpha byte
      end;
    end;

Blend1.BlendOp := AC_SRC_OVER;
Blend1.BlendFlags := 0;
Blend1.SourceConstantAlpha := $F0;
{this SourceConstantAlpha can be set to a value for overall blending
 for the AlphaFormat of AC_SRC_ALPHA which is equal to One}
Blend1.AlphaFormat := 1;
{AlphaFormat := 1 (AC_SRC_ALPHA) will get the alpha byte value to do the blend for that pixel}
AlphaBlend(Canvas.Handle, 63, 20, 32, 32,
           ShadowBmp.Canvas.Handle, 0, 0, 32, 32, Blend1);

FreeAndNil(ShadowBmp);
DrawIconEx(Canvas.handle,60,20, hCursor, 0, 0, 0, 0, DI_NORMAL);
end;
0
 
LVL 3

Author Comment

by:SteveWaite
ID: 9877397

Hey, I could just hand the points over simply for such a nice effort, but you have seen now the problem is an interesting one.. Perhaps instead there is a hidden window DC containing the final image rect? I've not found one, there's one showing an icon being dragged thats a child of the desktop window for example..

Any more ideas?
0
 
LVL 34

Expert Comment

by:Slick812
ID: 9880266
Yes, it was something I had not really considered, the shadow for a cursor is a relativly new thing, I had thought that a cursor would be handled much like an Icon for drawing, but in my testing, it looks like it is not done the same. . . The screen mouse cursor is really a system "thing" all by it's self, as it is not drawn on any screen blts that I know of,  I do not beleave that the screen cursor has any relation to a window's window, I think that in some systems the cursor image is hardware generated. . .

Perhaps instead there is a hidden window DC containing the final image rect?

I guess you mean of the cursor and shadow?

as I said, I do not think that there is anything (window, system overhead, normal bitmaps) associated with a screen Cursor, by now the windows system must have an assembly code direct access to the video buffers, for the most effecient cursor drawing and moving, but I really do not know of any. . . .

The code above is about all I could come up with. . .  but I did not do a google search  for the cursor theory, and the current windows system cursor shadow emplementation. . . I did do a search here at EE in delphi , but I did not see anything to give info about this. . . .

on some drag opps there is a Cursor, that shows what is being dragged, I have done some code that changes the cursor during drag, if there is any "window" involved with this, I know nothing about it
0
 
LVL 3

Author Comment

by:SteveWaite
ID: 9980061
Thanks to you both for bringing something to the table.
0
 
LVL 34

Expert Comment

by:Slick812
ID: 9980385
I saw something about writting video drivers, and it said that  code is included in the video driver that gets some bit map Info for the cursor, but that after it get the bitmap info, all the system sends is the X and Y position of the cursor when it changes, and the video driver will do all of the Cursor drawing. . .
0

Featured Post

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!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Create Database on Android via Delphi dbExpress 3 143
PHP preg_replace code convert to Delphi 14 98
MS Access from Delphi 31 100
Firemonkey Listview item popup menu ? 1 72
A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…

734 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