co_UserRedrawWindow函数是用来实现窗口重画的功能,实现代码如下:
#001 BOOL FASTCALL
#002 co_UserRedrawWindow(PWINDOW_OBJECT Window, const RECT* UpdateRect, HRGN UpdateRgn,
#003 ULONG Flags)
#004 {
#005 HRGN hRgn = NULL;
#006
#007 /*
#008 * Step 1.
#009 * Validation of passed parameters.
#010 */
#011
检验是否合适的参数。
#012 if (!IntIsWindowDrawable(Window) ||
#013 (Flags & (RDW_VALIDATE | RDW_INVALIDATE)) ==
#014 (RDW_VALIDATE | RDW_INVALIDATE))
#015 {
#016 return FALSE;
#017 }
#018
#019 /*
#020 * Step 2.
#021 * Transform the parameters UpdateRgn and UpdateRect into
#022 * a region hRgn specified in screen coordinates.
#023 */
#024
创建更新的区域。
#025 if (Flags & (RDW_INVALIDATE | RDW_VALIDATE))
#026 {
根据用户指定的区域进行更新。
#027 if (UpdateRgn != NULL)
#028 {
#029 hRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
#030 if (NtGdiCombineRgn(hRgn, UpdateRgn, NULL, RGN_COPY) == NULLREGION)
#031 {
#032 NtGdiDeleteObject(hRgn);
#033 hRgn = NULL;
#034 }
否则更新整个窗口。
#035 else
#036 NtGdiOffsetRgn(hRgn, Window->Wnd->ClientRect.left, Window->Wnd->ClientRect.top);
#037 }
#038 else if (UpdateRect != NULL)
#039 {
#040 if (!IntGdiIsEmptyRect(UpdateRect))
#041 {
#042 hRgn = UnsafeIntCreateRectRgnIndirect((RECT *)UpdateRect);
#043 NtGdiOffsetRgn(hRgn, Window->Wnd->ClientRect.left, Window->Wnd->ClientRect.top);
#044 }
#045 }
#046 else if ((Flags & (RDW_INVALIDATE | RDW_FRAME)) == (RDW_INVALIDATE | RDW_FRAME) ||
#047 (Flags & (RDW_VALIDATE | RDW_NOFRAME)) == (RDW_VALIDATE | RDW_NOFRAME))
#048 {
#049 if (!IntGdiIsEmptyRect(&Window->Wnd->WindowRect))
#050 hRgn = UnsafeIntCreateRectRgnIndirect(&Window->Wnd->WindowRect);
#051 }
#052 else
#053 {
创建客户区窗口区域更新。
#054 if (!IntGdiIsEmptyRect(&Window->Wnd->ClientRect))
#055 hRgn = UnsafeIntCreateRectRgnIndirect(&Window->Wnd->ClientRect);
#056 }
#057 }
#058
#059 /*
#060 * Step 3.
#061 * Adjust the window update region depending on hRgn and flags.
#062 */
#063
根据指定的区域进行更新。
#064 if (Flags & (RDW_INVALIDATE | RDW_VALIDATE | RDW_INTERNALPAINT | RDW_NOINTERNALPAINT) &&
#065 hRgn != NULL)
#066 {
#067 IntInvalidateWindows(Window, hRgn, Flags);
#068 }
#069
#070 /*
#071 * Step 4.
#072 * Repaint and erase windows if needed.
#073 */
#074
重新画窗口。
#075 if (Flags & (RDW_ERASENOW | RDW_UPDATENOW))
#076 {
#077 co_IntPaintWindows(Window, Flags, FALSE);
#078 }
#079
#080 /*
#081 * Step 5.
#082 * Cleanup ;-)
#083 */
#084
#085 if (hRgn != NULL)
#086 {
#087 NtGdiDeleteObject(hRgn);
#088 }
#089
#090 return TRUE;
#091 }