Software 版 (精华区)

发信人: checcy (老巴夺), 信区: Software
标  题: 设备场境(DC)在GDI中的应用
发信站: 哈工大紫丁香 (Sat Apr 11 13:20:17 1998), 转信

设备场境(DC)在GDI中的应用
□成都   李火亘

现在有很多Windows开发工具,如Borland
 C++、Visual C++,都对Windows图形设备界面(GDI)
进行了封装,这使得对Windows图形进行操作相当方便,可
以使用大量现成的GDI类,通过少许代码,就可以完成很强
大的功能。譬如,在Borland C++中,对于大量的文本或很
大的一幅位图,要想加入滚动功能是非常简单的,只需初始
化TScroller类的一个内部变量,并且把窗口的风格设为可滚
动的即可。本文通过一个放大镜实例来说明Windows设备场境
类的应用(使用Borland C++ 开发工具)。


本程序演示了一个桌面上的放大镜,运行以后出现一个窗口及
一个放大镜。你可以在桌面上移动放大镜,经过放大后的图像
出现在窗口中,还可把此程序加入到其他程序中,这样,得到
的程序就具有了放大浏览功能。

在Borland C++中,提供了很多设备场境类,如TWindowDC,
 TMemoryDC, TScreenDC等。这些类的基类都是TDC。每个类继
承了基类的特征,并且每个类又扩展了各自的功能。本程序主
要用到了TMemoryDC, TScreenDC, 以及TClientDC。TClientDC
提供进入某个窗口客户区的句柄,通过这个句柄,就可直接进入
绘图区进行绘图。TScreenDC提供了进入屏幕位图的直接句柄,
通过它,就可获得屏幕位图。而TMemoryDC提供了进入内存场境
的句柄,这个类相当有用,当你想产生动画效果时,可先在内存
位图中绘图,然后把位图传输到屏幕当前设备场境中,即可达到
无延迟的显示了。

程序一开始构造框架窗口,并且声明了一些成员变量和成员函数
,以及消息响应表。消息响应表是用来把消息和消息响应函数链
接起来。接下来,建立应用程序实例,并且重载了虚函数
InitMainWindow(),此函数主要用于创建主窗口,及设立窗口风
格、光标类型。下面的OwlMain() 函数启动应用程序。再下来定
义了消息响应表,把事件与响应函数链接起来。程序的主体在
EvMouseMove() 函数中,首先用SetCapture() 来捕获鼠标移动
事件,以使鼠标移动事件得到正确处理。下面定义了TScreenDC和
TClientDC两个设备场境句柄,ClientToScreen() 函数将鼠标坐
标从客户区坐标转化为屏幕坐标,只有这样窗口才能捕获所有的
鼠标事件(包括窗口之外的)。TBitmap类用于构造一个位图,其
大小为120 ( 120像素),此位图被选入内存场境中。这样,只要
作图时选用内存场境句柄,则所画内容就被记录在此位图中,要
对所画内容进行修改,比如放大,缩小等,就可直接对此位图进
行。PatBlt()函数用来对内存位图进行填色。获取屏幕上的图像
并转化为位图是通过GetPixel() 和SetPixel() 函数实现的,此
两函数用于取得或设置像素颜色。对图像进行放大是通过函数
StretchBlt() 来进行的,这个函数对位图进行缩放。BitBlt() 
函数把内存位图传送到当前屏幕上。只有通过内存位图作为中间
存储,才不会导致屏幕上有明显的延迟。除了源文件外,还需要
一个资源文件,其中包括一个光标资源,该资源用Borland C++
 中的Resource WorkShop生成。这个光标就是一个放大镜形状,
需要注意的是,设计好光标后,应把它的“热点”(hot spot)设
立在放大镜的中心。本例所设计的放大镜的有效区为所画圆的内
接矩形,其长为14,宽为10。设计时可先画出圆,然后在其中找
到一个最合适的内接矩形,并根据屏幕提示找出其长和宽尺寸。
如果尺寸与本例不一致,请修改程序中EvMouseMove() 函数中的
GetPixel() 和SetPixel() 函数的参数,以适应实际需要。

下面附源程序:(本程序在Borland C++4.5版本下调试通过,

编译时请注意选择OWL类库)
#include<owl\applicat.h>
#include<owl\framewin.h>
#include<stdlib.h>
#include<stdio.h>
#include″draw.rh″   // draw.rh文件是建立资源时自
                        //  动产生的 
class TDWin: public TFrameWindow{
public:
  TDWin();
  ~TDWin()
  {}
  int n;
  TBitmap bit1;
  TMemoryDC memdc;
  void EvLButtonDown(uint,TPoint& point);
  void EvRButtonDown(uint,TPoint& point);
  void EvMouseMove(uint,TPoint& point);
  DECLARE_RESPONSE_TABLE(TDWin);
  };
  class TDApp : public TApplication{
  public:
      virtual void InitMainWindow()
      {
      TDWin frame=new TDWin();
      SetMainWindow(frame);
      frame->Attr.W=150;
      frame->Attr.H=150;
      frame->Attr.Style&  
=~WS_MAXIMIZEBOX&~WS_MINIMIZEBOX;
     frame->SetCursor(
GetMainWindow()->GetModule(),CURSOR_1);}  };
      int OwlMain(int ,char [])
      {
      return TDApp().Run();
      }
      DEFINE_RESPONSE_TABLE1(TDWin,TFrameWindow)
      EV_WM_LBUTTONDOWN,
      EV_WM_RBUTTONDOWN,
      EV_WM_MOUSEMOVE,
      END_RESPONSE_TABLE;
      TDWin::TDWin(): TFrameWindow(0,″放大镜″){}
  void TDWin::EvLButtonDown(uint, TPoint& point)
  {
       ReleaseCapture();}
 void TDWin::EvRButtonDown(uint,TPoint& point)
  {
  PostQuitMessage(0);}             //退出
void TDWin::EvMouseMove(uint,TPoint & point)
        {
             SetCapture();
             TScreenDC sdc;
             TClientDC dc(this);
             TColor col;
             ClientToScreen(point);
             TBitmap bit2(dc,120,120);
             TMemoryDC memdc(dc);
             memdc.SelectObject(bit2);
             memdc.PatBlt(0,0,120,120,WHITENESS);
  for(int i=0;i<7;i++)  //其中7代表有效区的长度
                         //的一半
  for(int j=0;j<5;j++)  //5代表有效区宽度的一半
                   {
                    
col=sdc.GetPixel(point.x-j,point.y-i);
                     memdc.SetPixel(5-j,7-i,col);
                    
col=sdc.GetPixel(point.x+j,point.y-i);
                     memdc.SetPixel(5+j,7-i,col);
                    
col=sdc.GetPixel(point.x-j,point.y+i);
                     memdc.SetPixel(5-j,7+i,col);
                    
col=sdc.GetPixel(point.x+j,point.y+i);
                     memdc.SetPixel(5+j,7+i,col);
                     }
  memdc.StretchBlt(0,0,120,120,memdc,0,0,10,14);
      dc.BitBlt(0,0,125,125,memdc,0,0);
  memdc.RestoreBitmap();
          }




-- 
Chengyan Che - Software Freelancer, Harbin, P.R.China
-----------------------------------------------------------
Do you need a software developer for your project or just
for your killer money-making idea? Drop me a line and let
me know how I can help you out! 
mailto:checcy@public.hr.hl.cn
ICQ:5116726

--
☆ 来源:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: checcy@public.hr.hl.]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:2.407毫秒