⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 painting.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 4 页
字号:
      _SEH_END

      if (!NT_SUCCESS(Status))
      {
         SetLastNtError(Status);
         RETURN(ERROR);
      }
   }

   RETURN(Result);

CLEANUP:
   if (hrgnOwn && !hrgnUpdate)
   {
      NtGdiDeleteObject(hrgnOwn);
   }

   if (Window)
      UserDerefObjectCo(Window);

   DPRINT("Leave NtUserScrollWindowEx, ret=%i\n",_ret_);
   UserLeave();
   END_CLEANUP;
}


BOOL
UserDrawSysMenuButton(
   PWINDOW_OBJECT pWnd, 
   HDC hDc, 
   LPRECT lpRc, 
   BOOL Down)
{
   HICON hIcon;
   PCURICON_OBJECT pIcon;
   
   ASSERT(pWnd && lpRc);
   
   /* Get the icon to draw. We don't care about WM_GETICON here. */
   
   hIcon = pWnd->Class->hIconSm;
   
   if(!hIcon)
   {
      DPRINT("Wnd class has no small icon.\n");
      hIcon = pWnd->Class->hIcon;
   }
   
   if(!hIcon)
   {
      DPRINT("Wnd class hasn't any icon.\n");
      //FIXME: Draw "winlogo" icon. 
      return FALSE;
   }
   
   if(!(pIcon = UserGetCurIconObject(hIcon)))
   {
      DPRINT1("UserGetCurIconObject() failed!\n");
      return FALSE;
   }

   return UserDrawIconEx(hDc, lpRc->left, lpRc->top, pIcon,
                        UserGetSystemMetrics(SM_CXSMICON), 
                        UserGetSystemMetrics(SM_CYSMICON),
                        0, NULL, DI_NORMAL);
}

BOOL
UserDrawCaptionText(HDC hDc,
   const PUNICODE_STRING Text,
   const LPRECT lpRc,
   UINT uFlags)
{
   HFONT hOldFont = NULL, hFont = NULL;
   COLORREF OldTextColor;
   NONCLIENTMETRICS nclm;
   NTSTATUS Status;
   #ifndef NDEBUG
   INT i;
   DPRINT("%s:", __FUNCTION__);
   for(i = 0; i < Text->Length/sizeof(WCHAR); i++)
      DbgPrint("%C", Text->Buffer[i]);
   DbgPrint(", %d\n", Text->Length/sizeof(WCHAR));
   #endif
   
   nclm.cbSize = sizeof(nclm);
   if(!IntSystemParametersInfo(SPI_GETNONCLIENTMETRICS,
      sizeof(NONCLIENTMETRICS), &nclm, 0)) 
   {
      DPRINT1("%s: IntSystemParametersInfo() failed!\n", __FUNCTION__);
      return FALSE;
   }

   NtGdiSetBkMode(hDc, TRANSPARENT);

   if(uFlags & DC_SMALLCAP)
      Status = TextIntCreateFontIndirect(&nclm.lfSmCaptionFont, &hFont);
   else Status = TextIntCreateFontIndirect(&nclm.lfCaptionFont, &hFont);

   if(!NT_SUCCESS(Status)) 
   {
      DPRINT1("%s: TextIntCreateFontIndirect() failed! Status: 0x%x\n",
         __FUNCTION__, Status);
      return FALSE;
   }

   hOldFont = NtGdiSelectObject(hDc, hFont);
   if(!hOldFont) 
   {
      DPRINT1("%s: SelectObject() failed!\n", __FUNCTION__);
      NtGdiDeleteObject(hFont);
      return FALSE;
   }

   if(uFlags & DC_INBUTTON)
      OldTextColor = NtGdiSetTextColor(hDc, IntGetSysColor(COLOR_BTNTEXT));
   else OldTextColor = NtGdiSetTextColor(hDc, IntGetSysColor(uFlags & DC_ACTIVE
         ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT));
   
   //FIXME: If string doesn't fit to rc, truncate it and add ellipsis.
   
   NtGdiExtTextOut(hDc, lpRc->left, 
      lpRc->top, 0, NULL, Text->Buffer, 
      Text->Length/sizeof(WCHAR), NULL);
   
   NtGdiSetTextColor(hDc, OldTextColor);
   NtGdiSelectObject(hDc, hOldFont);
   NtGdiDeleteObject(hFont);
   
   return TRUE;
}

BOOL UserDrawCaption(
   PWINDOW_OBJECT pWnd,
   HDC hDc,
   LPCRECT lpRc,
   HFONT hFont,
   HICON hIcon,
   const PUNICODE_STRING str,
   UINT uFlags)
{
   BOOL Ret = FALSE;
   HBITMAP hMemBmp = NULL, hOldBmp = NULL;
   HBRUSH hOldBrush = NULL;
   HDC hMemDc = NULL;
   ULONG Height;
   UINT VCenter = 0, Padding = 0;
   RECT r = *lpRc;
   LONG ButtonWidth, IconWidth;
   BOOL HasIcon;
   
   //ASSERT(pWnd != NULL);

   hMemBmp = NtGdiCreateCompatibleBitmap(hDc, 
      lpRc->right - lpRc->left, 
      lpRc->bottom - lpRc->top);

   if(!hMemBmp)
   {
      DPRINT1("%s: NtGdiCreateCompatibleBitmap() failed!\n", __FUNCTION__);
      return FALSE;
   }

   hMemDc = NtGdiCreateCompatibleDC(hDc);
   if(!hMemDc)
   {
      DPRINT1("%s: NtGdiCreateCompatibleDC() failed!\n", __FUNCTION__);
      goto cleanup;
   }

   hOldBmp = NtGdiSelectObject(hMemDc, hMemBmp);
   if(!hOldBmp)
   {
      DPRINT1("%s: NtGdiSelectObject() failed!\n", __FUNCTION__);
      goto cleanup;
   }

   Height = UserGetSystemMetrics(SM_CYCAPTION) - 1;
   VCenter = (lpRc->bottom - lpRc->top) / 2;
   Padding = VCenter - (Height / 2);

   if ((!hIcon) && (pWnd != NULL))
   {
     HasIcon = (uFlags & DC_ICON) && (pWnd->Style & WS_SYSMENU) 
        && !(uFlags & DC_SMALLCAP) && !(pWnd->ExStyle & WS_EX_DLGMODALFRAME) 
        && !(pWnd->ExStyle & WS_EX_TOOLWINDOW);
   }
   else 
     HasIcon = (BOOL) hIcon;

   IconWidth = UserGetSystemMetrics(SM_CXSIZE) + Padding;

   r.left = Padding;
   r.right = r.left + (lpRc->right - lpRc->left);
   r.top = Padding;
   r.bottom = r.top + (Height / 2);

   // Draw the caption background
   if(uFlags & DC_INBUTTON)
   {
      hOldBrush = NtGdiSelectObject(hMemDc, 
         IntGetSysColorBrush(uFlags & DC_ACTIVE ?
            COLOR_BTNFACE : COLOR_BTNSHADOW));

      if(!hOldBrush)
      {
         DPRINT1("%s: NtGdiSelectObject() failed!\n", __FUNCTION__);
         goto cleanup;
      }

      if(!NtGdiPatBlt(hMemDc, 0, 0,
         lpRc->right - lpRc->left,
         lpRc->bottom - lpRc->top,
         PATCOPY)) 
      {
         DPRINT1("%s: NtGdiPatBlt() failed!\n", __FUNCTION__);
         goto cleanup;
      }
      
      if(HasIcon) r.left+=IconWidth;
   }
   else 
   {
      r.right = (lpRc->right - lpRc->left);
      if(uFlags & DC_SMALLCAP)
         ButtonWidth = UserGetSystemMetrics(SM_CXSMSIZE) - 2;
      else ButtonWidth = UserGetSystemMetrics(SM_CXSIZE) - 2;
        
      hOldBrush = NtGdiSelectObject(hMemDc, 
         IntGetSysColorBrush(uFlags & DC_ACTIVE ? 
            COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
   
      if(!hOldBrush)
      {
         DPRINT1("%s: NtGdiSelectObject() failed!\n", __FUNCTION__);
         goto cleanup;
      }

      if(HasIcon && (uFlags & DC_GRADIENT))
      {
         NtGdiPatBlt(hMemDc, 0, 0, 
            IconWidth+1, 
            lpRc->bottom - lpRc->top, 
            PATCOPY);
         r.left+=IconWidth;
      }
      else 
      {
         NtGdiPatBlt(hMemDc, 0, 0, 
            lpRc->right - lpRc->left, 
            lpRc->bottom - lpRc->top, 
            PATCOPY);
      }
         
      if(uFlags & DC_GRADIENT)
      {
         static GRADIENT_RECT gcap = {0, 1};
         TRIVERTEX vert[2];
         COLORREF Colors[2];
         PDC pMemDc;

		 if (pWnd != NULL)
		 {
			 if(pWnd->Style & WS_SYSMENU)
			 {
				r.right -= 3 + ButtonWidth;
				if(!(uFlags & DC_SMALLCAP))
				{
				   if(pWnd->Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX))
					  r.right -= 2 + 2 * ButtonWidth;
				   else r.right -= 2;
				   r.right -= 2;
				}
	            
				//Draw buttons background
				if(!NtGdiSelectObject(hMemDc, 
				   IntGetSysColorBrush(uFlags & DC_ACTIVE ? 
					  COLOR_GRADIENTACTIVECAPTION:COLOR_GRADIENTINACTIVECAPTION)))
				{
				   DPRINT1("%s: NtGdiSelectObject() failed!\n", __FUNCTION__);
				   goto cleanup;
				}

				NtGdiPatBlt(hMemDc, 
				   r.right, 
				   0, 
				   lpRc->right - lpRc->left - r.right, 
				   lpRc->bottom - lpRc->top, 
				   PATCOPY);
			 }
		 }

         Colors[0] = IntGetSysColor((uFlags & DC_ACTIVE) ? 
            COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION);

         Colors[1] = IntGetSysColor((uFlags & DC_ACTIVE) ? 
            COLOR_GRADIENTACTIVECAPTION : COLOR_GRADIENTINACTIVECAPTION);

         vert[0].x = r.left;
         vert[0].y = 0;
         vert[0].Red = (WORD)Colors[0]<<8;
         vert[0].Green = (WORD)Colors[0] & 0xFF00;
         vert[0].Blue = (WORD)(Colors[0]>>8) & 0xFF00;
         vert[0].Alpha = 0;

         vert[1].x = r.right;
         vert[1].y = lpRc->bottom - lpRc->top;
         vert[1].Red = (WORD)Colors[1]<<8;
         vert[1].Green = (WORD)Colors[1] & 0xFF00;
         vert[1].Blue = (WORD)(Colors[1]>>8) & 0xFF00;
         vert[1].Alpha = 0;
            
         pMemDc = DC_LockDc(hMemDc);
         if(!pMemDc)
         {
            DPRINT1("%s: Can't lock dc!\n", __FUNCTION__);
            goto cleanup;
         }

         if(!IntGdiGradientFill(pMemDc, vert, 2, &gcap, 
            1, GRADIENT_FILL_RECT_H))
         {
            DPRINT1("%s: IntGdiGradientFill() failed!\n", __FUNCTION__);
         }

         DC_UnlockDc(pMemDc);
      } //if(uFlags & DC_GRADIENT)
   }
   
   if(HasIcon)
   {
      r.top ++;
      r.left -= --IconWidth;
	  /* FIXME: Draw the Icon when pWnd == NULL but  hIcon is valid */
	  if (pWnd != NULL)
		UserDrawSysMenuButton(pWnd, hMemDc, &r, FALSE);
      r.left += IconWidth;
      r.top --;
   }

   r.top ++;
   r.left += 2;

   r.bottom = r.top + Height;

   if((uFlags & DC_TEXT))
   {
      if(!(uFlags & DC_GRADIENT))
      {
         r.right = (lpRc->right - lpRc->left);

         if(uFlags & DC_SMALLCAP) 
            ButtonWidth = UserGetSystemMetrics(SM_CXSMSIZE) - 2;
         else ButtonWidth = UserGetSystemMetrics(SM_CXSIZE) - 2;

         if(pWnd->Style & WS_SYSMENU)
         {
            r.right -= 3 + ButtonWidth;
            if(! (uFlags & DC_SMALLCAP))
            {
               if(pWnd->Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX))
                  r.right -= 2 + 2 * ButtonWidth;
               else r.right -= 2;
               r.right -= 2;
            }
         }
      }

	  /* FIXME: hFont isn't handled */
      if (str)
         UserDrawCaptionText(hMemDc, str, &r, uFlags);
	  else if (pWnd != NULL)
	     UserDrawCaptionText(hMemDc, &pWnd->WindowName, &r, uFlags);
   } 

   if(!NtGdiBitBlt(hDc, lpRc->left, lpRc->top, 
      lpRc->right - lpRc->left, lpRc->bottom - lpRc->top,
      hMemDc, 0, 0, SRCCOPY, 0, 0)) 
   {
      DPRINT1("%s: NtGdiBitBlt() failed!\n", __FUNCTION__);
      goto cleanup;
   }

   Ret = TRUE;

cleanup:
   if (hOldBrush) NtGdiSelectObject(hMemDc, hOldBrush);
   if (hOldBmp) NtGdiSelectObject(hMemDc, hOldBmp);
   if (hMemBmp) NtGdiDeleteObject(hMemBmp);
   if (hMemDc) NtGdiDeleteObjectApp(hMemDc);

   return Ret;
}


BOOL
STDCALL
NtUserDrawCaptionTemp(
   HWND hWnd,
   HDC hDC,
   LPCRECT lpRc,
   HFONT hFont,
   HICON hIcon,
   const PUNICODE_STRING str,
   UINT uFlags)
{
   PWINDOW_OBJECT pWnd = NULL;
   RECT SafeRect;
   UNICODE_STRING SafeStr = {0};
   BOOL Ret = FALSE;
   
   UserEnterExclusive();
   
   if (hWnd != NULL)
   {
     if(!(pWnd = UserGetWindowObject(hWnd)))
     {
        UserLeave();
        return FALSE;
     }
   }

   _SEH_TRY
   {
      ProbeForRead(lpRc, sizeof(RECT), sizeof(ULONG));
      RtlCopyMemory(&SafeRect, lpRc, sizeof(RECT));
      if (str != NULL)
	  {
        SafeStr = ProbeForReadUnicodeString(str);
	    if (SafeStr.Length != 0)
        {
          ProbeForRead(SafeStr.Buffer,
               SafeStr.Length,
               sizeof(WCHAR));
        }
		Ret = UserDrawCaption(pWnd, hDC, &SafeRect, hFont, hIcon, &SafeStr, uFlags);
      }
	  else
	    Ret = UserDrawCaption(pWnd, hDC, &SafeRect, hFont, hIcon, NULL, uFlags);
   }
   _SEH_HANDLE
   {
      SetLastNtError(_SEH_GetExceptionCode());
   }
   _SEH_END;
   
   UserLeave();
   return Ret;
}

BOOL 
STDCALL 
NtUserDrawCaption(HWND hWnd,
   HDC hDC,
   LPCRECT lpRc,
   UINT uFlags)
{
	return NtUserDrawCaptionTemp(hWnd, hDC, lpRc, 0, 0, NULL, uFlags);
}

BOOL
NTAPI
NtUserInvalidateRect(
    HWND hWnd,
    CONST RECT *lpUnsafeRect,
    BOOL bErase)
{
    return NtUserRedrawWindow(hWnd, lpUnsafeRect, NULL, RDW_INVALIDATE | (bErase? RDW_ERASE : 0));
}

BOOL
NTAPI
NtUserInvalidateRgn(
    HWND hWnd,
    HRGN hRgn,
    BOOL bErase)
{
    return NtUserRedrawWindow(hWnd, NULL, hRgn, RDW_INVALIDATE | (bErase? RDW_ERASE : 0));
}

/* EOF */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -