Programming Windows程式开发设计指南 第14章 点阵图和Bitblt

14. 点阵图和Bitblt 织梦内容管理系统

  本文来自织梦

点阵图是一个二维的位元阵列,它与图像的图素一一对应。当现实世界的图像被扫描成点阵图以後,图像被分割成网格,并以图素作为取样单位。在点阵图中的每个图素值指明了一个单位网格内图像的平均颜色。单色点阵图每个图素只需要一位元,灰色或彩色点阵图中每个图素需要多个位元。

copyright dedecms

点阵图代表了Windows程式内储存图像资讯的两种方法之一。储存图像资讯的另一种形式是metafile,我将在第十八章讨论。Metafile储存的就是对图像如何生成的描述,而不是将图像以数位化的图示代表。 织梦好,好织梦

以後我将更详细地讨论,Microsoft Windows 3.0定义了一种称为装置无关点阵图(DIBdevice-independent bitmap)。我将在下一章讨论DIB。本章主要讨论GDI点阵图物件,这是一种在Windows中比DIB更早支援的点阵图形资料。如同本章大量的范例程式所说明的,这种比DIB点阵图更早被Windows支援的图形格式仍然有其利用价值。

织梦好,好织梦

点阵图入门
 

dedecms.com

点阵图和metafile在电脑图形处理世界中都占有一席之地。点阵图经常用来表示来自真实世界的复杂图像,例如数位化的照片或者视讯图像。Metafile更适合於描述由人或者机器产生的图像,比如建筑蓝图。点阵图和metafile都能存於记忆体或作为档案存於磁片上,并且都能通过剪贴簿在Windows应用程式之间传输。

本文来自织梦

点阵图和metafile的区别在於位元映射图像和向量图像之间的差别。位元映射图像用离散的图素来处理输出设备;而向量图像用笛卡尔座标系统来处理输出设备,其线条和填充物件能被个别拖移。现在大多数的图像输出设备是位元映射设备,这包括视讯显示、点阵印表机、雷射印表机和喷墨印表机。而笔式绘图机则是向量输出设备。 织梦好,好织梦

点阵图有两个主要的缺点。第一个问题是容易受装置依赖性的影响。最明显的就是对颜色的依赖性,在单色设备上显示彩色点阵图的效果总是不能令人满意的。另一个问题是点阵图经常暗示了特定的显示解析度和图像纵横比。尽管点阵图能被拉伸和缩小,但是这样的处理通常包括复制或删除图素的某些行和列,这样会破坏图像的大小。而metafile在放大缩小後仍然能保持图形样貌不受破坏。

内容来自dedecms

点阵图的第二个缺点是需要很大的储存空间。例如,描述完整的640×480图素,16色的视频图形阵列(VGAVideo Graphics Array)萤幕的一幅点阵图需要大於150 KB的空间;一幅1024×768,并且每个图素为24位元颜色的图像则需要大於2 MB的空间。Metafile需要通常比点阵图来得少的空间。点阵图的储存空间由图像的大小及其包含的颜色决定,而metafile的储存空间则由图像的复杂程度和它所包含的GDI指令数决定。 本文来自织梦

然而,点阵图优於metafile之处在於速度。将点阵图复制给视讯显示器通常比复制基本图形档案的速度要快。最近几年,压缩技术允许压缩点阵图的档案大小,以使它能有效地通过电话线传输并广泛地用於Internet的网页上。

dedecms.com

点阵图的来源
 

本文来自织梦

点阵图可以手工建立,例如,使用Windows 98附带的「小画家」程式。一些人宁愿使用位元映射绘图软体也不使用向量绘图软体。他们假定:图形最後一定会复杂到不能用线条跟填充区域来表达。 织梦内容管理系统

点阵图图像也能由电脑程式计算生成。尽管大多数计算生成的图像能按向量图形metafile储存,但是高清晰度的画面或碎形图样通常还是需要点阵图。 copyright dedecms

现在,点阵图通常用於描述真实世界的图像,并且有许多硬体设备能让您把现实世界的图像输入到电脑。这类硬体通常使用 电荷耦合装置 (CCDcharge-coupled device),这种装置接触到光就释放电荷。有时这些CCD单元能排列成一组,一个图素对应一个CCD;为节约开支,只用一行CCD扫描图像。

copyright dedecms

在这些电脑CCD设备中, 扫描器 是最古老的。它用一行CCD沿著纸上图像(例如照片)的表面扫描。CCD根据光的强度产生电荷。类比数位转换器(ADCAnalog-to-digital converters)把电荷转换为数位讯号,然後排列成点阵图。 本文来自织梦

携带型摄像机也利用CCD单元组来捕捉影像。通常,这些影像是记录到录影带上。不过,这些视讯输出也能直接进入 影像捕捉器 (frame grabber),该装置能把类比视讯信号转换为一组图素值。这些影像捕捉器与任何相容的视讯信号来源都能同时使用,例如VCR、光碟、DVD播放机或有线电视解码器。 织梦内容管理系统

最近,数位照相机的价位对於家庭使用者来说开始变得负担得起了。它看起来很像普通照相机。但是数位照相机不使用底片,而用一组CCD来拦截图像,并且在ADC内部把数位图像直接储存在照相机内的记忆体中。通常,数位照相机与电脑的介面要通过序列埠。

织梦内容管理系统

点阵图尺寸
  织梦内容管理系统

点阵图呈矩形,并有空间尺寸,图像的高度和宽度都以图素为单位。例如,此网格可描述一个很小的点阵图:宽度为9图素,高度为6图素,或者更简单地计为9×6织梦内容管理系统


  本文来自织梦

dedecms.com

习惯上,点阵图的速记尺寸是先给出宽度。点阵图总数为9×6或者54图素。我将经常使用符号cxcy来表示点阵图的宽度和高度。c表示计数,因此cxcy是沿著x轴(水平)和y轴(垂直)的图素数。

copyright dedecms

我们能根据xy座标来描述点阵图上具体的图素。一般(并不都是这样),在网格内计算图素时,点阵图开始於图像的左上角。这样,在此点阵图右下角的图素座标就是(8, 5)。因为从0开始计数,所以此值比图像的宽度和高度小1织梦内容管理系统

点阵图的空间尺寸通常也指定了解析度,但这是一个有争议的词。我们说我们的视讯显示有640×480的解析度,但是雷射印表机的解析度只有每英寸300点。我喜欢用後一种情况中解析度的意思作为每单位图素的数量。点阵图在这种意义上的解析度指的是点阵图在特定测量单位中的图素数。不管怎样,当我使用解析度这个词语时,其定义的内容应该是明确的。

织梦好,好织梦

点阵图是矩形的,但是电脑记忆体空间是线性的。通常(但并不都是这样)点阵图按列储存在记忆体中,且从顶列图素开始到底列结束。(DIB是此规则的一个主要例外)。每一列,图素都从最左边的图素开始依次向右储存。这就好像储存几列文字中的各个字元。

dedecms.com

颜色和点阵图
  copyright dedecms

除空间尺寸以外,点阵图还有颜色尺寸。这里指的是每个图素所需要的位元数,有时也称为点阵图的 颜色深度 (color depth)、 位元数 (bit-count)或 位元/图素 (bppbits per pixel)数。点阵图中的每个图素都有相同数量的颜色位元。 织梦好,好织梦

每图素1位元的点阵图称为 二阶 (bilevel)、 二色 (bicolor)或者 单色 (monochrome)点阵图。每图素可以是010表示黑色,1可以表示白色,但并不总是这样。对於其他颜色,一个图素就需要有多个位元。可能的颜色值等於2位元数值。用2位元可以得到4种颜色,用4位元可以得16种颜色,8位元可得到256种颜色,16位元可得到65,536种颜色,而24位元可得到16,777,216种颜色。 织梦内容管理系统

如何将颜色位元的组合与人们所熟悉的颜色相对应是目前处理点阵图时经常碰到(而且常常是灾难)的问题。

织梦内容管理系统

实际的设备
 

织梦内容管理系统

点阵图可按其颜色位元数来分类;在Windows的发展过程中,不同的点阵图颜色格式取决於常用视讯显示卡的功能。实际上,我们可把视讯显示记忆体看作是一幅巨大的点阵图-我们从显示器上就可以看见。 内容来自dedecms

Windows 1.0多数采用的显示卡是IBM的彩色图像适配器(CGAColor Graphics Adapter)和单色图形卡(HGCHercules Graphics Card)。HGC是单色设备,而CGA也只能在Windows以单色图形模式使用。单色点阵图现在还很常用(例如,滑鼠的游标一般为单色),而且单色点阵图除显示图像以外还有其他用途。

内容来自dedecms

随著增强型图形显示卡(EGAEnhanced Graphics Adapter)的出现,Windows使用者开始接触16色的图形。每个图素需要4个颜色位元。(实际上,EGA比这里所讲的更复杂,它还包括一个64种颜色的调色盘,应用程式可以从中选择任意的16种颜色,但Windows只按较简单的方法使用EGA)。在EGA中使用的16种颜色是黑、白、两种灰色、高低亮度的红色、绿和蓝(三原色)、青色(蓝和绿组合的颜色)。现在认为这16种颜色是Windows的最低颜色标准。同样,其他16色点阵图也可以在Windows中显示。大多数的图示都是16色的点阵图。通常,简单的卡通图像也可以用这16种颜色制作。

copyright dedecms

16色点阵图中的颜色编码有时称为IRGB(高亮红绿蓝:Intensity-Red-Green-Blue),并且实际上是源自IBM CGA文字模式下最初使用的十六种颜色。每个图素所用的4IRGB颜色位元都映射为表14-1所示的Windows十六进位RGB颜色。

copyright dedecms

 

织梦好,好织梦

14-1

dedecms.com

 

IRGB copyright dedecms

RGB颜色 copyright dedecms

颜色名称 织梦内容管理系统

0000 织梦内容管理系统

00-00-00

dedecms.com

dedecms.com

0001 本文来自织梦

00-00-80

本文来自织梦

暗蓝 织梦好,好织梦

0010 本文来自织梦

00-80-00 本文来自织梦

暗绿

内容来自dedecms

0011 织梦好,好织梦

00-80-80 dedecms.com

暗青

内容来自dedecms

0100

织梦好,好织梦

80-00-00

内容来自dedecms

暗红 内容来自dedecms

0101

copyright dedecms

80-00-80 本文来自织梦

暗洋红 copyright dedecms

0110

copyright dedecms

80-80-00 copyright dedecms

暗黄 内容来自dedecms

0111

织梦好,好织梦

C0-C0-C0 copyright dedecms

亮灰

织梦好,好织梦

1000

内容来自dedecms

80-80-80 内容来自dedecms

暗灰 本文来自织梦

1001 内容来自dedecms

00-00-FF

内容来自dedecms

织梦好,好织梦

1010

织梦内容管理系统

00-FF-00 dedecms.com

绿

织梦好,好织梦

1011

copyright dedecms

00-FF-FF dedecms.com

织梦内容管理系统

1100

内容来自dedecms

FF-00-00 织梦好,好织梦

织梦内容管理系统

1101 织梦好,好织梦

FF-00-FF dedecms.com

洋红 copyright dedecms

1110 织梦内容管理系统

FF-FF-00

织梦内容管理系统

copyright dedecms

1111 dedecms.com

FF-FF-FF 内容来自dedecms

织梦好,好织梦

 

EGA的记忆体组成了四个「颜色面」,也就是说,定义每个图素颜色的四位元在记忆体中是不连续的。然而,这样组织显示记忆体便於使所有的亮度位元都排列在一起、所有的红色位元都排在一起,等等。这样听起来就好像一种设备依赖特性,即Windows程式写作者不需要了解所有细节,但这时应或多或少地知道一些。不过,这些颜色面会出现在一些API呼叫中,例如GetDeviceCapsCreateBitmap

dedecms.com

Windows 98Microsoft Windows NT需要VGA或解析度更高的图形卡。这是目前公认的显示卡的最低标准。 dedecms.com

1987年,IBM最早发表视讯图像阵列(Video Graphics ArrayVGA)以及PS/2系列的个人电脑。它提供了许多不同的显示模式,但最好的图像模式(Windows也使用其中之一)是水平显示640个图素,垂直显示480个图素,带有16种颜色。要显示256种颜色,最初的VGA必须切换到320×240的图形模式,这种图素数不适合Windows的正常工作。

内容来自dedecms

一般人们已经忘记了最初VGA卡的颜色限制,因为其他硬体制造商很快就开发了「Super-VGA」(SVGA)显示卡,它包括更多的视讯记忆体,可显示256种颜色并有多於640×480的模式。这是现在的标准,而且也是一件好事,因为对於现实世界中的图像来说,16种颜色过於简单,有些不适合。 dedecms.com

显示256种颜色的显示卡模式采用每图素8位元。不过,这些8位元值都不必与实际的颜色相符。事实上,显示卡提供了「调色盘对照表(palette lookup table)」,该表允许软体指定这8位元的颜色值,以便与实际颜色相符合。在Windows中,应用程式不能直接存取调色盘对照表。实际上,Windows储存了256种颜色中的20种,而应用程式可以通过「Windows调色盘管理器」来自订其余的236种颜色。关於这些内容,我将在第十六章详细介绍。调色盘管理器允许应用程式在256色显示器上显示实际点阵图。Windows所储存的20种颜色如表14-2所示。 本文来自织梦

  织梦好,好织梦

14-2

dedecms.com

 

IRGB

织梦好,好织梦

RGB颜色

内容来自dedecms

颜色名称 本文来自织梦

00000000 本文来自织梦

00-00-00 dedecms.com

copyright dedecms

00000001

dedecms.com

80-00-00

copyright dedecms

暗红

copyright dedecms

00000010

织梦内容管理系统

00-80-00 织梦好,好织梦

暗绿

织梦好,好织梦

00000011

织梦内容管理系统

80-80-00

织梦好,好织梦

暗黄

copyright dedecms

00000100 内容来自dedecms

00-00-80

本文来自织梦

暗蓝 dedecms.com

00000101

内容来自dedecms

80-00-80 本文来自织梦

暗洋红

织梦内容管理系统

00000110 织梦内容管理系统

00-80-80

织梦好,好织梦

暗青 dedecms.com

00000111 copyright dedecms

C0-C0-C0 织梦内容管理系统

亮灰

织梦好,好织梦

00001000

织梦好,好织梦

C0-DC-C0

织梦内容管理系统

美元绿 织梦内容管理系统

00001001

dedecms.com

A6-CA-F0

内容来自dedecms

天蓝 织梦内容管理系统

11110110 copyright dedecms

FF-FB-F0 织梦内容管理系统

乳白

本文来自织梦

11110111 织梦内容管理系统

A0-A0-A4

织梦好,好织梦

中性灰

copyright dedecms

11111000

copyright dedecms

80-80-80 织梦内容管理系统

暗灰

内容来自dedecms

11111001 本文来自织梦

FF-00-00 copyright dedecms

copyright dedecms

11111010

dedecms.com

00-FF-00 内容来自dedecms

绿 本文来自织梦

11111011 内容来自dedecms

FF-FF-00 内容来自dedecms

本文来自织梦

11111100 dedecms.com

00-00-FF copyright dedecms

内容来自dedecms

11111101 本文来自织梦

FF-00-FF dedecms.com

洋红 织梦内容管理系统

11111110

本文来自织梦

00-FF-FF 织梦好,好织梦

copyright dedecms

11111111 内容来自dedecms

FF-FF-FF 织梦好,好织梦

内容来自dedecms

 

最近几年,True-Color显示卡很普遍,它们在每图素使用16位元或24位元。有时每图素虽然用了16位元,其中有1位元不用,而其他15位元主要近似於红、绿和蓝。这样红、绿和蓝每种都有32色阶,组合起来就可以达到32,768种颜色。更普遍的是,6位元用於绿色(人类对此颜色最敏感),这样就可得到65,536种颜色。对於非技术性的PC使用者来说,他们并不喜欢看到诸如32,76865,536之类的数字,因此通常将这种视讯显示卡称为Hi-Color显示卡,它能提供数以千计的颜色。

织梦好,好织梦

到了每个图素24位元时,我们总共有了16,777,216种颜色(或者True Color、数百万的颜色),每个图素使用3位元组。这与今後的标准很相似,因为它大致代表了人类感官的极限而且也很方便。 dedecms.com

在呼叫GetDeviceCaps时(参见第五章的DEVCAPS程式),您能利用BITSPIXELPLANES常数来获得显示卡的颜色单位,这些值显示如表14-3所示

织梦好,好织梦

 

本文来自织梦

14-3

dedecms.com

 

BITSPIXEL 内容来自dedecms

PLANES

织梦内容管理系统

颜色数 dedecms.com

1

织梦好,好织梦

1 织梦好,好织梦

2

织梦内容管理系统

1 织梦好,好织梦

4 dedecms.com

16

本文来自织梦

8

织梦内容管理系统

1

dedecms.com

256

本文来自织梦

15或16 本文来自织梦

1

dedecms.com

32,768或65 536

copyright dedecms

24或32 copyright dedecms

1

织梦好,好织梦

16 777 216

copyright dedecms

 

最近,您应该不会再碰到单色显示器了,但即便碰到了,您的应用程式也应该不会发生问题。

织梦内容管理系统

GDI支援的点阵图
  织梦内容管理系统

Windows图形装置介面(GDIGraphics Device Interface)从1.0版开始支援点阵图。不过,一直到Windows 3.0以前,Windows下唯一支援GDI物件的只有点阵图,以点阵图代号来使用。这些GDI点阵图物件是单色的,或者与实际的图像输出设备(例如视讯显示器)有相同的颜色单位。例如,与16VGA相容的点阵图有四个颜色面。问题是这些颜色点阵图不能储存,也不能用於颜色单位不同的图像输出设备(如每图素占8位元就可以产生256种颜色的设备)上。

内容来自dedecms

Windows 3.0开始,定义了一种新的点阵图格式,我们称之为装置无关点阵图(device-independent bitmap),或者DIBDIB包括了自己的调色盘,其中显示了与RGB颜色相对应的图素位元。DIB能显示在任何位元映射输出设备上。这里唯一的问题是DIB的颜色通常一定会转换成设备实际表现出来的颜色。

copyright dedecms

DIB同时,Windows 3.0还介绍了「Windows调色盘管理器」,它让程式能够从显示的256种颜色中自订颜色。就像我们在第十六章所看到的那样,应用程式通常在显示DIB时使用「调色盘管理器」。 本文来自织梦

MicrosoftWindows 95(和Windows NT 4.0)中扩展了DIB的定义,并且在Windows 98(和Windows NT 5.0)中再次扩展。这些扩展增加了所谓的「图像颜色管理器(ICMImage Color Management),并允许DIB更精确地指定图像所需要的颜色。我将在第十五章简要讨论ICM内容来自dedecms

不论DIB多么重要,在处理点阵图时,早期的GDI点阵图物件依然扮演了重要的角色。掌握点阵图使用方式的最好方法是按各种用法在演进发展的时间顺序来学习,先从GDI点阵图物件和位元块传输的概念开始。

本文来自织梦

位元块传输
  内容来自dedecms

我前面提到过,您可以把整个视讯显示器看作是一幅大点阵图。您在萤幕上见到的图素由储存在视讯显示卡上记忆体中的位元来描述。任何视讯显示的矩形区域也都是一个点阵图,其大小是它所包含的行列数。

织梦好,好织梦

让我们从将图像从视讯显示的一个区域复制到另一个区域,开始我们在点阵图世界的旅行吧!这个是强大的BitBlt函式的工作。 本文来自织梦

Bitblt(读作「bit blit」)代表「位元块传输(bit-block transfer)」。BLT起源於一条组合语言指令,该指令在DEC PDP-10上用来传输记忆体块。术语「bitblt」第一次用在图像上与Xerox Palo Alto Research CenterPARC)设计的SmallTalk系统有关。在SmallTalk中,所有的图形输出操作都使用bitblt。程式写作者有时将blt用作动词,例如:「Then I wrote some code to blt the happy face to the screen and play a wave file.本文来自织梦

BitBlt函式移动的是图素,或者(更明确地)是一个位元映射图块。您将看到,术语「传输(transfer)」与BitBlt函式不尽相同。此函式实际上对图素执行了一次位元操作,而且可以产生一些有趣的结果。 织梦好,好织梦

简单的BitBlt
  copyright dedecms

程式14-1所示的BITBLT程式用BitBlt函式将程式系统的功能表图示(位於程式Windows的左上角)复制到它的显示区域。

织梦内容管理系统

 程式14-1  BITBLT dedecms.com 
BITBLT.C 织梦内容管理系统 
/*---------------------------------------------------------------------- 织梦内容管理系统 
        BITBLT.C --    BitBlt Demonstration 

织梦好,好织梦

                                                     (c) Charles Petzold, 1998 内容来自dedecms 
  -------------------------------------------------------------------*/ 织梦内容管理系统 
  织梦好,好织梦 
#include <windows.h> 织梦好,好织梦 
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; dedecms.com 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, 本文来自织梦 
                                      PSTR szCmdLine, int iCmdShow) 

dedecms.com

{ 

织梦内容管理系统

        static TCHAR   szAppName [] = TEXT ("BitBlt") ; 织梦内容管理系统 
        HWND                           hwnd ; 
织梦好,好织梦
        MSG                            msg ; 织梦内容管理系统 
        WNDCLASS                       wndclass ; 

本文来自织梦

  

dedecms.com

        wndclass.style                                = CS_HREDRAW | CS_VREDRAW ; 本文来自织梦 
        wndclass.lpfnWndProc                          = WndProc ; dedecms.com 
        wndclass.cbClsExtra                           = 0 ; 本文来自织梦 
        wndclass.cbWndExtra                           = 0 ; copyright dedecms 
        wndclass.hInstance                            = hInstance ; 
内容来自dedecms
        wndclass.hIcon                                = LoadIcon (NULL, IDI_INFORMATION) ; copyright dedecms 
        wndclass.hCursor                              = LoadCursor (NULL, IDC_ARROW) ; 
织梦内容管理系统
        wndclass.hbrBackground                = (HBRUSH) GetStockObject (WHITE_BRUSH) ; 

内容来自dedecms

        wndclass.lpszMenuName                 = NULL ; 本文来自织梦 
        wndclass.lpszClassName                = szAppName ; 织梦内容管理系统 
      

内容来自dedecms

        if (!RegisterClass (&wndclass)) copyright dedecms 
        { copyright dedecms 
                       MessageBox (NULL, TEXT ("This program requires Windows NT!"), 
内容来自dedecms
                                                                     szAppName, MB_ICONERROR) ; dedecms.com 
                       return 0 ; 

本文来自织梦

     } 

dedecms.com

      

copyright dedecms

        hwnd = CreateWindow (  szAppName, TEXT ("BitBlt Demo"),  织梦内容管理系统 
                              WS_OVERLAPPEDWINDOW,  

copyright dedecms

                                 CW_USEDEFAULT, CW_USEDEFAULT, 
内容来自dedecms
                                 CW_USEDEFAULT, CW_USEDEFAULT, 
织梦好,好织梦
                                 NULL, NULL, hInstance, NULL) ; 织梦内容管理系统 
  
dedecms.com
        ShowWindow (hwnd, iCmdShow) ; 织梦好,好织梦 
        UpdateWindow (hwnd) ; dedecms.com 
        while (GetMessage (&msg, NULL, 0, 0)) 

本文来自织梦

     { 
织梦好,好织梦
                               TranslateMessage (&msg) ; 本文来自织梦 
                               DispatchMessage (&msg) ; copyright dedecms 
     } copyright dedecms 
        return msg.wParam ; 
copyright dedecms
} 织梦内容管理系统 
  

dedecms.com

LRESULT CALLBACK WndProc (     HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) 

dedecms.com

{ copyright dedecms 
        static int             cxClient, cyClient, cxSource, cySource ; 

dedecms.com

        HDC                    hdcClient, hdcWindow ; 
织梦好,好织梦
        int                    x, y ; dedecms.com 
        PAINTSTRUCT            ps ; 本文来自织梦 
      内容来自dedecms 
        switch (message) 织梦好,好织梦 
        { 

copyright dedecms

        case WM_CREATE: copyright dedecms 
                               cxSource = GetSystemMetrics (SM_CXSIZEFRAME) + copyright dedecms 
                    GetSystemMetrics (SM_CXSIZE) ; 

内容来自dedecms

                               cySource = GetSystemMetrics (SM_CYSIZEFRAME) +  
dedecms.com
                    GetSystemMetrics (SM_CYCAPTION) ; copyright dedecms 
                               return 0 ; 织梦内容管理系统 
        case    WM_SIZE: copyright dedecms 
                               cxClient = LOWORD (lParam) ; 本文来自织梦 
                               cyClient = HIWORD (lParam) ; 本文来自织梦 
                               return 0 ; 

本文来自织梦

  织梦内容管理系统 
        case    WM_PAINT: 

内容来自dedecms

                               hdcClient = BeginPaint (hwnd, &ps) ; 

dedecms.com

                               hdcWindow = GetWindowDC (hwnd) ; 
织梦内容管理系统
         本文来自织梦 
                               for (y = 0 ; y < cyClient ; y += cySource) 

本文来自织梦

                               for (x = 0 ; x < cxClient ; x += cxSource) copyright dedecms 
                               { 本文来自织梦 
                               BitBlt (hdcClient, x, y, cxSource, cySource, dedecms.com 
                                                                     hdcWindow, 0, 0, SRCCOPY) ; copyright dedecms 
                               } dedecms.com 
  
织梦内容管理系统
                               ReleaseDC (hwnd, hdcWindow) ; 
copyright dedecms
                               EndPaint (hwnd, &ps) ; 内容来自dedecms 
                               return 0 ; 织梦内容管理系统 
  织梦内容管理系统 
        case    WM_DESTROY: dedecms.com 
                               PostQuitMessage (0) ; 内容来自dedecms 
                               return 0 ; 
内容来自dedecms
     } 织梦好,好织梦 
        return DefWindowProc (hwnd, message, wParam, lParam) ; 
本文来自织梦
} 织梦好,好织梦 

但为什么只用了一个BitBlt呢?实际上,那个BITBLT用系统功能表图示的多个副本来填满显示区域(在此情况下是资讯方块中普遍使用的IDI_INFORMATION图示),如图14-1所示。

织梦内容管理系统


 

内容来自dedecms

内容来自dedecms

  内容来自dedecms

14-1 BITBLT的萤幕显示

内容来自dedecms

 

BitBlt函式从称为「来源」的装置内容中将一个矩形区的图素传输到称为「目的(destination)」的另一个装置内容中相同大小的矩形区。此函式的语法如下:

本文来自织梦

BitBlt (hdcDst, xDst, yDst, cx, cy, hdcSrc, xSrc, ySrc, dwROP) ; 织梦好,好织梦 

来源和目的装置内容可以相同。

本文来自织梦

BITBLT程式中,目的装置内容是视窗的显示区域,装置内容代号从BeginPaint函式获得。来源装置内容是应用程式的整个视窗,此装置内容代号从GetWindowDC获得的。很明显地,这两个装置内容指的是同一个实际设备(视讯显示器)。不过,这两个装置内容的座标原点不同。

内容来自dedecms

xSrcySrc参数指明了来源图像左上角的座标位置。在BITBLT中,这两个参数设为0,表示图像从来源装置内容(也就是整个视窗)的左上角开始,cxcy参数是图像的宽度和高度。BITBLT根据从GetSytemMetrics函式获得的资讯来计算这些值。

dedecms.com

xDstyDst参数表示了复制图像位置左上角的座标位置。在BITBLT中,这两个参数设定为不同的值以便多次复制图像。对於第一次BitBlt呼叫,这两个参数设制为0,将图像复制到显示区域的左上角位置。 本文来自织梦

BitBlt的最後一个参数是位元映射操作型态。我将简短地讨论一下这个值。 内容来自dedecms

请注意,BitBlt是从实际视讯显示记忆体传输图素,而不是从系统功能表图示的其他图像传输。如果您移动BITBLT视窗以使部分系统功能表图示移出萤幕,然後调整BITBLT视窗的尺寸使其重画,这时您将发现BITBLT显示区域中显示的是功能表图示的一部分。BitBlt函式不再存取整个图像。

copyright dedecms

BitBlt函式中,来源和目的装置内容可以相同。您可以重新编写BITBLT以使WM_PAINT处理执行以下内容:

dedecms.com

BitBlt (hdcClient, 0, 0, cxSource, cySource,  

内容来自dedecms

                       hdcWindow, 0, 0, SRCCOPY) ; copyright dedecms 
for (y = 0 ; y < cyClient ; y += cySource) 

本文来自织梦

for (x = 0 ; x < cxClient ; x += cxSource) 织梦好,好织梦 
{ 

内容来自dedecms

        if (x > 0 || y > 0) 织梦好,好织梦 
                               BitBlt (hdcClient, x, y, cxSource, cySource, 
copyright dedecms
                       hdcClient, 0, 0, SRCCOPY) ; 
织梦好,好织梦
} copyright dedecms 

这将与前面显示的BITBLT一样产生相同的效果,只是显示区域左上角比较模糊。

织梦内容管理系统

BitBlt内的最大限制是两个装置内容必须是相容的。这意味著或者其中之一必须是单色的,或者两者的每个图素都相同的位元数。总而言之,您不能用此方法将萤幕上的某些图形复制到印表机。 织梦好,好织梦

拉伸点阵图
  copyright dedecms

BitBlt函式中,目的图像与来源图像的尺寸是相同的,因为函式只有两个参数来说明宽度和高度。如果您想在复制时拉伸或者压缩图像尺寸,可以使用StretchBlt函式。StretchBlt函式的语法如下: 织梦好,好织梦

StretchBlt (   hdcDst, xDst, yDst, cxDst, cyDst,  
copyright dedecms
                                      hdcSrc, xSrc, ySrc, cxSrc, cySrc, dwROP) ; 
内容来自dedecms

此函式添加了两个参数。现在的函式就分别包含了目的和来源各自的宽度和高度。STRETCH程式展示了StretchBlt函式,如程式14-2所示。 织梦好,好织梦

 程式14-2  STRETCH 
织梦内容管理系统
STRETCH.C 织梦好,好织梦 
/*-------------------------------------------------------------------------- copyright dedecms 
        STRETCH.C --   StretchBlt Demonstration 
织梦内容管理系统
                                                             (c) Charles Petzold, 1998 
dedecms.com
----------------------------------------------------------------------------*/ 
织梦好,好织梦
  
织梦好,好织梦
#include <windows.h> 

内容来自dedecms

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; 
内容来自dedecms
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, 织梦内容管理系统 
                   PSTR szCmdLine, int iCmdShow) 本文来自织梦 
{ dedecms.com 
        static TCHAR   szAppName [] = TEXT ("Stretch") ; 织梦内容管理系统 
        HWND                           hwnd ; 

内容来自dedecms

        MSG                            msg ; 
织梦内容管理系统
        WNDCLASS                       wndclass ; copyright dedecms 
  本文来自织梦 
        wndclass.style                                = CS_HREDRAW | CS_VREDRAW ; 

内容来自dedecms

        wndclass.lpfnWndProc                          = WndProc ; 本文来自织梦 
        wndclass.cbClsExtra                           = 0 ; 
织梦内容管理系统
        wndclass.cbWndExtra                           = 0 ; 织梦好,好织梦 
        wndclass.hInstance                            = hInstance ; copyright dedecms 
        wndclass.hIcon                                = LoadIcon (NULL, IDI_INFORMATION) ; 内容来自dedecms 
        wndclass.hCursor                              = LoadCursor (NULL, IDC_ARROW) ; 

内容来自dedecms

        wndclass.hbrBackground                = (HBRUSH) GetStockObject (WHITE_BRUSH) ; dedecms.com 
        wndclass.lpszMenuName                 = NULL ; copyright dedecms 
        wndclass.lpszClassName                = szAppName ; 

本文来自织梦

      

内容来自dedecms

        if (!RegisterClass (&wndclass)) 织梦好,好织梦 
        { 内容来自dedecms 
                       MessageBox (   NULL, TEXT ("This program requires Windows NT!"), 本文来自织梦 
                                                                     szAppName, MB_ICONERROR) ; 内容来自dedecms 
                       return 0 ; 内容来自dedecms 
     } 

内容来自dedecms

      本文来自织梦 
     hwnd = CreateWindow (szAppName, TEXT ("StretchBlt Demo"),  内容来自dedecms 
                          WS_OVERLAPPEDWINDOW,  本文来自织梦 
                          CW_USEDEFAULT, 

织梦好,好织梦

CW_USEDEFAULT, 

织梦内容管理系统

                          CW_USEDEFAULT, 
dedecms.com
CW_USEDEFAULT, 织梦好,好织梦 
                          NULL, NULL, hInstance, NULL) ; 
本文来自织梦
        ShowWindow (hwnd, iCmdShow) ; copyright dedecms 
        UpdateWindow (hwnd) ; 
copyright dedecms
  
内容来自dedecms
        while (GetMessage (&msg, NULL, 0, 0)) dedecms.com 
        { 
织梦好,好织梦
                                      TranslateMessage (&msg) ; 

织梦好,好织梦

                                      DispatchMessage (&msg) ; copyright dedecms 
        } 

本文来自织梦

        return msg.wParam ; 织梦内容管理系统 
} 

copyright dedecms

  dedecms.com 
LRESULT CALLBACK WndProc (     HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
织梦内容管理系统
{ 
copyright dedecms
        static int             cxClient, cyClient, cxSource, cySource ; 本文来自织梦 
        HDC                            hdcClient, hdcWindow ; 

本文来自织梦

        PAINTSTRUCT            ps ; 

copyright dedecms

      织梦内容管理系统 
        switch (message) 
内容来自dedecms
        { 
内容来自dedecms
        case    WM_CREATE: 织梦好,好织梦 
                               cxSource = GetSystemMetrics (SM_CXSIZEFRAME) + 
织梦内容管理系统
                    GetSystemMetrics (SM_CXSIZE) ; 
织梦好,好织梦
  dedecms.com 
                               cySource = GetSystemMetrics (SM_CYSIZEFRAME) +  

织梦内容管理系统

                    GetSystemMetrics (SM_CYCAPTION) ; 

本文来自织梦

                               return 0 ; 织梦好,好织梦 
  
内容来自dedecms
        case    WM_SIZE: 
copyright dedecms
                               cxClient = LOWORD (lParam) ; 织梦好,好织梦 
                               cyClient = HIWORD (lParam) ; 
本文来自织梦
                               return 0 ; 
织梦好,好织梦
  织梦内容管理系统 
        case    WM_PAINT: 

copyright dedecms

                               hdcClient = BeginPaint (hwnd, &ps) ; 

织梦好,好织梦

                               hdcWindow = GetWindowDC (hwnd) ; 
dedecms.com
  

本文来自织梦

                               StretchBlt (hdcClient, 0, 0, cxClient, cyClient, 织梦好,好织梦 
                    hdcWindow, 0, 0, cxSource, cySource, MERGECOPY) ; 织梦好,好织梦 
  内容来自dedecms 
                               ReleaseDC (hwnd, hdcWindow) ; 

dedecms.com

                               EndPaint (hwnd, &ps) ; 
织梦内容管理系统
                               return 0 ; 织梦内容管理系统 
  

copyright dedecms

        case    WM_DESTROY: 

copyright dedecms

                               PostQuitMessage (0) ; dedecms.com 
                               return 0 ; 
织梦好,好织梦
     } 
内容来自dedecms
        return DefWindowProc (hwnd, message, wParam, lParam) ; 
织梦内容管理系统
} 

织梦内容管理系统

此程式只有呼叫了StretchBlt函式一次,但是利用此函式以系统功能表图示填充了整个显示区域,如图14-2所示。 dedecms.com


  内容来自dedecms

织梦内容管理系统

  织梦内容管理系统

14-2 STRETCH的萤幕显示

本文来自织梦

 

BitBltStretchBlt函式中所有的座标与大小都是依据逻辑单位的。但是当您在BitBlt函式中定义了两个不同的装置内容,而这两个装置内容虽然参考同一个实际设备,却各自有著不同的映射模式,这时将发生什么结果呢?如果出现这种情况,呼叫BitBlt产生的结果就显得不明确了:cxcy参数都是逻辑单位,而它们同样应用於来源装置内容和目的装置内容中的矩形区。所有的座标和尺寸必须在实际的位元传输之前转换为装置座标。因为cxcy值同时用於来源和目的装置内容,所以此值必须转换为装置内容自己的单位。

织梦好,好织梦

当来源和目的装置内容相同,或者两个装置内容都使用MM_TEXT图像模式时,装置单位下的矩形尺寸在两个装置内容中会是相同的,然後才由Windows进行图素对图素的转换。不过,如果装置单位下的矩形尺寸在两个装置内容中不同时,则Windows就把此工作转交给更通用的StretchBlt函式。

内容来自dedecms

StretchBlt也允许水平或垂直翻转图像。如果cxSrccxDst标记(转换成装置单位以後)不同,那么StretchBlt就建立一个镜像:左右翻转。在STRETCH程式中,通过将xDst参数改为cxClient并将cxDst参数改成-cxClient,您就可以做到这一点。如果cySrccyDst不同,则StretchBlt会上下翻转图像。要在STRETCH程式中测试这一点,可将yDst参数改为cyClient并将cyDst参数改成-cyClient织梦好,好织梦

StretchBlt模式
 

dedecms.com

使用StretchBlt会碰到一些与点阵图大小缩放相关的一些根本问题。在扩展一个点阵图时,StretchBlt必须复制图素行或列。如果放大倍数不是原图的整数倍,那么此操作会造成产生的图像有些失真。 织梦好,好织梦

如果目的矩形比来源矩形小,那么StretchBlt在缩小图像时就必须把两行(或列)或者多行(或列)的图素合并到一行(或列)。完成此操作有四种方法,它根据装置内容伸展模式属性来选择其中一种方法。您可使用SetStretchBltMode函式来修改这个属性。 copyright dedecms

SetStretchBltMode (hdc, iMode) ; 内容来自dedecms 

iMode可取下列值: copyright dedecms

  • BLACKONWHITE或者STRETCH_ANDSCANS(内定)如果两个或多个图素得合并成一个图素,那么StretchBlt会对图素执行一个逻辑AND运算。这样的结果是只有全部的原始图素是白色时该图素才为白色,其实际意义是黑色图素控制了白色图素。这适用於白背景中主要是黑色的单色点阵图。
     
  • WHITEONBLACKSTRETCH_ORSCANS 如果两个或多个图素得合并成一个图素,那么StretchBlt执行逻辑OR运算。这样的结果是只有全部的原始图素都是黑色时才是黑色,也就是说由白色图素决定颜色。这适用於黑色背景中主要是白色的单色点阵图。
     
  • COLORONCOLORSTRETCH_DELETESCANS StretchBlt简单地消除图素行或列,而没有任何逻辑组合。这是通常是处理彩色点阵图的最佳方法。
     
  • HALFTONESTRETCH_HALFTONE Windows根据组合起来的来源颜色来计算目的的平均颜色。这将与半调调色盘联合使用,第十六章将展示这一程序。

    copyright dedecms


     

Windows还包括用於取得目前伸展模式的GetStretchBltMode函式。 织梦好,好织梦

位元映射操作
  本文来自织梦

BITBLTSTRETCH程式简单地将来源点阵图复制给了目的点阵图,在过程中也可能进行了缩放。这是把SRCCOPY作为BitBltStretchBlt函式最後一个参数的结果。SRCCOPY只是您能在这些函式中使用的256个位元映射操作中的一个。让我们先在STRETCH程式中做一个别的实验,然後再系统地研究位元映射操作。

本文来自织梦

尽量用NOTSRCCOPY来代替SRCCOPY。与它们名称一样,位元映射操作在复制点阵图时转换其颜色。在显示区域视窗,所有的颜色转换:黑色变成白色、白色变成黑色,蓝色变成黄色。现在试一下SRCINVERT,您将得到同样效果。如果试一下BLACKNESS,正如其名称一样,整个显示区域都将变成黑色,而WHITENESS则使其变成白色。

dedecms.com

现在试一试用下列三条叙述来代替StretchBlt呼叫:

dedecms.com

SelectObject (hdcClient, CreateHatchBrush (HS_DIAGCROSS, RGB (0, 0, 0))); copyright dedecms 
StretchBlt (   hdcClient, 0, 0, cxClient, cyClient, 

织梦好,好织梦

                                      hdcWindow, 0, 0, cxSource, cySource, MERGECOPY) ; 
织梦好,好织梦
  织梦内容管理系统 
DeleteObject (hdcClient, GetStockObject (WHITE_BRUSH)) ; copyright dedecms 

这次,您将在图像上看到一个菱形的画刷,这是什么?

内容来自dedecms

我在前面说过,BitBltStretchBlt函式不是简单的位元块传输。此函式实际在下面三种图像间执行位元操作。

dedecms.com

  • Source 来源点阵图,拉伸或压缩(如果有必要)到目的矩形的尺寸。
     
  • Destination BitBltStretchBlt呼叫之前的目的矩形。
     
  • Pattern 在目的装置内容中选择的目前画刷,水平或垂直地复制到目的矩形范围内。
     

结果是复制到了目的矩形中。

dedecms.com

位元映射操作与我们在第五章遇到的绘图模式在概念上相似。绘图模式采用图像物件的控制项方式,例如一条线就组合成一个目的。我们知道有16种绘图模式-也就是说,物件中的01画出时,唯一结果就是目的中01的组合。 dedecms.com

使用BitBltStretchBlt的位元映射操作包含了三个物件的组合,这将产生256种位元映射操作。有256种方法来组合来源点阵图、目的点阵图和图案。有15种位元映射操作已经命名-其中一些名称其实还不能够清楚清楚说明其意义-它们定义在WINGDI.H里头,其余的都有数值,列在/Platform SDK/Graphics and Multimedia Services/GDI/Raster Operation Codes/Ternary Raster Operations之中。 本文来自织梦

有名称的15ROP代码见表14-4

本文来自织梦

  本文来自织梦

14-4 织梦好,好织梦

 

图案(P):1 1 1 1 0 0 0 0 copyright dedecms

来源(s):1 1 0 0 1 1 0 0 本文来自织梦

目的(D):1 0 1 0 1 0 1 0 本文来自织梦

布林操作 织梦内容管理系统

ROP 代码 织梦好,好织梦

名称

copyright dedecms

结果:

织梦好,好织梦

0 0 0 0 0 0 0 0 织梦内容管理系统

0 织梦内容管理系统

0x000042

织梦内容管理系统

BLACKNESS

内容来自dedecms

 

dedecms.com

0 0 0 1 0 0 0 1

织梦好,好织梦

~(S ¦ D)

本文来自织梦

0x1100A6 内容来自dedecms

NOTSRCERASE dedecms.com

 

dedecms.com

0 0 1 1 0 0 1 1 本文来自织梦

~S 织梦好,好织梦

0x330008 本文来自织梦

NOTSRCCOPY dedecms.com

  copyright dedecms

0 1 0 0 0 1 0 0

本文来自织梦

S & ~D

dedecms.com

0x440328

织梦内容管理系统

SRCERASE 织梦好,好织梦

  内容来自dedecms

0 1 0 1 0 1 0 1

织梦好,好织梦

~D 织梦内容管理系统

0x550009 copyright dedecms

DSTINVERT

内容来自dedecms

 

本文来自织梦

0 1 0 1 1 0 1 0

本文来自织梦

P ^ D

织梦好,好织梦

0x5A0049

copyright dedecms

PATINVERT dedecms.com

  内容来自dedecms

0 1 1 0 0 1 1 0

dedecms.com

S ^ D

织梦好,好织梦

0x660046

本文来自织梦

SRCINVERT

织梦好,好织梦

 

copyright dedecms

1 0 0 0 1 0 0 0

织梦好,好织梦

S & D 内容来自dedecms

0x8800C6

copyright dedecms

SRCAND

织梦好,好织梦

  本文来自织梦

1 0 1 1 1 0 1 1 copyright dedecms

~S ¦ D

织梦好,好织梦

0xBB0226

本文来自织梦

MERGEPAINT 织梦好,好织梦

 

织梦内容管理系统

1 1 0 0 0 0 0 0 织梦内容管理系统

P & S 内容来自dedecms

0xC000CA

本文来自织梦

MERGECOPY 内容来自dedecms

  本文来自织梦

1 1 0 0 1 1 0 0

copyright dedecms

S 织梦好,好织梦

0xCC0020

copyright dedecms

SRCCOPY

织梦内容管理系统

  织梦好,好织梦

1 1 1 0 1 1 1 0

本文来自织梦

¦ D 织梦内容管理系统

0xEE0086 本文来自织梦

SRCPAINT 织梦好,好织梦

  dedecms.com

1 1 1 1 0 0 0 0 内容来自dedecms

P

织梦好,好织梦

0xF00021 本文来自织梦

PATCOPY

copyright dedecms

 

本文来自织梦

1 1 1 1 1 0 1 1

织梦好,好织梦

¦  ~S ¦  D

本文来自织梦

0xFB0A09 本文来自织梦

PATPAINT copyright dedecms

 

copyright dedecms

1 1 1 1 1 1 1 1 copyright dedecms

1 dedecms.com

0xFF0062 copyright dedecms

WHITENESS

织梦内容管理系统

 

此表格对於理解和使用位元映射操作非常重要,因此我们应花点时间来研究。

dedecms.com

在这个表格中,「ROP代码」行的值将传递给BitBltStretchBlt的最後一个参数;在「名称」行中的值在WINGDI.H定义。ROP代码的低字组协助装置驱动程式传输位元映射操作。高字组是0255之间的数值。此数值与第2列的图案的位元相同,这是在图案、来源和显示在顶部的目的之间进行位元操作的结果。「布林运算」列按C语法显示图案、来源和目的的组合方式。

dedecms.com

要开始了解此表,最简单的办法是假定您正处理一个单色系统(每图素1位元)其中0代表黑色,1代表白色。BLACKNESS操作的结果是不管是来源、目的和图案是什么,全部为零,因此目的将显示黑色。类似地,WHITENESS总导致目的呈白色。 织梦好,好织梦

现在假定您使用位元映射操作PATCOPY。这导致结果位元与图案位元相同,而忽略了来源和目的点阵图。换句话说,PATCOPY简单地将目前图案复制给了目的矩形。

copyright dedecms

PATPAINT位元映射操作包含一个更复杂的操作。其结果相同於在图案、目的和反转的来源之间进行位元或操作。当来源点阵图是黑色(0)时,其结果总是白色(1);当来源是白色(1)时,只要图案或目的为白色,则结果就是白色。换句话说,只有来源为白色而图案和目的都是黑色时,结果才是黑色。

织梦好,好织梦

彩色显示时每个图素都使用了多个位元。BitBltStretchBlt函式对每个颜色位元都分别提供了位元操作。例如,如果目的是红色而来源为蓝色,SRCPAINT位元映射操作把目的变成洋红色。注意,操作实际是按显示卡内储存的位元执行的。这些位元所对应的颜色取决於显示卡的调色盘的设定。Windows完成了此操作,以便位元映射操作能达到您预计的结果。不过,如果您修改了调色盘(我将在第十六章讨论),位元映射操作将产生无法预料的结果。 织梦内容管理系统

如要得到位元映射操作较好的应用程式,请参见本章後面的「非矩形点阵图图像」一节。

本文来自织梦

图案Blt
 

织梦好,好织梦

除了BitBltStretchBlt以外,Windows还包括一个称为PatBlt (「pattern block transfer:图案块传输」)的函式。这是三个「blt」函式中最简单的。与BitBltStretchBlt不同,它只使用一个目的装置内容。PatBlt语法是: copyright dedecms

PatBlt (hdc, x, y, cx, cy, dwROP) ; 织梦内容管理系统 

xycxcy参数位於逻辑单位。逻辑点(x,y)指定了矩形的左上角。矩形宽为cx单位,高为cy单位。这是PatBlt修改的矩形区域。PatBlt在画刷与目的装置内容上执行的逻辑操作由dwROP参数决定,此参数是ROP代码的子集-也就是说,您可以只使用那些不包括来源目的装置内容的ROP代码。下表列出了PatBlt支援的16个位元映射操作: dedecms.com

  织梦内容管理系统

14-5

织梦内容管理系统

 

图案(P):1 1 0 0

本文来自织梦

目的(D):1 0 1 0

织梦内容管理系统

布林操作 本文来自织梦

ROP 代码 织梦好,好织梦

名称

dedecms.com

结果:

dedecms.com

0 0 0 0

内容来自dedecms

0

织梦内容管理系统

0x000042

copyright dedecms

BLACKNESS

织梦内容管理系统

  内容来自dedecms

0 0 0 1

织梦好,好织梦

~(P | D) 织梦内容管理系统

0x0500A9 织梦内容管理系统

  本文来自织梦

  本文来自织梦

0 0 1 0 内容来自dedecms

~P & D

copyright dedecms

0x0A0329 本文来自织梦

  本文来自织梦

  dedecms.com

0 0 1 1 织梦好,好织梦

~P

本文来自织梦

0x0F0001 dedecms.com

 

内容来自dedecms

 

dedecms.com

0 1 0 0 copyright dedecms

P & ~D

本文来自织梦

0x500325

copyright dedecms

  dedecms.com

 

织梦内容管理系统

0 1 0 1

织梦好,好织梦

~D

织梦内容管理系统

0x550009 织梦内容管理系统

DSTINVERT

织梦好,好织梦

 

织梦好,好织梦

0 1 1 0 织梦内容管理系统

P ^ D 织梦好,好织梦

0x5A0049

dedecms.com

PATINVERT 本文来自织梦

 

dedecms.com

0 1 1 1

织梦内容管理系统

~(P & D)

copyright dedecms

0x5F00E9

copyright dedecms

 

织梦好,好织梦

 

本文来自织梦

1 0 0 0

织梦内容管理系统

P & D

内容来自dedecms

0xA000C9 copyright dedecms

  copyright dedecms

 

织梦好,好织梦

1 0 0 1 织梦内容管理系统

~(P ^ D) copyright dedecms

0xA50065 织梦好,好织梦

 

dedecms.com

 

织梦内容管理系统

1 0 1 0

织梦好,好织梦

D copyright dedecms

0xAA0029

织梦好,好织梦

  内容来自dedecms

 

本文来自织梦

1 0 1 1

内容来自dedecms

~P | D copyright dedecms

0xAF0229 织梦好,好织梦

  dedecms.com

  copyright dedecms

1 1 0 0 dedecms.com

P

织梦好,好织梦

0xF00021 织梦好,好织梦

PATCOPY

内容来自dedecms

 

织梦好,好织梦

1 1 0 1

织梦好,好织梦

P | ~D

dedecms.com

0xF50225 内容来自dedecms

  织梦内容管理系统

 

织梦内容管理系统

1 1 1 0

copyright dedecms

P | D

dedecms.com

0xFA0089

织梦好,好织梦

 

织梦好,好织梦

 

织梦好,好织梦

1 1 1 1

内容来自dedecms

1 copyright dedecms

0xFF0062 dedecms.com

WHITENESS 内容来自dedecms

 

下面列出了PatBlt一些更常见用途。如果想画一个黑色矩形,您可呼叫

本文来自织梦

PatBlt (hdc, x, y, cx, cy, BLACKNESS) ; 
dedecms.com

要画一个白色矩形,请用 copyright dedecms

PatBlt (hdc, x, y, cx, cy, WHITENESS) ; 
copyright dedecms

函式

织梦内容管理系统

PatBlt (hdc, x, y, cx, cy, DSTINVERT) ; 

本文来自织梦

用於改变矩形的颜色。如果目前装置内容中选择了WHITE_BRUSH,那么函式

织梦好,好织梦

PatBlt (hdc, x, y, cx, cy, PATINVERT) ; 织梦内容管理系统 

也改变矩形。

织梦内容管理系统

您可以再次呼叫FillRect函式来用画笔充满一个矩形区域: 本文来自织梦

FillRect (hdc, &rect, hBrush) ; 
本文来自织梦

FillRect函式相同於下列代码: dedecms.com

hBrush = SelectObject (hdc, hBrush) ; 
织梦好,好织梦
PatBlt (hdc,   rect.left, rect.top, 
copyright dedecms
                                      rect.right - rect.left, 

织梦好,好织梦

                                      rect.bottom - rect.top, PATCOPY) ; 
dedecms.com
SelectObject (hdc, hBrush) ; 内容来自dedecms 

实际上,此程式码是Windows用於执行FillRect函式的动作。如果您呼叫 织梦内容管理系统

InvertRect (hdc, &rect) ; 
本文来自织梦

Windows将其转换成函式:

本文来自织梦

PatBlt (hdc,   rect.left, rect.top, 

内容来自dedecms

                                      rect.right - rect.left, 

dedecms.com

                                      rect.bottom - rect.top, DSTINVERT) ; 内容来自dedecms 

在介绍PatBlt函式的语法时,我说过点(x,y)指出了矩形的左上角,而且此矩形宽度为cx单位,高度为cy单位。此叙述并不完全正确。BitBltPatBltStretchBlt是最合适的GDI画图函式,它们根据从一个角测得的逻辑宽度和高度来指定逻辑直角座标。矩形边框用到的其他所有GDI画图函式都要求根据左上角和右下角的座标来指定座标。对於MM_TEXT映射模式,上面讲述的PatBlt参数就是正确的。然而对於公制的映射模式来说,就不正确。如果您使用一的cxcy值,那么点(x,y)将是矩形的左下角。如果希望点(x,y)是矩形的左上角,那么cy参数必须设为矩形的负高度。 dedecms.com

如果想更精确,用PatBlt修改颜色的矩形将通过cx的绝对值获得逻辑宽度,通过cy的绝对值获得逻辑高度。这两个参数可以是负值。由逻辑点(x, y)和(x + cx, y + cy)给定的两个角定义了矩形。矩形的左上角通常属於PatBlt修改的区域。右上角则超出了矩形的范围。根据映射模式和cxcy参数的符号,矩形左上角的点应为(x, y)、(x, y + cy)、(x + cx, y)或者(x + cx, y + cy)。

copyright dedecms

如果给MM_LOENGLISH设定了映射模式,并且您想在显示区域左上角的一小块正方形上使用PatBlt,您可以使用 内容来自dedecms

PatBlt (hdc, 0, 0, 100, -100, dwROP) ; 

内容来自dedecms

copyright dedecms

PatBlt (hdc, 0, -100, 100, 100, dwROP) ; 
dedecms.com

copyright dedecms

PatBlt (hdc, 100, 0, -100, -100, dwROP) ; 织梦好,好织梦 

内容来自dedecms

PatBlt (hdc, 100, -100, -100, 100, dwROP) ; dedecms.com 

PatBlt设定正确参数最容易的方法是将xy设为矩形左上角。如果映射模式定义y座标随著向上卷动显示而增加,那么请使用负的cy参数。如果映射模式定义x座标向左增加(很少有人用),则需要使用负的cx参数。

copyright dedecms

GDI点阵图物件
  织梦内容管理系统

我在本章前面已提到过Windows1.0开始就支援GDI点阵图物件。因为在Windows 3.0发表了装置无关点阵图,GDI点阵图物件有时也称为装置相关点阵图,或者DDB。我尽量不全部引用device-dependent bitmap的全文,因为它看上去与device-independent bitmap类似。缩写DDB会好一些,因为我们很容易把它与DIB区别开来。

dedecms.com

对程式写作者来说,现存的两种不同型态的点阵图从Windows 3.0开始就更为混乱。许多有经验的Windows程式写作者都不能准确地理解DIBDDB之间的关系。(恐怕本书的Windows 3.0版本不能澄清这个问题)。诚然,DIBDDB在许多方面是相关的:DIBDDB能相互转换(尽管转换程序中会丢失一些资讯)。然而DIBDDB是不可以相互替换的,并且不能简单地选择一种方法来表示同一个可视资料。 织梦内容管理系统

如果我们能假设说DIB一定会替代DDB,那以後就会很方便了。但现实并不是如此,DDB还在Windows中扮演著很重要角色,尤其是您在乎程式执行表现好坏时。

内容来自dedecms

建立DDB
  内容来自dedecms

DDBWindows图形装置介面的图形物件之一(其中还包括绘图笔、画刷、字体、metafile和调色盘)。这些图形物件储存在GDI模组内部,由应用程式软体以代号数字的方式引用。您可以将DDB代号储存在一个HBITMAP(「handle to a bitmap:点阵图代号」)型态的变数中,例如: 本文来自织梦

HBITMAP hBitmap ; 

本文来自织梦

然後通过呼叫DDB建立的一个函式来获得代号,例如:CreateBitmap。这些函式配置并初始化GDI记忆体中的一些记忆体来储存关於点阵图的资讯,以及实际点阵图位元的资讯。应用程式不能直接存取这段记忆体。点阵图与装置内容无关。当程式使用完点阵图以後,就要清除这段记忆体:

copyright dedecms

DeleteObject (hBitmap) ; copyright dedecms 

如果程式执行时您使用了DDB,那么程式终止时,您可以完成上面的操作。

内容来自dedecms

CreateBitmap函式用法如下:

内容来自dedecms

hBitmap = CreateBitmap (cx, cy, cPlanes, cBitsPixel, bits) ; 

copyright dedecms

前两个参数是点阵图的宽度和高度(以图素为单位),第三个参数是颜色面的数目,第四个参数是每图素的位元数,第五个参数是指向一个以特定颜色格式存放的位元阵列的指标,阵列内存放有用来初始化该DDB的图像。如果您不想用一张现有的图像来初始化DDB,可以将最後一个参数设为NULL。以後您还是可以设定该DDB内图素的内容。

织梦内容管理系统

使用此函式时,Windows也允许建立您喜欢的特定型态GDI点阵图物件。例如,假设您希望点阵图宽7个图素、高9个图素、5?色位元面,并且每个图素占3位元,您只需要执行下面的操作: 本文来自织梦

hBitmap = CreateBitmap (7, 9, 5, 3, NULL) ; 
copyright dedecms

这时Windows会好好给您一个有效的点阵图代号。 本文来自织梦

在此函式呼叫期间,Windows将储存您传递给函式的资讯,并为图素位元配置记忆体。粗略的计算是此点阵图需要7×9×5×3,即945位元,这需要比118个位元组还多几个位元。

织梦好,好织梦

然而,Windows为点阵图配置好记忆体以後,每行图素都占用许多连贯的位元组,这样 织梦内容管理系统

iWidthBytes = 2 * ((cx * cBitsPixel + 15) / 16) ; copyright dedecms 

或者C程式写作者更倾向於写成:

内容来自dedecms

iWidthBytes = (cx * cBitsPixel + 15) & ~15) >> 3 ; 
本文来自织梦

因此,为DDB配置的记忆体就是: 内容来自dedecms

iBitmapBytes = cy * cPlanes * iWidthBytes ; 

内容来自dedecms

本例中,iWidthBytes4位元组,iBitmapBytes180位元组。 内容来自dedecms

现在,知道一张点阵图有5个颜色位元面,每图素占3个颜色位有什么意义吗?真是见鬼了,这甚至不能把它称作一个习题作业。虽然您让GDI内部配置了些记忆体,并且让这些记忆体有一定结构的内容,但是您这张点阵图完全作不出任何有用的事情来。 本文来自织梦

实际上,您将用两种型态的参数来呼叫CreateBitmap

织梦好,好织梦

  • cPlanescBitsPixel都等於1(表示单色点阵图);或者
     
  • cPlanescBitsPixel都等於某个特定装置内容的值,您可以使用PLANESBITSPIXEL索引来从GetDeviceCaps函式获得。
     

更现实的情况下,您只会在第一种情况下呼叫CreateBitmap。对於第二种情况,您可以用CreateCompatibleBitmap来简化问题:

copyright dedecms

hBitmap = CreateCompatibleBitmap (hdc, cx, cy) ; 织梦好,好织梦 

此函式建立了一个与设备相容的点阵图,此设备的装置内容代号由第一个参数给出。CreateCompatibleBitmap用装置内容代号来获得GetDeviceCaps资讯,然後将此资讯传递给CreateBitmap。除了与实际的装置内容有相同的记忆体组织之外,DDB与装置内容没有其他联系。

copyright dedecms

CreateDiscardableBitmap函式与CreateCompatibleBitmap的参数相同,并且功能上相同。在早期的Windows版本中,CreateDiscardableBitmap建立的点阵图可以在记忆体减少时由Windows将其从记忆体中清除,然後程式再重建点阵图资料。

本文来自织梦

第三个点阵图建立函式是CreateBitmapIndirectcopyright dedecms

hBitmap CreateBitmapIndirect (&bitmap) ; dedecms.com 

其中bitmapBITMAP型态的结构。BITMAP结构定义如下:

内容来自dedecms

typedef struct _tagBITMAP 
内容来自dedecms
{ 
织梦好,好织梦
        LONG           bmType ;                       // set to 0 
dedecms.com
        LONG           bmWidth ;                      // width in pixels 织梦好,好织梦 
        LONG           bmHeight ;                     // height in pixels copyright dedecms 
        LONG           bmWidthBytes ;                 // width of row in bytes 

织梦好,好织梦

        WORD           bmPlanes ;                     // number of color planes 织梦内容管理系统 
        WORD           bmBitsPixel ;                  // number of bits per pixel 

织梦好,好织梦

        LPVOID  bmBits ;                              // pointer to pixel bits 
dedecms.com
} 织梦内容管理系统 
BITMAP, * PBITMAP ; 

织梦好,好织梦

在呼叫CreateBitmapIndirect函式时,您不需要设定bmWidthBytes栏位。Windows将为您计算,您也可以将bmBits栏位设定为NULL,或者设定为初始化点阵图时用的图素位元位址。 织梦内容管理系统

GetObject函式内也使用BITMAP结构,首先定义一个BITMAP型态的结构。

内容来自dedecms

BITMAP bitmap ; 
dedecms.com

并呼叫函式如下:

copyright dedecms

GetObject (hBitmap, sizeof (BITMAP), &bitmap) ; 
copyright dedecms

Windows将用点阵图资讯填充BITMAP结构的栏位,不过,bmBits栏位等於NULLdedecms.com

您最後应呼叫DeleteObject来清除程式内建立的所有点阵图。 织梦好,好织梦

点阵图位元
  织梦内容管理系统

CreateBitmapCreateBitmapIndirect来建立设备相关GDI点阵图物件时,您可以给点阵图图素位元指定一个指标。或者您也可以让点阵图维持未初始化的状态。在建立点阵图以後,Windows还提供两个函式来获得并设定图素位元。

copyright dedecms

要设定图素位元,请呼叫: 织梦内容管理系统

SetBitmapBits (hBitmap, cBytes, &bits) ; 

copyright dedecms

GetBitmapBits函式有相同的语法:

织梦好,好织梦

GetBitmapBits (hBitmap, cBytes, &bits) ; 
copyright dedecms

在这两个函式中,cBytes指明要复制的位元组数,bits是最少cBytes大小的缓冲区。 织梦好,好织梦

DDB中的图素位元从顶列开始排列。我在前面说过,每列的位元组数都是偶数。除此之外,没什么好说明的了。如果点阵图是单色的,也就是说它有1个位元面并且每个图素占1位元,则每个图素不是1就是0。每列最左边的图素是本列第一个位元组最高位元的位元。我们在本章的後面讲完如何显示单色DDB之後,将做一个单色的DDB

本文来自织梦

对於非单色点阵图,应避免出现您需要知道图素位元含义的状况。例如,假定在8位颜色的VGA上执行Windows,您可以呼叫CreateCompatibleBitmap。通过GetDeviceCaps,您能够确定您正处理一个有1个颜色位元面和每图素8位元的设备。一个位元组储存一个图素。但是图素值0x37是什么意思呢?很明显是某种颜色,但到底是什么颜色呢?

copyright dedecms

图素实际上并不涉及任何固定的颜色,它只是一个值。DDB没有颜色表。问题的关键在於:当DDB显示在萤幕上时,图素的颜色是什么。它肯定是某种颜色,但具体是什么颜色呢?显示的图素将与在显示卡上的调色盘查看表里的0x37索引值代表的RGB颜色有关。这就是您现在碰到的装置依赖性。 dedecms.com

不过,不要只因为我们不知道图素值的含义,就假定非单色DDB没用。我们将简要看一下它们的用途。下一章,我们将看到SetBitmapBitsGetBitmapBits函式是如何被更有用的SetDIBitsGetDIBits函式所取代的。 dedecms.com

因此,基本的规则是这样的:不要用CreateBitmapCreateBitmapIndirectSetBitmapBits来设定彩色DDB的位元,您只能安全地使用这些函式来设定单色DDB的位元。(如果您在呼叫GetBitmapBits期间,从其他相同格式的DDB中获得位元,那么这些规则例外。) copyright dedecms

在继续之前,让我再讨论一下SetBitmapDimensionExGetBitmapDimensionEx函式。这些函式让您设定(和获得)点阵图的测量尺寸(以0.1毫米为单位)。这些资讯与点阵图解析度一起储存在GDI中,但不用於任何操作。它只是您与DDB联系的一个测量尺寸标识。

dedecms.com

记忆体装置内容
 

织梦好,好织梦

我们必须解决的下一个概念是记忆体装置内容。您需要用记忆体装置内容来处理GDI点阵图物件。 本文来自织梦

通常,装置内容指的是特殊的图形输出设备(例如视讯显示器或者印表机)及其装置驱动程式。记忆体装置内容只位於记忆体中,它不是真正的图形输出设备,但可以说与指定的真正设备「相容」。 dedecms.com

要建立一个记忆体装置内容,您必须首先有实际设备的装置内容代号。如果是hdc,那么您可以像下面那样建立记忆体装置内容:

dedecms.com

hdcMem = CreateCompatibleDC (hdc) ; dedecms.com 

通常,函式的呼叫比这更简单。如果您将参数设为NULL,那么Windows将建立一个与视讯显示器相相容的记忆体装置内容。应用程式建立的任何记忆体装置内容最终都通过呼叫DeleteDC来清除。 织梦好,好织梦

记忆体装置内容有一个与实际位元映射设备相同的显示平面。不过,最初此显示平面非常小-单色、1图素宽、1图素高。显示平面就是单独1位元。 本文来自织梦

当然,用1位元的显示平面,您不能做更多的工作,因此下一步就是扩大显示平面。您可以通过将一个GDI点阵图物件选进记忆体装置内容来完成这项工作,例如:

本文来自织梦

SelectObject (hdcMem, hBitmap) ; 

dedecms.com

此函式与您将画笔、画刷、字体、区域和调色盘选进装置内容的函式相同。然而,记忆体装置内容是您可以选进点阵图的唯一一种装置内容型态。(如果需要,您也可以将其他GDI物件选进记忆体装置内容。) 织梦内容管理系统

只有选进记忆体装置内容的点阵图是单色的,或者与记忆体装置内容相容设备有相同的色彩组织时,SelectObject才会起作用。这也是建立特殊的DDB(例如有5个位元面,且每图素3位元)没有用的原因。

本文来自织梦

现在情况是这样:SelectObject呼叫以後,DDB就是记忆体装置内容的显示平面。处理实际装置内容的每项操作,您几乎都可以用於记忆体装置内容。例如,如果用GDI画图函式在记忆体装置内容中画图,那么图像将画在点阵图上。这是非常有用的。还可以将记忆体装置内容作为来源,把视讯装置内容作为目的来呼叫BitBlt。这就是在显示器上绘制点阵图的方法。如果把视讯装置内容作为来源,把记忆体装置内容作为目的,那么呼叫BitBlt可将萤幕上的一些内容复制给点阵图。我们将看到这些都是可能的。 dedecms.com

载入点阵图资源
  内容来自dedecms

除了各种各样的点阵图建立函式以外,获得GDI点阵图物件代号的另一个方法就是呼叫LoadBitmap函式。使用此函式,您不必担心点阵图格式。在程式中,您只需简单地按资源来建立点阵图,这与建立图示或者滑鼠游标的方法类似。LoadBitmap函式的语法与LoadIconLoadCursor相同: 织梦好,好织梦

hBitmap = LoadBitmap (hInstance, szBitmapName) ; dedecms.com 

如果想载入系统点阵图,那么将第一个参数设为NULL。这些不同的点阵图是Windows视觉介面(例如关闭方块和勾选标记)的一小部分,它们的识别字以字母OBM开始。如果点阵图与整数识别字而不是与名称有联系,那么第二个参数就可以使用MAKEINTRESOURCE巨集。由LoadBitmap载入的所有点阵图最终应用DeleteObject清除。 dedecms.com

如果点阵图资源是单色的,那么从LoadBitmap传回的代号将指向一个单色的点阵图物件。如果点阵图资源不是单色,那么从LoadBitmap传回的代号将指向一个GDI点阵图物件,该物件与执行程式的视讯显示器有相同的色彩组织。因此,点阵图始终与视讯显示器相容,并且总是选进与视讯显示器相容的记忆体装置内容中。采用LoadBitmap呼叫後,就不用担心任何色彩转换的问题了。在下一章中,我们就知道LoadBitmap的具体运作方式了。

本文来自织梦

程式14-3所示的BRICKS1程式示范了载入一小张单色点阵图资源的方法。此点阵图本身不像砖块,但当它水平和垂直重复时,就与砖墙相似了。 dedecms.com

 程式14-3  BRICKS1 本文来自织梦 
BRICKS1.C 

织梦内容管理系统

/*-------------------------------------------------------------------------- 

织梦好,好织梦

        BRICKS1.C -- LoadBitmap Demonstration 本文来自织梦 
                                                             (c) Charles Petzold, 1998 

dedecms.com

----------------------------------------------------------------------------*/ 

copyright dedecms

  本文来自织梦 
#include <windows.h> dedecms.com 
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; 

dedecms.com

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, 织梦内容管理系统 
                               PSTR szCmdLine, int iCmdShow) 

织梦内容管理系统

{ 
copyright dedecms
        static TCHAR   szAppName [] = TEXT ("Bricks1") ; 织梦内容管理系统 
        HWND                           hwnd ; 

织梦内容管理系统

        MSG                            msg ; 

copyright dedecms

        WNDCLASS                       wndclass ; 织梦内容管理系统 
  织梦内容管理系统 
        wndclass.style                        = CS_HREDRAW | CS_VREDRAW ; 织梦好,好织梦 
        wndclass.lpfnWndProc                  = WndProc ; 

织梦好,好织梦

        wndclass.cbClsExtra                   = 0 ; 

织梦好,好织梦

        wndclass.cbWndExtra                   = 0 ; 

本文来自织梦

        wndclass.hInstance                    = hInstance ; dedecms.com 
        wndclass.hIcon                        = LoadIcon (NULL, IDI_APPLICATION) ; 
织梦好,好织梦
        wndclass.hCursor                      = LoadCursor (NULL, IDC_ARROW) ; 
本文来自织梦
        wndclass.hbrBackground                = (HBRUSH) GetStockObject (WHITE_BRUSH) ; 织梦好,好织梦 
        wndclass.lpszMenuName                 = NULL ; 
内容来自dedecms
        wndclass.lpszClassName                = szAppName ; 织梦好,好织梦 
      dedecms.com 
        if (!RegisterClass (&wndclass)) 织梦内容管理系统 
        { copyright dedecms 
                       MessageBox (NULL, TEXT ("This program requires Windows NT!"), 
织梦内容管理系统
                                                     szAppName, MB_ICONERROR) ; 
内容来自dedecms
                       return 0 ; 本文来自织梦 
     } 
织梦内容管理系统
      

内容来自dedecms

        hwnd = CreateWindow (  szAppName, TEXT ("LoadBitmap Demo"),  
dedecms.com
                                        WS_OVERLAPPEDWINDOW,  织梦好,好织梦 
                                        CW_USEDEFAULT, CW_USEDEFAULT, 
dedecms.com
                                        CW_USEDEFAULT, CW_USEDEFAULT, dedecms.com 
                                        NULL, NULL, hInstance, NULL) ; 内容来自dedecms 
  本文来自织梦 
        ShowWindow (hwnd, iCmdShow) ; dedecms.com 
        UpdateWindow (hwnd) ; 内容来自dedecms 
  copyright dedecms 
        while (GetMessage (&msg, NULL, 0, 0)) copyright dedecms 
        { 

织梦内容管理系统

                               TranslateMessage (&msg) ; 

内容来自dedecms

                               DispatchMessage (&msg) ; 
内容来自dedecms
        } copyright dedecms 
        return msg.wParam ; 内容来自dedecms 
} dedecms.com 
  dedecms.com 
LRESULT CALLBACK WndProc (     HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) 织梦好,好织梦 
{ 内容来自dedecms 
        static HBITMAP hBitmap ; 
dedecms.com
        static int                     cxClient, cyClient, cxSource, cySource ; 
织梦内容管理系统
        BITMAP                         bitmap ; 
织梦好,好织梦
        HDC                            hdc, hdcMem ; 本文来自织梦 
        HINSTANCE                      hInstance ; 内容来自dedecms 
        int                            x, y ; copyright dedecms 
        PAINTSTRUCT                    ps ; 织梦内容管理系统 
      内容来自dedecms 
        switch (message) 
copyright dedecms
        { 内容来自dedecms 
        case    WM_CREATE: copyright dedecms 
                               hInstance = ((LPCREATESTRUCT) lParam)->hInstance ; 

织梦好,好织梦

  
织梦内容管理系统
                               hBitmap = LoadBitmap (hInstance, TEXT ("Bricks")) ; 织梦好,好织梦 
  织梦内容管理系统 
                               GetObject (hBitmap, sizeof (BITMAP), &bitmap) ; 
内容来自dedecms
  本文来自织梦 
                               cxSource = bitmap.bmWidth ; 本文来自织梦 
                               cySource = bitmap.bmHeight ; 内容来自dedecms 
  织梦内容管理系统 
                               return 0 ; 
织梦内容管理系统
  织梦内容管理系统 
        case    WM_SIZE: 织梦好,好织梦 
                               cxClient = LOWORD (lParam) ; 
内容来自dedecms
                               cyClient = HIWORD (lParam) ; 

织梦好,好织梦

                               return 0 ; 

织梦好,好织梦

  copyright dedecms 
        case    WM_PAINT: 本文来自织梦 
                               hdc = BeginPaint (hwnd, &ps) ; 

本文来自织梦

  内容来自dedecms 
                               hdcMem = CreateCompatibleDC (hdc) ; 
内容来自dedecms
                               SelectObject (hdcMem, hBitmap) ; 

织梦好,好织梦

  
本文来自织梦
                               for (y = 0 ; y < cyClient ; y += cySource) 本文来自织梦 
                               for (x = 0 ; x < cxClient ; x += cxSource) 织梦内容管理系统 
                               { 织梦好,好织梦 
                       BitBlt (hdc, x, y, cxSource, cySource, hdcMem, 0, 0, SRCCOPY) ; 
织梦好,好织梦
          } 

dedecms.com

  

copyright dedecms

                               DeleteDC (hdcMem) ; 本文来自织梦 
                               EndPaint (hwnd, &ps) ; 
织梦内容管理系统
                               return 0 ; 内容来自dedecms 
         

copyright dedecms

        case    WM_DESTROY: 本文来自织梦 
                               DeleteObject (hBitmap) ; 
织梦内容管理系统
                               PostQuitMessage (0) ; 

织梦好,好织梦

                               return 0 ; 

dedecms.com

        } 

本文来自织梦

        return DefWindowProc (hwnd, message, wParam, lParam) ; 织梦好,好织梦 
} 

copyright dedecms

 BRICKS1.RC (摘录) 织梦好,好织梦 
//Microsoft Developer Studio generated resource script. 本文来自织梦 
#include "resource.h" 
本文来自织梦
#include "afxres.h" 

copyright dedecms

  

copyright dedecms

///////////////////////////////////////////////////////////////////////////// 本文来自织梦 
// Bitmap 织梦好,好织梦 
BRICKS                                        BITMAP  DISCARDABLE     "Bricks.bmp" 

内容来自dedecms

 

织梦好,好织梦

BRICKS.BMP dedecms.com

 


  dedecms.com

本文来自织梦

Visual C++ Developer Studio中建立点阵图时,应指明点阵图的高度和宽度都是8个图素,是单色,名称是「Bricks」。BRICKS1程式在WM_CREATE讯息处理期间载入了点阵图并用GetObject来确定点阵图的图素尺寸(以便当点阵图不是8图素见方时程式仍能继续工作)。以後,BRICKS1将在WM_DESTROY讯息中删除此点阵图。 织梦好,好织梦

WM_PAINT讯息处理期间,BRICKS1建立了一个与显示器相容的记忆体装置内容,并且选进了点阵图。然後是从记忆体装置内容到显示区域装置内容一系列的BitBlt函式呼叫,再删除记忆体装置内容。图14-3显示了程式的执行结果。

织梦内容管理系统

顺便说一下,Developer Studio建立的BRICKS.BMP档案是一个装置无关点阵图。您可能想在Developer Studio内建立一个彩色的BRICKS.BMP档案(您可自己选定颜色),并且保证一切工作正常。

织梦内容管理系统

我们看到DIB能转换成与视讯显示器相容的GDI点阵图物件。我们将在下一章看到这是如何操作的。

织梦好,好织梦


  织梦内容管理系统

copyright dedecms

  织梦好,好织梦

14-3 BRICKS1的萤幕显示

内容来自dedecms

 

单色点阵图格式
 

织梦内容管理系统

如果您在处理小块单色图像,那么您不必把它们当成资源来建立。与彩色点阵图物件不同,单色位元的格式相对简单一些,而且几乎能全部从您要建立的图像中分离出来。例如,假定您要建立下图所示的点阵图: 织梦好,好织梦


 

dedecms.com

本文来自织梦

您能写下一系列的位元(0代表黑色,1代表白色),这些位元直接对应於网格。从左到右读这些位元,您能给每8位元组配置一个十六进位元的位元组值。如果点阵图的宽度不是16的倍数,在位元组的右边用零填充,以得到偶数个位元组:

本文来自织梦

0 1 0 1 0 0 0 1 0 1 1 1 0 1 1 1 0 0 0 1 = 51 77 10 00 

copyright dedecms

0 1 0 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 0 1 = 57 77 50 00 内容来自dedecms 
0 0 0 1 0 0 1 1 0 1 1 1 0 1 1 1 0 1 0 1 = 13 77 50 00 织梦好,好织梦 
0 1 0 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 0 1 = 57 77 50 00 织梦内容管理系统 
0 1 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 = 51 11 10 00 
织梦内容管理系统

图素宽为20,扫描线高为5,位元组宽为4。您可以用下面的叙述来设定此点阵图的BITMAP结构:

内容来自dedecms

static BITMAP bitmap                  = { 0, 20, 5, 4, 1, 1 } ; 本文来自织梦 

并且可以将位元储存在BYTE阵列中:

copyright dedecms

static BYTE  bits []   = {     0x51, 0x77, 0x10, 0x00, 

织梦好,好织梦

                                      0x57, 0x77, 0x50, 0x00, dedecms.com 
                                              0x13, 0x77, 0x50, 0x00, 织梦好,好织梦 
                                   0x57, 0x77, 0x50, 0x00, 
copyright dedecms
                                0x51, 0x11, 0x10, 0x00 } ; 织梦内容管理系统 

CreateBitmapIndirect来建立点阵图需要下面两条叙述:

织梦好,好织梦

bitmap.bmBits = (PSTR) bits ;  

本文来自织梦

hBitmap = CreateBitmapIndirect (&bitmap) ; 织梦内容管理系统 

另一种方法是:

本文来自织梦

hBitmap = CreateBitmapIndirect (&bitmap) ; 

本文来自织梦

SetBitmapBits (hBitmap, sizeof bits, bits) ; dedecms.com 

您也可以用一道叙述来建立点阵图:

dedecms.com

hBitmap = CreateBitmap (20, 5, 1, 1, bits) ; 

本文来自织梦

在程式14-4显示的BRICKS2程式利用此技术直接建立了砖块点阵图,而没有使用资源。 织梦好,好织梦

 程式14-4  BRICKS2 内容来自dedecms 
BRICKS2.C 

内容来自dedecms

/*-------------------------------------------------------------------------- 本文来自织梦 
        BRICKS2.C --   CreateBitmap Demonstration 
本文来自织梦
                                                             (c) Charles Petzold, 1998 copyright dedecms 
---------------------------------------------------------------------------*/ copyright dedecms 
  

本文来自织梦

#include <windows.h> copyright dedecms 
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; 织梦内容管理系统 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, 
本文来自织梦
                    PSTR szCmdLine, int iCmdShow) 
dedecms.com
{ copyright dedecms 
        static TCHAR   szAppName [] = TEXT ("Bricks2") ; 织梦好,好织梦 
        HWND                           hwnd ; 织梦好,好织梦 
        MSG                            msg ; 
copyright dedecms
        WNDCLASS                       wndclass ; 

copyright dedecms

  

内容来自dedecms

        wndclass.style                        = CS_HREDRAW | CS_VREDRAW ; 

本文来自织梦

        wndclass.lpfnWndProc                  = WndProc ; 
织梦好,好织梦
        wndclass.cbClsExtra                   = 0 ; copyright dedecms 
        wndclass.cbWndExtra                   = 0 ; 
织梦内容管理系统
        wndclass.hInstance                    = hInstance ; dedecms.com 
        wndclass.hIcon                        = LoadIcon (NULL, IDI_APPLICATION) ; 内容来自dedecms 
        wndclass.hCursor                      = LoadCursor (NULL, IDC_ARROW) ; 

copyright dedecms

        wndclass.hbrBackground                = (HBRUSH) GetStockObject (WHITE_BRUSH) ; 
本文来自织梦
        wndclass.lpszMenuName                 = NULL ; 

本文来自织梦

        wndclass.lpszClassName                = szAppName ; 
织梦内容管理系统
      织梦好,好织梦 
        if (!RegisterClass (&wndclass)) 

copyright dedecms

        { dedecms.com 
                       MessageBox (   NULL, TEXT ("This program requires Windows NT!"), dedecms.com 
                               szAppName, MB_ICONERROR) ; 

copyright dedecms

                       return 0 ; 

dedecms.com

        } dedecms.com 
  织梦好,好织梦 
               hwnd = CreateWindow (szAppName, TEXT ("CreateBitmap Demo"),  内容来自dedecms 
                        WS_OVERLAPPEDWINDOW,  内容来自dedecms 
                        CW_USEDEFAULT, CW_USEDEFAULT, 织梦好,好织梦 
                        CW_USEDEFAULT, CW_USEDEFAULT, 
本文来自织梦
                        NULL, NULL, hInstance, NULL) ; 

copyright dedecms

  

copyright dedecms

        ShowWindow (hwnd, iCmdShow) ; 内容来自dedecms 
        UpdateWindow (hwnd) ; 
copyright dedecms
  
copyright dedecms
        while (GetMessage (&msg, NULL, 0, 0)) copyright dedecms 
        { 本文来自织梦 
                               TranslateMessage (&msg) ; 内容来自dedecms 
                               DispatchMessage (&msg) ; copyright dedecms 
        } 

本文来自织梦

        return msg.wParam ; 织梦内容管理系统 
} 

织梦内容管理系统

  
织梦好,好织梦
LRESULT CALLBACK WndProc (     HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) dedecms.com 
{ 
织梦好,好织梦
        static BITMA           Pbitmap = {    0, 8, 8, 2, 1, 1 } ; 

本文来自织梦

        static BYTE                    bits [8][2]={ 0xFF, 0, 0x0C, 0, 0x0C, 0, 0x0C, 0, 内容来自dedecms 
                                              0xFF, 0, 0xC0, 0, 0xC0, 0, 0xC0, 0 } ; 织梦好,好织梦 
        static HBITMAP hBitmap ; 
内容来自dedecms
        static int                     cxClient, cyClient, cxSource, cySource ; 
内容来自dedecms
        HDC                            hdc, hdcMem ; 
内容来自dedecms
        int                            x, y ; 

织梦好,好织梦

        PAINTSTRUCT                    ps ; 

本文来自织梦

      

织梦好,好织梦

        switch (message) 内容来自dedecms 
        { 
织梦内容管理系统
        case    WM_CREATE: 

织梦好,好织梦

                               bitmap.bmBits = bits ; 

织梦好,好织梦

                               hBitmap          = CreateBitmapIndirect (&bitmap) ; 

织梦好,好织梦

                               cxSource         = bitmap.bmWidth ; 织梦好,好织梦 
                               cySource         = bitmap.bmHeight ; 
dedecms.com
                               return 0 ; 织梦内容管理系统 
  
本文来自织梦
        case    WM_SIZE: 织梦好,好织梦 
                               cxClient = LOWORD (lParam) ; 
织梦内容管理系统
                               cyClient = HIWORD (lParam) ; copyright dedecms 
                               return 0 ; 
本文来自织梦
  

copyright dedecms

        case    WM_PAINT: 

织梦好,好织梦

                               hdc = BeginPaint (hwnd, &ps) ; 内容来自dedecms 
  dedecms.com 
                               hdcMem = CreateCompatibleDC (hdc) ; 
内容来自dedecms
                               SelectObject (hdcMem, hBitmap) ; 
织梦内容管理系统
  织梦内容管理系统 
                               for (y = 0 ; y < cyClient ; y += cySource) 

织梦内容管理系统

                               for (x = 0 ; x < cxClient ; x += cxSource) 织梦好,好织梦 
                               { 
本文来自织梦
                                      BitBlt (hdc, x, y, cxSource, cySource, hdcMem, 0, 0, SRCCOPY) ; 
织梦好,好织梦
                               } dedecms.com 
  织梦内容管理系统 
                               DeleteDC (hdcMem) ; 织梦好,好织梦 
                               EndPaint (hwnd, &ps) ; 
织梦内容管理系统
                               return 0 ; 本文来自织梦 
  织梦内容管理系统 
        case    WM_DESTROY: 

本文来自织梦

                               DeleteObject (hBitmap) ; 

织梦好,好织梦

                               PostQuitMessage (0) ; 织梦内容管理系统 
                               return 0 ; copyright dedecms 
        } 织梦内容管理系统 
        return DefWindowProc (hwnd, message, wParam, lParam) ; dedecms.com 
} 
织梦好,好织梦

您可以尝试一下与彩色点阵图相似的物件。例如,如果您的视讯显示器执行在256色模式下,那么您可以根据表14-2来定义彩色砖的每个图素。不过,当程式执行在其他显示模式下时,此程式码不起作用。以装置无关方式处理彩色点阵图需要使用下章讨论的DIBdedecms.com

点阵图中的画刷
  内容来自dedecms

BRICKS系列的最後一个专案是BRICKS3,如程式14-5所示。乍看此程式,您可能会有这种感觉:程式码哪里去了呢?

内容来自dedecms

 程式14-5  BRICKS3 织梦好,好织梦 
BRICKS3.C 织梦内容管理系统 
/*------------------------------------------------------------------------- 织梦好,好织梦 
        BRICKS3.C -- CreatePatternBrush Demonstration dedecms.com 
                                                             (c) Charles Petzold, 1998 copyright dedecms 
---------------------------------------------------------------------------*/ dedecms.com 
  织梦好,好织梦 
#include <windows.h> copyright dedecms 
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; 
本文来自织梦
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, copyright dedecms 
                               PSTR szCmdLine, int iCmdShow) dedecms.com 
{ dedecms.com 
        static TCHAR           szAppName [] = TEXT ("Bricks3") ; copyright dedecms 
        HBITMAP                hBitmap ; 
织梦内容管理系统
        HBRUSH                 hBrush ; 

织梦好,好织梦

        HWND                   hwnd ; 织梦好,好织梦 
        MSG                    msg ; 
copyright dedecms
        WNDCLASS               wndclass ; 
本文来自织梦
  
本文来自织梦
        hBitmap = LoadBitmap (hInstance, TEXT ("Bricks")) ; 
织梦内容管理系统
        hBrush = CreatePatternBrush (hBitmap) ; 
内容来自dedecms
        DeleteObject (hBitmap) ; 本文来自织梦 
  

copyright dedecms

        wndclass.style                                = CS_HREDRAW | CS_VREDRAW ; dedecms.com 
        wndclass.lpfnWndProc                          = WndProc ; 

dedecms.com

        wndclass.cbClsExtra                           = 0 ; dedecms.com 
        wndclass.cbWndExtra                           = 0 ; 

dedecms.com

        wndclass.hInstance                            = hInstance ; 
copyright dedecms
        wndclass.hIcon                                = LoadIcon (NULL, IDI_APPLICATION) ; 内容来自dedecms 
        wndclass.hCursor                              = LoadCursor (NULL, IDC_ARROW) ; 
dedecms.com
        wndclass.hbrBackground                = hBrush ;  dedecms.com 
        wndclass.lpszMenuName                 = NULL ; 
dedecms.com
        wndclass.lpszClassName                = szAppName ; 织梦内容管理系统 
      copyright dedecms 
        if (!RegisterClass (&wndclass)) dedecms.com 
        { 本文来自织梦 
                       MessageBox (   NULL, TEXT ("This program requires Windows NT!"), 

dedecms.com

                szAppName, MB_ICONERROR) ; 
dedecms.com
                       return 0 ; 内容来自dedecms 
     } 

内容来自dedecms

      
dedecms.com
        hwnd = CreateWindow (szAppName, TEXT ("CreatePatternBrush Demo"),  
dedecms.com
                               WS_OVERLAPPEDWINDOW,  织梦内容管理系统 
                               CW_USEDEFAULT, CW_USEDEFAULT, 织梦好,好织梦 
                               CW_USEDEFAULT, CW_USEDEFAULT, 
织梦内容管理系统
                               NULL, NULL, hInstance, NULL) ; 
织梦内容管理系统
  
dedecms.com
        ShowWindow (hwnd, iCmdShow) ; 

本文来自织梦

        UpdateWindow (hwnd) ; 内容来自dedecms 
  
本文来自织梦
        while (GetMessage (&msg, NULL, 0, 0)) 
copyright dedecms
       { 

织梦内容管理系统

                       TranslateMessage (&msg) ; 内容来自dedecms 
                       DispatchMessage (&msg) ; copyright dedecms 
     } 内容来自dedecms 
  织梦好,好织梦 
        DeleteObject (hBrush) ; 本文来自织梦 
        return msg.wParam ; 
copyright dedecms
} 
内容来自dedecms
  
本文来自织梦
LRESULT CALLBACK WndProc (     HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) 
本文来自织梦
{ 
copyright dedecms
        switch (message) copyright dedecms 
       { 织梦好,好织梦 
        case    WM_DESTROY: copyright dedecms 
                               PostQuitMessage (0) ; 

织梦好,好织梦

                               return 0 ; 织梦好,好织梦 
     } 

copyright dedecms

        return DefWindowProc (hwnd, message, wParam, lParam) ; dedecms.com 
} 织梦好,好织梦 
 BRICKS3.RC (摘录) 织梦好,好织梦 
//Microsoft Developer Studio generated resource script. 
dedecms.com
#include "resource.h" 
织梦好,好织梦
#include "afxres.h" dedecms.com 
  copyright dedecms 
///////////////////////////////////////////////////////////////////////////// 内容来自dedecms 
// Bitmap 
本文来自织梦
BRICKS                                        BITMAP  DISCARDABLE     "Bricks.bmp" 

dedecms.com

此程式与BRICKS1使用同一个BRICKS.BMP档案,而且视窗看上去也相同。

织梦好,好织梦

正如您看到的一样,视窗讯息处理程式没有更多的内容。BRICKS3实际上使用砖块图案作为视窗类别背景画刷,它在WNDCLASS结构的hbrBackground栏位中定义。 dedecms.com

您现在可能猜想GDI画刷是很小的点阵图,通常是8个图素见方。如果将LOGBRUSH结构的lbStyle栏位设定为BS_PATTERN,然後呼叫CreatePatternBrushCreateBrushIndirect,您就可以在点阵图外面来建立画刷了。此点阵图至少是宽高各8个图素。如果再大,Windows 98将只使用点阵图的左上角作为画刷。而Windows NT不受此限制,它会使用整个点阵图。

本文来自织梦

请记住,画刷和点阵图都是GDI物件,而且您应该在程式终止前删除您在程式中建立画刷和点阵图。如果您依据点阵图建立画刷,那么在用画刷画图时,Windows将复制点阵图位元到画刷所绘制的区域内。呼叫CreatePatternBrush(或者CreateBrushIndirect)之後,您可以立即删除点阵图而不会影响到画笔。类似地,您也可以删除画刷而不会影响到您选进的原始点阵图。注意,BRICKS3在建立画刷後删除了点阵图,并在程式终止前删除了画刷。 本文来自织梦

绘制点阵图
 

本文来自织梦

在视窗中绘图时,我们已经将点阵图当成绘图来源使用过了。这要求先将点阵图选进记忆体装置内容,并呼叫BitBlt或者StretchBlt。您也可以用记忆体装置内容代号作为所有实际呼叫的GDI函式中的第一参数。记忆体装置内容的动作与实际的装置内容相同,除非显示平面是点阵图。 dedecms.com

程式14-6所示的HELLOBIT程式展示了此项技术。程式在一个小点阵图上显示了字串「Hello, world!」,然後从点阵图到程式显示区域执行BitBltStretchBlt(依照选择的功能表选项而定)。

织梦好,好织梦

 程式14-6  HELLOBIT 

copyright dedecms

HELLOBIT.C 
本文来自织梦
/*----------------------------------------------------------------------- dedecms.com 
        HELLOBIT.C --          Bitmap Demonstration copyright dedecms 
                                                                     (c) Charles Petzold, 1998 

内容来自dedecms

-------------------------------------------------------------------------*/ 

dedecms.com

  
内容来自dedecms
#include <windows.h> 
织梦好,好织梦
#include "resource.h" 

织梦内容管理系统

  
织梦内容管理系统
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; 

织梦内容管理系统

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, 内容来自dedecms 
                    PSTR szCmdLine, int iCmdShow) 内容来自dedecms 
{ 
dedecms.com
        static TCHAR           szAppName [] = TEXT ("HelloBit") ; 本文来自织梦 
        HWND                               hwnd ; 

dedecms.com

        MSG                                   msg ; 
本文来自织梦
        WNDCLASS                              wndclass ; 内容来自dedecms 
  
织梦内容管理系统
        wndclass.style                                = CS_HREDRAW | CS_VREDRAW ; copyright dedecms 
        wndclass.lpfnWndProc                          = WndProc ; 

copyright dedecms

        wndclass.cbClsExtra                           = 0 ; 织梦内容管理系统 
        wndclass.cbWndExtra                           = 0 ; 

copyright dedecms

        wndclass.hInstance                            = hInstance ; 

织梦好,好织梦

        wndclass.hIcon                                = LoadIcon (NULL, IDI_APPLICATION) ; copyright dedecms 
        wndclass.hCursor                              = LoadCursor (NULL, IDC_ARROW) ; 织梦好,好织梦 
        wndclass.hbrBackground                = (HBRUSH) GetStockObject (WHITE_BRUSH) ; 织梦好,好织梦 
        wndclass.lpszMenuName                 = szAppName ; 

copyright dedecms

        wndclass.lpszClassName                = szAppName ; 
织梦内容管理系统
      
织梦内容管理系统
        if (!RegisterClass (&wndclass)) 织梦好,好织梦 
        { 织梦好,好织梦 
        MessageBox (   NULL, TEXT ("This program requires Windows NT!"), 

织梦内容管理系统

                                                             szAppName, MB_ICONERROR) ; 
织梦内容管理系统
       return 0 ; 
本文来自织梦
        } 

本文来自织梦

      

dedecms.com

        hwnd = CreateWindow (szAppName, TEXT ("HelloBit"),  织梦好,好织梦 
                          WS_OVERLAPPEDWINDOW,  本文来自织梦 
                          CW_USEDEFAULT, CW_USEDEFAULT, dedecms.com 
                          CW_USEDEFAULT, CW_USEDEFAULT, 

dedecms.com

                          NULL, NULL, hInstance, NULL) ; 
本文来自织梦
  织梦内容管理系统 
        ShowWindow (hwnd, iCmdShow) ; 本文来自织梦 
        UpdateWindow (hwnd) ; 
copyright dedecms
  

copyright dedecms

        while (GetMessage (&msg, NULL, 0, 0)) 
织梦好,好织梦
     { 

本文来自织梦

                       TranslateMessage (&msg) ; 

copyright dedecms

                       DispatchMessage (&msg) ; 
本文来自织梦
        } 
织梦好,好织梦
               return msg.wParam ; 
dedecms.com
} 

内容来自dedecms

  
内容来自dedecms
LRESULT CALLBACK WndProc (     HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) 
织梦内容管理系统
{ dedecms.com 
        static HBITMAP        hBitmap ; 

本文来自织梦

        static HDC            hdcMem ; 织梦内容管理系统 
        static         int     cxBitmap, cyBitmap, cxClient, cyClient, iSize = IDM_BIG ; 本文来自织梦 
        static TCHAR * szText = TEXT (" Hello, world! ") ; 内容来自dedecms 
        HDC                    hdc ; copyright dedecms 
        HMENU                  hMenu ; 

本文来自织梦

        int                    x, y ; copyright dedecms 
        PAINTSTRUCT            ps ; 

本文来自织梦

        SIZE                   size ; 

copyright dedecms

      
本文来自织梦
        switch (message) 织梦好,好织梦 
        { dedecms.com 
        case    WM_CREATE: 

copyright dedecms

                               hdc = GetDC (hwnd) ; 内容来自dedecms 
                               hdcMem  = CreateCompatibleDC (hdc) ; 织梦内容管理系统 
  

copyright dedecms

                               GetTextExtentPoint32 (hdc, szText, lstrlen (szText), &size) ; 本文来自织梦 
                               cxBitmap = size.cx ; 

织梦内容管理系统

                               cyBitmap = size.cy ; 

本文来自织梦

                               hBitmap = CreateCompatibleBitmap (hdc, cxBitmap, cyBitmap) ; 

本文来自织梦

  copyright dedecms 
                               ReleaseDC (hwnd, hdc) ; dedecms.com 
  dedecms.com 
                               SelectObject (hdcMem, hBitmap) ; 织梦好,好织梦 
                               TextOut (hdcMem, 0, 0, szText, lstrlen (szText)) ; copyright dedecms 
                               return 0 ; 内容来自dedecms 
  dedecms.com 
        case    WM_SIZE: 
织梦内容管理系统
                               cxClient = LOWORD (lParam) ; 

内容来自dedecms

                               cyClient = HIWORD (lParam) ; 

copyright dedecms

                               return 0 ; 
本文来自织梦
  

dedecms.com

        case    WM_COMMAND: 织梦好,好织梦 
                               hMenu = GetMenu (hwnd) ; 
dedecms.com
  

织梦好,好织梦

                               switch (LOWORD (wParam)) 

织梦内容管理系统

                               { copyright dedecms 
                               case    IDM_BIG: 
内容来自dedecms
                               case    IDM_SMALL: copyright dedecms 
                                              CheckMenuItem (hMenu, iSize, MF_UNCHECKED) ; 
dedecms.com
                                              iSize = LOWORD (wParam) ; 
织梦好,好织梦
                                              CheckMenuItem (hMenu, iSize, MF_CHECKED) ; 

内容来自dedecms

                                              InvalidateRect (hwnd, NULL, TRUE) ; 
dedecms.com
                                              break ; dedecms.com 
                               } dedecms.com 
                               return 0 ; dedecms.com 
  
copyright dedecms
        case    WM_PAINT: 本文来自织梦 
                               hdc = BeginPaint (hwnd, &ps) ; 内容来自dedecms 
  
织梦内容管理系统
                               switch (iSize) 织梦内容管理系统 
                               { 

本文来自织梦

                       case    IDM_BIG: 织梦内容管理系统 
                                              StretchBlt (hdc, 0, 0, cxClient, cyClient,  

织梦好,好织梦

                                      hdcMem, 0, 0, cxBitmap, cyBitmap, SRCCOPY) ; 
织梦内容管理系统
                                                                            break ; 织梦好,好织梦 
  

织梦好,好织梦

                               case    IDM_SMALL: 
织梦内容管理系统
                                              for (y = 0 ; y < cyClient ; y += cyBitmap) 本文来自织梦 
                                              for (x = 0 ; x < cxClient ; x += cxBitmap) 

copyright dedecms

                                              { 
本文来自织梦
                                      BitBlt (hdc, x, y, cxBitmap, cyBitmap,  本文来自织梦 
                               hdcMem, 0, 0, SRCCOPY) ; 内容来自dedecms 
                                                     } 

dedecms.com

                                                     break ; 

copyright dedecms

                               } 织梦好,好织梦 
  内容来自dedecms 
                               EndPaint (hwnd, &ps) ; 
织梦好,好织梦
                               return 0 ; dedecms.com 
  

copyright dedecms

        case    WM_DESTROY: 
内容来自dedecms
                               DeleteDC (hdcMem) ; 本文来自织梦 
                               DeleteObject (hBitmap) ; 

织梦内容管理系统

                               PostQuitMessage (0) ; 
内容来自dedecms
                               return 0 ; 

copyright dedecms

        } 内容来自dedecms 
        return DefWindowProc (hwnd, message, wParam, lParam) ; 织梦好,好织梦 
} 本文来自织梦 
 HELLOBIT.RC (摘录) 本文来自织梦 
//Microsoft Developer Studio generated resource script. dedecms.com 
#include "resource.h" 
内容来自dedecms
#include "afxres.h" 内容来自dedecms 
  内容来自dedecms 
///////////////////////////////////////////////////////////////////////////// dedecms.com 
// Menu 织梦好,好织梦 
HELLOBIT MENU DISCARDABLE  

dedecms.com

BEGIN 内容来自dedecms 
        POPUP "&Size" 

内容来自dedecms

        BEGIN copyright dedecms 
                               MENUITEM "&Big",               IDM_BIG, CHECKED 
本文来自织梦
                               MENUITEM "&Small",             IDM_SMALL 

织梦内容管理系统

        END 织梦好,好织梦 
END 织梦好,好织梦 
 RESOURCE.H (摘录) 织梦内容管理系统 
// Microsoft Developer Studio generated include file. 
织梦好,好织梦
// Used by HelloBit.rc 本文来自织梦 
  
织梦内容管理系统
#define IDM_BIG            40001 
织梦好,好织梦
#define IDM_SMALL          40002 
织梦内容管理系统

程式从呼叫GetTextExtentPoint32确定字串的图素尺寸开始。这些尺寸将成为与视讯显示相容的点阵图尺寸。当此点阵图被选进记忆体装置内容(也与视讯显示相容)後,再呼叫TextOut将文字显示在点阵图上。记忆体装置内容在程式执行期间保留。在处理WM_DESTROY资讯期间,HELLOBIT删除了点阵图和记忆体装置内容。 本文来自织梦

HELLOBIT中的一条功能表选项允许您显示点阵图尺寸,此尺寸或者是显示区域中水平和垂直方向平铺的实际尺寸,或者是缩放成显示区域大小的尺寸,如图14-4所示。正与您所见到的一样,这不是显示大尺寸字元的好方法!它只是小字体的放大版,并带有放大时产生的锯齿线。 织梦好,好织梦


 

织梦好,好织梦

织梦内容管理系统

 

织梦好,好织梦

14-4 HELLOBIT的萤幕显示 dedecms.com

 

您可能想知道一个程式,例如HELLOBIT,是否需要处理WM_DISPLAYCHANGE讯息。只要使用者(或者其他应用程式)修改了视讯显示大小或者颜色深度,应用程式就接收到此讯息。其中颜色深度的改变会导致记忆体装置内容和视讯装置内容不相容。但这并不会发生,因为当显示模式修改後,Windows自动修改了记忆体装置内容的颜色解析度。选进记忆体装置内容的点阵图仍然保持原样,但不会造成任何问题。 copyright dedecms

阴影点阵图
 

本文来自织梦

在记忆体装置内容绘图(也就是点阵图)的技术是执行「阴影点阵图(shadow bitmap)」的关键。此点阵图包含视窗显示区域中显示的所有内容。这样,对WM_PAINT讯息的处理就简化到简单的BitBlt

copyright dedecms

阴影点阵图在绘画程式中最有用。程式14-7所示的SKETCH程式并不是一个最完美的绘画程式,但它是一个开始。 本文来自织梦

 程式14-7  SKETCH 本文来自织梦 
SKETCH.C 

内容来自dedecms

/*------------------------------------------------------------------------- 
dedecms.com
        SKETCH.C -- Shadow Bitmap Demonstration 本文来自织梦 
                                                     (c) Charles Petzold, 1998 

本文来自织梦

---------------------------------------------------------------------------*/ 

copyright dedecms

  本文来自织梦 
#include <windows.h> 
织梦内容管理系统
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; 

copyright dedecms

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, 本文来自织梦 
                                                                     PSTR szCmdLine, int iCmdShow) 

dedecms.com

{ 

本文来自织梦

        static TCHAR           szAppName [] = TEXT ("Sketch") ; 
dedecms.com
        HWND                                  hwnd ; 织梦好,好织梦 
        MSG                                   msg ; 

本文来自织梦

        WNDCLASS                              wndclass ; 
织梦好,好织梦
  
copyright dedecms
        wndclass.style                                = CS_HREDRAW | CS_VREDRAW ; 

dedecms.com

        wndclass.lpfnWndProc                          = WndProc ; 
dedecms.com
        wndclass.cbClsExtra                           = 0 ; 

dedecms.com

        wndclass.cbWndExtra                           = 0 ; 
织梦好,好织梦
        wndclass.hInstance                            = hInstance ; 

本文来自织梦

        wndclass.hIcon                                = LoadIcon (NULL, IDI_APPLICATION) ; 

copyright dedecms

        wndclass.hCursor                              = LoadCursor (NULL, IDC_ARROW) ; 本文来自织梦 
        wndclass.hbrBackground                = (HBRUSH) GetStockObject (WHITE_BRUSH) ; 本文来自织梦 
        wndclass.lpszMenuName                 = NULL ; 

织梦好,好织梦

        wndclass.lpszClassName                = szAppName ; 
织梦好,好织梦
      dedecms.com 
        if (!RegisterClass (&wndclass)) 
本文来自织梦
        { 织梦好,好织梦 
                       MessageBox (   NULL, TEXT ("This program requires Windows NT!"), 织梦好,好织梦 
                szAppName, MB_ICONERROR) ; 

内容来自dedecms

                       return 0 ; copyright dedecms 
        } 本文来自织梦 
      本文来自织梦 
        hwnd = CreateWindow (szAppName, TEXT ("Sketch"),  copyright dedecms 
                             WS_OVERLAPPEDWINDOW,  dedecms.com 
                             CW_USEDEFAULT, CW_USEDEFAULT, 

本文来自织梦

                             CW_USEDEFAULT, CW_USEDEFAULT, 织梦好,好织梦 
                             NULL, NULL, hInstance, NULL) ; 内容来自dedecms 
  

织梦好,好织梦

        if (hwnd == NULL) 织梦好,好织梦 
        { 内容来自dedecms 
                       MessageBox (   NULL, TEXT ("Not enough memory to create bitmap!"), 
dedecms.com
                               szAppName, MB_ICONERROR) ; 

本文来自织梦

                       return 0 ; 

本文来自织梦

     } 

内容来自dedecms

  

织梦内容管理系统

        ShowWindow (hwnd, iCmdShow) ; 本文来自织梦 
        UpdateWindow (hwnd) ; 
内容来自dedecms
  

copyright dedecms

        while (GetMessage (&msg, NULL, 0, 0)) 

内容来自dedecms

     { 
织梦内容管理系统
                                      TranslateMessage (&msg) ; 内容来自dedecms 
                                      DispatchMessage (&msg) ; 织梦好,好织梦 
     } 
织梦好,好织梦
       return msg.wParam ; 
dedecms.com
} 内容来自dedecms 
  织梦好,好织梦 
void GetLargestDisplayMode (int * pcxBitmap, int * pcyBitmap) 内容来自dedecms 
{ 本文来自织梦 
        DEVMODE        devmode ; 
copyright dedecms
        int            iModeNum = 0 ; copyright dedecms 
  织梦内容管理系统 
        * pcxBitmap = * pcyBitmap = 0 ; 织梦好,好织梦 
  
织梦内容管理系统
        ZeroMemory (&devmode, sizeof (DEVMODE)) ; 
dedecms.com
        devmode.dmSize = sizeof (DEVMODE) ; 织梦内容管理系统 
      织梦好,好织梦 
        while (EnumDisplaySettings (NULL, iModeNum++, &devmode)) 
织梦好,好织梦
        { 
copyright dedecms
                       * pcxBitmap = max (* pcxBitmap, (int) devmode.dmPelsWidth) ; 织梦内容管理系统 
                       * pcyBitmap = max (* pcyBitmap, (int) devmode.dmPelsHeight) ; 织梦好,好织梦 
        } 

内容来自dedecms

} 织梦好,好织梦 
LRESULT CALLBACK WndProc (     HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) 

内容来自dedecms

{ 内容来自dedecms 
        static BOOL   fLeftButtonDown, fRightButtonDown ; 内容来自dedecms 
        static HBITMAP hBitmap ; 本文来自织梦 
        static HDC             hdcMem ; 织梦内容管理系统 
        static int             cxBitmap, cyBitmap, cxClient, cyClient, xMouse, yMouse ; dedecms.com 
        HDC                                   hdc ; 
copyright dedecms
        PAINTSTRUCT            ps ; 
copyright dedecms
      dedecms.com 
        switch (message) 织梦内容管理系统 
        { copyright dedecms 
        case    WM_CREATE: 

织梦内容管理系统

                               GetLargestDisplayMode (&cxBitmap, &cyBitmap) ; 

本文来自织梦

  

织梦好,好织梦

                               hdc = GetDC (hwnd) ; 

copyright dedecms

                               hBitmap = CreateCompatibleBitmap (hdc, cxBitmap, cyBitmap) ; dedecms.com 
                               hdcMem  = CreateCompatibleDC (hdc) ; 

copyright dedecms

                               ReleaseDC (hwnd, hdc) ; 
织梦好,好织梦
  织梦内容管理系统 
                       if (!hBitmap)                                 // no memory for bitmap copyright dedecms 
                       { 

本文来自织梦

                               DeleteDC (hdcMem) ; 织梦内容管理系统 
                               return -1 ; 
织梦内容管理系统
                       } 
织梦好,好织梦
  

织梦内容管理系统

                               SelectObject (hdcMem, hBitmap) ; 

内容来自dedecms

                               PatBlt (hdcMem, 0, 0, cxBitmap, cyBitmap, WHITENESS) ; 

dedecms.com

                               return 0 ; 织梦内容管理系统 
  
内容来自dedecms
        case    WM_SIZE: 
内容来自dedecms
                               cxClient = LOWORD (lParam) ; 

本文来自织梦

                               cyClient = HIWORD (lParam) ; 
内容来自dedecms
                               return 0 ; 

copyright dedecms

  
本文来自织梦
        case    WM_LBUTTONDOWN: 织梦内容管理系统 
                               if (!fRightButtonDown) 织梦内容管理系统 
                                              SetCapture (hwnd) ; 
copyright dedecms
  copyright dedecms 
                               xMouse = LOWORD (lParam) ; copyright dedecms 
                               yMouse = HIWORD (lParam) ; 本文来自织梦 
                               fLeftButtonDown = TRUE ; 织梦好,好织梦 
                               return 0 ; 

内容来自dedecms

  本文来自织梦 
        case    WM_LBUTTONUP: 

copyright dedecms

                               if (fLeftButtonDown) 本文来自织梦 
                                              SetCapture (NULL) ; dedecms.com 
           内容来自dedecms 
                               fLeftButtonDown = FALSE ; 

本文来自织梦

                               return 0 ; 

内容来自dedecms

           
织梦好,好织梦
        case    WM_RBUTTONDOWN: 本文来自织梦 
                               if (!fLeftButtonDown) 

copyright dedecms

                                              SetCapture (hwnd) ; 
内容来自dedecms
           
织梦好,好织梦
                               xMouse = LOWORD (lParam) ; 织梦内容管理系统 
                               yMouse = HIWORD (lParam) ; 

本文来自织梦

                               fRightButtonDown = TRUE ; 

本文来自织梦

                               return 0 ; 织梦内容管理系统 
           

dedecms.com

        case    WM_RBUTTONUP: 
织梦内容管理系统
                               if (fRightButtonDown)  织梦内容管理系统 
                               SetCapture (NULL) ; 织梦内容管理系统 
           
copyright dedecms
                               fRightButtonDown = FALSE ; 
本文来自织梦
                               return 0 ; 

本文来自织梦

  

织梦内容管理系统

        case    WM_MOUSEMOVE: 织梦好,好织梦 
                               if (!fLeftButtonDown && !fRightButtonDown) 
dedecms.com
                               return 0 ; 织梦好,好织梦 
  本文来自织梦 
                               hdc = GetDC (hwnd) ; 内容来自dedecms 
  
copyright dedecms
                               SelectObject (hdc,  copyright dedecms 
                             GetStockObject (fLeftButtonDown ? BLACK_PEN : WHITE_PEN)) ; 

内容来自dedecms

  

内容来自dedecms

                               SelectObject (hdcMem, 织梦好,好织梦 
                               GetStockObject (fLeftButtonDown ? BLACK_PEN : WHITE_PEN)) ; 
本文来自织梦
  

dedecms.com

                               MoveToEx (hdc,    xMouse, yMouse, NULL) ; 
dedecms.com
                               MoveToEx (hdcMem, xMouse, yMouse, NULL) ; copyright dedecms 
  内容来自dedecms 
                               xMouse = (short) LOWORD (lParam) ; 
本文来自织梦
                               yMouse = (short) HIWORD (lParam) ; 
织梦好,好织梦
  织梦内容管理系统 
                               LineTo (hdc,    xMouse, yMouse) ; 
本文来自织梦
                               LineTo (hdcMem, xMouse, yMouse) ; 
本文来自织梦
  织梦内容管理系统 
                               ReleaseDC (hwnd, hdc) ; 本文来自织梦 
                               return 0 ; 

本文来自织梦

  本文来自织梦 
        case    WM_PAINT: copyright dedecms 
                               hdc = BeginPaint (hwnd, &ps) ; 

织梦内容管理系统

                               BitBlt (hdc, 0, 0, cxClient, cyClient, hdcMem, 0, 0, SRCCOPY) ; 织梦内容管理系统 
  
dedecms.com
                               EndPaint (hwnd, &ps) ; 本文来自织梦 
                               return 0 ; 织梦内容管理系统 
  dedecms.com 
        case    WM_DESTROY: 本文来自织梦 
                               DeleteDC (hdcMem) ; 

本文来自织梦

                               DeleteObject (hBitmap) ; dedecms.com 
                               PostQuitMessage (0) ; 织梦内容管理系统 
                               return 0 ; 
本文来自织梦
        } 

织梦内容管理系统

        return DefWindowProc (hwnd, message, wParam, lParam) ; 内容来自dedecms 
} copyright dedecms 

要想在SKETCH中画线,请按下滑鼠左键并拖动滑鼠。要擦掉画过的东西(更确切地说,是画白线),请按下滑鼠右键并拖动滑鼠。要清空整个视窗,请结束程式,然後重新载入,一切从头再来。图14-5中显示的SKETCH程式图样表达了对频果公司的麦金塔电脑早期广告的敬意。

织梦内容管理系统


  内容来自dedecms

dedecms.com

 

本文来自织梦

14-5 SKETCH的萤幕显示

织梦好,好织梦

 

此阴影点阵图应多大?在本程式中,它应该大到能包含最大化视窗的整个显示区域。这一问题很容易根据GetSystemMetrics资讯计算得出,但如果使用者修改了显示设定後再显示,进而扩大了最大化时视窗的尺寸,这时将发生什么呢?SKETCH程式在EnumDisplaySettings函式的帮助下解决了此问题。此函式使用DEVMODE结构来传回全部有效视讯显示模式的资讯。第一次呼叫此函式时,应将EnumDisplaySettings的第二参数设为0,以後每次呼叫此值都增加。EnumDisplaySettings传回FALSE时完成。

本文来自织梦

与此同时,SKETCH将建立一个阴影点阵图,它比目前视讯显示模式的表面还多四倍,而且需要几百万位元组的记忆体。由於如此,SKETCH将检查点阵图是否建立成功了,如果没有建立,就从WM_CREATE传回-1,以表示错误。 本文来自织梦

WM_MOUSEMOVE讯息处理期间,按下滑鼠左键或者右键,并在记忆体装置内容和显示区域装置内容中画线时,SKETCH拦截滑鼠。如果画线方式更复杂的话,您可能想在一个函式中实作,程式将呼叫此函式两次-一次画在视讯装置内容上,一次画在记忆体装置内容上。 copyright dedecms

下面是一个有趣的实验:使SKETCH视窗小於全画面尺寸。随著滑鼠左键的按下,将滑鼠拖出视窗的右下角。因为SKETCH拦截滑鼠,所以它继续接收并处理WM_MOUSEMOVE讯息。现在扩大视窗,您将看到阴影点阵图包含您在SKETCH视窗外所画的内容。 织梦好,好织梦

在功能表中使用点阵图
 

织梦内容管理系统

您也可以用点阵图在功能表上显示选项。如果您联想起功能表中档案夹、剪贴簿和资源回收筒的图片,那么不要再想那些图片了。您应该考虑一下,功能表上显示点阵图对画图程式用途有多大,想像一下在功能表中使用不同字体和字体大小、线宽、阴影图案以及颜色。

织梦好,好织梦

GRAFMENU是展示图形功能表选项的范例程式。此程式顶层功能表如图14-6所示。放大的字母来自於40×16图素的单色点阵图档案,该档案在Visual C++ Developer Studio建立。从功能表上选择「FONT」将弹出三个选择项-「Courier New」、「Arial」和「Times New Roman」。它们是标准的Windows TrueType字体,并且每一个都按其相关的字体显示,如图14-7所示。这些点阵图在程式中用记忆体装置内容建立。 dedecms.com


 

织梦好,好织梦

织梦内容管理系统

  本文来自织梦

14-6 GRAFMENU程式的顶层功能表

织梦好,好织梦

 


 

dedecms.com

copyright dedecms

 

dedecms.com

14-7 GRAFMENU程式弹出的「FONT」功能表 本文来自织梦

 

最後,在拉下系统功能表时,您将获得一些「辅助」资讯,用「HELP」表示了新使用者的线上求助项目(参见图14-8)。此64×64图素的单色点阵图是在Developer Studio中建立的。

内容来自dedecms


 

本文来自织梦

本文来自织梦

  内容来自dedecms

14-8 GRAFMENU程式系统功能表

织梦好,好织梦

 

GRAFMENU程式,包括四个Developer Studio中建立的点阵图,如程式14-8所示。

内容来自dedecms

 程式14-8  GRAFMENU 内容来自dedecms 
GRAFMENU.C 织梦好,好织梦 
/*---------------------------------------------------------------------------- 

织梦好,好织梦

        GRAFMENU.C --          Demonstrates Bitmap Menu Items 

dedecms.com

                                                                     (c) Charles Petzold, 1998 
织梦内容管理系统
-----------------------------------------------------------------------------*/ 本文来自织梦 
  
织梦好,好织梦
#include <windows.h> 
copyright dedecms
#include "resource.h" dedecms.com 
  dedecms.com 
LRESULT                CALLBACK WndProc               (HWND, UINT, WPARAM, LPARAM) ; 

本文来自织梦

void                   AddHelpToSys                   (HINSTANCE, HWND) ; 织梦好,好织梦 
HMENU                  CreateMyMenu                   (HINSTANCE) ; 内容来自dedecms 
HBITMAP                StretchBitmap              (HBITMAP) ; copyright dedecms 
HBITMAP                GetBitmapFont                  (int) ; 
织梦好,好织梦
void                   DeleteAllBitmaps           (HWND) ; 
内容来自dedecms
TCHAR szAppName[] = TEXT ("GrafMenu") ; 织梦内容管理系统 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, 

本文来自织梦

                    PSTR szCmdLine, int iCmdShow) copyright dedecms 
{ 织梦内容管理系统 
        HWND                   hwnd ; 织梦好,好织梦 
        MSG                    msg ; 内容来自dedecms 
        WNDCLASS               wndclass ; 本文来自织梦 
      

copyright dedecms

        wndclass.style                                = CS_HREDRAW | CS_VREDRAW ; 本文来自织梦 
       wndclass.lpfnWndProc                          = WndProc ; 内容来自dedecms 
        wndclass.cbClsExtra                           = 0 ; 
内容来自dedecms
        wndclass.cbWndExtra                           = 0 ; 本文来自织梦 
        wndclass.hInstance                            = hInstance ; 

dedecms.com

        wndclass.hIcon                                = LoadIcon (NULL, IDI_APPLICATION) ; 

dedecms.com

        wndclass.hCursor                              = LoadCursor (NULL, IDC_ARROW) ; 本文来自织梦 
        wndclass.hbrBackground                = (HBRUSH) GetStockObject (WHITE_BRUSH) ; 

内容来自dedecms

        wndclass.lpszMenuName                 = NULL ; 
织梦好,好织梦
        wndclass.lpszClassName                = szAppName ; 

织梦内容管理系统

      

内容来自dedecms

        if (!RegisterClass (&wndclass)) 织梦好,好织梦 
        { 织梦内容管理系统 
                       MessageBox (   NULL, TEXT ("This program requires Windows NT!"), 织梦内容管理系统 
                               szAppName, MB_ICONERROR) ; 内容来自dedecms 
                       return 0 ; dedecms.com 
     } dedecms.com 
      

copyright dedecms

        hwnd = CreateWindow (szAppName,TEXT ("Bitmap Menu Demonstration"), 

织梦好,好织梦

                               WS_OVERLAPPEDWINDOW, 
copyright dedecms
                               CW_USEDEFAULT, CW_USEDEFAULT, 内容来自dedecms 
                               CW_USEDEFAULT, CW_USEDEFAULT, 

内容来自dedecms

                               NULL, NULL, hInstance, NULL) ; copyright dedecms 
      织梦好,好织梦 
        ShowWindow (hwnd, iCmdShow) ; 

织梦好,好织梦

        UpdateWindow (hwnd) ; 织梦内容管理系统 
      
织梦内容管理系统
        while (GetMessage (&msg, NULL, 0, 0)) dedecms.com 
        { 
织梦好,好织梦
                       TranslateMessage (&msg) ; copyright dedecms 
                       DispatchMessage (&msg) ; 本文来自织梦 
        } 本文来自织梦 
        return msg.wParam ; 

本文来自织梦

} 
dedecms.com
  

本文来自织梦

LRESULT CALLBACK WndProc (     HWND hwnd, UINT iMsg, WPARAM wParam,LPARAM lParam) dedecms.com 
{ 内容来自dedecms 
        HMENU                                 hMenu ; 织梦好,好织梦 
        static int             iCurrentFont = IDM_FONT_COUR ; 织梦好,好织梦 
      

dedecms.com

        switch (iMsg) 

织梦好,好织梦

        { 

织梦内容管理系统

        case WM_CREATE: 织梦内容管理系统 
                               AddHelpToSys (((LPCREATESTRUCT) lParam)->hInstance, hwnd) ; 织梦内容管理系统 
                               hMenu = CreateMyMenu (((LPCREATESTRUCT) lParam)->hInstance) ; dedecms.com 
                               SetMenu (hwnd, hMenu) ; 

织梦内容管理系统

                               CheckMenuItem (hMenu, iCurrentFont, MF_CHECKED) ; copyright dedecms 
                               return 0 ; copyright dedecms 
           

织梦好,好织梦

        case    WM_SYSCOMMAND: 

内容来自dedecms

                               switch (LOWORD (wParam)) 
织梦好,好织梦
                               { dedecms.com 
                               case    IDM_HELP: 
织梦内容管理系统
                                              MessageBox (hwnd, TEXT ("Help not yet implemented!"), 

织梦内容管理系统

                                      szAppName, MB_OK | MB_ICONEXCLAMATION) ; 

本文来自织梦

                                              return 0 ; 

本文来自织梦

                               } 本文来自织梦 
                               break ; 织梦好,好织梦 
           
copyright dedecms
        case    WM_COMMAND: 

copyright dedecms

                               switch (LOWORD (wParam)) 本文来自织梦 
                               { dedecms.com 
                               case    IDM_FILE_NEW: 本文来自织梦 
                               case    IDM_FILE_OPEN: copyright dedecms 
                               case    IDM_FILE_SAVE: 织梦好,好织梦 
                               case    IDM_FILE_SAVE_AS: 
织梦好,好织梦
                               case    IDM_EDIT_UNDO: 本文来自织梦 
                               case    IDM_EDIT_CUT: 本文来自织梦 
                               case    IDM_EDIT_COPY: 织梦内容管理系统 
                               case    IDM_EDIT_PASTE: copyright dedecms 
                               case    IDM_EDIT_CLEAR: dedecms.com 
                                              MessageBeep (0) ; 织梦好,好织梦 
                                              return 0 ; 本文来自织梦 
                     本文来自织梦 
                               case    IDM_FONT_COUR: copyright dedecms 
                               case    IDM_FONT_ARIAL: 

内容来自dedecms

                               case    IDM_FONT_TIMES: 织梦好,好织梦 
                                      hMenu = GetMenu (hwnd) ; 

本文来自织梦

                       CheckMenuItem (hMenu, iCurrentFont, MF_UNCHECKED) ; 

copyright dedecms

                                              iCurrentFont = LOWORD (wParam) ; 
织梦好,好织梦
                                              CheckMenuItem (hMenu, iCurrentFont, MF_CHECKED) ; 

内容来自dedecms

                                              return 0 ; 

本文来自织梦

                               } 内容来自dedecms 
                               break ; dedecms.com 
                织梦内容管理系统 
               case    WM_DESTROY: 

织梦好,好织梦

                                      DeleteAllBitmaps (hwnd) ; 

织梦内容管理系统

                                      PostQuitMessage (0) ; dedecms.com 
                                      return 0 ; 

dedecms.com

        } 
copyright dedecms
        return DefWindowProc (hwnd, iMsg, wParam, lParam) ; 织梦好,好织梦 
} 

织梦好,好织梦

  
织梦好,好织梦
/*-------------------------------------------------------------------------- 

本文来自织梦

        AddHelpToSys: Adds bitmap Help item to system menu 本文来自织梦 
  ------------------------------------------------------------------------*/ 

copyright dedecms

  内容来自dedecms 
void AddHelpToSys (HINSTANCE hInstance, HWND hwnd) 
copyright dedecms
{ dedecms.com 
        HBITMAP                hBitmap ; 
本文来自织梦
        HMENU                  hMenu ; 
织梦内容管理系统
  内容来自dedecms 
        hMenu = GetSystemMenu (hwnd, FALSE); 织梦好,好织梦 
        hBitmap = StretchBitmap (LoadBitmap (hInstance, TEXT ("BitmapHelp"))) ; 本文来自织梦 
        AppendMenu (hMenu, MF_SEPARATOR, 0, NULL) ; 

copyright dedecms

        AppendMenu (hMenu, MF_BITMAP, IDM_HELP, (PTSTR) (LONG) hBitmap) ; 本文来自织梦 
} 

织梦好,好织梦

  

织梦好,好织梦

/*------------------------------------------------------------------------ 
dedecms.com
   CreateMyMenu: Assembles menu from components dedecms.com 
--------------------------------------------------------------------------*/ 本文来自织梦 
  织梦内容管理系统 
HMENU CreateMyMenu (HINSTANCE hInstance) 
织梦内容管理系统
{ 本文来自织梦 
        HBITMAP                hBitmap ; 
copyright dedecms
        HMENU                  hMenu, hMenuPopup ; 

本文来自织梦

        int                    i ; 织梦好,好织梦 
  

dedecms.com

        hMenu = CreateMenu () ; dedecms.com 
        hMenuPopup = LoadMenu (hInstance, TEXT ("MenuFile")) ; dedecms.com 
        hBitmap = StretchBitmap (LoadBitmap (hInstance, TEXT ("BitmapFile"))) ; copyright dedecms 
        AppendMenu (hMenu, MF_BITMAP | MF_POPUP, (int) hMenuPopup, copyright dedecms 
                                                                     (PTSTR) (LONG) hBitmap) ; 织梦好,好织梦 
        hMenuPopup = LoadMenu (hInstance, TEXT ("MenuEdit")) ; 

内容来自dedecms

        hBitmap = StretchBitmap (LoadBitmap (hInstance, TEXT ("BitmapEdit"))) ; 本文来自织梦 
        AppendMenu (hMenu, MF_BITMAP | MF_POPUP, (int) hMenuPopup, 
本文来自织梦
                         (PTSTR) (LONG) hBitmap) ; 
内容来自dedecms
        hMenuPopup = CreateMenu () ; 

本文来自织梦

        for (i = 0 ; i < 3 ; i++) dedecms.com 
     { 内容来自dedecms 
                       hBitmap = GetBitmapFont (i) ; dedecms.com 
                       AppendMenu (hMenuPopup, MF_BITMAP, IDM_FONT_COUR + i,  dedecms.com 
                         (PTSTR) (LONG) hBitmap) ; 

织梦好,好织梦

        } 

织梦好,好织梦

  
织梦内容管理系统
        hBitmap = StretchBitmap (LoadBitmap (hInstance, TEXT ("BitmapFont"))) ; 织梦好,好织梦 
        AppendMenu (hMenu, MF_BITMAP | MF_POPUP, (int) hMenuPopup, dedecms.com 
                        (PTSTR) (LONG) hBitmap) ; 

内容来自dedecms

        return hMenu ; copyright dedecms 
} 本文来自织梦 
  dedecms.com 
/*------------------------------------------------------------------------- 织梦内容管理系统 
   StretchBitmap: Scales bitmap to display resolution 

copyright dedecms

---------------------------------------------------------------------------*/ 
dedecms.com
  
内容来自dedecms
HBITMAP StretchBitmap (HBITMAP hBitmap1) 

织梦好,好织梦

{ 本文来自织梦 
        BITMAP                         bm1, bm2 ; 本文来自织梦 
        HBITMAP                       hBitmap2 ; 
内容来自dedecms
        HDC                            hdc, hdcMem1, hdcMem2 ; 内容来自dedecms 
        int                            cxChar, cyChar ; 
内容来自dedecms
  
织梦好,好织梦
                       // Get the width and height of a system font character 
内容来自dedecms
  copyright dedecms 
        cxChar = LOWORD (GetDialogBaseUnits ()) ; 织梦内容管理系统 
        cyChar = HIWORD (GetDialogBaseUnits ()) ; copyright dedecms 
  织梦好,好织梦 
                       // Create 2 memory DCs compatible with the display 内容来自dedecms 
        hdc = CreateIC (TEXT ("DISPLAY"), NULL, NULL, NULL) ; 

内容来自dedecms

        hdcMem1 = CreateCompatibleDC (hdc) ; 内容来自dedecms 
        hdcMem2 = CreateCompatibleDC (hdc) ; dedecms.com 
        DeleteDC (hdc) ; 
dedecms.com
  

织梦好,好织梦

                       // Get the dimensions of the bitmap to be stretched copyright dedecms 
        GetObject (hBitmap1, sizeof (BITMAP), (PTSTR) &bm1) ; 

织梦内容管理系统

                       // Scale these dimensions based on the system font size 内容来自dedecms 
        bm2 = bm1 ; 本文来自织梦 
        bm2.bmWidth                    = (cxChar * bm2.bmWidth)  / 4 ; 

dedecms.com

       bm2.bmHeight                   = (cyChar * bm2.bmHeight) / 8 ; 织梦好,好织梦 
        bm2.bmWidthBytes               = ((bm2.bmWidth + 15) / 16) * 2 ; dedecms.com 
  
本文来自织梦
                       // Create a new bitmap of larger size 
织梦内容管理系统
      
内容来自dedecms
        hBitmap2 = CreateBitmapIndirect (&bm2) ; copyright dedecms 
                       // Select the bitmaps in the memory DCs and do a StretchBlt 

copyright dedecms

        SelectObject (hdcMem1, hBitmap1) ; dedecms.com 
        SelectObject (hdcMem2, hBitmap2) ; 

织梦好,好织梦

        StretchBlt (hdcMem2, 0, 0, bm2.bmWidth, bm2.bmHeight, 
内容来自dedecms
                       hdcMem1, 0, 0, bm1.bmWidth, bm1.bmHeight, SRCCOPY) ; 

内容来自dedecms

                               // Clean up copyright dedecms 
        DeleteDC (hdcMem1) ; 织梦内容管理系统 
        DeleteDC (hdcMem2) ; 
织梦内容管理系统
        DeleteObject (hBitmap1) ; 
织梦内容管理系统
      内容来自dedecms 
        return hBitmap2 ; 

织梦内容管理系统

} 

本文来自织梦

  
copyright dedecms
/*--------------------------------------------------------------------------- 
本文来自织梦
   GetBitmapFont: Creates bitmaps with font names dedecms.com 
-----------------------------------------------------------------------------*/ 
织梦内容管理系统
  
本文来自织梦
HBITMAP GetBitmapFont (int i) 织梦内容管理系统 
{ 织梦好,好织梦 
        static TCHAR  * szFaceName[3]= {      TEXT ("Courier New"), TEXT ("Arial"),  

本文来自织梦

        TEXT ("Times New Roman") } ; 内容来自dedecms 
        HBITMAP                               hBitmap ; 织梦内容管理系统 
        HDC                                   hdc, hdcMem ; 

copyright dedecms

        HFONT                                 hFont ; 本文来自织梦 
        SIZE                                  size ; 

dedecms.com

        TEXTMETRIC                            tm ; 
内容来自dedecms
      

本文来自织梦

        hdc = CreateIC (TEXT ("DISPLAY"), NULL, NULL, NULL) ; 

内容来自dedecms

        GetTextMetrics (hdc, &tm) ; 织梦内容管理系统 
      内容来自dedecms 
        hdcMem = CreateCompatibleDC (hdc) ; 织梦内容管理系统 
        hFont  = CreateFont (2 * tm.tmHeight, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 织梦内容管理系统 
                                szFaceName[i]) ; 织梦内容管理系统 
  
dedecms.com
        hFont = (HFONT) SelectObject (hdcMem, hFont) ; 本文来自织梦 
        GetTextExtentPoint32 (hdcMem, szFaceName[i],  dedecms.com 
        lstrlen (szFaceName[i]), &size); dedecms.com 
        hBitmap = CreateBitmap (size.cx, size.cy, 1, 1, NULL) ; 
本文来自织梦
        SelectObject (hdcMem, hBitmap) ; 织梦内容管理系统 
      

本文来自织梦

        TextOut (hdcMem, 0, 0, szFaceName[i], lstrlen (szFaceName[i])) ; 织梦内容管理系统 
        DeleteObject (SelectObject (hdcMem, hFont)) ; 
织梦内容管理系统
        DeleteDC (hdcMem) ; 
织梦好,好织梦
        DeleteDC (hdc) ; copyright dedecms 
      织梦好,好织梦 
        return hBitmap ; 
织梦内容管理系统
} dedecms.com 
  copyright dedecms 
/*---------------------------------------------------------------------------  
内容来自dedecms
   DeleteAllBitmaps: Deletes all the bitmaps in the menu 织梦好,好织梦 
  -------------------------------------------------------------------------*/ copyright dedecms 
  copyright dedecms 
void DeleteAllBitmaps (HWND hwnd) 
织梦内容管理系统
{ 织梦好,好织梦 
        HMENU                          hMenu ; 织梦内容管理系统 
        int                            i ; copyright dedecms 
        MENUITEMINFO mii = { sizeof (MENUITEMINFO), MIIM_SUBMENU | MIIM_TYPE } ; 织梦好,好织梦 
                               // Delete Help bitmap on system menu copyright dedecms 
        hMenu = GetSystemMenu (hwnd, FALSE); 

内容来自dedecms

        GetMenuItemInfo (hMenu, IDM_HELP, FALSE, &mii) ; 

织梦内容管理系统

        DeleteObject ((HBITMAP) mii.dwTypeData) ; 本文来自织梦 
  本文来自织梦 
                               // Delete top-level menu bitmaps 内容来自dedecms 
        hMenu = GetMenu (hwnd) ; dedecms.com 
        for (i = 0 ; i < 3 ; i++) 
织梦内容管理系统
        { 

织梦内容管理系统

                               GetMenuItemInfo (hMenu, i, TRUE, &mii) ; 

copyright dedecms

                               DeleteObject ((HBITMAP) mii.dwTypeData) ; 
本文来自织梦
        } 
织梦好,好织梦
  本文来自织梦 
                               // Delete bitmap items on Font menu 本文来自织梦 
        hMenu = mii.hSubMenu ;; 
本文来自织梦
        for (i = 0 ; i < 3 ; i++) copyright dedecms 
        { 织梦好,好织梦 
                       GetMenuItemInfo (hMenu, i, TRUE, &mii) ; copyright dedecms 
                       DeleteObject ((HBITMAP) mii.dwTypeData) ; 

内容来自dedecms

        } 

copyright dedecms

} copyright dedecms 
 GRAFMENU.RC (摘录) 

织梦好,好织梦

//Microsoft Developer Studio generated resource script. 织梦好,好织梦 
#include "resource.h" 

本文来自织梦

#include "afxres.h" copyright dedecms 
  copyright dedecms 
///////////////////////////////////////////////////////////////////////////// 内容来自dedecms 
// Menu 

dedecms.com

MENUFILE MENU DISCARDABLE  
织梦内容管理系统
BEGIN 

本文来自织梦

               MENUITEM "&New",                      IDM_FILE_NEW 内容来自dedecms 
               MENUITEM "&Open...",                  IDM_FILE_OPEN 
织梦内容管理系统
               MENUITEM "&Save",                     IDM_FILE_SAVE dedecms.com 
               MENUITEM "Save &As...",               IDM_FILE_SAVE_AS copyright dedecms 
END 

内容来自dedecms

MENUEDIT MENU DISCARDABLE  
copyright dedecms
BEGIN 

copyright dedecms

               MENUITEM "&Undo",                     IDM_EDIT_UNDO 

内容来自dedecms

               MENUITEM SEPARATOR 
dedecms.com
               MENUITEM "Cu&t",                      IDM_EDIT_CUT copyright dedecms 
               MENUITEM "&Copy",                     IDM_EDIT_COPY 

本文来自织梦

               MENUITEM "&Paste",                    IDM_EDIT_PASTE copyright dedecms 
               MENUITEM "De&lete",            IDM_EDIT_CLEAR 本文来自织梦 
END 内容来自dedecms 
  内容来自dedecms 
///////////////////////////////////////////////////////////////////////////// 
copyright dedecms
// Bitmap 本文来自织梦 
BITMAPFONT      BITMAP     DISCARDABLE     "Fontlabl.bmp" copyright dedecms 
BITMAPHELP      BITMAP     DISCARDABLE     "Bighelp.bmp" 

copyright dedecms

BITMAPEDIT      BITMAP     DISCARDABLE     "Editlabl.bmp" 

织梦内容管理系统

BITMAPFILE      BITMAP     DISCARDABLE     "Filelabl.bmp" 
织梦好,好织梦
 RESOURCE.H (摘录) 

织梦内容管理系统

// Microsoft Developer Studio generated include file. 本文来自织梦 
// Used by GrafMenu.rc 织梦好,好织梦 
  内容来自dedecms 
#define IDM_FONT_COUR    101 copyright dedecms 
#define IDM_FONT_ARIAL   102 

dedecms.com

#define IDM_FONT_TIMES   103 

织梦好,好织梦

#define IDM_HELP         104 内容来自dedecms 
#define IDM_EDIT_UNDO    40005 
内容来自dedecms
#define IDM_EDIT_CUT     40006 copyright dedecms 
#define IDM_EDIT_COPY    40007 
织梦内容管理系统
#define IDM_EDIT_PASTE   40008 织梦好,好织梦 
#define IDM_EDIT_CLEAR   40009 dedecms.com 
#define IDM_FILE_NEW     40010 

内容来自dedecms

#define IDM_FILE_OPEN    40011 copyright dedecms 
#define IDM_FILE_SAVE    40012 dedecms.com 
#define IDM_FILE_SAVE_AS 40013 

织梦好,好织梦

  dedecms.com

EDITLABL.BMP
 

dedecms.com

织梦好,好织梦

FILELABL.BMP
 
织梦好,好织梦

dedecms.com

FONTLABL.BMP
 

本文来自织梦

内容来自dedecms

BIGHELP.BMP
 

本文来自织梦

本文来自织梦

 

要将点阵图插入功能表,可以利用AppendMenuInsertMenu。点阵图有两个来源:可以在Visual C++ Developer Studio建立点阵图,包括资源脚本中的点阵图档案,并在程式使用LoadBitmap时将点阵图资源载入到记忆体,然後呼叫AppendMenuInsertMenu将点阵图附加到功能表上。但是用这种方法会有一些问题:点阵图不适於所有显示模式的解析度和纵横比;有时您需要缩放载入的点阵图以解决此问题。另一种方法是:在程式内部建立点阵图,并将它选进记忆体装置内容,画出来,然後再附加到功能表中。

织梦内容管理系统

GRAFMENU中的GetBitmapFont函式的参数为012,传回一个点阵图代号。此点阵图包含字串「Courier New」、「Arial」或「Times New Roman」,而且字体是各自对应的字体,大小是正常系统字体的两倍。让我们看看GetBitmapFont是怎么做的。(下面的程式码与GRAFMENU.C档案中的有些不同。为了清楚起见,我用「Arial」字体相应的值代替了引用szFaceName阵列。)

织梦内容管理系统

第一步是用TEXTMETRIC结构来确定目前系统字体的大小,并建立一个与目前萤幕相容的记忆体装置内容:

copyright dedecms

hdc = CreateIC (TEXT ("DISPLAY"), NULL, NULL, NULL) ; 织梦内容管理系统 
GetTextMetrics (hdc, &tm) ; 
dedecms.com
hdcMem = CreateCompatibleDC (hdc) ; 织梦好,好织梦 

CreateFont函式建立了一种逻辑字体,该字体高是系统字体的两倍,而且逻辑名称为「Arial」:

dedecms.com

hFont = CreateFont (2 * tm.tmHeight, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, copyright dedecms 
                                                     TEXT ("Arial")) ; 织梦好,好织梦 

从记忆体装置内容中选择该字体,然後储存内定字体代号:

内容来自dedecms

hFont = (HFONT) SelectObject (hdcMem, hFont) ; 本文来自织梦 

现在,当我们向记忆体装置内容写一些文字时,Windows就会使用选进装置内容的TrueType Arial字体了。 dedecms.com

但这个记忆体装置内容最初只有一个单图素单色设备平面。我们必须建立一个足够大的点阵图以容纳我们所要显示的文字。通过GetTextExtentPoint32函式,可以取得文字的大小,而用CreateBitmap可以根据这些尺寸来建立点阵图: 内容来自dedecms

GetTextExtentPoint32 (hdcMem, TEXT ("Arial"), 5, &size) ; 
内容来自dedecms
hBitmap = CreateBitmap (size.cx, size.cy, 1, 1, NULL) ; 本文来自织梦 
SelectObject (hdcMem, hBitmap) ; 

内容来自dedecms

现在这个装置内容是一个单色的显示平面,大小也是严格的文字尺寸。我们现在要做的就是书写文字: copyright dedecms

TextOut (hdcMem, 0, 0, TEXT ("Arial"), 5) ; 
织梦内容管理系统

除了清除,所有的工作都完成了。要清除,我们可以用SelectObject将系统字体(带有代号hFont)重新选进装置内容,然後删除SelectObject传回的前一个字体代号,也就是Arial字体代号: 内容来自dedecms

DeleteObject (SelectObject (hdcMem, hFont)) ; copyright dedecms 

现在可以删除两个装置内容:

copyright dedecms

DeleteDC (hdcMem) ; 内容来自dedecms 
DeleteDC (hdc) ; 

dedecms.com

这样,我们就获得了一个点阵图,该点阵图上有Arial字体的字串「Arial」。

dedecms.com

当我们需要缩放字体以适应不同显示解析度或纵横比时,记忆体装置内容也能解决问题。在GRAFMENU程式中,我建立了四个点阵图,这些点阵图只适用於系统字体高8图素、宽4图素的显示。对於其他尺寸的系统字体,只能缩放点阵图。GRAFMENU中的StretchBitmap函式完成此功能。 织梦好,好织梦

第一步是获得显示的装置内容,然後取得系统字体的文字规格,接下来建立两个记忆体装置内容:

织梦好,好织梦

hdc = CreateIC (TEXT ("DISPLAY"), NULL, NULL, NULL) ; copyright dedecms 
GetTextMetrics (hdc, &tm) ; 

织梦内容管理系统

hdcMem1 = CreateCompatibleDC (hdc) ; 
本文来自织梦
hdcMem2 = CreateCompatibleDC (hdc) ;  

内容来自dedecms

DeleteDC (hdc) ; 
copyright dedecms

传递给函式的点阵图代号是hBitmap1。程式能用GetObject获得点阵图的大小: 织梦好,好织梦

GetObject (hBitmap1, sizeof (BITMAP), (PSTR) &bm1) ; 
dedecms.com

此操作将尺寸复制到BITMAP型态的结构bm1中。结构bm2等於结构bm1,然後根据系统字体大小来修改某些栏位: dedecms.com

bm2 = bm1 ; 本文来自织梦 
bm2.bmWidth                    = (tm.tmAveCharWidth * bm2.bmWidth)  / 4 ; 

织梦好,好织梦

bm2.bmHeight                   = (tm.tmHeight       * bm2.bmHeight) / 8 ; 

copyright dedecms

bm2.bmWidthBytes               = ((bm2.bmWidth + 15) / 16) * 2 ; 本文来自织梦 

下一个点阵图带有代号hBitmap2,可以根据动态的尺寸建立: 织梦内容管理系统

hBitmap2 = CreateBitmapIndirect (&bm2) ; 

copyright dedecms

然後将这两个点阵图选进两个记忆体装置内容中:

dedecms.com

SelectObject (hdcMem1, hBitmap1) ; 
copyright dedecms
SelectObject (hdcMem2, hBitmap2) ; 
dedecms.com

我们想把第一个点阵图复制给第二个点阵图,并在此程序中进行拉伸。这包括StretchBlt呼叫:

dedecms.com

StretchBlt (   hdcMem2, 0, 0, bm2.bmWidth, bm2.bmHeight, 织梦好,好织梦 
                               hdcMem1, 0, 0, bm1.bmWidth, bm1.bmHeight, SRCCOPY) ; 织梦好,好织梦 

现在第二幅图适当地缩放了,我们可将其用到功能表中。剩下的清除工作很简单: copyright dedecms

DeleteDC (hdcMem1) ; 

copyright dedecms

DeleteDC (hdcMem2) ; dedecms.com 
DeleteObject (hBitmap1) ; 
织梦好,好织梦

在建造功能表时,GRAFMENU中的CreateMyMenu函式呼叫了StretchBitmapGetBitmapFont函式。GRAFMENU在资源档案中定义了两个功能表,在选择「File」和「Edit」选项时会弹出这两个功能表。函式开始先取得一个空功能表的代号: dedecms.com

hMenu = CreateMenu () ; 
内容来自dedecms

从资源档案载入「File」的突现式功能表(包括四个选项:「New」、「Open」、「Save」和「Save as」):

本文来自织梦

hMenuPopup = LoadMenu (hInstance, TEXT ("MenuFile")) ; 织梦内容管理系统 

从资源档案还载入了包含「FILE」的点阵图,并用StretchBitmap进行了拉伸: copyright dedecms

hBitmapFile = StretchBitmap (LoadBitmap (hInstance, TEXT ("BitmapFile"))) ; 
copyright dedecms

点阵图代号和突现式功能表代号都是AppendMenu呼叫的参数:

织梦内容管理系统

AppendMenu (hMenu, MF_BITMAP | MF_POPUP, hMenuPopup, (PTSTR) (LONG)  织梦内容管理系统 
hBitmapFile) ; dedecms.com 

Edit」功能表类似程序如下:

内容来自dedecms

hMenuPopup     = LoadMenu (hInstance, TEXT ("MenuEdit")) ; 织梦内容管理系统 
hBitmapEdit    = StretchBitmap (LoadBitmap (hInstance, TEXT ("BitmapEdit"))) ; 
织梦内容管理系统
AppendMenu (hMenu, MF_BITMAP | MF_POPUP, hMenuPopup, (PTSTR)(LONG) hBitmapEdit) ; 
内容来自dedecms

呼叫GetBitmapFont函式可以构造这三种不同字体的突现式功能表: copyright dedecms

hMenuPopup = CreateMenu () ; 
copyright dedecms
for (i = 0 ; i < 3 ; i++) 

copyright dedecms

{ 

本文来自织梦

        hBitmapPopFont [i] = GetBitmapFont (i) ; 织梦内容管理系统 
        AppendMenu (hMenuPopup, MF_BITMAP, IDM_FONT_COUR + i, 

织梦好,好织梦

                         (PTSTR) (LONG) hMenuPopupFont [i]) ; 

本文来自织梦

} 织梦内容管理系统 

然後将突现式功能表添加到功能表中: 织梦好,好织梦

hBitmapFont = StretchBitmap (LoadBitmap (hInstance, "BitmapFont")) ; 织梦好,好织梦 
AppendMenu (   hMenu, MF_BITMAP | MF_POPUP, hMenuPopup, (PTSTR) (LONG)                                      hBitmapFont) ; 

织梦内容管理系统

WndProc通过呼叫SetMenu,完成了视窗功能表的建立工作。

dedecms.com

GRAFMENU还改变了AddHelpToSys函式中的系统功能表。此函式首先获得一个系统功能表代号: copyright dedecms

hMenu = GetSystemMenu (hwnd, FALSE) ; 
织梦内容管理系统

这将载入「HELP」点阵图,并将其拉伸到适当尺寸: 内容来自dedecms

hBitmapHelp = StretchBitmap (LoadBitmap (hInstance, TEXT ("BitmapHelp"))) ; dedecms.com 

这将给系统功能表添加一条分隔线和拉伸的点阵图:

织梦内容管理系统

AppendMenu (hMenu, MF_SEPARATOR, 0, NULL) ; 
本文来自织梦
AppendMenu (hMenu, MF_BITMAP, IDM_HELP, (PTSTR)(LONG) hBitmapHelp) ; 织梦好,好织梦 

GRAFMENU在退出之前呼叫一个函式来清除并删除所有点阵图。

copyright dedecms

下面是在功能表中使用点阵图的一些注意事项。 dedecms.com

在顶层功能表中,Windows调整功能表列的高度以适应最高的点阵图。其他点阵图(或字串)是根据功能表列的顶端对齐的。如果在顶层功能表中使用了点阵图,那么从使用常数SM_CYMENUGetSystemMetrics得到的功能表列大小将不再有效。 copyright dedecms

执行GRAFMENU期间可以看到:在突现式功能表中,您可使用带有点阵图功能表项的勾选标记,但勾选标记是正常尺寸。如果不满意,您可以建立一个自订的勾选标记,并使用SetMenuItemBitmaps织梦内容管理系统

在功能表中使用非文字(或者使用非系统字体的文字)的另一种方法是「拥有者绘制」功能表。

本文来自织梦

功能表的键盘介面是另一个问题。当功能表含有文字时,Windows会自动添加键盘介面。要选择一个功能表项,可以使用Alt与字串中的一个字母的组合键。而一旦在功能表中放置了点阵图,就删除了键盘介面。即使点阵图表达了一定的含义,但Windows并不知道。 dedecms.com

目前我们可以使用WM_MENUCHAR讯息。当您按下Alt和与功能表项不相符的一个字元键的组合键时,Windows将向您的视窗讯息处理程式发送一个WM_MENUCHAR讯息。GRAFMENU需要截取WM_MENUCHAR讯息并检查wParam的值(即按键的ASCII码)。如果这个值对应一个功能表项,那么向Windows传回双字组:其中高字组为2,低字组是与该键相关的功能表项索引值。然後由Windows处理余下的事。 织梦好,好织梦

非矩形点阵图图像
 

copyright dedecms

点阵图都是矩形,但不需要都显示成矩形。例如,假定您有一个矩形点阵图图像,但您却想将它显示成椭圆形。

内容来自dedecms

首先,这听起来很简单。您只需将图像载入Visual C++ Developer Studio或者Windows的「画图」程式(或者更昂贵的应用程式),然後用白色的画笔将图像四周画上白色。这时将获得一幅椭圆形的图像,而椭圆的外面就成了白色。只有当背景色为白色时此点阵图才能正确显示,如果在其他背景色上显示,您就会发现椭圆形的图像和背景之间有一个白色的矩形。这种效果不好。 织梦内容管理系统

有一种非常通用的技术可解决此类问题。这种技术包括「遮罩(mask)」点阵图和一些位元映射操作。遮罩是一种单色点阵图,它与您要显示的矩形点阵图图像尺寸相同。每个遮罩的图素都对应点阵图图像的一个图素。遮罩图素是1(白色),对应著点阵图图素显示;是0(黑色),则显示背景色。(或者遮罩点阵图与此相反,这根据您使用的位元映射操作而有一些相对应的变化。)

内容来自dedecms

让我们看看BITMASK程式是如何实作这一技术的。如程式14-9所示。 内容来自dedecms

 程式14-9  BITMASK 

织梦好,好织梦

BITMASK.C 
copyright dedecms
/*--------------------------------------------------------------------------- 
织梦内容管理系统
        BITMASK.C --   Bitmap Masking Demonstration 本文来自织梦 
                               (c) Charles Petzold, 1998 

内容来自dedecms

----------------------------------------------------------------------------*/ 
dedecms.com
  织梦好,好织梦 
#include <windows.h> 

copyright dedecms

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; 

dedecms.com

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, 
本文来自织梦
                       PSTR szCmdLine, int iCmdShow) copyright dedecms 
{ 本文来自织梦 
        static TCHAR           szAppName [] = TEXT ("BitMask") ; 织梦好,好织梦 
        HWND                                  hwnd ; 
内容来自dedecms
        MSG                                   msg ; 

内容来自dedecms

        WNDCLASS                              wndclass ; 

织梦内容管理系统

  
内容来自dedecms
        wndclass.style                                = CS_HREDRAW | CS_VREDRAW ; 

copyright dedecms

        wndclass.lpfnWndProc                          = WndProc ; 

本文来自织梦

        wndclass.cbClsExtra                           = 0 ; dedecms.com 
        wndclass.cbWndExtra                           = 0 ; 织梦好,好织梦 
        wndclass.hInstance                            = hInstance ; 

dedecms.com

        wndclass.hIcon                                = LoadIcon (NULL, IDI_APPLICATION) ; 

本文来自织梦

        wndclass.hCursor                              = LoadCursor (NULL, IDC_ARROW) ; 织梦好,好织梦 
        wndclass.hbrBackground                = (HBRUSH) GetStockObject (LTGRAY_BRUSH) ; 内容来自dedecms 
        wndclass.lpszMenuName                 = NULL ; 织梦内容管理系统 
        wndclass.lpszClassName                = szAppName ; 
本文来自织梦
      
dedecms.com
        if (!RegisterClass (&wndclass)) 

织梦内容管理系统

        { 

内容来自dedecms

                       MessageBox (NULL, TEXT ("This program requires Windows NT!"), 织梦好,好织梦 
                               szAppName, MB_ICONERROR) ; 内容来自dedecms 
                       return 0 ; 
织梦内容管理系统
     } 织梦好,好织梦 
      

织梦内容管理系统

        hwnd = CreateWindow (szAppName, TEXT ("Bitmap Masking Demo"),  

织梦内容管理系统

                               WS_OVERLAPPEDWINDOW,  
织梦好,好织梦
                               CW_USEDEFAULT, CW_USEDEFAULT, 
内容来自dedecms
                               CW_USEDEFAULT, CW_USEDEFAULT, 
织梦内容管理系统
                               NULL, NULL, hInstance, NULL) ; 
织梦内容管理系统
  

copyright dedecms

        ShowWindow (hwnd, iCmdShow) ; 
织梦好,好织梦
        UpdateWindow (hwnd) ; 织梦好,好织梦 
  

内容来自dedecms

        while (GetMessage (&msg, NULL, 0, 0)) copyright dedecms 
        { 

dedecms.com

                               TranslateMessage (&msg) ; 织梦好,好织梦 
                               DispatchMessage (&msg) ; 本文来自织梦 
        } 本文来自织梦 
        return msg.wParam ; 
dedecms.com
} 织梦好,好织梦 
  织梦好,好织梦 
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) 
dedecms.com
{ 

dedecms.com

        static HBITMAP                 hBitmapImag, hBitmapMask ; 
dedecms.com
        static HINSTANCE               hInstance ; 织梦内容管理系统 
        static int                     cxClient, cyClient, cxBitmap, cyBitmap ; 内容来自dedecms 
        BITMAP                         bitmap ; 

dedecms.com

        HDC                            hdc, hdcMemImag, hdcMemMask ; 
dedecms.com
        int                            x, y ; 
copyright dedecms
        PAINTSTRUCT                    ps ; 

本文来自织梦

      
本文来自织梦
        switch (message) 
织梦内容管理系统
     { 
本文来自织梦
        case WM_CREATE: copyright dedecms 
                               hInstance = ((LPCREATESTRUCT) lParam)->hInstance ; dedecms.com 
                                      // Load the original image and get its size dedecms.com 
                               hBitmapImag = LoadBitmap (hInstance, TEXT ("Matthew")) ; 
dedecms.com
                               GetObject (hBitmapImag, sizeof (BITMAP), &bitmap) ; 
织梦好,好织梦
                               cxBitmap = bitmap.bmWidth ; copyright dedecms 
                               cyBitmap = bitmap.bmHeight ; 
内容来自dedecms
  copyright dedecms 
                                      // Select the original image into a memory DC copyright dedecms 
                               hdcMemImag  = CreateCompatibleDC (NULL) ; copyright dedecms 
                               SelectObject (hdcMemImag, hBitmapImag) ; 织梦好,好织梦 
                                      // Create the monochrome mask bitmap and memory DC 织梦内容管理系统 
                               hBitmapMask = CreateBitmap (cxBitmap, cyBitmap, 1, 1, NULL) ; copyright dedecms 
                               hdcMemMask = CreateCompatibleDC (NULL) ; 
内容来自dedecms
                               SelectObject (hdcMemMask, hBitmapMask) ; 本文来自织梦 
  
本文来自织梦
                                      // Color the mask bitmap black with a white ellipse 
织梦好,好织梦
                               SelectObject (hdcMemMask, GetStockObject (BLACK_BRUSH)) ; dedecms.com 
                               Rectangle (hdcMemMask, 0, 0, cxBitmap, cyBitmap) ; 本文来自织梦 
                               SelectObject (hdcMemMask, GetStockObject (WHITE_BRUSH)) ; 
dedecms.com
                               Ellipse (hdcMemMask, 0, 0, cxBitmap, cyBitmap) ; 
dedecms.com
  本文来自织梦 
                                      // Mask the original image 

copyright dedecms

                               BitBlt (hdcMemImag, 0, 0, cxBitmap, cyBitmap,  

织梦内容管理系统

                                      hdcMemMask, 0, 0, SRCAND) ; copyright dedecms 
                               DeleteDC (hdcMemImag) ; dedecms.com 
                               DeleteDC (hdcMemMask) ; 
织梦好,好织梦
                               return 0 ; 内容来自dedecms 
  织梦内容管理系统 
        case    WM_SIZE: dedecms.com 
                               cxClient = LOWORD (lParam) ; 

织梦内容管理系统

                               cyClient = HIWORD (lParam) ; copyright dedecms 
                               return 0 ; 

copyright dedecms

  dedecms.com 
        case    WM_PAINT: 
织梦内容管理系统
                               hdc = BeginPaint (hwnd, &ps) ; 织梦内容管理系统 
  
本文来自织梦
                                     // Select bitmaps into memory DCs 内容来自dedecms 
  copyright dedecms 
                               hdcMemImag = CreateCompatibleDC (hdc) ; 
内容来自dedecms
                               SelectObject (hdcMemImag, hBitmapImag) ; 

本文来自织梦

  内容来自dedecms 
                               hdcMemMask = CreateCompatibleDC (hdc) ; 本文来自织梦 
                               SelectObject (hdcMemMask, hBitmapMask) ; 
本文来自织梦
  copyright dedecms 
                                      // Center image 
本文来自织梦
  
本文来自织梦
                               x = (cxClient - cxBitmap) / 2 ; 
dedecms.com
                               y = (cyClient - cyBitmap) / 2 ; 
dedecms.com
                内容来自dedecms 
                                      // Do the bitblts 本文来自织梦 
  
织梦内容管理系统
                               BitBlt (hdc, x, y, cxBitmap, cyBitmap, hdcMemMask, 0, 0, 0x220326) ; 
copyright dedecms
                               BitBlt (hdc, x, y, cxBitmap, cyBitmap, hdcMemImag, 0, 0, SRCPAINT) ; dedecms.com 
  copyright dedecms 
                               DeleteDC (hdcMemImag) ; 
copyright dedecms
                               DeleteDC (hdcMemMask) ; dedecms.com 
                               EndPaint (hwnd, &ps) ; 
织梦好,好织梦
                               return 0 ; 织梦好,好织梦 
  
内容来自dedecms
        case    WM_DESTROY: 
内容来自dedecms
                               DeleteObject (hBitmapImag) ; 本文来自织梦 
                               DeleteObject (hBitmapMask) ; 
织梦内容管理系统
                               PostQuitMessage (0) ; 本文来自织梦 
                               return 0 ; 
本文来自织梦
     } 本文来自织梦 
        return DefWindowProc (hwnd, message, wParam, lParam) ; 本文来自织梦 
} 织梦好,好织梦 
 BITMASK.RC 织梦好,好织梦 
// Microsoft Developer Studio generated resource script. 本文来自织梦 
#include "resource.h" 织梦好,好织梦 
#include "afxres.h" 
织梦内容管理系统
  内容来自dedecms 
///////////////////////////////////////////////////////////////////////////// 
织梦内容管理系统
// Bitmap copyright dedecms 
MATTHEW                 BITMAP        DISCARDABLE     "matthew.bmp" dedecms.com 

资源档案中的MATTHEW.BMP档案是我侄子的一幅黑白数位照片,宽200图素,高320图素,每图素8位元。不过,另外制作个BITMASK只是因为此档案的内容是任何东西都可以。

织梦好,好织梦

注意,BITMASK将视窗背景设为亮灰色。这样就确保我们能正确地遮罩点阵图,而不只是将其涂成白色。

copyright dedecms

下面让我们看一下WM_CREATE的处理程序:BITMASKLoadBitmap函式获得hBitmapImag变数中原始图像的代号。用GetObject函式可取得点阵图的宽度高度。然後将点阵图代号选进代号为hdcMemImag的记忆体装置内容中。

dedecms.com

程式建立的下一个单色点阵图与原来的图大小相同,其代号储存在hBitmapMask,并选进代号为hdcMemMask的记忆体装置内容中。在记忆体装置内容中,使用GDI函式,遮罩点阵图就涂成了黑色背景和一个白色的椭圆:

织梦好,好织梦

SelectObject (hdcMemMask, GetStockObject (BLACK_BRUSH)) ; 本文来自织梦 
Rectangle (hdcMemMask, 0, 0, cxBitmap, cyBitmap) ; 

copyright dedecms

SelectObject (hdcMemMask, GetStockObject (WHITE_BRUSH)) ; copyright dedecms 
Ellipse (hdcMemMask, 0, 0, cxBitmap, cyBitmap) ; 

织梦内容管理系统

因为这是一个单色的点阵图,所以黑色区域的位元是0,而白色区域的位元是1

内容来自dedecms

然後BitBlt呼叫就按此遮罩修改了原图像:

dedecms.com

BitBlt (hdcMemImag, 0, 0, cxBitmap, cyBitmap,  dedecms.com 
                               hdcMemMask, 0, 0, SRCAND) ; 本文来自织梦 

SRCAND位元映射操作在来源位元(遮罩点阵图)和目的位元(原图像)之间执行了位元AND操作。只要遮罩点阵图是白色,就显示目的;只要遮罩是黑色,则目的就也是黑色。现在原图像中就形成了一个黑色包围的椭圆区域。

内容来自dedecms

现在让我们看一下WM_PAINT处理程序。此程序同时改变了选进记忆体装置内容中的图像点阵图和遮罩点阵图。两次BitBlt呼叫完成了这个魔术,第一次在视窗上执行遮罩点阵图的BitBltdedecms.com

BitBlt (hdc, x, y, cxBitmap, cyBitmap, hdcMemMask, 0, 0, 0x220326) ; 

内容来自dedecms

这里使用了一个没有名称的位元映射操作。逻辑运算子是D & ~S。回忆来源-即遮罩点阵图-是黑色(位元值0)包围的一个白色(位元值1)椭圆。位元映射操作首先将来源反色,也就是改成白色包围的黑色椭圆。然後位元操作在这个已转换的来源和目的(即视窗上)之间执行位元AND操作。当目的和位元值1AND」时保持不变;与位元值0AND」时,目的将变黑。因此,BitBlt操作将在视窗上画一个黑色的椭圆。

copyright dedecms

第二次的BitBlt呼叫则在视窗中绘制图像点阵图: 内容来自dedecms

BitBlt (hdc, x, y, cxBitmap, cyBitmap, hdcMemImag, 0, 0, SRCPAINT) ; 

本文来自织梦

位元映射操作在来源和目的之间执行位元「OR」操作。由於来源点阵图的外面是黑色,因此保持目的不变;而在椭圆区域内,目的是黑色,因此图像就原封不动地复制了过来。执行结果如图14-9所示。 织梦内容管理系统

注意事项: 织梦好,好织梦

有时您需要一个很复杂的遮罩-例如,抹去原始图像的整个背景。您将需要在画图程式中手工建立然後将其储存到成档案。 dedecms.com


 

copyright dedecms

copyright dedecms

 

织梦内容管理系统

14-9 BITMASK的萤幕显示

copyright dedecms

 

如果正在为Windows NT编写类似的应用程式,那么您可以使用与MASKBIT程式类似的MaskBlt函式,而只需要更少的函式呼叫。Windows NT还包括另一个类似BitBlt的函式,Windows 98不支援该函式。此函式是PlgBlt(「平行四边形位元块移动:parallelogram blt」)。这个函式可以对图像进行旋转或者倾斜点阵图图像。 内容来自dedecms

最後,如果在您的机器上执行BITMASK程式,您就只会看见黑色、白色和两个灰色的阴影,这是因为您执行的显示模式是16色或256色。对於16色模式,显示效果无法改进,但在256色模式下可以改变调色盘以显示灰阶。您将在第十六章学会如何设定调色盘。 织梦好,好织梦

简单的动画
  dedecms.com

小张的点阵图显示起来非常快,因此可以将点阵图和Windows计时器联合使用,来完成一些基本的动画。 织梦好,好织梦

现在开始这个弹球程式。 copyright dedecms

BOUNCE程式,如程式14-10所示,产生了一个在视窗显示区域弹来弹去的小球。该程式利用计时器来控制小球的行进速度。小球本身是一幅点阵图,程式首先通过建立点阵图来建立小球,将其选进记忆体装置内容,然後呼叫一些简单的GDI函式。程式用BitBlt从一个记忆体装置内容将这个点阵图小球画到显示器上。

内容来自dedecms

 程式14-10  BOUNCE 
织梦内容管理系统
BOUNCE.C 本文来自织梦 
/*--------------------------------------------------------------------------- 
dedecms.com
        BOUNCE.C --    Bouncing Ball Program 织梦好,好织梦 
                                                     (c) Charles Petzold, 1998 
copyright dedecms
----------------------------------------------------------------------------*/ dedecms.com 
  

copyright dedecms

#include <windows.h> 本文来自织梦 
#define ID_TIMER    1 
织梦好,好织梦
  内容来自dedecms 
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; 

本文来自织梦

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, copyright dedecms 
                                                                     PSTR szCmdLine, int iCmdShow) 内容来自dedecms 
{ 
织梦内容管理系统
        static TCHAR szAppName[] = TEXT ("Bounce") ; 内容来自dedecms 
        HWND                                  hwnd ; 
dedecms.com
        MSG                                   msg ; 

内容来自dedecms

        WNDCLASS                              wndclass ; dedecms.com 
  

织梦内容管理系统

        wndclass.style                                = CS_HREDRAW | CS_VREDRAW ; 内容来自dedecms 
        wndclass.lpfnWndProc                          = WndProc ; 本文来自织梦 
        wndclass.cbClsExtra                           = 0 ; 本文来自织梦 
        wndclass.cbWndExtra                           = 0 ; 

内容来自dedecms

        wndclass.hInstance                            = hInstance ; 内容来自dedecms 
        wndclass.hIcon                                = LoadIcon (NULL, IDI_APPLICATION) ; copyright dedecms 
        wndclass.hCursor                              = LoadCursor (NULL, IDC_ARROW) ; 
织梦内容管理系统
        wndclass.hbrBackground                = (HBRUSH) GetStockObject (WHITE_BRUSH) ; 
内容来自dedecms
        wndclass.lpszMenuName                 = NULL ; 内容来自dedecms 
        wndclass.lpszClassName                = szAppName ; dedecms.com 
      dedecms.com 
        if (!RegisterClass (&wndclass)) 
织梦内容管理系统
        { 

dedecms.com

                       MessageBox (   NULL, TEXT ("This program requires Windows NT!"), 
本文来自织梦
                                                                     szAppName, MB_ICONERROR) ; 织梦内容管理系统 
                       return 0 ; 织梦内容管理系统 
        } 
织梦好,好织梦
      织梦好,好织梦 
        hwnd = CreateWindow (  szAppName, TEXT ("Bouncing Ball"), 
织梦好,好织梦
                                      WS_OVERLAPPEDWINDOW, 
内容来自dedecms
                                      CW_USEDEFAULT, CW_USEDEFAULT, 
copyright dedecms
                                      CW_USEDEFAULT, CW_USEDEFAULT, copyright dedecms 
                                      NULL, NULL, hInstance, NULL) ; 内容来自dedecms 
      内容来自dedecms 
        ShowWindow (hwnd, iCmdShow) ; 

内容来自dedecms

        UpdateWindow (hwnd) ; 

内容来自dedecms

        while (GetMessage (&msg, NULL, 0, 0)) 
织梦好,好织梦
        { copyright dedecms 
                       TranslateMessage (&msg) ; 

织梦好,好织梦

                       DispatchMessage (&msg) ; 织梦好,好织梦 
        } 

本文来自织梦

        return msg.wParam ; 织梦好,好织梦 
} 本文来自织梦 
  copyright dedecms 
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) dedecms.com 
{ 织梦好,好织梦 
        static HBITMAP hBitmap ; dedecms.com 
        static int                   cxClient, cyClient, xCenter, yCenter, cxTotal, cyTotal, 织梦内容管理系统 
                      cxRadius,                      cyRadius, cxMove, cyMove, xPixel, yPixel ; copyright dedecms 
        HBRUSH                                hBrush ; 

内容来自dedecms

        HDC                                   hdc, hdcMem ; 

织梦内容管理系统

        int                                   iScale ; 本文来自织梦 
      

织梦内容管理系统

        switch (iMsg) copyright dedecms 
        { 

织梦好,好织梦

        case    WM_CREATE: 

织梦好,好织梦

                               hdc = GetDC (hwnd) ; dedecms.com 
                               xPixel = GetDeviceCaps (hdc, ASPECTX) ; 
内容来自dedecms
                               yPixel = GetDeviceCaps (hdc, ASPECTY) ; 织梦好,好织梦 
                               ReleaseDC (hwnd, hdc) ; 

dedecms.com

           织梦内容管理系统 
                               SetTimer (hwnd, ID_TIMER, 50, NULL) ; 

内容来自dedecms

                               return 0 ; 织梦好,好织梦 
           本文来自织梦 
        case    WM_SIZE: 织梦好,好织梦 
                               xCenter = (cxClient = LOWORD (lParam)) / 2 ; 

本文来自织梦

                               yCenter = (cyClient = HIWORD (lParam)) / 2 ; 
copyright dedecms
           copyright dedecms 
                               iScale = min (cxClient * xPixel, cyClient * yPixel) / 16 ; 织梦内容管理系统 
           内容来自dedecms 
                               cxRadius = iScale / xPixel ; 织梦内容管理系统 
                               cyRadius = iScale / yPixel ; copyright dedecms 
           织梦好,好织梦 
                               cxMove = max (1, cxRadius / 2) ; 

内容来自dedecms

                               cyMove = max (1, cyRadius / 2) ; 
织梦内容管理系统
           

dedecms.com

                               cxTotal = 2 * (cxRadius + cxMove) ; 

织梦内容管理系统

                               cyTotal = 2 * (cyRadius + cyMove) ; 
内容来自dedecms
           织梦好,好织梦 
                               if (hBitmap) 
本文来自织梦
                                              DeleteObject (hBitmap) ; 织梦好,好织梦 
                               hdc = GetDC (hwnd) ; 织梦内容管理系统 
                               hdcMem = CreateCompatibleDC (hdc) ; 

dedecms.com

                               hBitmap = CreateCompatibleBitmap (hdc, cxTotal, cyTotal) ; 

本文来自织梦

                               ReleaseDC (hwnd, hdc) ; 

织梦好,好织梦

           织梦好,好织梦 
                               SelectObject (hdcMem, hBitmap) ; 织梦好,好织梦 
                               Rectangle (hdcMem, -1, -1, cxTotal + 1, cyTotal + 1) ; 

织梦内容管理系统

           
dedecms.com
                               hBrush = CreateHatchBrush (HS_DIAGCROSS, 0L) ; 

内容来自dedecms

                               SelectObject (hdcMem, hBrush) ; 织梦内容管理系统 
                               SetBkColor (hdcMem, RGB (255, 0, 255)) ; dedecms.com 
                               Ellipse (hdcMem, cxMove, cyMove, cxTotal - cxMove, cyTotal - cyMove) ; 
dedecms.com
                               DeleteDC (hdcMem) ; 织梦好,好织梦 
                               DeleteObject (hBrush) ; 

织梦好,好织梦

                               return 0 ; 织梦内容管理系统 
           本文来自织梦 
        case    WM_TIMER: 
织梦内容管理系统
                               if (!hBitmap) 织梦好,好织梦 
                                              break ; 本文来自织梦 
           织梦内容管理系统 
                               hdc = GetDC (hwnd) ; 

织梦内容管理系统

                               hdcMem = CreateCompatibleDC (hdc) ; dedecms.com 
                               SelectObject (hdcMem, hBitmap) ; 织梦内容管理系统 
           
织梦好,好织梦
                               BitBlt (hdc, xCenter - cxTotal / 2, 
dedecms.com
                                                             yCenter - cyTotal / 2, cxTotal, cyTotal, 

copyright dedecms

                                                             hdcMem, 0, 0, SRCCOPY) ; 织梦内容管理系统 
           本文来自织梦 
                               ReleaseDC (hwnd, hdc) ; dedecms.com 
                               DeleteDC (hdcMem) ; 内容来自dedecms 
           本文来自织梦 
                               xCenter += cxMove ; copyright dedecms 
                               yCenter += cyMove ; 织梦内容管理系统 
           本文来自织梦 
                               if ((xCenter + cxRadius >= cxClient) || (xCenter - cxRadius <= 0)) 内容来自dedecms 
                                              cxMove = -cxMove ; 织梦好,好织梦 
           dedecms.com 
                               if ((yCenter + cyRadius >= cyClient) || (yCenter - cyRadius <= 0)) 
织梦内容管理系统
                                              cyMove = -cyMove ; 织梦好,好织梦 
           dedecms.com 
                               return 0 ; 
本文来自织梦
           

织梦好,好织梦

        case    WM_DESTROY: 

dedecms.com

                               if (hBitmap) 

织梦内容管理系统

                                              DeleteObject (hBitmap) ; 

织梦内容管理系统

           织梦好,好织梦 
                               KillTimer (hwnd, ID_TIMER) ; 
copyright dedecms
                               PostQuitMessage (0) ; dedecms.com 
                               return 0 ; 内容来自dedecms 
     } 织梦内容管理系统 
        return DefWindowProc (hwnd, iMsg, wParam, lParam) ; dedecms.com 
} dedecms.com 

BOUNCE每次收到一个WM_SIZE讯息时都重画小球。这就需要与视讯显示器相容的记忆体装置内容: 织梦好,好织梦

hdcMem = CreateCompatibleDC (hdc) ; 
copyright dedecms

小球的直径设为视窗显示区域高度或宽度中较短者的十六分之一。不过,程式构造的点阵图却比小球大:从点阵图中心到点阵图四个边的距离是小球半径的1.5倍: 织梦内容管理系统

hBitmap = CreateCompatibleBitmap (hdc, cxTotal, cyTotal) ; 
织梦好,好织梦

将点阵图选进记忆体装置内容後,整个点阵图背景设成白色:

dedecms.com

Rectangle (hdcMem, -1, -1, xTotal + 1, yTotal + 1) ; 
织梦内容管理系统

那些不固定的座标使矩形边框在点阵图之外著色。一个对角线开口的画刷选进记忆体装置内容,并将小球画在点阵图的中央:

织梦好,好织梦

Ellipse (hdcMem, xMove, yMove, xTotal - xMove, yTotal - yMove) ; 
织梦好,好织梦

当小球移动时,小球边界的空白会有效地删除前一时刻的小球图像。在另一个位置重画小球只需在BitBlt呼叫中使用SRCCOPYROP代码: 织梦内容管理系统

BitBlt (hdc, xCenter - cxTotal / 2, yCenter - cyTotal / 2, cxTotal, cyTotal, 织梦好,好织梦 
                       hdcMem, 0, 0, SRCCOPY) ; 织梦内容管理系统 

BOUNCE程式只是展示了在显示器上移动图像的最简单的方法。在一般情况下,这种方法并不能令人满意。如果您对动画感兴趣,那么除了在来源和目的之间执行或操作以外,您还应该研究其他的ROP代码(例如SRCINVERT)。其他动画技术包括Windows调色盘(以及AnimatePalette函式)和CreateDIBSection函式。对於更高级的动画您只好放弃GDI而使用DirectX介面了。

织梦内容管理系统

视窗外的点阵图
  内容来自dedecms

SCRAMBLE程式,如程式14-11所示,编写非常粗糙,我本来不应该展示这个程式,但它示范了一些有趣的技术,而且在交换两个显示矩形内容的BitBlt操作的程序中,用记忆体装置内容作为临时储存空间。

织梦内容管理系统

 程式14-11  SCRAMBLE copyright dedecms 
SCRAMBLE.C 
内容来自dedecms
/*--------------------------------------------------------------------------- 织梦好,好织梦 
   SCRAMBLE.C --       Scramble (and Unscramble) Screen dedecms.com 
                                                             (c) Charles Petzold, 1998 织梦内容管理系统 
-----------------------------------------------------------------------------*/ 

内容来自dedecms

  本文来自织梦 
#include <windows.h> 织梦内容管理系统 
  

copyright dedecms

#define NUM 300 

织梦好,好织梦

  织梦内容管理系统 
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; 
dedecms.com
  

dedecms.com

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, 
织梦内容管理系统
                                                                     PSTR szCmdLine, int iCmdShow) 
织梦内容管理系统
{ 

dedecms.com

        static int             iKeep [NUM][4] ; 
copyright dedecms
        HDC                                   hdcScr, hdcMem ; 

织梦内容管理系统

        int                                   cx, cy ; 织梦好,好织梦 
        HBITMAP                        hBitmap ; 

copyright dedecms

        HWND                                  hwnd ; copyright dedecms 
        int                                   i, j, x1, y1, x2, y2 ; 

本文来自织梦

  织梦好,好织梦 
        if (LockWindowUpdate (hwnd = GetDesktopWindow ())) 

copyright dedecms

        { 织梦好,好织梦 
                       hdcScr  = GetDCEx (hwnd, NULL, DCX_CACHE | DCX_LOCKWINDOWUPDATE) ; 

内容来自dedecms

                       hdcMem = CreateCompatibleDC (hdcScr) ; 
dedecms.com
                       cx      = GetSystemMetrics (SM_CXSCREEN) / 10 ; 
本文来自织梦
                       cy      = GetSystemMetrics (SM_CYSCREEN) / 10 ; 织梦好,好织梦 
                       hBitmap = CreateCompatibleBitmap (hdcScr, cx, cy) ; 
copyright dedecms
          

内容来自dedecms

                       SelectObject (hdcMem, hBitmap) ; 
copyright dedecms
               srand ((int) GetCurrentTime ()) ; 织梦好,好织梦 
           

内容来自dedecms

                       for (i = 0 ; i < 2   ; i++) 
dedecms.com
                       for (j = 0 ; j < NUM ; j++) 内容来自dedecms 
                       { dedecms.com 
                               if (i == 0) 

织梦好,好织梦

                               { 内容来自dedecms 
                                      iKeep [j] [0] = x1 = cx * (rand () % 10) ; 
内容来自dedecms
                                      iKeep [j] [1] = y1 = cy * (rand () % 10) ; 

copyright dedecms

                                      iKeep [j] [2] = x2 = cx * (rand () % 10) ; dedecms.com 
                                      iKeep [j] [3] = y2 = cy * (rand () % 10) ; 
dedecms.com
                               } 

dedecms.com

                               else 

内容来自dedecms

                               { 织梦内容管理系统 
                                              x1 = iKeep [NUM - 1 - j] [0] ; 
内容来自dedecms
                                              y1 = iKeep [NUM - 1 - j] [1] ; 
本文来自织梦
                                              x2 = iKeep [NUM - 1 - j] [2] ; 
copyright dedecms
                                              y2 = iKeep [NUM - 1 - j] [3] ; 织梦好,好织梦 
                               } dedecms.com 
                               BitBlt (hdcMem,  0,  0, cx, cy, hdcScr, x1, y1, SRCCOPY) ; copyright dedecms 
                               BitBlt (hdcScr, x1, y1, cx, cy, hdcScr, x2, y2, SRCCOPY) ; 本文来自织梦 
                               BitBlt (hdcScr, x2, y2, cx, cy, hdcMem,  0,  0, SRCCOPY) ; 内容来自dedecms 
                     织梦内容管理系统 
                       Sleep (10) ; 

织梦好,好织梦

                       } 本文来自织梦 
                
本文来自织梦
                       DeleteDC (hdcMem) ; 
dedecms.com
                       ReleaseDC (hwnd, hdcScr) ; 
织梦内容管理系统
                       DeleteObject (hBitmap) ; 
本文来自织梦
              内容来自dedecms 
                       LockWindowUpdate (NULL) ; 
织梦好,好织梦
        } 

织梦好,好织梦

        return FALSE ; copyright dedecms 
} 

内容来自dedecms

SCRAMBLE没有视窗讯息处理程式。在WinMain中,它首先呼叫带有桌面视窗代号的LockWindowUpdate。此函式暂时防止其他程式更新萤幕。然後SCRAMBLE通过呼叫带有参数DCX_LOCKWINDOWUPDATEGetDCEx来获得整个萤幕的装置内容。这样就只有SCRAMBLE可以更新萤幕了。

内容来自dedecms

然後SCRAMBLE确定全萤幕的尺寸,并将长宽分别除以10。程式用这个尺寸(名称是cxcy)来建立一个点阵图,并将该点阵图选进记忆体装置内容。 织梦内容管理系统

使用C语言的rand函式,SCRAMBLE计算出四个随机值(两个座标点)作为cxcy的倍数。程式透过三次呼叫BitBlt函式来交换两个矩形块中显示的内容。第一次将从第一个座标点开始的矩形复制到记忆体装置内容。第二次BitBlt将从第二座标点开始的矩形复制到第一点开始的位置。第三次将记忆体装置内容中的矩形复制到第二个座标点开始的区域。 织梦内容管理系统

此程序将有效地交换显示器上两个矩形中的内容。SCRAMBLE执行300次交换,这时的萤幕显示肯定是一团糟。但不用担心,因为SCRAMBLE记得是怎么把显示弄得这样一团糟的,接著在退出前它会按相反的次序恢复原来的桌面显示(锁定萤幕前的画面)! 织梦内容管理系统

您也可以用记忆体装置内容将一个点阵图复制给另一个点阵图。例如,假定您要建立一个点阵图,该点阵图只包含另一个点阵图左上角的图形。如果原来的图像代号为hBitmap,那么您可以将其尺寸复制到一个BITMAP型态的结构中: copyright dedecms

GetObject (hBitmap, sizeof (BITMAP), &bm) ; 
织梦好,好织梦

然後建立一个未初始化的新点阵图,该点阵图的尺寸是原来图的1/4本文来自织梦

hBitmap2 = CreateBitmap (      bm.bmWidth / 2, bm.bmHeight / 2, 
dedecms.com
                               bm.bmPlanes, bm.bmBitsPixel, NULL) ; 
织梦好,好织梦

现在建立两个记忆体装置内容,并将原来点阵图和新点阵图选分别进这两个记忆体装置内容: 织梦好,好织梦

hdcMem1 = CreateCompatibleDC (hdc) ; 本文来自织梦 
hdcMem2 = CreateCompatibleDC (hdc) ; 

内容来自dedecms

  

copyright dedecms

SelectObject (hdcMem1, hBitmap) ; 
织梦好,好织梦
SelectObject (hdcMem2, hBitmap2) ; 

织梦内容管理系统

最後,将第一个点阵图的左上角复制给第二个:

织梦内容管理系统

BitBlt (       hdcMem2, 0, 0, bm.bmWidth / 2, bm.bmHeight / 2, 

内容来自dedecms

                               hdcMem1, 0, 0, SRCCOPY) ; copyright dedecms 

剩下的只是清除工作:

copyright dedecms

DeleteDC (hdcMem1) ; 
内容来自dedecms
DeleteDC (hdcMem2) ; 织梦内容管理系统 
DeleteObject (hBitmap) ; 本文来自织梦 

BLOWUP.C程式,如图14-21所示,也用视窗更新锁定来在程式视窗之外显示一个捕捉的矩形。此程式允许使用者用滑鼠圈选萤幕上的矩形区域,然後BLOWUP将该区域的内容复制到点阵图。在WM_PAINT讯息处理期间,点阵图复制到程式的显示区域,必要时将拉伸或压缩。(参见程式14-12。)

织梦内容管理系统

 程式14-12  BLOWUP 内容来自dedecms 
BLOWUP.C 
织梦内容管理系统
/*-------------------------------------------------------------------------- 

织梦好,好织梦

        BLOWUP.C --    Video Magnifier Program 
织梦好,好织梦
                                                     (c) Charles Petzold, 1998 dedecms.com 
----------------------------------------------------------------------------*/ 内容来自dedecms 
  
copyright dedecms
#include <windows.h>    

dedecms.com

#include <stdlib.h>                                          // for abs definition 
dedecms.com
#include "resource.h"   织梦好,好织梦 
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; 织梦好,好织梦 
  copyright dedecms 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, copyright dedecms 
                                                                     PSTR szCmdLine, int iCmdShow) 
内容来自dedecms
{ 织梦内容管理系统 
        static TCHAR           szAppName [] = TEXT ("Blowup") ; copyright dedecms 
        HACCEL                                hAccel ; 

织梦好,好织梦

        HWND                                  hwnd ; 本文来自织梦 
        MSG                                   msg ; 

织梦好,好织梦

        WNDCLASS                              wndclass ; 织梦好,好织梦 
  
copyright dedecms
        wndclass.style                                = CS_HREDRAW | CS_VREDRAW ; dedecms.com 
        wndclass.lpfnWndProc                          = WndProc ; 
内容来自dedecms
        wndclass.cbClsExtra                           = 0 ; 

copyright dedecms

        wndclass.cbWndExtra                           = 0 ; 内容来自dedecms 
        wndclass.hInstance                            = hInstance ; 内容来自dedecms 
        wndclass.hIcon                                = LoadIcon (NULL, IDI_APPLICATION) ; 
dedecms.com
        wndclass.hCursor                              = LoadCursor (NULL, IDC_ARROW) ; 

内容来自dedecms

        wndclass.hbrBackground                = (HBRUSH) GetStockObject (WHITE_BRUSH) ; 

织梦好,好织梦

        wndclass.lpszMenuName                 = szAppName ; 织梦内容管理系统 
        wndclass.lpszClassName                = szAppName ; 
dedecms.com
      内容来自dedecms 
        if (!RegisterClass (&wndclass)) dedecms.com 
        { 

内容来自dedecms

                       MessageBox (   NULL, TEXT ("This program requires Windows NT!"), 

织梦内容管理系统

                                                                     szAppName, MB_ICONERROR) ; 织梦好,好织梦 
                       return 0 ; 本文来自织梦 
        } 本文来自织梦 
      
织梦内容管理系统
        hwnd = CreateWindow (  szAppName, TEXT ("Blow-Up Mouse Demo"),  
本文来自织梦
                                          WS_OVERLAPPEDWINDOW,  内容来自dedecms 
                                              CW_USEDEFAULT, CW_USEDEFAULT, dedecms.com 
                                              CW_USEDEFAULT, CW_USEDEFAULT, 内容来自dedecms 
                                              NULL, NULL, hInstance, NULL) ; 内容来自dedecms 
  内容来自dedecms 
        ShowWindow (hwnd, iCmdShow) ; dedecms.com 
        UpdateWindow (hwnd) ; 内容来自dedecms 
  dedecms.com 
        hAccel = LoadAccelerators (hInstance, szAppName) ; 织梦好,好织梦 
        while (GetMessage (&msg, NULL, 0, 0)) dedecms.com 
        { 

织梦内容管理系统

                       if (!TranslateAccelerator (hwnd, hAccel, &msg)) 本文来自织梦 
                       { 
本文来自织梦
                                      TranslateMessage (&msg) ; 织梦内容管理系统 
                                      DispatchMessage (&msg) ; 

copyright dedecms

                       } dedecms.com 
        } 

dedecms.com

        return msg.wParam ; 本文来自织梦 
} 
织梦好,好织梦
  
dedecms.com
void InvertBlock (HWND hwndScr, HWND hwnd, POINT ptBeg, POINT ptEnd) 
织梦内容管理系统
{        dedecms.com 
        HDC hdc ; 本文来自织梦 
        hdc = GetDCEx (hwndScr, NULL, DCX_CACHE | DCX_LOCKWINDOWUPDATE) ; 
织梦内容管理系统
        ClientToScreen (hwnd, &ptBeg) ; copyright dedecms 
        ClientToScreen (hwnd, &ptEnd) ; 

本文来自织梦

        PatBlt (hdc, ptBeg.x, ptBeg.y, ptEnd.x - ptBeg.x, ptEnd.y - ptBeg.y, 
织梦好,好织梦
                                              DSTINVERT) ; 

织梦内容管理系统

        ReleaseDC (hwndScr, hdc) ; 织梦内容管理系统 
} 织梦好,好织梦 
  内容来自dedecms 
HBITMAP CopyBitmap (HBITMAP hBitmapSrc) 
本文来自织梦
{ 
织梦好,好织梦
        BITMAP                 bitmap ; 织梦内容管理系统 
        HBITMAP                hBitmapDst ; 织梦好,好织梦 
        HDC                            hdcSrc, hdcDst ; dedecms.com 
  织梦内容管理系统 
        GetObject (hBitmapSrc, sizeof (BITMAP), &bitmap) ; 

dedecms.com

        hBitmapDst = CreateBitmapIndirect (&bitmap) ; 

内容来自dedecms

  

织梦好,好织梦

        hdcSrc = CreateCompatibleDC (NULL) ; 

织梦好,好织梦

        hdcDst = CreateCompatibleDC (NULL) ; 

本文来自织梦

  
copyright dedecms
        SelectObject (hdcSrc, hBitmapSrc) ; 

织梦好,好织梦

        SelectObject (hdcDst, hBitmapDst) ; 织梦内容管理系统 
  
织梦内容管理系统
        BitBlt (hdcDst, 0, 0, bitmap.bmWidth, bitmap.bmHeight, 内容来自dedecms 
                                      hdcSrc, 0, 0, SRCCOPY) ; 

dedecms.com

        DeleteDC (hdcSrc) ; 
内容来自dedecms
        DeleteDC (hdcDst) ; 织梦好,好织梦 
  
本文来自织梦
        return hBitmapDst ; copyright dedecms 
} dedecms.com 
  
本文来自织梦
LRESULT CALLBACK WndProc (     HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) 织梦内容管理系统 
{ 织梦好,好织梦 
        static BOOL            bCapturing, bBlocking ; dedecms.com 
        static HBITMAP     hBitmap ; 

织梦好,好织梦

        static HWND            hwndScr ; dedecms.com 
        static POINT           ptBeg, ptEnd ; 

dedecms.com

        BITMAP                 bm ; 

织梦内容管理系统

        HBITMAP                hBitmapClip ; 织梦好,好织梦 
        HDC                    hdc, hdcMem ; dedecms.com 
        int                    iEnable ; 
copyright dedecms
        PAINTSTRUCT            ps ; 织梦好,好织梦 
        RECT                   rect ; 内容来自dedecms 
  

内容来自dedecms

        switch (message) 织梦内容管理系统 
        { 
dedecms.com
        case    WM_LBUTTONDOWN: 
copyright dedecms
                               if (!bCapturing) 
织梦内容管理系统
                               { 本文来自织梦 
                                      if (LockWindowUpdate (hwndScr = GetDesktopWindow ())) 
织梦内容管理系统
                                      { 内容来自dedecms 
                                                     bCapturing = TRUE ; 织梦内容管理系统 
                                                     SetCapture (hwnd) ; 织梦好,好织梦 
                                                     SetCursor (LoadCursor (NULL, IDC_CROSS)) ; copyright dedecms 
                                      } dedecms.com 
                                      else 织梦好,好织梦 
                                                     MessageBeep (0) ; 
copyright dedecms
                                      } 
织梦内容管理系统
                                      return 0 ; 织梦内容管理系统 
  内容来自dedecms 
        case    WM_RBUTTONDOWN: 本文来自织梦 
                               if (bCapturing) 

本文来自织梦

                               { copyright dedecms 
                                      bBlocking = TRUE ; dedecms.com 
                                      ptBeg.x = LOWORD (lParam) ; 织梦好,好织梦 
                                      ptBeg.y = HIWORD (lParam) ; 本文来自织梦 
                                      ptEnd = ptBeg ; 
内容来自dedecms
                                      InvertBlock (hwndScr, hwnd, ptBeg, ptEnd) ; 
copyright dedecms
                               } 
本文来自织梦
                               return 0 ; 织梦内容管理系统 
  
copyright dedecms
        case    WM_MOUSEMOVE: dedecms.com 
                               if (bBlocking) 

本文来自织梦

                               { copyright dedecms 
                                      InvertBlock (hwndScr, hwnd, ptBeg, ptEnd) ; 

本文来自织梦

                                      ptEnd.x = LOWORD (lParam) ; 内容来自dedecms 
                                      ptEnd.y = HIWORD (lParam) ; 织梦内容管理系统 
                                      InvertBlock (hwndScr, hwnd, ptBeg, ptEnd) ; 

dedecms.com

                               } 内容来自dedecms 
                               return 0 ; 

本文来自织梦

  
本文来自织梦
        case    WM_LBUTTONUP: 
copyright dedecms
        case    WM_RBUTTONUP: 

本文来自织梦

                               if (bBlocking) 内容来自dedecms 
                               { 

dedecms.com

                                              InvertBlock (hwndScr, hwnd, ptBeg, ptEnd) ; 本文来自织梦 
                                              ptEnd.x = LOWORD (lParam) ; 

织梦内容管理系统

                                              ptEnd.y = HIWORD (lParam) ; 

内容来自dedecms

  
织梦内容管理系统
                                              if (hBitmap) 本文来自织梦 
                                              { dedecms.com 
                                                             DeleteObject (hBitmap) ; 
本文来自织梦
                                                             hBitmap = NULL ; copyright dedecms 
                                              } 

织梦好,好织梦

  内容来自dedecms 
                                              hdc = GetDC (hwnd) ; copyright dedecms 
                                              hdcMem = CreateCompatibleDC (hdc) ; 织梦好,好织梦 
                                              hBitmap= CreateCompatibleBitmap (hdc,  

内容来自dedecms

                                abs (ptEnd.x - ptBeg.x), 

织梦内容管理系统

                                abs (ptEnd.y - ptBeg.y)) ; dedecms.com 
  织梦内容管理系统 
                       SelectObject (hdcMem, hBitmap) ; 
织梦内容管理系统
  本文来自织梦 
                       StretchBlt (hdcMem, 0, 0,             abs (ptEnd.x - ptBeg.x), 
织梦内容管理系统
                               abs (ptEnd.y - ptBeg.y),  本文来自织梦 
                    hdc, ptBeg.x,     ptBeg.y, ptEnd.x - ptBeg.x,  
织梦内容管理系统
                                    ptEnd.y - ptBeg.y, SRCCOPY) ; 本文来自织梦 
                                                     DeleteDC (hdcMem) ; 

dedecms.com

                                                     ReleaseDC (hwnd, hdc) ; 织梦内容管理系统 
                                                     InvalidateRect (hwnd, NULL, TRUE) ; 织梦内容管理系统 
                               } 

dedecms.com

                               if (bBlocking || bCapturing) 

copyright dedecms

                               { 内容来自dedecms 
                                      bBlocking = bCapturing = FALSE ; 

内容来自dedecms

                                      SetCursor (LoadCursor (NULL, IDC_ARROW)) ; 
dedecms.com
                                      ReleaseCapture () ; 
织梦好,好织梦
                                      LockWindowUpdate (NULL) ; 
dedecms.com
                               } dedecms.com 
                               return 0 ; 

copyright dedecms

  内容来自dedecms 
        case    WM_INITMENUPOPUP: 
织梦好,好织梦
                               iEnable =      IsClipboardFormatAvailable (CF_BITMAP) ?  

本文来自织梦

                    MF_ENABLED : MF_GRAYED ; copyright dedecms 
  内容来自dedecms 
                              EnableMenuItem ((HMENU) wParam, IDM_EDIT_PASTE, iEnable) ; copyright dedecms 
  dedecms.com 
                               iEnable = hBitmap ? MF_ENABLED : MF_GRAYED ; 内容来自dedecms 
  

内容来自dedecms

                               EnableMenuItem ((HMENU) wParam, IDM_EDIT_CUT,    iEnable) ; 织梦内容管理系统 
                               EnableMenuItem ((HMENU) wParam, IDM_EDIT_COPY,   iEnable) ; 
织梦好,好织梦
                               EnableMenuItem ((HMENU) wParam, IDM_EDIT_DELETE, iEnable) ; 
copyright dedecms
                               return 0 ; 本文来自织梦 
  
copyright dedecms
        case    WM_COMMAND: 织梦内容管理系统 
                               switch (LOWORD (wParam)) 

dedecms.com

                               { copyright dedecms 
                       case IDM_EDIT_CUT: dedecms.com 
                               case IDM_EDIT_COPY: 
本文来自织梦
                                              if (hBitmap) 
内容来自dedecms
                                              { 
内容来自dedecms
                                      hBitmapClip = CopyBitmap (hBitmap) ; copyright dedecms 
                                      OpenClipboard (hwnd) ; 本文来自织梦 
                                      EmptyClipboard () ; 内容来自dedecms 
                               SetClipboardData (CF_BITMAP, hBitmapClip) ; 

dedecms.com

                                              } 本文来自织梦 
                                              if (LOWORD (wParam) == IDM_EDIT_COPY) dedecms.com 
                                                                     return 0 ; 织梦内容管理系统 
                            //fall through for IDM_EDIT_CUT copyright dedecms 
                               case    IDM_EDIT_DELETE: dedecms.com 
                                              if (hBitmap) 本文来自织梦 
                                              { 
本文来自织梦
                                                             DeleteObject (hBitmap) ; 织梦内容管理系统 
                                                             hBitmap = NULL ; 

dedecms.com

                                              } dedecms.com 
                                                     InvalidateRect (hwnd, NULL, TRUE) ; 
织梦内容管理系统
                                                     return 0 ; 

织梦好,好织梦

  
织梦内容管理系统
                               case    IDM_EDIT_PASTE: 
dedecms.com
                                                     if (hBitmap) 
织梦好,好织梦
                                                     { 
dedecms.com
                                                     DeleteObject (hBitmap) ; 

织梦内容管理系统

                                                     hBitmap = NULL ; 内容来自dedecms 
                               } 织梦好,好织梦 
                               OpenClipboard (hwnd) ; 
内容来自dedecms
                               hBitmapClip = GetClipboardData (CF_BITMAP) ; 
dedecms.com
  织梦好,好织梦 
                               if (hBitmapClip) 
本文来自织梦
                                                     hBitmap = CopyBitmap (hBitmapClip) ; 
dedecms.com
  

内容来自dedecms

                               CloseClipboard () ; 内容来自dedecms 
                               InvalidateRect (hwnd, NULL, TRUE) ; 内容来自dedecms 
                               return 0 ; dedecms.com 
                       } 
织梦内容管理系统
               break ; 
织梦好,好织梦
        case    WM_PAINT: copyright dedecms 
                               hdc = BeginPaint (hwnd, &ps) ; 

内容来自dedecms

  
织梦好,好织梦
                               if (hBitmap) 
copyright dedecms
                               { 

copyright dedecms

                                      GetClientRect (hwnd, &rect) ; 
织梦好,好织梦
  本文来自织梦 
                                      hdcMem = CreateCompatibleDC (hdc) ; 

本文来自织梦

                                      SelectObject (hdcMem, hBitmap) ; copyright dedecms 
                                      GetObject (hBitmap, sizeof (BITMAP), (PSTR) &bm) ; 

织梦好,好织梦

                                      SetStretchBltMode (hdc, COLORONCOLOR) ; 织梦内容管理系统 
  织梦好,好织梦 
                                      StretchBlt (hdc,    0, 0, rect.right, rect.bottom, copyright dedecms 
                     hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY) ; 

织梦好,好织梦

  

dedecms.com

                                      DeleteDC (hdcMem) ; 内容来自dedecms 
                               } 

本文来自织梦

                               EndPaint (hwnd, &ps) ; 织梦内容管理系统 
                               return 0 ; 织梦好,好织梦 
  

本文来自织梦

        case    WM_DESTROY: 织梦内容管理系统 
                               if (hBitmap) 

内容来自dedecms

                                              DeleteObject (hBitmap) ; 

内容来自dedecms

  

织梦好,好织梦

                       PostQuitMessage (0) ; 本文来自织梦 
               return 0 ; dedecms.com 
     } dedecms.com 
        return DefWindowProc (hwnd, message, wParam, lParam) ; 织梦好,好织梦 
} dedecms.com 
 BLOWUP.RC (摘录) 内容来自dedecms 
//Microsoft Developer Studio generated resource script. 织梦好,好织梦 
#include "resource.h" 本文来自织梦 
#include "afxres.h" 

dedecms.com

  

dedecms.com

///////////////////////////////////////////////////////////////////////////// 本文来自织梦 
// Menu 

dedecms.com

BLOWUP MENU DISCARDABLE  本文来自织梦 
BEGIN 

本文来自织梦

        POPUP "&Edit" 
内容来自dedecms
        BEGIN copyright dedecms 
        MENUITEM "Cu&t\tCtrl+X",              IDM_EDIT_CUT 
内容来自dedecms
        MENUITEM "&Copy\tCtrl+C",             IDM_EDIT_COPY 
织梦内容管理系统
        MENUITEM "&Paste\tCtrl+V",            IDM_EDIT_PASTE 

织梦内容管理系统

        MENUITEM "De&lete\tDelete",          IDM_EDIT_DELETE 
织梦内容管理系统
        END 
织梦好,好织梦
END 织梦内容管理系统 
  本文来自织梦 
///////////////////////////////////////////////////////////////////////////// 
织梦内容管理系统
// Accelerator 内容来自dedecms 
BLOWUP ACCELERATORS DISCARDABLE  织梦内容管理系统 
BEGIN 
copyright dedecms
        "C",      IDM_EDIT_COPY,     VIRTKEY, CONTROL, NOINVERT 
本文来自织梦
        "V",      IDM_EDIT_PASTE,    VIRTKEY, CONTROL, NOINVERT 

织梦好,好织梦

        VK_DELETE,         IDM_EDIT_DELETE,   VIRTKEY, NOINVERT 
内容来自dedecms
        "X",      IDM_EDIT_CUT,      VIRTKEY, CONTROL, NOINVERT 内容来自dedecms 
END 
本文来自织梦
 RESOURCE.H (摘录) 
织梦内容管理系统
// Microsoft Developer Studio generated include file. copyright dedecms 
// Used by Blowup.rc 
copyright dedecms
  内容来自dedecms 
#define IDM_EDIT_CUT         40001 

织梦内容管理系统

#define IDM_EDIT_COPY        40002 
织梦内容管理系统
#define IDM_EDIT_PASTE       40003 本文来自织梦 
#define IDM_EDIT_DELETE      40004 
内容来自dedecms


  织梦好,好织梦

织梦好,好织梦

  本文来自织梦

14-10 BLOWUP显示的一个范例 织梦内容管理系统

 

由於滑鼠拦截的限制,所以开始使用BLOWUP时会有些困难,需要逐渐适应。下面是使用本程式的方法: 织梦好,好织梦

  1. BLOWUP显示区域按下滑鼠左键不放,滑鼠指标会变成「+」字型。
  2. 继续按住左键,将滑鼠移到萤幕上的任何其他位置。滑鼠游标的位置就是您要圈选的矩形区域的左上角。
  3. 继续按住左键,按下滑鼠右键,然後拖动滑鼠到您要圈选的矩形区域的右下角。释放滑鼠左键和右键。(释放滑鼠左、右键次序无关紧要。)

滑鼠游标恢复成箭头状,这时您圈选的矩形区域已复制到了BLOWUP的显示区域,并作了适当的压缩或拉伸变化。

内容来自dedecms

如果您从右上角到左下角选取的话,BLOWUP将显示矩形区域的镜像。如果从左下到右上角选取,BLOWUP将显示颠倒的图像。如果从右上角至左上角选取,程式将综合两种效果。 织梦好,好织梦

BLOWUP还包含将点阵图复制到剪贴簿,以及将剪贴簿中的点阵图复制到程式的处理功能。BLOWUP处理WM_INITMENUPOPUP讯息来启用或禁用「Edit」功能表中的不同选项,并通过WM_COMMAND讯息来处理这些功能表项。您应该对这些程式码的结构比较熟悉,因为它们与第十二章中的复制和粘贴文字项目的处理方式在本质上是一样的。 dedecms.com

不过,对於点阵图,剪贴簿物件不是整体代号而是点阵图代号。当您使用CF_BITMAP时,GetClipboardData函式传回一个HBITMAP物件,而且SetClipboardData函式接收一个HBITMAP物件。如果您想将点阵图传送给剪贴簿又想保留副本以供程式本身使用,那么您必须复制点阵图。同样,如果您从剪贴簿上粘贴了一幅点阵图,也应该做一个副本。BLOWUP中的CopyBitmap函式是通过取得现存点阵图的BITMAP结构,并在CreateBitmapIndirect函式中用这个结构建立一个新点阵图来完成此项操作的。(变数名的尾码SrcDst分别代表「来源」和「目的」。) 两个点阵图都被选进记忆体装置内容,而且通过呼叫BitBlt来复制点阵图内容。(另一种复制位元的方法,可以先按点阵图大小配置一块记忆体,然後为来源点阵图呼叫GetBitmapBits,为目的点阵图呼叫SetBitmapBits。) 织梦好,好织梦

我发现BLOWUP对於检查Windows及其应用程式中大量分散的小点阵图和图片非常有用。 内容来自dedecms