Hi, I need U help:
     In memory DC,   create a compatible memory dc and bitmap as background,and create another compatible dc and bitmap ,the moving bitmap should pass throught the background bitmap while the background image keep still,then bitblt to window client area DC to display the result.
   How do I? Doest it refer to SRCPAINT raster in Bitblt function?
   Many TXS!
   Best Regard.
Posted on 2005-11-07 03:07:40 by Luckrock
The easiest option is to hold both your background bitmap and the other bitmap in their own separate compatible DCs. You also keep the current coordinates (top left corner) of the other bitmap.

Then, whenever you want to display the other bitmap at some other location, bitblt part of the background bitmap (the size of the other bitmap) where the current other bitmap is located to restore your background before you bitblt the other bitmap to the new location. Update the current coordinates of the other bitmap.

Raymond
Posted on 2005-11-07 10:12:27 by Raymond
Hi,Raymond,
          Many thanks to your reply.
      "The easiest option is to hold both your background bitmap and the other bitmap in their own separate compatible DCs. ". as what you said, Yes, I save the two bitmap in different compatible DCs:
       
In WM_CREATE MESSAGE ,create a still bitmap (painted by 20 green line) as background,as follow code piece:

        ;Create the first( Background)  Dc and bitmap 
        invoke CreateCompatibleDC,hdc
        mov    hdc_Grid,eax
        invoke CreateCompatibleBitmap,hdc_Grid,maxX,maxY
        mov    hBitmap_Grid,eax
        invoke  SelectObject,hdc_Grid,hBitmap_Grid                     
        mov   eax,cOScopeLeft                                           ;set This bitmap  coordinates and size
mov   rcGrid.left,eax
add   eax,cOScopeWidth
mov   rcGrid.right,eax        
        mov   eax,cOScopeTop
        mov   rcGrid.top,eax
        add   eax,cOScopeHeight
        mov   rcGrid.bottom,eax ;
       
        invoke  SelectObject,hdc_Grid,hBrush_Black                        ;paint it with black brush
        invoke  PatBlt, hdc_Grid,0 , 0, maxX, maxY, PATCOPY
       
                  invoke SelectObject,hdc_Grid,hPenGreen         ;draw 20 horizonal green lines as background
                  mov COUNT,0                         
                  m2m pt.x,rcGrid.left                         
                  m2m pt.y,rcGrid.top
                  .while COUNT!=20                     
                         inc  COUNT
                         invoke MoveToEx,hdc_Grid,pt.x,pt.y,NULL
                         invoke LineTo,  hdc_Grid,cOScopeWidth, pt.y
                         add  pt.y,20                         ;Grid Step=20 pixels
                         ;PrintDec pt.y
                  .endw


     In WM_CREATE Message ,create the 2nd Dc and bitmap ?Name = Plot)
     and in WM_TIMER message ,a square wave generator append this wave to Plot bitmap as a moving   picture,as the following two code pieces:

      ;WM_CREAT Message
      ; Create a compatible  Plot bitmap
        invoke  CreateCompatibleDC, hdc                              ;current DC memory
        mov     hdc_Plot,eax
        invoke  CreateCompatibleBitmap, hdc, maxX, maxY
        mov     hBitmap_Plot,eax
        invoke  SelectObject, hdc_Plot, hBitmap_Plot              ;select Memory DC
   
        mov   eax,cOScopeLeft                                        ;set the rect area of the bitmap
mov   rcPlot.left,eax
add   eax,cOScopeWidth
mov   rcPlot.right,eax ; set to cOScopeLeft+cOScopeWidht
        mov   eax,cOScopeTop
        mov   rcPlot.top,eax
        add   eax,cOScopeHeight
        mov   rcPlot.bottom,eax        
        invoke  SelectObject, hdc_Plot, hBrush_White                ;paint with white
        invoke  PatBlt, hdc_Plot,0 , 0, maxX, maxY, PATCOPY


        and in the WM_TIMER Message ,a SQUARE WAVE GENERATOR append the square wave point on right edge of Plot Bitmap .On every 50 ms interval,connect the old point to new point ?Produced by SQUARE WAVE GENERATOR),and shift this bitmap to left by nShiftPixels[=4]

    .elseif uMsg==WM_TIMER
        m2m PreviousPoint,CurrentPoint   ;CurrentPoint ->PreviousPoint

        .if (NUM>=0)&&(NUM<=30)     ;SQUARE WAVE GENERATOR
             mov  CurrentPoint,54
             inc  NUM
           
             .elseif (NUM>=31)&&(NUM<=59)
              mov CurrentPoint,103
              inc NUM
             .elseif (NUM==60)
              mov CurrentPoint,103
              mov NUM,0
        .endif
       
        ;grab the right side of the plot (exluding nShiftPixels on the left)
        ;move this grabbed bitmap to the left by m_nShiftPixels
        mov    ecx,cOScopeWidth
        sub    ecx,nShiftPixels
        ;mov    ecx,eax              ;cOScopeWidth - nShiftPixels --> ecx
        mov    eax,cOScopeLeft
        add    eax,nShiftPixels     ;cOScopeLeft + nShiftPixels -->eax

        ;Shift the Plot bitmap to left by nShiftPixels
        invoke  BitBlt, hdc_Plot, cOScopeLeft, cOScopeTop, ecx, cOScopeHeight,\   
                        hdc_Plot, eax, cOScopeTop, SRCCOPY
invoke  InvalidateRect, hWnd, ADDR rcPlot,0

        ; establish a rectangle over the right side of plot
        ; which now needs to be cleaned up proir to adding the new point
        ; rectCleanUp = m_rectPlot ;
        ; rectCleanUp.left  = rectCleanUp.right - m_nShiftPixels ;
         m2m rcCleanUp.right       ,rcPlot.right
         mov eax                       ,rcCleanUp.right
         sub eax                        ,nShiftPixels
         mov rcCleanUp.left          ,eax
         m2m rcCleanUp.top         ,rcPlot.top
         m2m rcCleanUp.bottom      ,rcPlot.bottom

        ;fill the cleanup area with the background
          invoke FillRect,hdc_Plot,ADDR rcCleanUp,hBrush_Black
         
         ;grab the plot pen
         invoke SelectObject,hdc_Plot,hPenGreen
         
         ; move to the previous point           
         ;!!!Should be modified for PreviousPoint are actual value of data
         mov eax,          rcPlot.right
         sub eax,          nShiftPixels
         mov prevX,        eax
         m2m prevY,        PreviousPoint
         invoke MoveToEx,hdc_Plot,prevX,prevY,NULL
         

         ; draw to the current point
         mov eax,         nShiftPixels
         shr eax,         1
         mov nHalfShiftPixels, eax       ;get half shift pixels value,should draw in center for current Point DATA
         mov eax,         rcPlot.right
         sub eax,         nHalfShiftPixels
         mov currX,       eax
         m2m currY,       CurrentPoint
         
         invoke   LineTo,hdc_Plot,currX,currY

       
      O.K., be patient,Raymond, "bitblt part of the background bitmap (the size of the other bitmap) where the current other bitmap is located to restore your background before you bitblt the other bitmap to the new location"
    What I have used in this program is different from what U said above.
    I combine these two bitmap using SRCPAINT ,by  Bitblt the moving bitmap to background bitmap ,and update the DC
    in WM_PAINT.


       .elseif uMsg==WM_PAINT                               
        ;Copy those virtual window (memory DC ) onto screen
        invoke BeginPaint,hWnd, ADDR ps    ;get current DC in hdc
        mov hdc,eax
       
       
        invoke CreateCompatibleDC,hdc
        mov hdc_OScope  ,eax
        invoke CreateCompatibleBitmap,hdc_OScope,maxX,maxY
        mov  hBitmap_OScope,eax
       
        invoke BitBlt,hdc_OScope,cOScopeLeft,cOScopeTop,cOScopeWidth,cOScopeHeight,\
                      hdc_Grid,rcGrid.left,rcGrid.top,SRCCOPY
       
        invoke BitBlt,hdc_OScope,cOScopeLeft,cOScopeTop,cOScopeWidth,cOScopeHeight,\
                      hdc_Plot,rcPlot.left,rcPlot.top,SRCPAINT
        invoke BitBlt,hdc,cOScopeLeft,cOScopeTop,cOScopeWidth,cOScopeHeight,\
                      hdc_OScope,cOScopeLeft,cOScopeTop,SRCCOPY
       
       
       
        mov eax,ps.rcPaint.right
        sub eax,ps.rcPaint.left
        mov ecx,ps.rcPaint.bottom
        sub ecx,ps.rcPaint.top
       
        invoke  BitBlt, hdc,   ps.rcPaint.left, ps.rcPaint.top, eax, ecx, \
  hdc_Plot, ps.rcPaint.left, ps.rcPaint.top, SRCCOPY

        invoke EndPaint,hWnd, ADDR ps 


        The program sceen shot is here:
       

        what make me crazy is: only the plot square wave shift to left as what I think,but the background
(20 green line grids) has disappeared.
       I thought the bugs may be lie in the WM_PAINT message routine,but I DONT know where. :mad:
       
       Could u help to analyse ?
   
Many,many ,many.. thanks.
Posted on 2005-11-07 21:28:59 by Luckrock
One thing I am noticing in the WM_PAINT is that you are combining the hdc_Grid and the hdc_Plot in hdc_OScope, then you bitblt that onto your hdc. But then you follow that by a bitblt of your hdc_Plot onto the same hdc.

Raymond
Posted on 2005-11-08 22:00:47 by Raymond
Yes,
        You are right!
        Let me modify it and try again.

       
        But before that ,I have now deleted the Grid Bitmap from dc memory, and paint it directly to hdc,  after Bitblt from hdc_Plot to hdc.
        See Attchement file. It work well.
       
       Thanks,anyway,you are the kindest people I ever meet in this forum .
       Best Regards.

:

  .elseif uMsg==WM_PAINT                             
     
        invoke BeginPaint,hWnd, ADDR ps    ;get current DC in hdc
        mov hdc,eax
       
        ;Draw Grid           
        invoke SelectObject,hdc_Plot,hPenGreen    ;select into DC
        ;create Horizon Grid
        mov COUNT,0                          ;initial count=0
        m2m pt.x,rcPlot.left                          ;initial Grid Start Point
        m2m pt.y,rcPlot.top
        .while COUNT<=20                  ;loop 20 times
              add  pt.y,20                    ;Grid Step=20 pixels
              inc  COUNT         
              invoke MoveToEx,hdc_Plot,pt.x,pt.y,NULL
              invoke LineTo,  hdc_Plot,rcPlot.right, pt.y
        .endw
        ;Copy those virtual window (memory DC ) onto screen
        mov    eax, rcPlot.right
        sub    eax, rcPlot.left
        ;add    eax, 1
        mov    ecx, rcPlot.bottom
        sub    ecx, rcPlot.top
        ;add    ecx, 1
        invoke  BitBlt, hdc,rcPlot.left, rcPlot.top, eax, ecx, \
hdc_Plot,rcPlot.left, rcPlot.top, SRCCOPY

      ;Draw Inner frame
        mov ecx,OScopeBrdWidth           
        RGB 0,200,0                           
        invoke Frame3D,hdc,eax,eax,\                                    ;
              rcPlot.left,rcPlot.top,rcPlot.right,rcPlot.bottom, ecx 
        ;-------------------------
        ;Draw Outter Frame
        ;-------------------------
          ;first,calculat the space between outer frame and inner frame
        xor eax,eax
        xor ecx,ecx
        mov ecx,4
        mov eax,tm.tmAveCharWidth
        mul ecx
        mov ecx, eax                ;save the space (3* average char width) in ecx
        mov eax, rcPlot.left
        sub eax, ecx
        mov rcOuterFrame.left,eax  ; rcOuterFrame.left=rcPlot.left-space
        mov eax, rcPlot.right
        add eax, ecx
        mov rcOuterFrame.right,eax  ;rcOuterFrame.right=rcPlot.right+space
        mov eax, tm.tmHeight
        mov ecx,2
        mul ecx
        mov ecx,eax
        mov eax,rcPlot.top
        sub eax,ecx
        mov rcOuterFrame.top,eax
        mov eax,rcPlot.bottom
        add eax,ecx
        mov rcOuterFrame.bottom,eax
        RGB 240,10,150
        invoke Frame3D,hdc,eax,eax,\            ;draw outer Oscillator Window Frame
              rcOuterFrame.left,rcOuterFrame.top,rcOuterFrame.right,rcOuterFrame.bottom,3 
Attachments:
Posted on 2005-11-09 09:53:49 by Luckrock
Well,
    it doest work,
  the method" two momery bitmap dc combine into another memory bitmap dc, then bitblt to screen" seem to hopeless for my code.
  I give it up. no way out...


.elseif uMsg==WM_PAINT                             
        ;Copy those virtual window (memory DC ) onto screen
        invoke BeginPaint,hWnd, ADDR ps    ;get current DC in hdc
        mov hdc,eax

        invoke CreateCompatibleDC,hdc
        mov hdc_Mem  ,eax
        invoke CreateCompatibleBitmap,hdc_Mem,maxX,maxY
        mov  hBitmap_Mem,eax
       
        invoke BitBlt,hdc_Mem,cOScopeLeft,cOScopeTop,cOScopeWidth,cOScopeHeight,\
                      hdc_Grid,rcGrid.left,rcGrid.top,SRCCOPY
       
        invoke BitBlt,hdc_Mem,cOScopeLeft,cOScopeTop,cOScopeWidth,cOScopeHeight,\
                      hdc_Plot,rcPlot.left,rcPlot.top,SRCPAINT
        invoke BitBlt,hdc,cOScopeLeft,cOScopeTop,cOScopeWidth,cOScopeHeight,\
                      hdc_Mem,cOScopeLeft,cOScopeTop,SRCCOPY   
        invoke EndPaint,hWnd, ADDR ps 
       


        what actually confuse me is  "SRCPAINT" raster,what is the hell it meaning? Two night spent debuging this method...

     
   
Posted on 2005-11-09 10:31:04 by Luckrock
The following function is equal to "TransparentBlt" WinAPI function. I wrote this function when I read that Win9x has some bug associated with it. All those pushes prepare the stack so that 7 functions are being called with 1 'call'. Those 7 Functions are commented-out. You can go ahead and cut those pushes (and the 'call' after them) and uncomment those 7 calls ---  it'll be the same (I'm just a bit paranoid about optimizations :P ). The code is in TASM syntax, but it's easy to convert to MASM, or something. The funcions' names are in brackets (and start with "_") because I'm using dynamic linking to GDI32.dll. Just change them to proper names. I hope it'll help you somehow.

labels. To make it simplier to understand the code, here's how I name the labels:  "rtfrblt" means "return from blit".  if there is a number (like "rtfrblt2") then it means there's something to be done before returning (usually some cleanup).

parameters:
hdcDest --  destination device context
x1, y1, w1, h1 ---  destination rectangle
hdcSrc -- source device context
x2, y2  --- source rectangle
color -- transparent color

NOTE: If you cut the pushes and uncomment those 7 calls, then make sure to delete "align 4" directive (the one right after the commented calls)

;---------------------------------------------
align 4
proc  TransparentBlit uses ebx esi edi, hdcDest, x1, y1, w1, h1, hdcSrc, x2, y2, color

LOCAL hdcmask1,hdcmask2,hdctemp1,hdctemp2:dword ;device contexts
LOCAL bmono1,bmono2,btemp1,btemp2:dword     ;bitmaps
LOCAL bit1,bkcol,bit2,bit4:dword        ;previous values

            xor     edi, edi
            call    [_CreateCompatibleDC],
            or      eax, eax
            jz      rtfrblt
            mov     , eax
            call    [_CreateBitmap], , , 1, 1, edi
            or      eax, eax
            jz      rtfrblt2
            mov     , eax
            call    [_SelectObject], , eax
            or      eax, eax
            jz      rtfrblt3
            mov     , eax
            call    [_SetBkColor], ,
            mov     , eax
            call    [_BitBlt], , edi, edi, , , , , , SRCCOPY
            call    [_CreateCompatibleDC],
            or      eax, eax
            jz      rtfrblt4
            mov     , eax
            call    [_CreateBitmap], , , 1, 1, edi
            or      eax, eax
            jz      rtfrblt5
            mov     , eax
            call    [_SelectObject], , eax
            or      eax, eax
            jz      rtfrblt6
            mov     , eax
            call    [_BitBlt], , edi, edi, , , , edi, edi, NOTSRCCOPY
            call    [_CreateCompatibleDC],
            or      eax, eax
            jz      rtfrblt7
            mov     , eax
            call    [_CreateCompatibleDC],
            or      eax, eax
            jz      rtfrblt8
            mov     , eax
            call    [_CreateCompatibleBitmap], , ,
            or      eax, eax
            jz      rtfrblt9
            mov     , eax
            call    [_CreateCompatibleBitmap], , ,
            or      eax, eax
            jz      rtfrblt10
            mov     , eax
            call    [_SelectObject], , eax
            or      eax, eax
            jz      rtfrblt11
            mov     , eax
            call    [_SelectObject], ,
            or      eax, eax
            jz      rtfrblt12
            ;mov    , eax

            push    eax     ;7
            push      ;7
            mov     eax,
            mov     ebx,
            mov     ecx,
            mov     edx,
            mov     esi, [_BitBlt]
            push    offset rtfrblt13
            push    SRCCOPY     ;6
            push    edi     ;6
            push    edi     ;6
            push    eax     ;6
            push    edx     ;6
            push    ecx     ;6
            push            ;6
            push            ;6
            push       ;6
            push    [_SelectObject] ;7
            push    SRCPAINT    ;5
            push    edi     ;5
            push    edi     ;5
            push    ebx     ;5
            push    edx     ;5
            push    ecx     ;5
            push    edi     ;5
            push    edi     ;5
            push    eax     ;5
            push    esi     ;6
            push    SRCAND      ;4
            push    edi     ;4
            push    edi     ;4
            push      ;4
            push    edx     ;4
            push    ecx     ;4
            push    edi     ;4
            push    edi     ;4
            push    ebx     ;4
            push    esi     ;5
            push    SRCCOPY     ;3
            push    edi     ;3
            push    edi     ;3
            push        ;3
            push    edx     ;3
            push    ecx     ;3
            push    edi     ;3
            push    edi     ;3
            push    ebx     ;3
            push    esi     ;4
            push    SRCAND      ;2
            push    edi     ;2
            push    edi     ;2
            push      ;2
            push    edx     ;2
            push    ecx     ;2
            push    edi     ;2
            push    edi     ;2
            push    eax     ;2
            push    esi     ;3
            push    SRCCOPY     ;1
            push    edi     ;1
            push    edi     ;1
            push       ;1
            push    edx     ;1
            push    ecx     ;1
            push    edi     ;1
            push    edi     ;1
            push    eax     ;1
            push    esi     ;2
            jmp     esi     ;1


        ;   call    [_BitBlt], , edi, edi, , , , edi, edi, SRCCOPY
        ;   call    [_BitBlt], , edi, edi, , , , edi, edi, SRCAND
        ;   call    [_BitBlt], , edi, edi, , , , edi, edi, SRCCOPY
        ;   call    [_BitBlt], , edi, edi, , , , edi, edi, SRCAND
        ;   call    [_BitBlt], , edi, edi, , , , edi, edi, SRCPAINT
        ;   call    [_BitBlt], , , , , , , edi, edi, SRCCOPY
        ;   call    [_SelectObject], ,

align 4

rtfrblt13:
rtfrblt12:      call    [_SelectObject], ,
rtfrblt11:      call    [_DeleteObject],
rtfrblt10:      call    [_DeleteObject],
rtfrblt9:       call    [_DeleteDC],
rtfrblt8:       call    [_DeleteDC],
rtfrblt7:       call    [_SelectObject], ,
rtfrblt6:       call    [_DeleteObject],
rtfrblt5:       call    [_DeleteDC],
rtfrblt4:       call    [_SetBkColor], ,
            call    [_SelectObject], ,
rtfrblt3:       call    [_DeleteObject],
rtfrblt2:       call    [_DeleteDC],
rtfrblt:        ret
endp    TransparentBlit
;---------------------------------------------
Posted on 2005-11-09 10:40:26 by ti_mo_n
HI, ti_mo_n
    Thanks for your advice.
    I have google the word 'SRCPAINT'. and found the concept 'Transparent bitmap' and download several paper to study.
    But now I have to turn to next step. to draw a knob control  to adjust  the shift  frequency ofbitmap.
  I hope i could use the transparent bitmap in some other day.you know,i write program in my spare time.
  For this program ,directly draw on hdc ,is enough speed and simple.
 
    Anyway thanks for your kindness .
    With my regards.

   
Posted on 2005-11-10 08:18:30 by Luckrock