News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Question about using BitBlt function

Started by vega, March 21, 2009, 08:20:11 PM

Previous topic - Next topic

vega

Hi, I have one problem about using BitBlt function.
I want to drag an image on client area by left mouse button down & mouse move, as like ACDSee.
My idea is as follows:

When Image.display.Dialog is created (= WM_INITDIALOG),
   Image.Head.Coordinates(ImageHeadX, ImageHeadY) sets to 0.

Then, 'WM_PAINT' message Routine invokes 'BitBlt' function with normal 'Start' head.position.

   Invoke  BitBlt, hDC, 0, 0, imageWidth, imageHeight, hMemDC, ImageHeadX, ImageHeadY, SRCCOPY
   is converted to
   Invoke  BitBlt, hDC, 0, 0, imageWidth, imageHeight, hMemDC, 0, 0, SRCCOPY



When left mouse button is down, (= WM_LBUTTONDOWN)
   Stores current cusor position into CursorX1pos, CursorY1pos.

and then Mouse is moved, (= WM_MOUSEMOVE, MK_LBUTTON)
   Gets current cusor position in CursorXpos, CursorYpos.
   then,
   Gets differents between them(= CursorX1pos - CursorXpos, CursorY1pos - CursorYpos )
   and stores it(Results) into ImageHeadX, ImageHeadY
   and sets 'MoveImageFlag'.

When left mouse button is up, (= WM_LBUTTONUP)
   Sends 'WM_PAINT' message to Image display Window(hWnd).
   
Then, 'WM_PAINT' message Routine invokes 'BitBlt' function
   with variable Image.Head.Coordinates(ImageHeadX, ImageHeadY).

   Invoke  BitBlt, hDC, 0, 0, imageWidth, imageHeight, hMemDC, ImageHeadX, ImageHeadY, SRCCOPY



But, these routine does not working.
I don't know How&Why.
Teach me, please.

    -Asm.Student-
 





         Begin of procedure  CreateImageDialogProc
       
            ;;ready for display Dialog.Icon
            ;;=Invoke  GlobalAlloc, GMEM_FIXED or GMEM_ZEROINIT, 32
            Make global buffer memory with size  32, GMEM_FIXED+GMEM_ZEROINIT 
            Mov  lpGlobalMemory, EAX
           
            Push  hIcon
            ;;=Pop  lpGlobalMemory
            Pop   [EAX]
           
            ;;gets Screen width & Height
            Invoke  GetSystemMetrics, SM_CXSCREEN
            Mov  ScreenRect.right, EAX
            Invoke  GetSystemMetrics, SM_CYSCREEN
            Mov  ScreenRect.bottom, EAX
   
            Mov  EAX, imageHeight
            Add  EAX, 32
            Mov  EBX, imageWidth
            Add  EBX, 10
           
            Style1 = WS_THICKFRAME+WS_CAPTION+WS_SYSMENU+WS_MINIMIZEBOX+WS_MAXIMIZEBOX+WS_VISIBLE

            Set dialog template  "ImageViewer ver0.0.0", "MS Sans Serif", 10, Style1, \
                0, \              ;;sets number of Controls(Button,Static,Icon, etc) in DialogBox
                0,0,100,50, \     ;;sets default size of DialogBox
                1024
           
            Call modal dialog   hInstance, 0, OperateImageDialogProc, ADDR lpGlobalMemory
   
            Remove global buffer memory  lpGlobalMemory
            Ret
           
         End of procedure  CreateImageDialogProc
       



         Data block
            Set null dword  CursorX1pos
            Set null dword  CursorY1pos
            Set null dword  CursorXpos
            Set null dword  CursorYpos
            Set null dword  ImageHeadX
            Set null dword  ImageHeadY
            Set null byte   MoveImageFlag
         End block
         

         Begin of procedure  OperateImageDialogProc, <hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM>
   
            .IF uMsg is WM_INITDIALOG
   
               ;; Displays DialogBox Icon
               Mov  EAX, lParam
               Mov  EAX, [EAX]
               Invoke  SendMessage, hWnd, WM_SETICON, 1, [EAX]
   
               ;; changes Frame.Size of DialogBox as Image Size
               ;
               Mov  EBX, imageWidth
               ;;adds as Left.Right.Frame.Boarder thickness
               Add  EBX, 8
               .IF EBX > ScreenRect.right
                  Mov  EBX, ScreenRect.right
               .ENDIF   

               Mov  EAX, imageHeight
               ;;adds as Caption & Bottom.Boarder thickness
               Add  EAX, 27
               .IF EAX > ScreenRect.bottom
                  Mov  EAX, ScreenRect.bottom
               .ENDIF   

               Change window position and size with  hWnd, 0, 0, EBX, EAX
               Change window title  hWnd, ADDR ImageFileNameBuffer
               
               Mov  ImageHeadX, 0
               Mov  ImageHeadY, 0
               
               ;;then flow jump to Routine for WM_PAINT



            .ELSEIF uMsg is WM_LBUTTONUP
   
               .IF MoveImageFlag is 1
                  Send message to  hWnd, WM_PAINT
               .ENDIF   



             .ELSEIF uMsg is WM_LBUTTONDOWN
               
               .IF wParam is MK_LBUTTON
                  ;;= Get high and low order word into EAX EBX from  lParam
                  Mov  EAX, lParam
                  Clear  EBX
                  ;;Get low order word into EBX
                  Mov  BX, AX
                  ;;Get high order word into EAX
                  Shr  EAX, 16
                 
                  Mov  CursorX1pos, EBX
                  Mov  CursorY1pos, EAX
               .ENDIF
   
   
   
            .ELSEIF uMsg is WM_MOUSEMOVE
               .IF wParam is MK_LBUTTON
             
                  ;;if Mouse moves during Left.Mouse.Button is down
                  ;; displays specified bitmap image with changed position.
                  ;
                  ;; xPos = LOWORD(lParam);  // horizontal position of cursor
                  ;; yPos = HIWORD(lParam);  // vertical position of cursor
                  ;
                 
                  ;;= Get high and low order word into EAX EBX from  lParam
                  Mov  EAX, lParam
                  Clear  EBX
                  ;;Gets low order word into EBX
                  Mov  BX, AX
                  ;;Gets high order word into EAX
                  Shr  EAX, 16
                 
                  Mov  CursorXpos, EBX
                  Mov  CursorYpos, EAX
                 
                  Mov  EAX, CursorX1pos
                  .IF EAX > CursorXpos
                     Sub  EAX, CursorXpos
                     Mov  ImageHeadX, EAX
                     Mov  MoveImageFlag, 1
                  .ENDIF
                     
                  Mov  EAX, CursorY1pos
                  .IF EAX > CursorYpos
                     Sub  EAX, CursorYpos
                     Mov  ImageHeadY, EAX
                     Mov  MoveImageFlag, 1
                  .ENDIF

               .ENDIF   
                   
               

               
            .ELSEIF uMsg is WM_PAINT
           
               Invoke  BeginPaint, hWnd, ADDR PaintStruc
               Mov  hDC, EAX
     
               ;;creates Memory.DC which used by DC and gets Memory.DC handle
               Invoke  CreateCompatibleDC, hDC
               Mov  hMemDC, EAX
               
               ;; stores Bitmap into memory_DC
               Invoke  SelectObject, hMemDC, hBitmap
               
               ;; displays specified bitmap image
               Invoke  BitBlt, hDC, 0, 0, imageWidth, imageHeight, hMemDC, ImageHeadX, ImageHeadY, SRCCOPY
   
               .IF MoveImageFlag is 1
                  Mov  MoveImageFlag, 0
                  Mov  ImageHeadX, 0
                  Mov  ImageHeadY, 0
               .ENDIF   
                 
               Invoke  DeleteDC, hMemDC
               Invoke  EndPaint, hWnd, ADDR PaintStruc
               
               
   
   
            .ELSEIF uMsg is WM_CLOSE
     
               Invoke  DeleteObject, hBitmap
               Invoke  EndDialog, hWnd, NULL
     

            .ELSE
               Mov  EAX, FALSE
               Ret

            .ENDIF
     
   
       
            Mov  EAX, TRUE
            Ret
   
         End of procedure  OperateImageDialogProc





vega

In my test,
Image is normally moved to specified coordinates by this method (adds two test line as bellow).

   Mov  ImageHeadX, 20
   Mov  ImageHeadY, 20
   Invoke  BitBlt, hDC, 0, 0, imageWidth, imageHeight, hMemDC, ImageHeadX, ImageHeadY, SRCCOPY


I think,
it may be caused that the variable ImageHeadX and ImageHeadY is initialized by any reason.
it seems be effected by Window Message Loop.
but I don't know exactly, why?




 

PBrennick

vega,

I know very little about using graphics in that manner but, there is one thing I _do_ know; without the MessageLoop interaction the WM_PAINT message would never be sent after processing WM_INITDIALOG. So certainly something MUST be going on with it. I am curious about one thing; why are you using a dialog box. The automatic handling of messages used by dialogs IMO is not as workable as with a standard window. In both cases CreateWindow is used but it is not done in as controllable way as if you used a standard window. I have no idea if this is an issue but I do see this as a possible area that could cause concern.

Paul
The GeneSys Project is available from:
The Repository or My crappy website