




已阅读5页,还剩18页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
中国IT动力,最新最全的IT技术教程最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档 | 网通镜像 首 页|程序开发|操作系统|软件应用|图形图象|网络应用|精文荟萃|教育认证|硬件维护|未整理篇|站长教程 ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql 服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证 硬件维护 CPU 主板 硬盘 内存 显卡 显示器 键盘鼠标 声卡音箱 打印机 机箱电源 BIOS 网卡 C# Java Delphi 2005 当前位置: 程序开发 编程语言 Visual C+ MFC或CPP Palettes 作者:lemonade 时间:2001-10-05 09:57 出处:互联网 责编:chinaitpower 摘要:PalettesPalettesHave you ever written a Windows application that makes generous use of color only to find that the output looks crummy on 16-color and 256-color video adapters? Theres not a whole lot you can do about it when the adapter itself supports only 16 colors, but you can do plenty to improve output on 256-color devices. The key to better color output is MFCs CPalette class. Before we get into the specifics of CPalette, lets briefly review how color information is encoded in Windows and what Windows does with the color information that you provide.How Windows Uses ColorOne of the benefits of a device-independent output model is that you can specify the colors an application uses without regard for the physical characteristics of the output device. When you pass a color to the Windows GDI, you pass a COLORREF value containing 8 bits each for red, green, and blue. The RGB macro combines individual red, green, and blue values into a single COLORREF. The statementCOLORREF clr = RGB (255, 0, 255);creates a COLORREF value named clr that represents magentathe color you get when you mix equal parts red and blue. Conversely, you can extract 8-bit red, green, and blue values from a COLORREF value with the GetRValue, GetGValue, and GetBValue macros. A number of GDI functions, including those that create pens and brushes, accept COLORREF values.What the GDI does with the COLORREF values you pass it depends on several factors, including the color resolution of the video hardware and the context in which the colors are used. In the simplest and most desirable scenario, the video adapter is a 24-bits-per-pixel device and COLORREF values translate directly into colors on the screen. Video adapters that support 24-bit color, or true color, are becoming increasingly common, but Windows still runs on millions of PCs whose video adapters are limited to 4 or 8 bits per pixel. Typically, these devices are palletized devices, meaning that they support a wide range of colors but can display only a limited number of colors at one time. A standard VGA, for example, can display 262,144 different colors6 bits each for red, green, and blue. However, a VGA running at a resolution of 640 by 480 pixels can display only 16 different colors at once because each pixel is limited to 4 bits of color information in the video buffer. The more common case is a video adapter that can display more than 16.7 million colors but can display only 256 colors at once. The 256 colors that can be displayed are determined from RGB values that are programmed into the adapters hardware palette.Windows handles palletized devices by preprogramming a standard selection of colors into the adapters hardware palette. A 256-color adapter is preprogrammed with the 20 so-called static colors shown in the following table. The four colors marked with asterisks are subject to change at the operating systems behest, so you shouldnt write code that depends on their presence.Static Palette ColorsColorRGBColorRGBBlack000Cream*255251240Dark red12800Intermediate gray*160160164Dark green01280Medium gray128128128Dark yellow1281280Red25500Dark blue00128Green02550Dark magenta1280128Yellow2552550Dark cyan0128128Blue00255Light gray192192192Magenta2550255Money green*192220192Cyan0255255Sky blue*166202240White255255255*Denotes default colors that are subject to change.When you draw on a palletized device, the GDI maps each COLORREF value to the nearest static color using a simple color-matching algorithm. If you pass a COLORREF value to a function that creates a pen, Windows assigns the pen the nearest static color. If you pass a COLOREF value to a function that creates a brush and there isnt a matching static color, Windows dithers the brush color using static colors. Because the static colors include a diverse (if limited) assortment of hues, Windows can do a reasonable job of simulating any COLORREF value you throw at it. A picture painted with 100 different shades of red wont come out very well because Windows will simulate all 100 shades with just two reds. But youre guaranteed that red wont undergo a wholesale transformation to blue, green, or some other color, because the static colors are always there and are always available.For many applications, the primitive form of color mapping that Windows performs using static colors is good enough. But for others, accurate color output is a foremost concern and 20 colors just wont get the job done. In a single-tasking environment such as MS-DOS, a program running on a 256-color adapter can program the hardware palette itself and use any 256 colors it wants. In Windows, applications cant be allowed to program the hardware palette directly because the video adapter is a shared resource. So how do you take advantage of the 236 colors left unused in a 256-color adapter after Windows adds the 20 static colors? The answer lies in a GDI object known as a logical palette.Logical Palettes and the CPalette ClassA logical palette is a table of RGB color values that tells Windows what colors an application would like to display. A related term, system palette, refers to the adapters hardware color palette. At an applications request, the palette manager built into Windows will transfer the colors in a logical palette to unused entries in the system palettea process known as realizing a paletteso that the application can take full advantage of the video adapters color capabilities. With the help of a logical palette, an application running on a 256-color video adapter can use the 20 static colors plus an additional 236 colors of its choosing. And because all requests to realize a palette go through the GDI, the palette manager can serve as an arbitrator between programs with conflicting color needs and thus ensure that the system palette is used cooperatively.What happens if two or more applications realize logical palettes and the sum total of the colors they request is more than the 236 additional colors a 256-color video adapter can handle? The palette manager assigns color priorities based on each windows position in the z-order. The window at the top of the z-order receives top priority, the window thats second gets the next highest priority, and so on. If the foreground window realizes a palette of 200 colors, all 200 get mapped to the system palette. If a background window then realizes a palette of, say, 100 colors, 36 get programmed into the unused slots remaining in the system palette and 64 get mapped to the nearest matching colors. Thats the worst case. Unless directed to do otherwise, the palette manager avoids duplicating entries in the system palette. Therefore, if 4 of the foreground windows colors and 10 of the background windows colors match static colors, and if another 10 of the background windows colors match nonstatic colors in the foreground window, the background window ends up getting 60 exact matches in the system palette.You can see the palette manager at work by switching Windows to 256-color mode, launching two instances of the Windows Paint applet, loading a different 256-color bitmap in each, and clicking back and forth between the two. The bitmap in the foreground will always look the best because it gets first crack at the system palette. The bitmap in the background gets whats left over. If both bitmaps use similar colors, the background image wont look too bad. But if the colors are vastly differentfor example, if bitmap A contains lots of bright, vibrant colors whereas bitmap B uses primarily earth tonesthe image in the background window might be so color-corrupted that its hardly recognizable. The palette managers role in the process is to try to satisfy the needs of both programs. When those needs conflict, the foreground window receives priority over all others so that the application the user is working with looks the best.Creating a Logical PaletteWriting an application that uses a logical palette isnt difficult. In MFC, logical palettes are represented by the CPalette class and are created and initialized with CPalette member functions. Once a logical palette is created, it can be selected into a device context and realized with CDC member functions.CPalette provides two member functions for palette creation. CreatePalette creates a custom palette from RGB values you specify; CreateHalftonePalette creates a halftone palette containing a generic and fairly uniform distribution of colors. Custom palettes give better results when an image contains few distinctly different colors but many subtle variations in tone. Halftone palettes work well for images containing a wide range of colors. The statementsCPalette palette;palette.CreateHalftonePalette (pDC);create a halftone palette tailored to the device context pointed to by pDC. If the device context corresponds to a 256-color device, the halftone palette will also contain 256 colors. Twenty of the colors will match the static colors; the other 236 will expand the selection of colors available by adding subtler shades of red, green, and blue and mixtures of these primary colors. Specifically, a 256-color halftone palette includes all the colors in a 6-by-6-by-6-color cube (colors composed of six shades each of red, green, and blue), plus an array of grays for gray-scale imaging and other colors handpicked by the GDI. Passing a NULL DC handle to CreateHalftonePalette creates a 256-color halftone palette independent of the characteristics of the output device. However, because CPalette:CreateHalftonePalette mistakenly asserts in debug builds if passed a NULL DC handle, you must drop down to the Windows API to take advantage of this feature:CPalette palette;palette.Attach (:CreateHalftonePalette (NULL);:CreateHalftonePalette is the API equivalent of CPalette:CreateHalftonePalette.Creating a custom palette is a little more work because before you call CreatePalette, you must initialize a LOGPALETTE structure with entries describing the palettes colors. LOGPALETTE is defined as follows.typedef struct tagLOGPALETTE WORD palVersion; WORD palNumEntries; PALETTEENTRY palPalEntry1; LOGPALETTE;palVersion specifies the LOGPALETTE version number; in all current releases of Windows, it should be set to 0x300. palNumEntries specifies the number of colors in the palette. palPalEntry is an array of PALETTEENTRY structures defining the colors. The number of elements in the array should equal the value of palNumEntries. PALETTEENTRY is defined like this:typedef struct tagPALETTEENTRY BYTE peRed; BYTE peGreen; BYTE peBlue; BYTE peFlags; PALETTEENTRY;peRed, peGreen, and peBlue specify a colors 8-bit RGB components. peFlags contains zero or more bit flags describing the type of palette entry. It can be set to any of the values shown here, or to 0 to create a normal palette entry:FlagDescriptionPC_EXPLICITCreates a palette entry that specifies an index into the system palette rather than an RGB color. Used by programs that display the contents of the system palette.PC_NOCOLLAPSECreates a palette entry thats mapped to an unused entry in the system palette even if theres already an entry for that color. Used to ensure the uniqueness of palette colors.PC_RESERVEDCreates a palette entry thats private to this application. When a PC_RESERVED entry is added to the system palette, it isnt mapped to colors in other logical palettes even if the colors match. Used by programs that perform palette animation.Most of the time, peFlags is simply set to 0. Well discuss one use for the PC_RESERVED flag later in this chapter, in the section on palette animation.The PALETTEENTRY array in the LOGPALETTE structure is declared with just one array element because Windows has no way of anticipating how many colors a logical palette will contain. As a result, you cant just declare an instance of LOGPALETTE on the stack and fill it in; instead, you have to allocate memory for it based on the number of PALETTEENTRY structures it contains. The following code allocates a full LOGPALETTE structure on the stack and then creates a logical palette containing 32 shades of red:struct LOGPALETTE lp; PALETTEENTRY ape31; pal;LOGPALETTE* pLP = (LOGPALETTE*) &pal;pLP-palVersion = 0x300;pLP-palNumEntries = 32;for (int i=0; ipalPalEntryi.peRed = i * 8; pLP-palPalEntryi.peGreen = 0; pLP-palPalEntryi.peBlue = 0; pLP-palPalEntryi.peFlags = 0;CPalette palette;palette.CreatePalette (pLP);Like other GDI objects, logical palettes should be deleted when theyre no longer needed. A logical palette represented by a CPalette object is automatically deleted when the corresponding CPalette object is deleted or goes out of scope.How many entries can a logical palette contain? As many as you want it to. Of course, the number of colors that can be mapped directly to the system palette is limited by the capabilities of the video adapter. If you realize a palette containing 1,024 colors on a 256-color output device, only the first 236 will be mapped directly; the remaining colors will be matched as closely as possible to colors already in the system palette. When you use logical palettes (especially large ones), its helpful to arrange the colors in order of importance, where palPalEntry0 defines the most important color, palPalEntry1 defines the next most important color, and so on. The palette manager maps palette colors in array order, so by putting important colors first, you increase the chances that those colors will be displayed in their native form. In general, you shouldnt make a logical palette any larger than it has to be. Large palettes take longer to realize, and the more palette colors a foreground window uses, the fewer colors the palette manager can make available to palette-aware windows lower in the z-order.After a palette is created, you can retrieve individual palette entries with CPalette:GetPaletteEntries or change them with CPalette:SetPaletteEntries. You can also resize a palette with CPalette:ResizePalette. If the palette is enlarged, the new palette entries initially contain all 0s.Realizing a Logical PaletteFor a logical palette to be effective, it must be selected into a device context and realized before any drawing takes place. The current logical palette is a device context attribute, just as the current pen and brush are device context attributes. (In case youre wondering, a device contexts default logical palette is a trivial one whose entries correspond to the static colors.) The following OnPaint handler selects the logical palette m_palette into a paint device context and realizes the palette before repainting the screen:void CMainWindow:OnPaint () CPaintDC dc (this); CPalette* pOldPalette = dc.SelectPalette (&m_palette, FALSE); dc.RealizePalette (); / Do some drawing. dc.SelectPalette (pOldPalette, FALSE);In this example, the pointer to the default palette is saved and used later to select m_palette out of the device context. Note that palettes are selected with CDC:SelectPalette instead of CDC:SelectObject. The second parameter is a BOOL value that, if TRUE, forces the palette to behave as if it were in the background even when the window that selected it is in the foreground. Background palettes can be handy in applications that use multiple palettes, but normally youll specify FALSE in calls to SelectPalette. CDC:RealizePalette realizes the palette thats currently selected into the device context by asking the palette manager to map colors from the logical palette to the system palette.Drawing with Palette ColorsOnce you create a palette, select it into a device context, and realize it, youre ready to start drawing. If you use CDC:BitBlt to display a bitmap, the realized colors are used automatically. But if youre drawing images with brushes or pens or using functions such as CDC:FloodFill that use neither a brush nor a pen directly but do accept COLORREF values, theres something else you must consider.The RGB macro is one of three macros that create COLORREF values. The others are PALETTEINDEX and PALETTERGB. Which of the three macros you use determines how the GDI treats the resultant COLORREF. When you draw with a COLORREF value created with the RGB macro, the GDI ignores the colors that were added to the system palette when the logical palette was realized and uses only the static colors. If you want the GDI to use all the palette colors, use the PALETTERGB macro. PALETTERGB creates a palette-relative color. The PALETTEINDEX macro creates a COLORREF value that specifies an index into a logical palette rather than an RGB color value. This value is called a palette-index color value. Its the fastest kind of color to draw with because it prevents the GDI from having to match RGB color values
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 端午节团课课件
- 端午节假期班会课件
- 宠物自由买卖协议书范本
- 竞赛宣传课件图片模板
- 竞聘自我介绍课件视频
- 工地施工欠款协议书范本
- 2025年湿法加工合成云母粉项目合作计划书
- 2025年表面改性金属材料项目合作计划书
- 心理健康课件短视频
- 空气课件教学课件
- 2024年第一季度医疗安全(不良)事件分析报告
- 北京市第三十九中学2024 -2025 学年上学期 七年级数学学科期中试卷
- 民法典物业管理培训
- 隔板理论获奖课件
- 项目施工副经理工作计划
- 2024至2030年中国医药销售外包(CSO)行业市场运行及投资策略咨询报告
- 高中文言文试题练习题(有答案)百度文库
- DB43-T 2142-2021学校食堂建设与食品安全管理规范
- 电厂锅炉大修施工方案
- 第八届全国职工职业技能大赛(焊工)辽宁选拔赛试题库-下(判断题)
- DL∕T 2447-2021 水电站防水淹厂房安全检查技术规程
评论
0/150
提交评论