예제 #1
0
/*
 * @implemented
 */
BOOL
APIENTRY
NtUserGetClipCursor(
    RECTL *lpRect)
{
    /* FIXME: Check if process has WINSTA_READATTRIBUTES */
    PSYSTEM_CURSORINFO CurInfo;
    RECTL Rect;
    NTSTATUS Status;
    DECLARE_RETURN(BOOL);

    TRACE("Enter NtUserGetClipCursor\n");
    UserEnterExclusive();

    if (!lpRect)
        RETURN(FALSE);

    CurInfo = IntGetSysCursorInfo();
    if (CurInfo->bClipped)
    {
        Rect = CurInfo->rcClip;
    }
    else
    {
        Rect.left = 0;
        Rect.top = 0;
        Rect.right = UserGetSystemMetrics(SM_CXSCREEN);
        Rect.bottom = UserGetSystemMetrics(SM_CYSCREEN);
    }

    Status = MmCopyToCaller(lpRect, &Rect, sizeof(RECT));
    if (!NT_SUCCESS(Status))
    {
        SetLastNtError(Status);
        RETURN(FALSE);
    }

    RETURN(TRUE);

CLEANUP:
    TRACE("Leave NtUserGetClipCursor, ret=%i\n",_ret_);
    UserLeave();
    END_CLEANUP;
}
예제 #2
0
/* Compute the scroll bar rectangle, in drawing coordinates (i.e. client coords for SB_CTL, window coords for SB_VERT and
 * SB_HORZ). 'arrowSize' returns the width or height of an arrow (depending on * the orientation of the scrollbar),
 * 'thumbSize' returns the size of the thumb, and 'thumbPos' returns the position of the thumb relative to the left or to
 * the top. Return TRUE if the scrollbar is vertical, FALSE if horizontal.
 */
BOOL FASTCALL
IntGetScrollBarRect (PWND Wnd, INT nBar, RECTL *lprect)
{
   BOOL vertical;
   RECTL ClientRect = Wnd->rcClient;
   RECTL WindowRect = Wnd->rcWindow;

   switch (nBar)
   {
      case SB_HORZ:
         lprect->left = ClientRect.left - WindowRect.left;
         lprect->top = ClientRect.bottom - WindowRect.top;
         lprect->right = ClientRect.right - WindowRect.left;
         lprect->bottom = lprect->top + UserGetSystemMetrics (SM_CYHSCROLL);
         vertical = FALSE;
         break;

      case SB_VERT:
         if(Wnd->ExStyle & WS_EX_LEFTSCROLLBAR)
         {
            lprect->right = ClientRect.left - WindowRect.left;
            lprect->left = lprect->right - UserGetSystemMetrics(SM_CXVSCROLL);
         }
         else
         {
            lprect->left = ClientRect.right - WindowRect.left;
            lprect->right = lprect->left + UserGetSystemMetrics(SM_CXVSCROLL);
         }
         lprect->top = ClientRect.top - WindowRect.top;
         lprect->bottom = ClientRect.bottom - WindowRect.top;
         vertical = TRUE;
         break;

      case SB_CTL:
         IntGetClientRect (Wnd, lprect);
         vertical = ((Wnd->style & SBS_VERT) != 0);
         break;

      default:
         return FALSE;
   }

   return vertical;
}
예제 #3
0
BOOL
APIENTRY
NtUserCreateCaret(
   HWND hWnd,
   HBITMAP hBitmap,
   int nWidth,
   int nHeight)
{
   PWND Window;
   PTHREADINFO pti;
   PUSER_MESSAGE_QUEUE ThreadQueue;
   DECLARE_RETURN(BOOL);

   TRACE("Enter NtUserCreateCaret\n");
   UserEnterExclusive();

   if(!(Window = UserGetWindowObject(hWnd)))
   {
      RETURN(FALSE);
   }

   if(Window->head.pti->pEThread != PsGetCurrentThread())
   {
      EngSetLastError(ERROR_ACCESS_DENIED);
      RETURN(FALSE);
   }

   pti = PsGetCurrentThreadWin32Thread();
   ThreadQueue = pti->MessageQueue;

   if (ThreadQueue->CaretInfo->Visible)
   {
      IntKillTimer(Window, IDCARETTIMER, TRUE);
      co_IntHideCaret(ThreadQueue->CaretInfo);
   }

   ThreadQueue->CaretInfo->hWnd = hWnd;
   if(hBitmap)
   {
      ThreadQueue->CaretInfo->Bitmap = hBitmap;
      ThreadQueue->CaretInfo->Size.cx = ThreadQueue->CaretInfo->Size.cy = 0;
   }
   else
   {
      if (nWidth == 0)
      {
          nWidth = UserGetSystemMetrics(SM_CXBORDER);
      }
      if (nHeight == 0)
      {
          nHeight = UserGetSystemMetrics(SM_CYBORDER);
      }
      ThreadQueue->CaretInfo->Bitmap = (HBITMAP)0;
      ThreadQueue->CaretInfo->Size.cx = nWidth;
      ThreadQueue->CaretInfo->Size.cy = nHeight;
   }
   ThreadQueue->CaretInfo->Visible = 0;
   ThreadQueue->CaretInfo->Showing = 0;

   IntSetTimer( Window, IDCARETTIMER, gpsi->dtCaretBlink, CaretSystemTimerProc, TMRF_SYSTEM );

   IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window, OBJID_CARET, CHILDID_SELF, 0);

   RETURN(TRUE);

CLEANUP:
   TRACE("Leave NtUserCreateCaret, ret=%i\n",_ret_);
   UserLeave();
   END_CLEANUP;
}
예제 #4
0
DWORD FASTCALL
GetNCHitEx(PWND pWnd, POINT pt)
{
   RECT rcWindow, rcClient;
   DWORD Style, ExStyle;

   if (!pWnd) return HTNOWHERE;

   if (pWnd == UserGetDesktopWindow()) // pWnd->fnid == FNID_DESKTOP)
   {
      rcClient.left = rcClient.top = rcWindow.left = rcWindow.top = 0;
      rcWindow.right  = UserGetSystemMetrics(SM_CXSCREEN);
      rcWindow.bottom = UserGetSystemMetrics(SM_CYSCREEN);
      rcClient.right  = UserGetSystemMetrics(SM_CXSCREEN);
      rcClient.bottom = UserGetSystemMetrics(SM_CYSCREEN);
   }
   else
   {
      rcClient = pWnd->rcClient;
      rcWindow = pWnd->rcWindow;
   }

   if (!RECTL_bPointInRect(&rcWindow, pt.x, pt.y)) return HTNOWHERE;

   Style = pWnd->style;
   ExStyle = pWnd->ExStyle;

   if (Style & WS_MINIMIZE) return HTCAPTION;

   if (RECTL_bPointInRect( &rcClient,  pt.x, pt.y )) return HTCLIENT;

   /* Check borders */
   if (HAS_THICKFRAME( Style, ExStyle ))
   {
      RECTL_vInflateRect(&rcWindow, -UserGetSystemMetrics(SM_CXFRAME), -UserGetSystemMetrics(SM_CYFRAME) );
      if (!RECTL_bPointInRect(&rcWindow, pt.x, pt.y ))
      {
            /* Check top sizing border */
            if (pt.y < rcWindow.top)
            {
                if (pt.x < rcWindow.left+UserGetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
                if (pt.x >= rcWindow.right-UserGetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
                return HTTOP;
            }
            /* Check bottom sizing border */
            if (pt.y >= rcWindow.bottom)
            {
                if (pt.x < rcWindow.left+UserGetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
                if (pt.x >= rcWindow.right-UserGetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
                return HTBOTTOM;
            }
            /* Check left sizing border */
            if (pt.x < rcWindow.left)
            {
                if (pt.y < rcWindow.top+UserGetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
                if (pt.y >= rcWindow.bottom-UserGetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
                return HTLEFT;
            }
            /* Check right sizing border */
            if (pt.x >= rcWindow.right)
            {
                if (pt.y < rcWindow.top+UserGetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
                if (pt.y >= rcWindow.bottom-UserGetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
                return HTRIGHT;
            }
        }
    }
    else  /* No thick frame */
    {
        if (HAS_DLGFRAME( Style, ExStyle ))
            RECTL_vInflateRect(&rcWindow, -UserGetSystemMetrics(SM_CXDLGFRAME), -UserGetSystemMetrics(SM_CYDLGFRAME));
        else if (HAS_THINFRAME( Style, ExStyle ))
            RECTL_vInflateRect(&rcWindow, -UserGetSystemMetrics(SM_CXBORDER), -UserGetSystemMetrics(SM_CYBORDER));
        if (!RECTL_bPointInRect( &rcWindow, pt.x, pt.y  )) return HTBORDER;
    }

    /* Check caption */

    if ((Style & WS_CAPTION) == WS_CAPTION)
    {
        if (ExStyle & WS_EX_TOOLWINDOW)
            rcWindow.top += UserGetSystemMetrics(SM_CYSMCAPTION) - 1;
        else
            rcWindow.top += UserGetSystemMetrics(SM_CYCAPTION) - 1;
        if (!RECTL_bPointInRect( &rcWindow, pt.x, pt.y ))
        {
            BOOL min_or_max_box = (Style & WS_SYSMENU) && (Style & (WS_MINIMIZEBOX|WS_MAXIMIZEBOX));
            if (ExStyle & WS_EX_LAYOUTRTL)
            {
                /* Check system menu */
                if ((Style & WS_SYSMENU) && !(ExStyle & WS_EX_TOOLWINDOW) && NC_IconForWindow(pWnd))
                {
                    rcWindow.right -= UserGetSystemMetrics(SM_CYCAPTION) - 1;
                    if (pt.x > rcWindow.right) return HTSYSMENU;
                }

                /* Check close button */
                if (Style & WS_SYSMENU)
                {
                    rcWindow.left += UserGetSystemMetrics(SM_CYCAPTION);
                    if (pt.x < rcWindow.left) return HTCLOSE;
                }

                /* Check maximize box */
                /* In Win95 there is automatically a Maximize button when there is a minimize one */
                if (min_or_max_box && !(ExStyle & WS_EX_TOOLWINDOW))
                {
                    rcWindow.left += UserGetSystemMetrics(SM_CXSIZE);
                    if (pt.x < rcWindow.left) return HTMAXBUTTON;
                }

                /* Check minimize box */
                if (min_or_max_box && !(ExStyle & WS_EX_TOOLWINDOW))
                {
                    rcWindow.left += UserGetSystemMetrics(SM_CXSIZE);
                    if (pt.x < rcWindow.left) return HTMINBUTTON;
                }
            }
            else
            {
                /* Check system menu */
                if ((Style & WS_SYSMENU) && !(ExStyle & WS_EX_TOOLWINDOW) && NC_IconForWindow(pWnd))
                {
                    rcWindow.left += UserGetSystemMetrics(SM_CYCAPTION) - 1;
                    if (pt.x < rcWindow.left) return HTSYSMENU;
                }

                /* Check close button */
                if (Style & WS_SYSMENU)
                {
                    rcWindow.right -= UserGetSystemMetrics(SM_CYCAPTION);
                    if (pt.x > rcWindow.right) return HTCLOSE;
                }

                /* Check maximize box */
                /* In Win95 there is automatically a Maximize button when there is a minimize one */
                if (min_or_max_box && !(ExStyle & WS_EX_TOOLWINDOW))
                {
                    rcWindow.right -= UserGetSystemMetrics(SM_CXSIZE);
                    if (pt.x > rcWindow.right) return HTMAXBUTTON;
                }

                /* Check minimize box */
                if (min_or_max_box && !(ExStyle & WS_EX_TOOLWINDOW))
                {
                    rcWindow.right -= UserGetSystemMetrics(SM_CXSIZE);
                    if (pt.x > rcWindow.right) return HTMINBUTTON;
                }
            }
            return HTCAPTION;
        }
    }

      /* Check menu bar */

    if (HAS_MENU( pWnd, Style ) && (pt.y < rcClient.top) &&
        (pt.x >= rcClient.left) && (pt.x < rcClient.right))
        return HTMENU;

      /* Check vertical scroll bar */

    if (ExStyle & WS_EX_LAYOUTRTL) ExStyle ^= WS_EX_LEFTSCROLLBAR;
    if (Style & WS_VSCROLL)
    {
        if((ExStyle & WS_EX_LEFTSCROLLBAR) != 0)
            rcClient.left -= UserGetSystemMetrics(SM_CXVSCROLL);
        else
            rcClient.right += UserGetSystemMetrics(SM_CXVSCROLL);
        if (RECTL_bPointInRect( &rcClient, pt.x, pt.y )) return HTVSCROLL;
    }

      /* Check horizontal scroll bar */

    if (Style & WS_HSCROLL)
    {
        rcClient.bottom += UserGetSystemMetrics(SM_CYHSCROLL);
        if (RECTL_bPointInRect( &rcClient, pt.x, pt.y ))
        {
            /* Check size box */
            if ((Style & WS_VSCROLL) &&
                ((((ExStyle & WS_EX_LEFTSCROLLBAR) != 0) && (pt.x <= rcClient.left + UserGetSystemMetrics(SM_CXVSCROLL))) ||
                (((ExStyle & WS_EX_LEFTSCROLLBAR) == 0) && (pt.x >= rcClient.right - UserGetSystemMetrics(SM_CXVSCROLL)))))
                return HTSIZE;
            return HTHSCROLL;
        }
    }

    /* Has to return HTNOWHERE if nothing was found
       Could happen when a window has a customized non client area */
    return HTNOWHERE;
}
예제 #5
0
/* Mostly inspired from wine code.
 * We use low level functions because:
 *  - at this point, the icon bitmap could have a different bit depth than the DC,
 *    making it thus impossible to use NtCreateCompatibleDC and selecting the bitmap.
 *    This happens after a mode setting change.
 *  - it avoids massive GDI objects locking when only the destination surface needs it.
 *  - It makes (small) performance gains.
 */
BOOL
UserDrawIconEx(
    HDC hDc,
    INT xLeft,
    INT yTop,
    PCURICON_OBJECT pIcon,
    INT cxWidth,
    INT cyHeight,
    UINT istepIfAniCur,
    HBRUSH hbrFlickerFreeDraw,
    UINT diFlags)
{
    PSURFACE psurfDest, psurfMask, psurfColor; //, psurfOffScreen = NULL;
    PDC pdc = NULL;
    BOOL Ret = FALSE;
    HBITMAP hbmMask, hbmColor, hbmAlpha;
    BOOL bOffScreen;
    RECTL rcDest, rcSrc;
    CLIPOBJ* pdcClipObj = NULL;
    EXLATEOBJ exlo;
    
    /* Stupid case */
    if((diFlags & DI_NORMAL) == 0)
    {
        ERR("DrawIconEx called without mask or color bitmap to draw.\n");
        return FALSE;
    }

    if (pIcon->CURSORF_flags & CURSORF_ACON)
    {
        ACON* pAcon = (ACON*)pIcon;
        if(istepIfAniCur >= pAcon->cicur)
        {
            ERR("NtUserDrawIconEx: istepIfAniCur too big!\n");
            return FALSE;
        }
        pIcon = pAcon->aspcur[pAcon->aicur[istepIfAniCur]];
    }

    hbmMask = pIcon->hbmMask;
    hbmColor = pIcon->hbmColor;
    hbmAlpha = pIcon->hbmAlpha;
    
    /*
     * Get our objects. 
     * Shared locks are enough, we are only reading those bitmaps
     */
    psurfMask = SURFACE_ShareLockSurface(hbmMask);
    if(psurfMask == NULL)
    {
        ERR("Unable to lock the mask surface.\n");
        return FALSE;
    }
    
    /* Color bitmap is not mandatory */
    if(hbmColor == NULL)
    {
        /* But then the mask bitmap must have the information in it's bottom half */
        ASSERT(psurfMask->SurfObj.sizlBitmap.cy == 2*pIcon->cy);
        psurfColor = NULL;
    }
    else if ((psurfColor = SURFACE_ShareLockSurface(hbmColor)) == NULL)
    {
        ERR("Unable to lock the color bitmap.\n");
        SURFACE_ShareUnlockSurface(psurfMask);
        return FALSE;
    }
    
    pdc = DC_LockDc(hDc);
    if(!pdc)
    {
        ERR("Could not lock the destination DC.\n");
        SURFACE_ShareUnlockSurface(psurfMask);
        if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
        return FALSE;
    }
    /* Calculate destination rectangle */
    RECTL_vSetRect(&rcDest, xLeft, yTop, xLeft + cxWidth, yTop + cyHeight);
    IntLPtoDP(pdc, (LPPOINT)&rcDest, 2);
    RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
    
    /* Prepare the underlying surface */
    DC_vPrepareDCsForBlit(pdc, rcDest, NULL, rcDest);

    /* We now have our destination surface and rectangle */
    psurfDest = pdc->dclevel.pSurface;
    
    if(psurfDest == NULL)
    {
        /* Empty DC */
        DC_vFinishBlit(pdc, NULL);
        DC_UnlockDc(pdc);
        SURFACE_ShareUnlockSurface(psurfMask);
        if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
        return FALSE;
    }
    
    /* Set source rect */
    RECTL_vSetRect(&rcSrc, 0, 0, pIcon->cx, pIcon->cy);

    /* Fix width parameter, if needed */
    if (!cxWidth)
    {
        if(diFlags & DI_DEFAULTSIZE)
            cxWidth = is_icon(pIcon) ? 
                UserGetSystemMetrics(SM_CXICON) : UserGetSystemMetrics(SM_CXCURSOR);
        else
            cxWidth = pIcon->cx;
    }
    
    /* Fix height parameter, if needed */
    if (!cyHeight)
    {
        if(diFlags & DI_DEFAULTSIZE)
            cyHeight = is_icon(pIcon) ? 
                UserGetSystemMetrics(SM_CYICON) : UserGetSystemMetrics(SM_CYCURSOR);
        else
            cyHeight = pIcon->cy;
    }

    /* Should we render off-screen? */
    bOffScreen = hbrFlickerFreeDraw && 
        (GDI_HANDLE_GET_TYPE(hbrFlickerFreeDraw) == GDI_OBJECT_TYPE_BRUSH);

    if (bOffScreen)
    {
        /* Yes: Allocate and paint the offscreen surface */
        EBRUSHOBJ eboFill;
        PBRUSH pbrush = BRUSH_ShareLockBrush(hbrFlickerFreeDraw);
        
        TRACE("Performing off-screen rendering.\n");
        
        if(!pbrush)
        {
            ERR("Failed to get brush object.\n");
            goto Cleanup;
        }

#if 0 //We lock the hdc surface during the whole function it makes no sense to use an offscreen surface for "flicker free" drawing
        psurfOffScreen = SURFACE_AllocSurface(STYPE_BITMAP,
            cxWidth, cyHeight, psurfDest->SurfObj.iBitmapFormat,
            0, 0, NULL);
        if(!psurfOffScreen)
        {
            ERR("Failed to allocate the off-screen surface.\n");
            BRUSH_ShareUnlockBrush(pbrush);
            goto Cleanup;
        }
        
        /* Paint the brush */
        EBRUSHOBJ_vInit(&eboFill, pbrush, psurfOffScreen, 0x00FFFFFF, 0, NULL);
        RECTL_vSetRect(&rcDest, 0, 0, cxWidth, cyHeight);
        
        Ret = IntEngBitBlt(&psurfOffScreen->SurfObj,
            NULL,
            NULL,
            NULL,
            NULL,
            &rcDest,
            NULL,
            NULL,
            &eboFill.BrushObject,
            &pbrush->ptOrigin,
            ROP4_PATCOPY);

        /* Clean up everything */
        EBRUSHOBJ_vCleanup(&eboFill);
        BRUSH_ShareUnlockBrush(pbrush);
            
        if(!Ret)
        {
            ERR("Failed to paint the off-screen surface.\n");
            goto Cleanup;
        }
        
        /* We now have our destination surface */
        psurfDest = psurfOffScreen;
#else
        pdcClipObj = pdc->rosdc.CombinedClip;
        /* Paint the brush */
        EBRUSHOBJ_vInit(&eboFill, pbrush, psurfDest, 0x00FFFFFF, 0, NULL);
        
        Ret = IntEngBitBlt(&psurfDest->SurfObj,
            NULL,
            NULL,
            pdcClipObj,
            NULL,
            &rcDest,
            NULL,
            NULL,
            &eboFill.BrushObject,
            &pbrush->ptOrigin,
            ROP4_PATCOPY);

        /* Clean up everything */
        EBRUSHOBJ_vCleanup(&eboFill);
        BRUSH_ShareUnlockBrush(pbrush);
            
        if(!Ret)
        {
            ERR("Failed to paint the off-screen surface.\n");
            goto Cleanup;
        }
#endif
    }
    else
    {
        /* We directly draw to the DC */
        TRACE("Performing on screen rendering.\n");
        pdcClipObj = pdc->rosdc.CombinedClip;
        // psurfOffScreen = NULL;
    }

    /* Now do the rendering */
	if(hbmAlpha && ((diFlags & DI_NORMAL) == DI_NORMAL))
	{
	    BLENDOBJ blendobj = { {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA } };
        PSURFACE psurf = NULL;

        psurf = SURFACE_ShareLockSurface(hbmAlpha);
        if(!psurf)
        {
            ERR("SURFACE_LockSurface failed!\n");
            goto NoAlpha;
        }
        
        /* Initialize color translation object */
        EXLATEOBJ_vInitialize(&exlo, psurf->ppal, psurfDest->ppal, 0xFFFFFFFF, 0xFFFFFFFF, 0);
        
        /* Now do it */
        Ret = IntEngAlphaBlend(&psurfDest->SurfObj,
                               &psurf->SurfObj,
                               pdcClipObj,
                               &exlo.xlo,
                               &rcDest,
                               &rcSrc,
                               &blendobj);
        
        EXLATEOBJ_vCleanup(&exlo);
        SURFACE_ShareUnlockSurface(psurf);
        if(Ret) goto done;
		ERR("NtGdiAlphaBlend failed!\n");
    }
NoAlpha:
    if (diFlags & DI_MASK)
    {
        DWORD rop4 = (diFlags & DI_IMAGE) ? ROP4_SRCAND : ROP4_SRCCOPY;
        
        EXLATEOBJ_vInitSrcMonoXlate(&exlo, psurfDest->ppal, 0x00FFFFFF, 0);
        
        Ret = IntEngStretchBlt(&psurfDest->SurfObj,
                               &psurfMask->SurfObj,
                               NULL,
                               pdcClipObj,
                               &exlo.xlo,
                               NULL,
                               &rcDest,
                               &rcSrc,
                               NULL,
                               NULL,
                               NULL,
                               rop4);
        
        EXLATEOBJ_vCleanup(&exlo);

        if(!Ret)
        {
            ERR("Failed to mask the bitmap data.\n");
            goto Cleanup;
        }
    }

    if(diFlags & DI_IMAGE)
    {
		if (psurfColor)
        {
            DWORD rop4 = (diFlags & DI_MASK) ? ROP4_SRCINVERT : ROP4_SRCCOPY ;
            
            EXLATEOBJ_vInitialize(&exlo, psurfColor->ppal, psurfDest->ppal, 0x00FFFFFF, 0x00FFFFFF, 0);
            
            Ret = IntEngStretchBlt(&psurfDest->SurfObj,
                                   &psurfColor->SurfObj,
                                   NULL,
                                   pdcClipObj,
                                   &exlo.xlo,
                                   NULL,
                                   &rcDest,
                                   &rcSrc,
                                   NULL,
                                   NULL,
                                   NULL,
                                   rop4);
        
            EXLATEOBJ_vCleanup(&exlo);

            if(!Ret)
            {
                ERR("Failed to render the icon bitmap.\n");
                goto Cleanup;
            }
        }
        else
        {
            /* Mask bitmap holds the information in its bottom half */
            DWORD rop4 = (diFlags & DI_MASK) ? ROP4_SRCINVERT : ROP4_SRCCOPY;
            RECTL_vOffsetRect(&rcSrc, 0, pIcon->cy);
            
            EXLATEOBJ_vInitSrcMonoXlate(&exlo, psurfDest->ppal, 0x00FFFFFF, 0);
        
            Ret = IntEngStretchBlt(&psurfDest->SurfObj,
                                   &psurfMask->SurfObj,
                                   NULL,
                                   pdcClipObj,
                                   &exlo.xlo,
                                   NULL,
                                   &rcDest,
                                   &rcSrc,
                                   NULL,
                                   NULL,
                                   NULL,
                                   rop4);
            
            EXLATEOBJ_vCleanup(&exlo);

            if(!Ret)
            {
                ERR("Failed to render the icon bitmap.\n");
                goto Cleanup;
            }
        }
    }

done:
#if 0
    /* We're done. Was it a double buffered draw ? */
    if(bOffScreen)
    {
        /* Yes. Draw it back to our DC */
        POINTL ptSrc = {0, 0};

        /* Calculate destination rectangle */
        RECTL_vSetRect(&rcDest, xLeft, yTop, xLeft + cxWidth, yTop + cyHeight);
        IntLPtoDP(pdc, (LPPOINT)&rcDest, 2);
        RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
        
        /* Get the clip object */
        pdcClipObj = pdc->rosdc.CombinedClip;
        
        /* We now have our destination surface and rectangle */
        psurfDest = pdc->dclevel.pSurface;
        
        /* Color translation */
        EXLATEOBJ_vInitialize(&exlo, psurfOffScreen->ppal, psurfDest->ppal, 0x00FFFFFF, 0x00FFFFFF, 0);
        
        /* Blt it! */
        Ret = IntEngBitBlt(&psurfDest->SurfObj,
                           &psurfOffScreen->SurfObj,
                           NULL,
                           pdcClipObj,
                           &exlo.xlo,
                           &rcDest,
                           &ptSrc,
                           NULL,
                           NULL,
                           NULL,
                           ROP4_SRCCOPY);
                           
        EXLATEOBJ_vCleanup(&exlo);
    }
#endif
Cleanup:
    if(pdc)
    {
        DC_vFinishBlit(pdc, NULL);
        DC_UnlockDc(pdc);
    }

#if 0
    /* Delete off screen rendering surface */
    if(psurfOffScreen)
        GDIOBJ_vDeleteObject(&psurfOffScreen->BaseObject);
#endif

    /* Unlock other surfaces */
    SURFACE_ShareUnlockSurface(psurfMask);
    if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);

    return Ret;
}
예제 #6
0
파일: scrollbar.c 프로젝트: GYGit/reactos
BOOL FASTCALL
IntCalculateThumb(PWND Wnd, LONG idObject, PSCROLLBARINFO psbi, PSBDATA pSBData)
{
   INT Thumb, ThumbBox, ThumbPos, cxy, mx;
   RECTL ClientRect;

   switch(idObject)
   {
      case SB_HORZ:
         Thumb = UserGetSystemMetrics(SM_CXHSCROLL);
         cxy = psbi->rcScrollBar.right - psbi->rcScrollBar.left;
         break;
      case SB_VERT:
         Thumb = UserGetSystemMetrics(SM_CYVSCROLL);
         cxy = psbi->rcScrollBar.bottom - psbi->rcScrollBar.top;
         break;
      case SB_CTL:
         IntGetClientRect(Wnd, &ClientRect);
         if(Wnd->style & SBS_VERT)
         {
            Thumb = UserGetSystemMetrics(SM_CYVSCROLL);
            cxy = ClientRect.bottom - ClientRect.top;
         }
         else
         {
            Thumb = UserGetSystemMetrics(SM_CXHSCROLL);
            cxy = ClientRect.right - ClientRect.left;
         }
         break;
      default:
         return FALSE;
   }

   ThumbPos = Thumb;
   /* Calculate Thumb */
   if(cxy <= (2 * Thumb))
   {
      Thumb = cxy / 2;
      psbi->xyThumbTop = 0;
      psbi->xyThumbBottom = 0;
      ThumbPos = Thumb;
   }
   else
   {
      ThumbBox = pSBData->page ? MINTRACKTHUMB : UserGetSystemMetrics(SM_CXHTHUMB);
      cxy -= (2 * Thumb);
      if(cxy >= ThumbBox)
      {
         if(pSBData->page)
         {
            ThumbBox = max(EngMulDiv(cxy, pSBData->page, pSBData->posMax - pSBData->posMin + 1), ThumbBox);
         }

         if(cxy > ThumbBox)
         {
            mx = pSBData->posMax - max(pSBData->page - 1, 0);
            if(pSBData->posMin < mx)
               ThumbPos = Thumb + EngMulDiv(cxy - ThumbBox, pSBData->pos - pSBData->posMin, mx - pSBData->posMin);
            else
               ThumbPos = Thumb + ThumbBox;
         }

         psbi->xyThumbTop = ThumbPos;
         psbi->xyThumbBottom = ThumbPos + ThumbBox;
      }
      else
      {
         psbi->xyThumbTop = 0;
         psbi->xyThumbBottom = 0;
      }
   }
   psbi->dxyLineButton = Thumb;

   return TRUE;
}
예제 #7
0
파일: scrollbar.c 프로젝트: GYGit/reactos
BOOL FASTCALL
IntGetScrollBarRect (PWND Wnd, INT nBar, RECTL *lprect)
{
   BOOL vertical;
   *lprect = Wnd->rcClient;

   RECTL_vOffsetRect( lprect, -Wnd->rcWindow.left, -Wnd->rcWindow.top );
   if (Wnd->ExStyle & WS_EX_LAYOUTRTL)
      mirror_rect( &Wnd->rcWindow, lprect );

   switch (nBar)
   {
      case SB_HORZ:
         lprect->top = lprect->bottom;
         lprect->bottom += UserGetSystemMetrics (SM_CYHSCROLL);
         if (Wnd->style & WS_BORDER)
         {
            lprect->left--;
            lprect->right++;
         }
         else if (Wnd->style & WS_VSCROLL)
         {
            lprect->right++;
         }
         vertical = FALSE;
         break;

      case SB_VERT:
         if(Wnd->ExStyle & WS_EX_LEFTSCROLLBAR)
         {
            lprect->right = lprect->left;
            lprect->left -= UserGetSystemMetrics(SM_CXVSCROLL);
         }
         else
         {
            lprect->left = lprect->right;
            lprect->right += UserGetSystemMetrics(SM_CXVSCROLL);
         }
         if (Wnd->style & WS_BORDER)
         {
            lprect->top--;
            lprect->bottom++;
         }
         else if (Wnd->style & WS_HSCROLL)
         {
            lprect->bottom++;
         }
         vertical = TRUE;
         break;

      case SB_CTL:
         IntGetClientRect (Wnd, lprect);
         vertical = !!(Wnd->style & SBS_VERT);
         break;

      default:
         return FALSE;
   }

   return vertical;
}