相濡以沫

鱼遇于池,池涸,相濡以沫,相鞠以湿,不若相忘于海。(爱技术、爱时尚)

用户操作
[即时聊天] [发私信] [加为好友]
挨踢老人ID:onlyzhangqin
3131023次访问,排名1,好友286人,关注者1065人。
大便的离去是马桶的招唤,还是肛门的不挽留?
onlyzhangqin的文章
原创 672 篇
翻译 11 篇
转载 18940 篇
评论 268 篇
挨踢老人的公告
点我聊QQ


最近评论
jianwei824:上大一的时候我也写过这样的一个程序,通过这个才真正开始对编程着迷,但编了好多年又迷了!
feiniao2008:学习
mynote:30岁而已,当了总统还是最年轻的总统呢。
jerry_yn:我想知道你的无线模块有中继功能吗?
huangkui800:好 嘿嘿
文章分类
收藏
相册
超女里不多的美女
都是美女
好看好玩
著名的照片
技术
Cisco网络技术(Net130.Com)
CSS在线编辑
DotNet男孩社区
IP查询
Sunmoonfire's artistic matrix
UML软件工程组织
一个好博客(RSS)
中国协议分析网
中国项目管理网
微软帮助和支持
朋友
又一个好博客(RSS)
小人鱼的秘密
我的站长天下
其它
AC MILAN官网
Badged
deshow 在线制作服务
E书下载
IT公司速查手册
msn在线留言
Slide
Webfetti
东方资源
中华电脑书库
博客网址价值评估工具
我爱e书
我的下载Blog
存档
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
订阅到BlogLines
订阅到Yahoo
订阅到GouGou
订阅到飞鸽
订阅到Rojo
订阅到newsgator
订阅到netvibes

转载 Visual C++实现带阴影弹出窗口的效果。收藏

新一篇: Greatfreefonts:免费英文字体下载分享站。 | 旧一篇: ASP.NET 中整合JavaScript的技巧。

 



淘宝书店:http://shop35357269.taobao.com
我的非技术博客:http://wholdman.blogcn.com

    

一.问题的提出

   在WINDOWS的WINHELPER帮助系统中大量使用一类带阴影的弹出窗口, 这类窗口非常简洁,并具有立体感,它们用来显示一些只读信息.此类弹出窗口不同于一般的窗口,它们没有标题和滚动杆,但都具有带阴影的边框, 并且其窗口的大小随显示字符串多少而自动调节,当显示信息弹出之后,任何来自键盘或鼠标的消息都将导致弹出窗口的消失。 然而WINDOWS API接口中没有现成的函数来实现此项功能,即使是最新版的 VISUAL C++ MFC也没有提供现成的类和函数来实现带阴影的此类窗口。为此,笔者基于面向对象的程序设计思想,从CWnd派生一个新类来实现这个功能,并且将该类窗口的所有函数完全封装在一起,使用就像调用“ MessageBox()”函数显示信息一样简单。

二.实现方法的几个关键部分说明如下

   要解决怎样画非用户区的问题:当WINDOWS需要创建一个窗口时,它发送两个消息:WM_NCPAINT和 WM_PAINT到应用程序消息队列。WM_NCPAINT用于重画窗口的非用户区,如标题,边框和滚动杆,本程序正是响应WM_NCPAINT消息来重画带阴影的弹出窗口的边框;画客户区很简单,只需响应WM_PAINT消息处理字符的显示即可.2.如何动态调整弹出窗口的尺寸:大家知道,在一个矩形内显示文本串时,常用函数DrawText(HDC hDC,LPTSTR lpszText,int cbCount,RECT FAR* lpRect,UINT fuFormat).但是,此时我们的带阴影的弹出窗口并为建立.当然不能利用它来显示.然而,我们注意到上述函数中的最后一个参数FuFormat, 它是文字格式的组合,其中有一个鲜为人知的参数 DT_CALCRECT, 使用这个参数,字符串不显示,但它根据当前字体测量待显示串的高度, 本程序正是根据这个参数来确定弹出窗口的大小,并以此建立一个随字符串大小而变化的窗口,下面给出其实现该功能的片断:

 void CShadowWnd::ShowText(CString sText)
dc.CreateDC("DISPLAY",NULL,NULL,NULL); //创建一个显示设备描述表
dc.SelectObject(GetStockObject(SYSTEM_FONT)); //选择字体到设备描述表
CRect rect(0,0,MAXWIDTH,0);// 

//获得待显示的字符串 sText 的实际高度和宽度,并将其存入矩形rect中   

  dc.DrawText(sText,rect,DT_WORDBREAK|DT_CENTER|DT_CALCRECT|DT_NOPREFIX);

3.怎样获取对系统的控制权:

   在带阴影的弹出窗口显示之后,怎样获取对系统的控制权,使得当用户按下键盘任意键或鼠标时都将使带阴影的弹出窗口消失,这里采取的方法是,当弹出窗口创建和显示之后,立即进入一个消息循环,从应用程序队列中获取所有消息,并判断是否为鼠标消息或键盘消息,如是,则摧毁窗口结束,并将控制权归还给调用程序.实现片断如下:
//进入消息循环,获取全部消息,控制整个系统 

  MSG Msg;

  BOOL bDone;

  SetCapture();

  bDone=FALSE;

  while(!bDone)

  {

    if(PeekMessage(&Msg,NULL,0,0,PM_REMOVE))

      if(Msg.message==WM_KEYDOWN||Msg.message==WM_SYSKEYDOWN||

        Msg.message==WM_LBUTTONDOWN||Msg.message==WM_RBUTTONDOWN)

        bDone=TRUE;

      else

      {

        TranslateMessage(&Msg);

        DispatchMessage(&Msg);

      }

  }

  ReleaseCapture();

  DestroyWindow();

……

}

 
. 带阴影的类 CShadowWnd 类的头文件及其实现文件的全部细节 
 

//头文件:
#if !defined(AFX_SHADOWWND_H__B971A958_59CC_11D2_AC8F_0060084237F6__INCLUDED_)

#define AFX_SHADOWWND_H__B971A958_59CC_11D2_AC8F_0060084237F6__INCLUDED_

#if _MSC_VER >= 1000

#pragma once

#endif // _MSC_VER >= 1000

// ShadowWnd.h : header file

//

/////////////////////////////////////////////////////////////////////////////

// CShadowWnd window

class CShadowWnd : public CWnd

{

// Construction

public:

  CShadowWnd();

// Attributes

public:

// Operations

public:

// Overrides

  // ClassWizard generated virtual function overrides

  //{{AFX_VIRTUAL(CShadowWnd)

  public:

  virtual BOOL Create(const RECT& rect, CWnd* pParentWnd);

  //}}AFX_VIRTUAL

// Implementation

public:

  CString m_sShowText;

  void ShowReadOnlyText(CString sText);

  CBrush m_bmpBrush;

  virtual ~CShadowWnd();

// Generated message map functions

protected:

  //{{AFX_MSG(CShadowWnd)

  afx_msg void OnNcPaint();

  afx_msg void OnPaint();

 

  afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

  //}}AFX_MSG

  DECLARE_MESSAGE_MAP()

};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}

// microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_SHADOWWND_H__B971A958_59CC_11D2_AC8F_0060084237F6__INCLUDED_)

//实现文件
}

// ShadowWnd.cpp : implementation file

//

#include "stdafx.h"

#include "Shadow.h"

#include "ShadowWnd.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

//定义常数

static int aPattern[]={0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55};//阴影位图数组

#define SPOPUP_SHADOWWIDTH  10 //阴影宽度

#define SPOPUP_SHADOWHEIGHT 13 //阴影高度

#define MAXWIDTH  400 //显示字符矩形的最大宽度

/////////////////////////////////////////////////////////////////////////////

// CShadowWnd

CShadowWnd::CShadowWnd()

{

  CBitmap bmp;

  bmp.CreateBitmap(8,8,1,1,(void* )aPattern);//创建一个阴影位图

  m_bmpBrush.CreatePatternBrush(&bmp); //创建一把阴影刷

}

CShadowWnd::~CShadowWnd()

{

}

BEGIN_MESSAGE_MAP(CShadowWnd, CWnd)

  //{{AFX_MSG_MAP(CShadowWnd)

  ON_WM_NCPAINT()

  ON_WM_PAINT()

  ON_WM_CREATE()

  //}}AFX_MSG_MAP

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CShadowWnd message handlers

BOOL CShadowWnd::Create(const RECT& rect, CWnd* pParentWnd)

{

  // TODO: Add your specialized code here and/or call the base class

  const char*  pClassName=AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW);

  return CWnd::CreateEx(WS_EX_STATICEDGE,pClassName, "Shadow window", WS_POPUP,

    rect.left,rect.top,rect.right,rect.bottom,

    pParentWnd->GetSafeHwnd(),0,NULL);

}
void CShadowWnd::OnNcPaint()

{

  // TODO: Add your message handler code here

  CWindowDC dc(this);

  CRect rc;

  GetWindowRect(&rc);

  rc.right-=rc.left; //width

  rc.bottom-=rc.top; //height

  rc.top=0;

  rc.left=0;

  m_bmpBrush.UnrealizeObject();

  CBrush* OldBrush=dc.SelectObject(&m_bmpBrush);

//画底部阴影

  dc.PatBlt(rc.left+SPOPUP_SHADOWWIDTH,rc.bottom-SPOPUP_SHADOWHEIGHT,

    rc.right-SPOPUP_SHADOWWIDTH,SPOPUP_SHADOWHEIGHT,PATCOPY);

//画右边阴影

  dc.PatBlt(rc.right-SPOPUP_SHADOWWIDTH,rc.top+SPOPUP_SHADOWHEIGHT,

    SPOPUP_SHADOWWIDTH,rc.bottom,PATCOPY);

  dc.SelectObject(OldBrush); //restore old brush

  CBrush* pBrush=CBrush::FromHandle(GetSysColorBrush(COLOR_WINDOWFRAME));

  rc.right-=SPOPUP_SHADOWWIDTH;

  rc.bottom-=SPOPUP_SHADOWHEIGHT;

  dc.FrameRect(rc,pBrush); //画边框

  // Do not call CWnd::OnNcPaint() for painting messages

}

void CShadowWnd::OnPaint()

{

  CPaintDC dc(this); // device context for painting

  

  // TODO: Add your message handler code here

  CRect rect;

  GetClientRect(&rect);

  rect.left+=5; rect.top+=5;

  rect.right-=SPOPUP_SHADOWWIDTH;

  rect.bottom-=SPOPUP_SHADOWHEIGHT;

  dc.SetTextColor(RGB(0,0,255));//设置显示文本颜色

  dc.DrawText(m_sShowText,rect,DT_WORDBREAK|DT_NOPREFIX);

  // Do not call CWnd::OnPaint() for painting messages

}

void CShadowWnd::ShowReadOnlyText(CString sText)

{

  m_sShowText=sText; //存入显示字符串

  CDC dc;

  dc.CreateDC("DISPLAY",NULL,NULL,NULL); //创建一个显示设备描述表

  dc.SelectObject(GetStockObject(SYSTEM_FONT)); //选择字体到设备描述表

  CRect rect(0,0,MAXWIDTH,0);

//获得待显示的字符串 sText 的实际高度和宽度

  dc.DrawText(sText,rect,DT_WORDBREAK|DT_CENTER|DT_CALCRECT|DT_NOPREFIX);

//为矩形留些余量

  rect.right+=3*SPOPUP_SHADOWWIDTH;

  rect.bottom+=3*SPOPUP_SHADOWHEIGHT;

  this->Create(rect,0);//创建窗口

  this->ShowWindow(SW_SHOW); //显示窗口

  this->UpdateWindow(); //立刻更新窗口

//进入消息循环,获取全部消息,控制整个系统

  MSG Msg;

  BOOL bDone;

  SetCapture();

  bDone=FALSE;

  while(!bDone)

  {

    if(PeekMessage(&Msg,NULL,0,0,PM_REMOVE))

      if(Msg.message==WM_KEYDOWN||Msg.message==WM_SYSKEYDOWN||

        Msg.message==WM_LBUTTONDOWN||Msg.message==WM_RBUTTONDOWN)

        bDone=TRUE;

      else

      {

        TranslateMessage(&Msg);

        DispatchMessage(&Msg);

      }

  }

  ReleaseCapture();

  DestroyWindow();

}

int CShadowWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

  if (CWnd::OnCreate(lpCreateStruct) == -1)

    return -1;

  

  // TODO: Add your specialized creation code here

  CenterWindow();

  return 0;

}

 

四.使用方法:

1.   将该类增加到一个项目文件中

2. 在你欲使用函数的类(一般为视类或框架窗口类)中增加一个成员变量(如:CshadowWnd m_ShadowWnd),当需要使用带阴影的弹出窗口显示信息时,调用成员函数(如: m_ShadowWnd.ShowText(String sText)即可,无须考虑其实现细节

本程序在Visual C++ 5.0环境下编译通过.

    此例也说明了对于WINDOWS 下的程序设计,必须掌握OOP 方法,同时也体现   出VISUAL C++ MFC类库的强大功能.


搜索是最好的老师,要善用搜索!!!

Google


发表于 @ 2008年08月07日 11:50:00|评论(loading...)|收藏

新一篇: Greatfreefonts:免费英文字体下载分享站。 | 旧一篇: ASP.NET 中整合JavaScript的技巧。

评论:没有评论。

发表评论  


当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
Csdn Blog version 3.1a
Copyright © 挨踢老人