Use VC to achieve Win95 / NT under the next picture fade out of the two skills Yue Chao Wei Zhang Qiufeng
For the fade out of the image, I believe that people who have played a game will not feel unfamiliar. It is often a transition of a game scene with another scene, giving people a light, fierce feeling, not like directly switching the scene image, so almost all games contain this feature. At the same time, if you join the fade out of your own application, you can play a pleasing role.
The principle of fade in the fade-in stunt processing in DOS is to directly control the palette of the system hardware device, so that the value of each color in the palette is gradually increased from 0 to the value of a given image, that is, fade in, In contrast, it achieved fade out. Therefore, fade in fade out is visible everywhere in the DOS game.
Today, due to the upgrade of the operating system, especially in the operating system of Win95 / NT, it is directly modified hardware. But not there is no way. The following is the two methods that I have passed and commissioned in the Win95 / NT environment and shared with everyone. In order to facilitate the comparison of the two methods, we handle these two methods to the command message processing function to add in the VIEW item of the main menu, and will be introduced one by one below.
The following debugging environment is VC 5.0, Win95 / NT, and we will filter some error handles for the simple and increased success rate, so we must use the image of the 256 color bitmap file for the BMP format.
First, use the API function setDibitStodevice () to achieve fade out
For this approach, this issue was published in Hubei Jianglong in the second issue of 98 years, but he was fully prepared using SDK. Based on his principles, this method is transplanted into the Win95 / NT environment via VC 5.0. Therefore, for the basic principles of using setDibitStodevice () to achieve fade out, please refer to the article No. 2 Jianglong in this article, which has a detailed description, here I don't have to say more. Here is the main steps to implement it with VC :
1. Start VC 5.0, select New from File, select the MFVApp Wizard (Exe) under Project to create a portfolio, named Slowshow, accept all other defaults from AppWizard.
2. Open the Menu framework in the resource, add the id code for the view value of the VIEW Value Price, CAPTION for UseSetDibitStodevice, then right-click on the mouse to select ClassWizard, select the SlowShowView processing class to use the default Set.
3, open SlowShowView.cpp, add #define step 150 at the beginning, then find the command message processing function
ONUSESETDIBITSTODEVICE () Join the code as follows:
Void CslowShowView :: OnViewuseSetDibitStodevice ()
{
// Todo: add your command handler code here
CSTRING FILENAME;
Cfiledialog DLG (True, Null, Null,
OFN_OVERWRITEPROMPT,
"BMP (*. BMP) | * .bmp ||", null;
IF (DLG.DOMODAL () == idok) // Displays file dialog
FileName = DLG.GetPathName (); // Get file name
File: // The above is selected to select the bitmap file dialog.
Cfile File (FileName, CFile :: ModeRead | CFILE :: Sharedenynne); File: // Open File DWORD BFOFFBITS;
DWORD BFSIZE;
Word bftype;
File.read (& bftype, sizeof (word)); // Get file type identifier 'bm'
File.read (& bfsize, sizeof (dword)); // Get the total length of the file
File.seek (2 * sizeof (word), cfile :: current); // file location
File.read (& bfoffbits, sizeof (dword)); // reads image data to the offset distance at the beginning of the file
LpbitmapInfo lpbitmapinfo;
INT size = bfoffbits- 14; // Total length of the palette information and BitmapInfo structure
LPbitmapInfo = (lpbitmapinfo) new byte [size]; / / is allocated to BitmapInfo structure
File.seek (14, cfile :: begin);
File.readhuge (lpbitmapinfo, size); // read palette information and BitmapInfo structure
LPVOID PBITSRC;
PBITSRC = (LPVOID) New char [bfsize-bfoffbits]; / / For image æ 分 é'
File.readhuge (PBITSRC, BFSIZE-BFOFFBITS); // Read image data
File.close (); file: // Turn the file
LPLOGPALETTE OLDLPAL;
Oldlpal = (LPLOGPALETTE) New Byte [SizeOf (LogPalette) 256 * SizeOf (PaletteEntry)];
File: // Assign space for the created logical palette
Oldlpal-> paRversion = 0x300; // Make the palette to grave
Oldlpal-> PALNUMENTRIES = 256; // Use eight color data
For (int i = 0; i <256; i )
{
Oldlpal-> palpalent [i] .pled =
LPbitmapInfo-> Bmicolors [i] .rgbred;
Oldlpal-> Palpalent [i] .pegreen =
Lpbitmapinfo-> Bmicolors [i] .rgbgreen
Oldlpal-> Palpalent [i] .peblue =
LPbitmapInfo-> Bmicolors [i] .rgbblue;
Oldlpal-> Palpalent [i] .peflags = 0;
File: // The above is stored in the newly created logical palette Oldlpal for the palette information in the file.
}
CDC * PDC;
PDC = GetDC ();
CGDIObject * Pold = PDC-> SelectStockObject (Black_brush);
CRECT ARRY;
GetClientRect (& arry);
PDC-> FillRect (Arry, NULL);
ValidateRect (& arry); // Show the window client area and makes the customer area invalid
LPLOGPALETTTE NEWLPAL;
Newlpal = (LPLOGPALETTE) New Byte [SizeOf (Logpalette) (256 * sizeof (PaletteEntry)];
Newlpal-> paalversion = 0x300;
Newlpal-> PALNUMENTRIES = 256;
File: // Create a new logical palette for the saved palette information for (int J = 0; j <= 1; J )
{
For (int m = 0; M <= step; m )
{
IF (j == 0) // gradually
For (int i = 0; i <256; i )
{
Newlpal-> palpalent [i] .pered =
Oldlpal-> Palpalent [i] .pered * m / step;
Newlpal-> Palpalent [i] .pegreen =
Oldlpal-> Palpalent [i] .pegreen * m / step;
Newlpal-> Palpalent [i] .peblue =
Oldlpal-> Palpalent [i] .peblue * m / step;
Newlpal-> palpalent [i] .peflags = 0;
File: // Change the transfer board information and store the new logical palette
}
Else file: // Fade out
For (int i = 0; i <256; i )
{
Newlpal-> palpalent [i] .pered =
Oldlpal-> Palpalent [i] .pered * (step-m) / step;
Newlpal-> Palpalent [i] .pegreen =
Oldlpal-> Palpalent [i] .pegreen * (step-m) / step;
Newlpal-> Palpalent [i] .peblue =
Oldlpal-> Palpalent [i] .peblue * (step-m) / step;
Newlpal-> palpalent [i] .peflags = 0; // change the transfer board information and store the new logical palette
}
CPALETTE * HPAL = New CPALETTE;
CPALETTE * HOLDPAL;
HPAL-> CREATEPALETTE (NewLpal);
Holdpal = PDC-> SELECTPALETTTE (HPAL, FALSE);
PDC-> RealizePalette ();
File: // Creating a palette processing class, selecting it in the current device and implemented
:: setDibitStodevice (PDC-> M_HDC,
(arry.right-lpbitmapinfo-> bmiheader.biwidth) / 2,
(arry.bottom-lpbitmapinfo-> bmiheader.biheight) / 2, //
LPbitmapInfo-> Bmiheader.biwidth,
LPbitmapInfo-> Bmiheader.biheight,
0,0,0, lpbitmapinfo-> bmiheader.biheight,
PBITSRC, LPBITMAPINFO, DIB_RGB_COLORS;
File: // Use the API global function setDibitStodevice () display image data in the current window
PDC-> SelectPalette (Holdpal, 0);
Delete hpal; // In order not to affect the system palette, you should create a palette processing class to delete it.
}
}
Delete PBITSRC; // Release image data in memory
Delete lpbitmapinfo; // Release BitmapInfo structure in memory
Delete newlpal; // Release Create a palette in memory
Delete oldlpal; // Release Create a palette in memory
PDC-> SELECTOBJECT (POLD); // Restore Brush
ReleaseDC (PDC); // Release DC
}
Note: In the Win95 / NT environment, setDibitStodevice () The last parameter unit fucoloruse can be set to dib_rgb_colors, the condition is that the color properties of the Win95 / NT system must be 256 colors, more than or lower than the fade out of the fade out. Can pass on the desktop Click Right click, select the properties bar to change the system color value. At the same time, if you are using the setDibitStodevice () display image in the WINDOWS NT, it is a complex process. Windows NT first creates a DIB to the server side to create a DDB before you can output the data in the DDB to the video memory, and when DIB exceeds 56K, the system also assigns buffers, full display,! This thing is a guy that is expensive and inches, and it is still not good. In the face of such demanding requirements, we have to find another law. After some pain, we finally found it in the multimedia part of VC until now, it is excited now, and it is not required to have a simple, and the effect is absolutely first-class DrawDIB function group. Use it is that you must include vfw.h and vfw32.lib library files in your MFC class library. Below will be the specific steps of making, you have to look at it carefully! Second, using the DrawDib function group to implement the fade out of the bitmap
1. Introduction to DrawDIB Function Group
Microsoft provides a set of high-performance function groups that draw DIB bitmaps in MultiMedia in its Win32 SDK for a bitmap DIB with the device. They support the DIB of 8, 16-bit, 24-bit, 32-bit image depth. It can stretch and shake the image, and also support the decompression, data streams, and more display adapters of the image. It only supports color information table format to DIB_RGB_COLORS format image does not support dib_pal_colors and dib_pal_indices, only support SRCCOPY grating mode.
2, DrawDIB function group general operation process
2. 1. By initializing the DrawDib function group by using the DrawDibopen () function. It will get a very important DrawDib device scenario necessary for all DrawDib functions, so it should be the initial operation.
2.2, through DrawDibbegin () initialize the dedicated DrawDib device scene, easy DrawDibDraw (), if it is not used to initialize, you can also use DrawDibDraw () to perform the initialization of DrawDIB device scenes.
2.3, the image is displayed by DrawDibdraw (), which may be single, or an image sequence.
2.4, release the DrawDib device scene through DrawDibClose (), so it should be the last DrawDIB operation.
3. Use DrawDIB to achieve the principle of palette animation
This principle is mainly by changing the RGB color value in the PaletteEntry queue, and is provided to a series of DrawDIB drawing functions, ie dynamic changes the color value of each RGB in the original image palette. The key parameter LPPE is A struct pointer for the LPPaletteentry queue containing a new color value, LPBI is a structural pointer for LPBitMapInfoHeader (this structure is included in the BitmapInfo structure, LPBITS is the address of the image data. The specific implementation flow chart is as follows:
HDC = Getdc (hwnd);
HDD = DRAWDIBOPEN ();
DrawDibbegin (HDD, ..., DDF_anImate); // Sign DDF_Animate means that allows the chase palette to create a LPPALETTEENTRY queue pointer LPPE, and assign space;
For (i = 0; i <= 255; i )
{LPPE color queue`s RGB value = RGB value in the image file * I / Step;
DrawDibRealize (HDD, HDC, FBACKGRAUND);
DrawDibchangePalette (HDD, ISTART, ILEN, LPPE);
DrawDibdraw (HDD, HDC, ..., LPBI, LPBITS, ...., DDF_SAME_DRAW | DDF_SAME_HDC);
File: // wherein the flag DDF_SAME_DRAW indicates the BitMapInfoHeader structure address of the displayed image.
File: / / The size of the source rectangle and the destination rectangle does not change, DDF_SAME_HDC indicates that the DC handle is constant.
File: // and does not use the bitmap sequence, only single bitmap
Release the allocated image memory;
DrawDibClose (HDD);
ReleaseDC (HWND, HDC);
}
The various function parameters used in it are expressed as follows:
Bool DrawDibbegin (HDrawDib HDD, File: // Dedicated DrawDIB Device Scene by DrawDibopen ()
HDC HDC, // Current Equipment Handle
INT DXDEST, FILE: / / Target Rectangular Width
INT DYDEST, FILE: / / Target Rectangular Height
LPbitMapInfoHeader LPBI, File: // Pointing the BitmapInfoHeader structure pointer to the image you need to display
INT DXSRC, File: // Need to display the image width
Int dysrc, file: // Need to display the image height
UINT WFLAGS FILE: / / Initialize the sign of the bitmap, here should be set to DDF_animate
);
Uint DrawDibRealize (HDRawdib HDD, //
HDC HDC, File: //
Bool FBACKGROUND FILE: / / This saving palette is selected in the False, and if it is TURE, it is selected to enter the background.
);
Bool DrawDibchangePalette (HDRawdib HDD, File: //
INT iStart, // Create a start value of the number of Paletteentry color queues, this is 0
INT Ilen, // Create a maximum number of columns number of PaletteEntry color queues, this is 255
LPPALETTEENTRY LPPE FILE: // A structural pointer for a PaletteEntry queue containing new color values
);
Bool DrawDibdraw (HDRawdib HDD, File: //
HDC HDC, File: //
INT XDST, File: // Target Polk Dot X Coordinate
INT YDST, FILE: / / Target Dot Y Coordinate
INT DXDST, FILE: / / Target Rectangular Width
INT DYDST, FILE: / / Target Rectangular Height
LPbitMapInfoHeader lpbi, // Pointing the BitmapInfoHeader structure pointer to the image that needs to be displayed
LPVOID LPBITS, FILE: / / is the address of the image data that needs to be displayed
INT xsrc, // Source Rectangular Polk Dot X Coordinate INT YSRC, File: // Source Rectangular Polk Dots Y Coordinate
INT dxsrc, / / need to display image width
Int dysrc, file: // Need to display the image height
UINT WFLAGS // Operate the flag of the bitmap, this should be set DDF_SAME_DRAW | DDF_SAME_HDC
);
The above is just a profile to use the DrawDib function group, to get a more detailed description, see the MFC reference code.
4, the specific steps to achieve fade out:
4.1, using the project Slowshow above, open stdafx.h to join the code as follows:
#include
#pragme Comment (Lib, "VFW32.LIB")
4.2, open the MENU dialog, in the view number of the VIEW Vegetable Price Single Add to IDC_USE_DRAWDIBDRAW, CAPTION is UsedRawDibdrawDibdraw, then right-click Simple UsedRawDibdraw, menu item Select ClassWizard, select the SlowShowVIEW handling class Use the default settings .
4.3, open the SlowShowView.cpp file, find the onusedrawdibdraw () command message handler to join the code as follows:
Void cslowshowview :: OnViewusedrawDibdraw ()
{
// Todo: add your command handler code here
CSTRING FILENAME;
Cfiledialog DLG (True, Null, Null,
OFN_OVERWRITEPROMPT,
"BMP (*. BMP) | * .bmp ||", null;
IF (DLG.Domodal () == iDok) file: // Displays file dialog
FileName = DLG.GetPathName (); // Get file name
File: // The above is selected to select the bitmap file dialog.
Cfile File (FileName, CFile :: ModeRead | CFILE :: Sharedenynne); // Open file
Word bftype;
DWORD BFSIZE;
File.read (& bftype, sizeof (word)); // Get file type identifier 'bm'
File.read (& bfsize, sizeof (dword)); // Get the total length of the file
DWORD BFOFFBITS;
File.seek (2 * sizeof (word), cfile :: current); // file location
File.read (& bfoffbits, sizeof (dword)); // reads image data to the offset distance at the beginning of the file
LpbitmapInfo lpbitmapinfo;
INT size = bfoffbits- 14; // Total length of the palette information and BitmapInfo structure
LPbitmapInfo = (lpbitmapinfo) new byte [size]; / / is allocated to BitmapInfo structure
File.seek (14, cfile :: begin);
File.readhuge (lpbitmapinfo, size); // read palette information and BitmapInfo structure
LPVOID PBITSRC;
PBITSRC = (LPVOID) New char [bfsize-bfoffbits]; / / For image æ 分 é'
File.readhuge (PBITSRC, BFSIZE-BFOFFBITS); // Read image data
File.close (); file: // Turn the file
LPLOGPALETTE OLDLPAL;
Oldlpal = (LPLOGPALETTE) New Byte [SizeOf (LogPalette) 256 * SizeOf (PaletteEntry)]; file: // Assign space for the created logical palette
Oldlpal-> paRversion = 0x300; // Make the palette to grave
Oldlpal-> PALNUMENTRIES = 256; // Use eight color data
For (int i = 0; i <256; i )
{
Oldlpal-> palpalent [i] .pled =
LPbitmapInfo-> Bmicolors [i] .rgbred;
Oldlpal-> Palpalent [i] .pegreen =
Lpbitmapinfo-> Bmicolors [i] .rgbgreen
Oldlpal-> Palpalent [i] .peblue =
LPbitmapInfo-> Bmicolors [i] .rgbblue;
Oldlpal-> Palpalent [i] .peflags = 0;
File: // The above is stored in the newly created logical palette Oldlpal for the palette information in the file.
}
CDC * PDC;
PDC = GetDC ();
CGDIObject * Pold = PDC-> SelectStockObject (Black_brush);
CRECT ARRY;
GetClientRect (& arry);
PDC-> FillRect (Arry, NULL);
ValidateRect (& arry); // Show the window client area and makes the customer area invalid
HDrawDIB HDD = :: drawdibopen ();
File: // Initialize the DrawDIB function group and get the HDRAWDIB handle must be of this DrawDIB function group.
:: DrawDibbegin (HDD, PDC-> M_HDC,
LPbitmapInfo-> Bmiheader.biwidth,
LPbitmapInfo-> Bmiheader.biheight,
& lpbitmapinfo-> Bmiheader,
LPbitmapInfo-> Bmiheader.biwidth,
LPbitmapInfo-> Bmiheader.biheight,
DDF_animate);
File: / / Prepare the information required for the DrawDibDraw () function
File: // The flag bit here must be set to DDF_animate, which indicates that the information change of the palette in the DrawDIB device scene can be changed.
LPPALETEENTRY Entry;
Entry = (lppaletteentry) New byte [256 * sizeof (PaletteEntry)];
File: // Create a PaletteEntry structure pointer that can be changed
For (int J = 0; j <= 1; j )
{
For (int m = 0; M <= step; m )
{
IF (j == 0) // fade into
For (int i = 0; i <256; i )
{
Entry [i] .pered = Oldlpal-> Palpalent [i] .pered * m / step;
Entry [i] .pegreen = Oldlpal-> Palpalent [i] .pegreen * m / step;
Entry [i] .peblue = oldlpal-> palpalentry [i] .peblue * m / step;
Entry [i] .peflags = 0;
File: // Change the palette information and store the newly created PaletteEntry pointer}
Else file: // Fade out
For (int i = 0; i <256; i )
{
Entry [i] .pered = oldlpal-> palpalent [i] .pered * (step-m) / step;
Entry [i] .pegreen = oldlpal-> palpalent [i] .pegreen * (step-m) / step;
Entry [i] .peblue = oldlpal-> palpalent [i] .peblue * (step-m) / step;
Entry [i] .peflags = 0;
File: // Change the palette information and store the newly created PaletteEntry pointer
}
:: DrawDibRealize (HDD, PDC-> M_HDC, FALSE);
:: DrawDibchangePalette (HDD, 0, 255, Entry);
:: DrawDibdraw (HDD, PDC-> M_HDC,
(arry.right-lpbitmapinfo-> bmiheader.biwidth) / 2,
(arry.bottom-lpbitmapinfo-> bmiheader.biheight) / 2,
File: // Case
LPbitmapInfo-> Bmiheader.biwidth,
LPbitmapInfo-> Bmiheader.biheight,
& lpbitmapinfo-> Bmiheader,
PBITSRC,
0, 0,
LPbitmapInfo-> Bmiheader.biwidth,
LPbitmapInfo-> Bmiheader.biheight,
DDF_SAME_DRAW | DDF_SAME_HDC);
File: // Display image data according to the current status in the DrawDIB device scene
File: // wherein the flag DDF_SAME_DRAW indicates the BitMapInfoHeader structure address of the displayed image.
File: / / The size of the source rectangle and the destination rectangle does not change, DDF_SAME_HDC indicates that the DC handle is constant.
File: // and does not use the bitmap sequence, only single bitmap
}
}
:: DrawDibClose (HDD); // Clear DrawDIB device scene, release the DrawDib handle
PDC-> SelectObject (POLD); // Restore Original Painting Brush
Delete PBITSRC; // Release image data in memory
Delete lpbitmapinfo; // Release BitmapInfo structure in memory
Delete oldlpal; // Release Create a palette in memory
ReleaseDC (PDC); // Release DC
}
At this point, the two methods have been introduced, and the compilation is running. how about it? Is it a professional level. It's hard to confuse, DrawDIB performance is great, and the speed is much more faster than setDibitStodevice (). The requirements for the system are also quite casual, should have a display adaptive automatic jitter function, so it can smoothly complete the fade of the task regardless of the system color, and the effect does not have a great impact, do not believe it quickly A try.