Analysis on the realization of desktop elves

zhaozj2021-02-16  52

1. Software development

I want everyone to be familiar with the desktop elves, I don't want to have one? The author wanted to make a compilation, and its purpose is actually in order to get the beauty of the eyebrows, which leads out the purpose of I developed this software. If the reader has the same needs, please continue to look down, I will discuss this issue with you. Note The following sample code is described in Delphi.

2. Realization principle

In fact, the principle of desktop elves are very simple, mainly from the following steps:

1. Get the HDC of the desktop window.

The API is defined as follows:

GetDC function is used to obtain graphical device descriptors for the specified window

HDC Getdc

HWND HWND / / window handle

);

E.g:

Desktopdc: HDC; / / Define Graphical Device Description Table Handle of Desktop Window

Desktopdc: = getdc (0);

Or Desktopdc: = Getdc (getDesktopWindow ());

2. Create a memory bitmap and save the area to the desktop to save to the memory bitmap to restore the desktop when the drawing is completed. To this end, I define a function:

Procedure SaveBackground (BKCANVAS: Tcanvas; // Canvas Objects

SP_W: integer; // to save the width of the area

SP_H: integer; // to save the height of the area

Nx: integer; // To save the X coordinate of the area

Ny: integer; // to save the Y coordinate of the area

3. Transparently copy the animation object to the desktop plot area, the author used a GDIAPI function to make this feature.

Defined as follows:

Bool Transparentblt (HDC HDCDEST, / / ​​Target Graphics Device Description Table Handle

INT nxorigindest, // Drawing rectangular X coordinate

INT NYORIGINDEST, / / ​​Drawing Rectangular Y coordinate

INT nwidthdest, // Drawing rectangle width

INT HHEIGHTDEST, / / ​​Drawing Rectangle Height

HDC HDCSRC, // Source Graphics Device Description Table Handle

INT nxoriginsrc, // source drawing rectangular X coordinate

INT NYORIGINSRC, // Source Picture Rectangle Y coordinate

INT nwidthsrc, // source drawing rectangle width

INT NHEIGHTSRC, / / ​​Source Drawing Rectangle Height

UINT CRTRANSPARENT / / Set Transparent Color RGB (R, G, B)

);

note:

Windows NT: Requires 5.0 or above

Windows: Need Windows 98 or above

Other low versions are not supported.

This function is included in msimg32.dll.

The author defines a Tranbit function to dynamically call the TransparentBLT function, see Section III in specific definitions.

4. Copy the memory bitmap generated in the second step to the desktop. This frame of animation is displayed. Constantly loop 1-4, you can see continuous animation scenes.

3. Specific code

The following is a demo, debugging in Delphi5.0 Windows2000p. Create a form FORM1, put two image controls, named image1, image2, put a Timer control, name Timer1. Prepare two bitmaps, one put into image1, and put it into image2. The author used the bitmap of the following style (intercepted part), you can draw animation objects yourself, or borrow others, the author is a picture of Microsoft.

From the picture, you can see that many consecutive animation frames are included, and a picture completes an action, such as rotating a week, etc., each frame animation is exactly the same, in addition to the animated objects other pixels with a transparent color filler. Ok, you can see the specific code.

Unit unitmain;

Interface

Uses

Windows, Messages, Sysutils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, Stdctrls, MMSystem

Type

TFORM1 = Class (TFORM)

Timer1: TTIMER; // Explosion Timer

Image1: timage; // Store the picture of the explosion

Image2: Timage; // Picture of Storage Aircraft

Procedure Timer1Timer (Sender: TOBJECT);

Procedure formcreate (Sender: TOBJECT);

Procedure formclose (Sender: Tobject; VAR Action: Tclosection);

Private

{Private Declarations}

Desktopdc: HDC; // Description Table Scele

Stop: boolean; // Control loop variable

Expnum: integer; // Explosion Current number

Procedure evode (x: integer; y: integer); // explosion function

Procedure shipmove (x: integer; y: integer); // aircraft function

public

{Public declarations}

END;

VAR

FORM1: TFORM1;

IMPLEMENTATION

{$ R * .dfm}

/ / Save the desktop background

Procedure SaveBackground (Bkcanvas: Tcanvas;

SP_W: Integer;

SP_H: Integer;

NX: integer;

NY: integer;

VAR SC: Tcanvas;

Begin

SC: = Tcanvas.create;

Try

Sc.handle: = getdc (0);

BKCANVAS.COPYRECT (RECT (0, 0, SP_W, SP_H), SC, RECT (NX, NX SP_W, NY SP_H));

ReleaseDC (0, sc.handle);

Finally

Sc.free;

END;

END;

/ / Transparent copy image function

// Static call API function TRANSPARENTBLT

PROCEDURE TRANBIT (HDCDEST: HDC;

NxORIGINDEST: INTEGER;

NYORIGINDEST: INTEGER;

NWIDTHDEST: INTEGER;

HHEIGHTDEST: Integer;

HDCSRC: HDC;

NxORIGINSRC: Integer;

NYORIGINSRC: Integer;

NWIDTHSRC: INTEGER;

NHEIGHTSRC: Integer;

Crtransparent: uint);

VAR

LibHandle: hwnd; // Dynamic connection library handle

// Function prototype definition

Dllname: Procedure (HDCDest: HDC;

NxORIGINDEST: INTEGER;

NYORIGINDEST: INTEGER;

NWIDTHDEST: INTEGER;

HHEIGHTDEST: Integer;

HDCSRC: HDC;

NxORIGINSRC: Integer;

NYORIGINSRC: Integer;

NWIDTHSRC: INTEGER;

NHEIGHTSRC: Integer;

Crtransparent: uint; stdcall;

Begin

// The following is a routine business in the static call DLL

LibHandle: = loadingLibrary ('msimg32.dll');

IF libhandle <32 THEN

Begin

MessageBox (form1.handle, 'not found msimg32.dll', 'error', 0); exit;

END;

@Dllname: = getProcaddress (libhandle, 'transparentblt');

IF @ dllname = nil dam

Begin

MessageBox (Form1.Handle, 'Not found transparentblt in msimg32.dll', 'error', 0);

Freelibrary (librandle);

EXIT;

END;

Try

Transparentblt (HDCDest,

Nxorigindest,

NYORIGINDEST,

NWIDTHDEST,

Hheightdest,

HDCSRC,

Nxoriginsrc,

NYORIGINSRC,

NWIDTHSRC,

NHEIGHTSRC,

Crtransparent);

Finally

Freelibrary (librandle);

END;

END;

// Explosion function

// Explosion occurred at the X, Y coordinate of the desktop

Procedure TFORM1.EXPLODE (X: Integer; Y: Integer);

VAR

Bitmapb: Tbitmap; // Save the memory bitmap of the desktop specified area

W: integer; // a frame of one frame

H: INTEGER; // One frame of animation

i: integer;

J: integer;

Begin

Bitmapb: = Tbitmap.create;

Try

// Animation bitmap is 4 * 5 = 20 frames

W: = image1.width div 4; // calculate the width of each frame

H: = image1.height div 5; // calculate the height of each frame

// Initialization of the size of the map

Bitmapb.height: = h;

Bitmapb.width: = W;

/ / Save bitmaps in the specified area on your desktop

// Note that since the explosion is done in the same location, just save the explosion area once.

SaveBackground (Bitmapb.canvas, W, H, X, Y);

For i: = 0 to 4 do

Begin

For j: = 0 to 3 do

Begin

// Painted the corresponding frame on the desktop

Tranbit (Desktopdc, X, Y, W, H,

Image1.canvas.handle, J * W, I * H, W, H, RGB (208, 2, 178);

Sleep (20); // Show speed too fast, pause 20 milliseconds

// Restore the desktop

Bitblt (Desktopdc, X, Y, W, H, Bitmapb.canvas.Handle, 0, 0, SRCCopy);

END;

END;

Finally

Bitmapb.free;

END;

END;

// Aircraft flight function

// Parameter X, Y Specifies the destination of the aircraft flight

Procedure TFORM1.SHIPMOVE (X: Integer; Y: Integer);

VAR

W: integer;

H: integer;

i: integer;

J: integer;

K: integer;

l: integer;

Bitmapb: Tbitmap;

Begin

Randomize ();

Bitmapb: = Tbitmap.create;

Try

// Animation bitmap is 4 * 16-3 frame empty frame = 61 frames

W: = image2.width Div 4;

H: = image2.height Div 16;

Bitmapb.height: = h;

Bitmapb.width: = W;

K: = 0;

L: = 0;

While Not Stop DO

For i: = 0 to 15 DOFOR J: = 0 to 3 DO

Begin

IF (i = 15) and (i> 0) Then Break; // If you are empty frame, you will not draw it.

/ / Save bitmaps in the specified area on your desktop

// Note that since the flight is done in different locations, it is necessary to save the desktop area that will be drawn.

SaveBackground (Bitmapb.canvas, W, H, K, L);

Tranbit (Desktopdc, K, L, W, H, Image2.canvas.handle, J * W, I * H, W, H, RGB (208, 2, 178));

Sleep (10);

Bitblt (Desktopdc, K, L, W, H, Bitmapb.canvas.Handle, 0, 0, Srcopy);

IF (k

IF (l

if Timer1.enabled = False Then

IF (k> x-10) THEN / / stop flying in the destination, and detonate bombs

Begin

STOP: = True;

Timer1.enabled: = true; // bomb detonator

END;

END;

Finally

Bitmapb.free;

END;

END;

Procedure TFORM1.TIMER1TIMER (Sender: TOBJECT);

VAR

X, Y: integer;

Begin

IF (expnum = 0) THEN

Begin

Explode (Screen.Width Div 2-20, Screen.height Div 2-20);

SNDPLAYSOUND ('Explosion.wav', SND_NOSTOP);

ExpNum: = evnum 1;

end

Else if Expnum <10 THEN / / Explosion up to 10 times

Begin

// Generate a random position

x: = random (screen.width-100);

Y: = random (screen.height-100);

Explode (x, y); // explosion

SNDPLAYSOUND ('Explosion.wav', SND_NOSTOP); // Playing Explosion Sound

ExpNum: = evnum 1;

end

Else

Begin

STOP: = True;

Timer1.enabled: = FALSE;

CLOSE ();

END;

END;

Procedure TFORM1.FormCreate (Sender: TOBJECT);

Begin

Desktopdc: = getdc (0);

ExtractFilePath (Application.exename);

STOP: = false;

ExpNum: = 0;

// The aircraft starts to fly, the destination is the center of the screen

Self.shipmove (Screen.Width Div 2, Screen.height Div 2);

END;

Procedure TFORM1.FORMCLOSE (Sender: TpoBject; VAR Action: Tclosection);

Begin

STOP: = True;

Timer1.enabled: = FALSE;

ReleaseDC (0, Desktopdc);

END;

End.

4 Conclusion

As we hope, a aircraft flew into the desktop, slowly approaching the center of the screen, exploding when it arrived at the destination, and led a series of explosions. The procedure has completed our hopes smoothly, but there are still many shortcomings, and it is best to use DirectX to complete the animation, so that the effect may be better. If you are interested in it, send me E_mail to me, let us discuss. (E_mail: codehunter@sohu.com) 3/29/2001 4:18:19 PM

转载请注明原文地址:https://www.9cbs.com/read-28135.html

New Post(0)