News:

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

Attempting to display Progress Bar

Started by Don57, November 12, 2011, 08:09:23 PM

Previous topic - Next topic

Don57

I am attempting to draw a progress bar for my encryption program, but am totally confused at the moment. I am successful at creating the pen, but am unable to select the object. The problem is in the device context handle. Do I use the handle created by BeginPaint, or the one created by CreateCompatableDC in WndProc uMsg==WM_PAINT , or do I have to make those calls again to obtain the DC ?



      invoke  CreatePen, PS_SOLID, PenWidth, PenColor                      ; handle returned in eax
      mov     hPen,eax                                                                     ; save the pen handle
     
      invoke  SelectObject, hGlobalDC, hPen
      mov     hPenOld,eax
     
      invoke MoveToEx, hBitmap, 135d, 350d, NULL                               ; set pen for start of draw

      invoke LineTo, hBitmap, 622d, 355d                                             ; draw the line

      invoke    SelectObject, hBitmap, hPenOld
      invoke    DeleteObject, eax


AParsons


qWord

Don57,

you have an back buffer (DC+Bitmap), which is used to draw/fill the whole client area or only parts of it?
Why not using windows progress bars?
FPU in a trice: SmplMath
It's that simple!

drizz

The truth cannot be learned ... it can only be recognized.

Don57

The trouble is that I am trying to draw the status bar on top of a custom bitmap, which is the user interface for the program. I thought that the DC that I established to draw the bitmap would be valid until the program was closed. As I understand it a handle in windows is merely the memory address. For example hInstance for a program is merely it's address in memory, I assumed that that would apply to the DC handle as well.

qWord

If you have created the bitmap and the DC, you can uses the handle as long as you wish - if you do not longer need the DC, simply destroy the bitmap and then the DC.
If I understand you right, your client area of the Window is stored in a Bitmap+DC (=UI=hGlobalDC), which you have created? If so, you are copying this DC to the screen while handling WM_PAINT? In this case, drawing the status bar would take place when the progress bar's value has changed and not while handling WM_PAINT (you would directly draw to your memory-DC, which holds the UI).
you may supply your code?

.elseif uMsg == WM_PAINT
    invoke BeginPaint,hWnd,ADDR ps
    mov edx,ps.rcPaint.right
    sub edx,ps.rcPaint.left
    mov ecx,ps.rcPaint.bottom
    sub ecx,ps.rcPaint.top
    invoke BitBlt,ps.hdc,ps.rcPaint.left,ps.rcPaint.top,edx,ecx,hGlobalDC,ps.rcPaint.left,ps.rcPaint.top,SRCCOPY
    invoke EndPaint,hWnd,ADDR ps

...
.elseif uMsg == ...
    ; Progress bar's value has changed!
    ; draw to hGlobalDC ( you may define a function for that task)
    ...
    ; fill rect-structure with region to update
    invoke InvalidateRect,hWnd,ADDR rect,FALSE
FPU in a trice: SmplMath
It's that simple!

Don57

Still very confused. Here are some snippets of code.


   WndProc proc hWnd:HWND, uMsg:UINT, wParam, lParam

     LOCAL  ps:PAINTSTRUCT
     LOCAL  hdc:HDC                                                           
     LOCAL  hMemDC:HDC                                                     
     LOCAL  rect:RECT


     .IF uMsg==WM_CREATE

                invoke LoadBitmap, hInstance, OPENING_SCREEN               
                mov hBitmap, eax                                                           

     .ELSEIF uMsg==WM_PAINT

                invoke BeginPaint, hWnd, addr ps                           
                mov  hdc,eax                                                     

                invoke CreateCompatibleDC, hdc                             
                mov  hMemDC,eax                                               
                                                                           

                mov  hGlobalDC,eax                                         ; DC for use in other procs


                invoke SelectObject, hMemDC, hBitmap                     
                invoke GetClientRect, hWnd, addr rect                     
                                                                         

                invoke BitBlt, hdc,0,0,rect.right,\                        ; transfer to display buffer
                               rect.bottom,hMemDC,\
                               0,0,SRCCOPY


                invoke DeleteDC, hMemDC                                    ; delete the device context
                invoke EndPaint, hWnd, addr ps                             ; free DC handle

.ELSEIF uMsg==WM_LBUTTONDOWN                                          ; if user left click window

                   mov  eax,lParam                                         ; get the mouse co-ordinates
                   push eax                                                ; save them
                   and  eax,0FFFFh                                         ; we just want the last word
                   cwde                                                    ; create a double word
                   mov  dwMouseX,eax                                       ; save the X position
                   pop  eax                                                ; get lParam again
                   shr  eax,16d                                            ; put the high word in the low word
                   mov  dwMouseY,eax 


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

The call to   Progress_Bar proc  is after each block of data is written from the buffer. The buffer size is set according to the system granularity.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Progress_Bar proc


     invoke  CreatePen, PS_SOLID, PenWidth, PenColor                     
     mov     hPen,eax                                                     
     
     
      invoke  SelectObject, hGlobalDC, hPen
      mov     hPenOld,eax
     
     
      invoke MoveToEx, hBitmap, 135d, 350d, NULL                               ; set pen for start of draw

      invoke LineTo, hBitmap, 622d, 355d                                             ; draw the line  arbitrary co-ordinates to get it working



      invoke    SelectObject, hBitmap, hPenOld
      invoke    DeleteObject, eax

    ret

   Progress_Bar endp


jj2007

> invoke DeleteDC, hMemDC

Before doing that, you should deselect the bitmap.

qWord

Quote from: Don57 on November 16, 2011, 06:23:29 PM
Still very confused. Here are some snippets of code.
[...]
You are trying to use a bitmap like a DC - that won't work: You must select the loaded bitmap into your global DC (this is done at initialization).
In the attachment an example.

qWord
FPU in a trice: SmplMath
It's that simple!

Don57

I just downloaded your code, there is quite a bit there. It will take me a while to read over. It looks like you spent a bit of time writting it. Thank you. :clap: