dcsimg
Results 1 to 9 of 9

Thread: [RESOLVED] MaskBlt ROP?

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,206

    Resolved [RESOLVED] MaskBlt ROP?

    Other discussions related to this topic got me to take a stab at playing with GDI MaskBlt calls. As I always say, I'm not a gaming and graphics guy so perhaps this is in the wrong forum?


    I had code to generate a mask from a BITMAP and a color, and I've used this with success along with PlgBlt calls but MaskBlt wants a quaternary raster op code and the correct one isn't obvious to me.

    This works but surely there must be a better way?

    Code:
    Option Explicit
    
    'Picture1 is invisible.  Acts as a source DC and BITMAP.
    
    Private Const QROP_FORESRCCOPY_BACKPATINVERT As Long = &H5ACC0000
    
    Private Declare Function MaskBlt Lib "gdi32" ( _
        ByVal hdcDest As Long, _
        ByVal nXDest As Long, _
        ByVal nYDest As Long, _
        ByVal nWidth As Long, _
        ByVal nHeight As Long, _
        ByVal hdcSrc As Long, _
        ByVal nXSrc As Long, _
        ByVal nYSrc As Long, _
        ByVal hbmMask As Long, _
        ByVal xMask As Long, _
        ByVal yMask As Long, _
        Optional ByVal dwRop As Long = QROP_FORESRCCOPY_BACKPATINVERT) As Long
    
    Private Sub Form_Load()
        Dim Mask As StdPicture
        Dim WidthPx As Long
        Dim HeightPx As Long
        Dim CachedFillStyle As Integer 'Hold original value so we can restore it.  If the
                                       'rest of the Form code doesn't care we can just
                                       'assign solid at design-time.
    
        Set Mask = MaskMaker.Mask(Picture1.Picture, vbGreen)
        AutoRedraw = True
        With Picture1
            WidthPx = ScaleX(.Picture.Width, vbHimetric, vbPixels)
            HeightPx = ScaleY(.Picture.Height, vbHimetric, vbPixels)
            CachedFillStyle = FillStyle
            FillStyle = vbFSSolid 'We need this because we use the pattern here.
            MaskBlt hDC, _
                    Int((ScaleX(ScaleWidth, ScaleMode, vbPixels) - WidthPx) / 2 + 0.5), _
                    Int((ScaleY(ScaleHeight, ScaleMode, vbPixels) - HeightPx) / 2 + 0.5), _
                    WidthPx, _
                    HeightPx, _
                    .hDC, _
                    0, _
                    0, _
                    Mask.Handle, _
                    0, _
                    0
            FillStyle = CachedFillStyle
        End With
        AutoRedraw = False
    End Sub
    The MaskMaker class is used to create a mask StdPicture from the Picture property of the hidden Picture1 PictureBox.

    Name:  sshot.png
Views: 102
Size:  5.0 KB


    Normally I'd probably just use TransparentBlt or even use a source GIF with transparency and VB's Render method myself.

    I'm not sure "high color GIFs" are supported in GDI yet though so I suppose 256 colors might not be enough for some purposes. But once you get over 256 colors or so you are normally into territory where a designated transparent color or mask color becomes unreliable anyway.
    Attached Files Attached Files

  2. #2
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,215

    Re: MaskBlt ROP?

    There is a MAKEROP4 macro. If code can be found, that might make it easier to figure out?

    The macro takes two ternary raster operation codes as input, one for the foreground and one for the background, and packs their Boolean operation indexes into the high-order word of a 32-bit value. The low-order word of this value will be ignored.
    So, I'm guessing it would look something like: (PATCOPY Or SRCINVERT) shifted into the HiWord. Substitute the 2 ROPs appropriately. Just a guess though.
    Last edited by LaVolpe; Jun 15th, 2019 at 05:04 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  3. #3

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,206

    Re: MaskBlt ROP?

    The macro just does what that prose is saying. There is nothing in the SDK to suggest what arguments to pass to it.


    I guess my real question was what ROP value would copy the foreground and not alter the background without using a pattern (FillStyle)?

    I tried a search but never came up with any VB6 programs... or to be honest any programs or advice that gave the desired result. It almost feels like everybody stumbles over the very same issue and punts.

    I probably would punt as well most of the time. As I said TransparentBlt and friends are usually a lot less work. I only found creating masks to be helpful along with PlgBlt when I wanted to do cutouts from a "sheet" image and rotate them.

  4. #4
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,215

    Re: MaskBlt ROP?

    Creating those ROPs always made my head spin & preferred to find the one I needed/wanted from someone else's efforts

    https://docs.microsoft.com/en-us/win...ter-operations

    FYI: I was close in my guess, but not right
    #define MAKEROP4(fore, back) (DWORD) (((back)<<8) & 0xFF000000) | (fore))
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  5. #5

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,206

    Re: MaskBlt ROP?

    For anyone without the Windows SDK who wants to follow along:

    Code:
    /* Binary raster ops */
    #define R2_BLACK            1   /*  0       */
    #define R2_NOTMERGEPEN      2   /* DPon     */
    #define R2_MASKNOTPEN       3   /* DPna     */
    #define R2_NOTCOPYPEN       4   /* PN       */
    #define R2_MASKPENNOT       5   /* PDna     */
    #define R2_NOT              6   /* Dn       */
    #define R2_XORPEN           7   /* DPx      */
    #define R2_NOTMASKPEN       8   /* DPan     */
    #define R2_MASKPEN          9   /* DPa      */
    #define R2_NOTXORPEN        10  /* DPxn     */
    #define R2_NOP              11  /* D        */
    #define R2_MERGENOTPEN      12  /* DPno     */
    #define R2_COPYPEN          13  /* P        */
    #define R2_MERGEPENNOT      14  /* PDno     */
    #define R2_MERGEPEN         15  /* DPo      */
    #define R2_WHITE            16  /*  1       */
    #define R2_LAST             16
    
    /* Ternary raster operations */
    #define SRCCOPY             (DWORD)0x00CC0020 /* dest = source                   */
    #define SRCPAINT            (DWORD)0x00EE0086 /* dest = source OR dest           */
    #define SRCAND              (DWORD)0x008800C6 /* dest = source AND dest          */
    #define SRCINVERT           (DWORD)0x00660046 /* dest = source XOR dest          */
    #define SRCERASE            (DWORD)0x00440328 /* dest = source AND (NOT dest )   */
    #define NOTSRCCOPY          (DWORD)0x00330008 /* dest = (NOT source)             */
    #define NOTSRCERASE         (DWORD)0x001100A6 /* dest = (NOT src) AND (NOT dest) */
    #define MERGECOPY           (DWORD)0x00C000CA /* dest = (source AND pattern)     */
    #define MERGEPAINT          (DWORD)0x00BB0226 /* dest = (NOT source) OR dest     */
    #define PATCOPY             (DWORD)0x00F00021 /* dest = pattern                  */
    #define PATPAINT            (DWORD)0x00FB0A09 /* dest = DPSnoo                   */
    #define PATINVERT           (DWORD)0x005A0049 /* dest = pattern XOR dest         */
    #define DSTINVERT           (DWORD)0x00550009 /* dest = (NOT dest)               */
    #define BLACKNESS           (DWORD)0x00000042 /* dest = BLACK                    */
    #define WHITENESS           (DWORD)0x00FF0062 /* dest = WHITE                    */
    #if(WINVER >= 0x0500)
    
    #define NOMIRRORBITMAP               (DWORD)0x80000000 /* Do not Mirror the bitmap in this call */
    #define CAPTUREBLT                   (DWORD)0x40000000 /* Include layered windows */
    #endif /* WINVER >= 0x0500 */
    
    
    /* Quaternary raster codes */
    #define MAKEROP4(fore,back) (DWORD)((((back) << 8) & 0xFF000000) | (fore))

  6. #6

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,206

    Re: MaskBlt ROP?

    What I wanted for the background was a "dest = dest" (DSTCOPY?) but I don't see that option, which is why I used a pattern-oriented value.

  7. #7

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,206

    Re: MaskBlt ROP?

    More digging finally turned it up:

    Code:
    Option Explicit
    
    'Picture1 is invisible.  Acts as a source DC and BITMAP.
    
    'Private Const DSTCOPY = &HAA0029
    Private Const QROP_FORESRCCOPY_BACKDSTCOPY As Long = &HAACC0000
    
    Private Declare Function MaskBlt Lib "gdi32" ( _
        ByVal hdcDest As Long, _
        ByVal nXDest As Long, _
        ByVal nYDest As Long, _
        ByVal nWidth As Long, _
        ByVal nHeight As Long, _
        ByVal hdcSrc As Long, _
        ByVal nXSrc As Long, _
        ByVal nYSrc As Long, _
        ByVal hbmMask As Long, _
        ByVal xMask As Long, _
        ByVal yMask As Long, _
        Optional ByVal dwRop As Long = QROP_FORESRCCOPY_BACKDSTCOPY) As Long
    
    Private Sub Form_Load()
        Dim Mask As StdPicture
        Dim WidthPx As Long
        Dim HeightPx As Long
    
        Set Mask = MaskMaker.Mask(Picture1.Picture, vbGreen)
        AutoRedraw = True
        With Picture1
            WidthPx = ScaleX(.Picture.Width, vbHimetric, vbPixels)
            HeightPx = ScaleY(.Picture.Height, vbHimetric, vbPixels)
            MaskBlt hDC, _
                    Int((ScaleX(ScaleWidth, ScaleMode, vbPixels) - WidthPx) / 2 + 0.5), _
                    Int((ScaleY(ScaleHeight, ScaleMode, vbPixels) - HeightPx) / 2 + 0.5), _
                    WidthPx, _
                    HeightPx, _
                    .hDC, _
                    0, _
                    0, _
                    Mask.Handle, _
                    0, _
                    0
        End With
        AutoRedraw = False
    End Sub

  8. #8
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,215

    Re: [RESOLVED] MaskBlt ROP?

    Cool, and looking at those ternary codes from the MSDN link, what is the ROP for just the destination? &H00AA0029

    If using that macro, we'd have ((&HAA0029 << 8) And &HFF000000) Or &HCC0020 = &HAACC0020 for the ROP4. But per MSDN, the loWord is ignored from that macro, so the value actually used from that ROP would simply be &HAACC0000 as your new constant shows.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  9. #9

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,206

    Re: [RESOLVED] MaskBlt ROP?

    I thought this would be easier to track down. I found a hint in a fairly recent SO post but I was a bit too dense to make use of it. Later I found a 1999 forum thread on a VBForums sister site that hit me over the head with the answer.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width