Visual C++窗体设计技巧集

本文介绍了如何使用Visual C++实现窗体的各种高级设计,包括制作透明窗体、设置动画显示的框架窗口图标、防止窗口闪烁的方法、全屏显示功能以及在任务栏上显示和隐藏应用程序图标。通过示例代码详细讲解了如何实现这些功能,适合对VC++窗体设计感兴趣的开发者参考。
摘要由CSDN通过智能技术生成
 

  [前言:]有好的界面软件就成功了一半,本文将向您介绍怎样设计一些有“稀奇古怪”形状的窗体,如何设定窗体的颜色、如何设置任务栏和状态栏以及菜单图标等等,通过这些技巧能更深入的理解VC的文档-视图结构。

  如何制作透明窗体
  使用SetLayeredWindowAttributes可以方便的制作透明窗体,此函数在w2k以上才支持,而且如果希望

直接使用的话,可能需要下载最新的SDK。不过此函数在w2k的user32.dll里有实现,所以如果你不希望下载巨大的sdk的话,可以直接使用GetProcAddress获取该函数的指针。


  SetLayeredWindowAttributes的函数原型如下:

BOOL SetLayeredWindowAttributes(
HWND hwnd, // handle to the layered window
COLORREF crKey, // specifies the color key
BYTE bAlpha, // value for the blend function
DWORD dwFlags // action
);


Windows NT/2000/XP: Included in Windows 2000 and later.
Windows 95/98/Me: Unsupported.(注意了,在win9x里没法使用的)
Header: Declared in Winuser.h; include Windows.h.
Library: Use User32.lib.

  一些常量:


WS_EX_LAYERED = 0x80000;
LWA_ALPHA = 0x2;
LWA_COLORKEY=0x1;

  其中dwFlags有LWA_ALPHA和LWA_COLORKEY

  LWA_ALPHA被设置的话,通过bAlpha决定透明度.

  LWA_COLORKEY被设置的话,则指定被透明掉的颜色为crKey,其他颜色则正常显示.

  要使使窗体拥有透明效果,首先要有WS_EX_LAYERED扩展属性(旧的sdk没有定义这个属性,所以可以直接指定为0x80000).

  例子代码:

  在OnInitDialog()加入:

//加入WS_EX_LAYERED扩展属性
SetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE,
GetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE)^0x80000);
HINSTANCE hInst = LoadLibrary("User32.DLL");
if(hInst)
{
 typedef BOOL (WINAPI *MYFUNC)(HWND,COLORREF,BYTE,DWORD);
 MYFUNC fun = NULL;
 //取得SetLayeredWindowAttributes函数指针
 fun=(MYFUNC)GetProcAddress(hInst, "SetLayeredWindowAttributes");
 if(fun)fun(this->GetSafeHwnd(),0,128,2);
 FreeLibrary(hInst);
}

  稍加修改还可以作出淡出淡入的效果. 注意第三个参数(128)不要取得太小了,为0的话就完全透明,看不到了。

  如何使框架窗口的图标为动画显示

  可以用TIMER,但是TIMER不能有效的定时。因为TIMER发送的是窗口消息,当窗口忙于处理键盘、鼠标等消息时就不能及时处理TIMER,会使间隔时间变得很长 。

  可以考虑用一个单独得TIMER线程,用Sleep()定时来解决此问题。


UINT Timer(LPVOID param)
{
 HWND hWnd=(HWND)param;
 while(1)
 {
  Sleep(ms);
  PostMessage(hWnd,CH_PICTURE,NULL,NULL)
 }
}

  Sleep(ms)后发送自定义消息。消息处理函数就选择某一个ICON或BITMAP来显示。如 :


MyBotton.SetBitmap((HBITMAP)Bitmap[i]);

  Bitmap是一个位图数组,存放有j个位图。消息处理函数运行一次,i就累加一次,当i==j时,i就回到0;

  防止窗口闪烁的方法

  1、将Invalidate()替换为InvalidateRect()。

  Invalidate()会导致整个窗口的图象重画,需要的时间比较长,而InvalidateRect()仅仅重画Rect区域内的内容,所以所需时间会少一些。虫虫以前很懒,经常为一小块区域的重画就调用Invalidate(),不愿意自己去计算需要重画的Rect,但是事实是,如果你确实需要改善闪烁的情况,计算一个Rect所用的时间比起重画那些不需要重画的内容所需要的时间要少得多。

  2、禁止系统搽除你的窗口。

  系统在需要重画窗口的时候会帮你用指定的背景色来搽除窗口。可是,也许需要重画的区域也许非常小。或者,在你重画这些东西之间还要经过大量的计算才能开始。这个时候你可以禁止系统搽掉原来的图象。直到你已经计算好了所有的数据,自己把那些需要搽掉的部分用背景色覆盖掉(如:dc.FillRect(rect,&brush);rect是需要搽除的区域,brush是带背景色的刷子),再画上新的图形。要禁止系统搽除你的窗口,可以重载OnEraseBkgnd()函数,让其直接返回TRUE就可以了。如

BOOL CMyWin::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
//return CWnd::OnEraseBkgnd(pDC);//把系统原来的这条语句注释掉。
}

  3、有效的进行搽除。

  搽除背景的时候,不要该搽不该搽的地方都搽。比如,你在一个窗口上放了一个很大的Edit框,几乎占了整个窗口,那么你频繁的搽除整个窗口背景将导致Edit不停重画形成剧烈的闪烁。事实上你可以CRgn创建一个需要搽除的区域,只搽除这一部分。如

GetClientRect(rectClient);
rgn1.CreateRectRgnIndirect(rectClient);
rgn2.CreateRectRgnIndirect(m_rectEdit);
if(rgn1.CombineRgn(&rgn1,&rgn2,RGN_XOR) == ERROR)//处理后的rgn1只包括了Edit框之外的客户区域,这样,Edit将不会被我的背景覆盖而导致重画。
{
ASSERT(FALSE);
return ;
}
brush.CreateSolidBrush(m_clrBackgnd);
pDC->FillRgn(&rgn1,&brush);
brush.DeleteObject();

  注意:在使用这个方法的时候要同时使用方法二。别忘了,到时候又说虫虫的办法不灵。

  4、使用MemoryDC先在内存里把图画好,再复制到屏幕上。

  这对于一次画图过程很长的情况比较管用。毕竟内存操作比较快,而且复制到屏幕又是一次性的,至少不会出现可以明显看出一个东东从左画到右的情况。

void CMyWin::OnPaint()
{
CPaintDC dc1(this); // device context for painting
dcMemory.CreateCompatibleDC(&dc1);
CBitmap bmp;//这里的Bitmap是必须的,否则当心弄出一个大黑块哦。
bmp.CreateCompatibleBitmap(&dc1,rectClient.Width(),rectClient.Height());
dcMemory.SelectObject(&bmp);

//接下来你想怎么画就怎么画吧。
//dcMemory.FillRect(rectClient,&brush);

dc1.BitBlt(0,0,rectClient.Width(),rectClient.Height(),&dcMemory,0,0,SRCCOPY);
dcMemory.DeleteDC();
// Do not call CWnd::OnPaint() for painting messages
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1,cstatic_filespec.zip静态文本中用省略号显示长文件名(3KB)2,cstatic_filespec_demo.zip静态文本中用省略号显示长文件名的演示程序(14KB)3,newlabel_app.zipCNewLabel--高级的CStatic派生(39KB)4,jumpytext_demo.zip跳动的文本类演示程序(138KB)<END)5,jumpytext_src.zip跳动的文本类(5KB)<END)6,alexf_histogram_src.zip由CStatic派生的柱状图控制(3KB)7,alexf_histogram.zip由CStatic派生的柱状图控制演示程序(20KB)8,history_edit.zip滚动显示历史信息的编辑控制 (2KB)9,history_edit_demo.zip滚动显示历史信息的编辑控制演示程序 (14KB)10,bcmenu23.zip用工具条的位图资源制作自绘菜单(59KB)11,owner_drawn_menu4.zip自动使用工具条的位图资源制作自绘菜单(109KB)12,contentmenu.zip一个非常COOL的导航菜单(3KB)13,contentmenu_demo.zip一个非常COOL的导航菜单演示程序(37KB)14,freemenu.zip随意设定颜色和字体的自绘菜单(35KB)15,menutip.zip实现菜单的工具提示演示程序(33KB)16,dockmenubar_src.zipDevStudio样式的泊位菜单条(不用MSIE)(27KB)17,dockmenubar_demo.zipDevStudio样式的泊位菜单条演示程序(不用MSIE)(58KB)18,label_edit.zip可编辑的标号控制(5KB)19,flat_scrollbar.zip扁平滚动条控制(11KB)20,avidemo.zip动画控制的例子(145KB)21,balloontooltip_src.zip像气球一样的工具提示(7KB)22,balloontooltip_demo.zip像气球一样的工具提示演示程序(49KB)23,check_frame.zip一个有用的CheckFrame控制(31KB)24,extended_tooltip.zip扩展的ToolTipCtrl类(21KB)25,progress_in_status2_src.zip在状态栏里显示进度条(4KB)26,progress_in_status2_demo.zip在状态栏里显示进度条演示程序(39KB)27,vcmenu.zipVisual Studio/Office 97 式样的扁平工具条和可泊位菜单条(350KB)28,flatbar_source.zip另一个扁平工具条(不需要MSIE)(11KB)29,flatbar_sample_project.zip另一个扁平工具条(不需要MSIE)工程程序(185KB)30,enh_flatbar_source.zip另一个扁平工具条(不需要MSIE)增强版(25KB)31,enh_flatbar_sample.zip另一个扁平工具条(不需要MSIE)演示增强版(56KB)32,customizable_tb.zip可定制的工具条(25KB)33,treemenudemo.zip一个类似IE4的收藏夹/历史/频道视图的控制(72KB)34,cdirtreectrl_demo.zipDirTreeCtrl--显示文件夹和文件演示程序(56KB)35,cdirtreectrl_src.zipDirTreeCtrl--显示文件夹和文件(6KB)36,a
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值