问题描写叙述:
就是首先用CDC来截图,保存图片的路径通过dlg窗体来手动设置并传入。但是截下来的图片就会连带那个对话框也截图下来。
见图片;
部分代码:
解决方式:
涉及到的函数有:
BOOL UpdateWindow(HWND hWnd // 窗体的句柄);
假设窗体更新的区域不为空,UpdateWindow函数通过发送一个WM_PAINT消息来更新指定窗体的客户区。
函数绕过应用程序的消息队列。直接发送WM_PAINT消息给指定窗体的窗体过程,假设更新区域为空,则不发送消息。
void Invalidate( BOOL bErase = TRUE );
參数: bErase 决定了是否要在WM_PAINT消息前发送WN_ERASEBKGND
该函数的作用是使整个窗体客户区无效。窗体的客户区无效意味着须要重绘。比如。假设一个被其他窗体遮住的窗体变成了前台窗体,那么原来被遮住的部分就是无效的,须要重绘。这时Windows会在应用程序的消息队列中放置WM_PAINT消息。
MFC为窗体类提供了WM_PAINT的消息处理函数OnPaint,OnPaint负责重绘窗体。
视图类有一些例外,在视图类的OnPaint函数中调用了OnDraw函数。实际的重绘工作由OnDraw来完毕。參数bErase为TRUE时。重绘区域内的背景将被擦除,否则,背景将保持不变。
差别:
UpdateWindow( )的作用是使窗体马上重绘。
调用Invalidate等函数后窗体不会马上重绘。这是由于WM_PAINT消息的优先级非常低,它须要等消息队列中的其他消息发送完后才干被处理。调用UpdateWindow函数可使WM_PAINT被直接发送到目标窗体,从而导致窗体马上重绘。
联系:
系统会在多个不同的时机发送WM_PAINT消息:当第一次创建一个窗体时。当改变窗体的大小时。当把窗体从还有一个窗体背后移出时,当最大化或最小化窗体时,等等,这些动作都是由系统管理的,应用仅仅是被动地接收该消息。在消息处理函数中进行绘制操作;大多数的时候应用也须要可以主动引发窗体中的绘制操作,比方当窗体显示的数据改变的时候。这通常是通过InvalidateRect和 InvalidateRgn函数来完毕的。
InvalidateRect和InvalidateRgn把指定的区域加到窗体的Update Region中,当应用的消息队列没有其他消息时,假设窗体的Update Region不为空时,系统就会自己主动产生WM_PAINT消息。
系统为什么不在调用Invalidate时发送WM_PAINT消息呢?又为什么非要等应用消息队列为空时才发送WM_PAINT消息呢?这是由于系统把在窗体中的绘制操作当作一种低优先级的操作,于是尽可能地推后做,这样有利于提高绘制的效率:在两个WM_PAINT消息之间多个Invalidate调用使之失效的区域就会被累加起来,然后在一个WM_PAINT消息中一次得到更新。不仅能避免多次反复地更新同一区域,也优化了应用的更新操作。像这样的通过InvalidateRect和InvalidateRgn来使窗体区域无效,依赖于系统在合适的时机发送WM_PAINT消息的机
制实际上是一种异步工作方式,也就是说,在无效化窗体区域和发送WM_PAINT消息之间是有延迟的;有时候这样的延迟并非我们希望的。这时我们当然可以在无效化窗体区域后利用SendMessage 发送一条WM_PAINT消息来强制马上重画,但不如使用Windows GDI为我们提供的更方便和强大的函数:UpdateWindow和RedrawWindow。UpdateWindow会检查窗体的Update Region。当其不为空时才发送WM_PAINT消息;RedrawWindow则给我们很多其他的控制:是否重画非客户区和背景。是否总是发送WM_PAINT消息而无论Update
Region是否为空等