user-0 提问: ValidateRect窗口句柄为NULL时的功能是什么

回复:
user: user-1
content: 猜测应该没什么用，应该是兼容以前的系统如Win3.1。下面是Windows源码中的内容，可以参考一下 另外，如果有兴趣，你可以下载ReactOS源码，找一下ValidateRect源代码看看 /***************************************************************************\ * xxxValidateRect (API) * * * History: * 16-Jul-1991 DarrinM   Ported from Win 3.1 sources. \***************************************************************************/  BOOL xxxValidateRect(     PWND   pwnd,     LPRECT lprcValid) {     CheckLock(pwnd);      /*      * BACKWARD COMPATIBILITY HACK      *      * In Windows 3.0 and less, ValidateRect/InvalidateRect() call with      * hwnd == NULL always INVALIDATED and ERASED the entire desktop, and      * synchronously sent WM_ERASEBKGND and WM_NCPAINT messages before      * returning.  The Rgn() calls did not have this behavior.      */     if (pwnd == NULL) {         return xxxRedrawWindow(                 pwnd,                 NULL,                 NULL,                 RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE | RDW_ERASENOW);     } else {         return xxxRedrawWindow(pwnd, lprcValid, NULL, RDW_VALIDATE);     } }  /***************************************************************************\ * xxxRedrawWindow (API) * * Forward to xxxInvalidateWindow if the window is visible. * * BACKWARD COMPATIBILITY HACK * * In Windows 3.0 and less, ValidateRect/InvalidateRect() call with pwnd == NULL * always INVALIDATED and ERASED all windows, and synchronously sent * WM_ERASEBKGND and WM_NCPAINT messages before returning.  The Rgn() calls * did not have this behavior. This case is handled in * InvalidateRect/ValidateRect. * * History: * 16-Jul-1991 DarrinM   Ported from Win 3.1 sources. \***************************************************************************/  BOOL xxxRedrawWindow(     PWND   pwnd,     LPRECT lprcUpdate,     HRGN   hrgnUpdate,     DWORD  flags) {     CheckLock(pwnd);      /*      * Always map NULL to the desktop.      */     if (pwnd == NULL) {         pwnd = PtiCurrent()->rpdesk->pDeskInfo->spwnd;     }      UserAssert(pwnd != NULL);      if (IsVisible(pwnd)) {          TL   tlpwnd;         HRGN hrgn = hrgnUpdate;          if (flags & (RDW_VALIDATE | RDW_INVALIDATE)) {              /*              * Create a (in)validate region in client window coordinates.              */             if (hrgn == NULL) {                 if (!lprcUpdate) {                     hrgn = HRGN_FULL;                 } else {                     hrgn = ghrgnInv0;  #ifdef USE_MIRRORING                     if (TestWF(pwnd, WEFLAYOUTRTL)) {                         MirrorRect(pwnd, lprcUpdate);                     } #endif                      if (pwnd == PWNDDESKTOP(pwnd)) {                         SetRectRgnIndirect(hrgn, lprcUpdate);                     } else {                         GreSetRectRgn(                                 hrgn,                                 lprcUpdate->left + pwnd->rcClient.left,                                 lprcUpdate->top + pwnd->rcClient.top,                                 lprcUpdate->right + pwnd->rcClient.left,                                 lprcUpdate->bottom + pwnd->rcClient.top);                     }                 }             } else {                 /*                  * If necessary, make a copy of the passed-in region, because                  * we'll be trashing it...                  */                 if (hrgn != HRGN_FULL) {                     CopyRgn(ghrgnInv0, hrgn);  #ifdef USE_MIRRORING                     MirrorRegion(pwnd, ghrgnInv0, TRUE); #endif                      hrgn = ghrgnInv0;                 }                  if (pwnd != PWNDDESKTOP(pwnd)) {                     GreOffsetRgn(hrgn, pwnd->rcClient.left, pwnd->rcClient.top);                 }             }         }          ThreadLock(pwnd, &tlpwnd);         xxxInternalInvalidate(pwnd, hrgn, flags | RDW_REDRAWWINDOW);         ThreadUnlock(&tlpwnd);     }      return TRUE; }  BOOL NtUserValidateRect(  // API ValidateRect     IN HWND hwnd,     IN CONST RECT *lpRect OPTIONAL) {     PWND pwnd;     TL tlpwnd;     RECT rc;      BEGINRECV(BOOL, FALSE);      /*      * Probe arguments      */     if (ARGUMENT_PRESENT(lpRect)) {         try {             rc = ProbeAndReadRect(lpRect);             lpRect = &rc;         } except (StubExceptionHandler(TRUE)) {             MSGERROR(0);         }     }      ValidateHWNDOPT(pwnd, hwnd);      ThreadLock(pwnd, &tlpwnd);      retval = xxxValidateRect(pwnd, (PRECT)lpRect);      ThreadUnlock(&tlpwnd);      TRACE("NtUserValidateRect");     ENDRECV(); }

user: user-2
content: 引用 2 楼 六道佩恩 的回复:[quote=引用 1 楼 user-2 的回复:] 你问问题的角度很刁钻啊，官方文档只是说了，每个参数单独是NULL的意义，并没有指出，两个同时都是NULL时的意义，也有可能是无意义的 .....第二个NULL表示整个客户区啊，，，哪里有问题[/quote] 个人觉得，你怎么每天都在研究界面什么的，我觉得这种够用就行了，你想写出特别的功能，就得从底层重写控件，有这功夫研究底层的东西比较有用

user: user-0
content: 引用 1 楼 user-2 的回复:你问问题的角度很刁钻啊，官方文档只是说了，每个参数单独是NULL的意义，并没有指出，两个同时都是NULL时的意义，也有可能是无意义的 .....第二个NULL表示整个客户区啊，，，哪里有问题

user: user-2
content: 你问问题的角度很刁钻啊，官方文档只是说了，每个参数单独是NULL的意义，并没有指出，两个同时都是NULL时的意义，也有可能是无意义的