News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Problems showing text over a progress bar

Started by NoCforMe, December 28, 2017, 02:50:13 PM

Previous topic - Next topic

NoCforMe

First of all, this problem is completely nit-picky; it's just a matter of cosmetics, of things not looking just the way I'd like them to.

What I did was figure out how to put text showing the percentage completed of a task over a progress bar, by getting the control's device context, then using TextOut() to write text over it. Works fine. Only thing is, I don't seem to be able to modify the DC in any way without the text disappearing completely. (What I'd like to do is to make the text background transparent; as things stand now, the progress bar bars disappear behind the text and don't show up until they come out the other side. Looks a little funny.)

Here's my code (all the relevant parts, anyhow):


.data
ProgressBarHandle HWND ?
PercentFmt DB "%d%%", 0

.code
;=====================================================
; ShowProgress (count)
;
; Shows progress of fractal creation both as a progress bar
; (with the percentage of progress shown on the bar) and as
; a number in the status bar.
;
; "count" is the count of lines, in the range 0 - $imageSize/10
;=====================================================

ShowProgress PROC count:DWORD
LOCAL textLen:DWORD, hDC:HDC, gpRect:RECT, sizeStruct:_SIZE, buffer[32]:BYTE

; Set the extent of the progress bar and display it:
INVOKE SendMessage, ProgressBarHandle, PBM_SETPOS, count, 0

; Put the percentage of progress on the progress bar:
INVOKE GetDC, ProgressBarHandle
MOV hDC, EAX
MOV EAX, count
XOR EDX, EDX
MOV ECX, 10
DIV ECX
INVOKE wsprintf, ADDR buffer, OFFSET PercentFmt, EAX
MOV textLen, EAX

; Get sizes of both text & progress bar control, calculate text X/Y pos.:
INVOKE GetTextExtentPoint32, hDC, ADDR buffer, textLen, ADDR sizeStruct
INVOKE GetClientRect, ProgressBarHandle, ADDR gpRect
MOV ECX, gpRect.right
SHR ECX, 1
MOV EAX, sizeStruct.x
SHR EAX, 1 ;Text len./2.
SUB ECX, EAX ;ECX = text X-pos.
MOV EDX, gpRect.bottom
SHR EDX, 1
MOV EAX, sizeStruct.y
SHR EAX, 1 ;Text height/2.
SUB EDX, EAX ;EDX = text Y-pos.

; Display text on progress bar:
;*****  Apparently, anything you do to mess with the DC here renders the text invisible ...
; INVOKE SetBkMode, hDC, TRANSPARENT
; INVOKE SelectObject, hDC, StdControlFont ;This global is set earlier.
; INVOKE SetTextColor, hDC, 0FFh

; This works OK:
INVOKE TextOut, hDC, ECX, EDX, ADDR buffer, textLen

INVOKE ReleaseDC, ProgressBarHandle, hDC

; Now show count on status bar:
INVOKE wsprintf, ADDR buffer, OFFSET FractalProgressFmt, count
INVOKE  SendMessage, StatusHandle, SB_SETTEXT, 3, ADDR buffer

RET

ShowProgress ENDP



Notes:
The progress bar is created as part of a dialog. It works fine (as a progress bar). However, if I do anything to mess with the DC used to place text on the bar, the text doesn't display at all. (See the commented-out stuff in the code above.) For instance, if I try to set the text background to transparent (using INVOKE SetBkMode, hDC, TRANSPARENT), I get nada, zip, zero. (Same thing if I try to set it to OPAQUE.) Same thing if I try to load a different font, change the font color, basically do anything to the device context.

Other info:
o Win XP, SP 3
o Using a manifest in my build for visual styles

I'm ready to accept that maybe this is just an unresolvable problem with XP, which of course means it'll never be fixed since no longer supported by Micro$oft. Regarding the manifest, it makes no difference if I use the manifest or not; if I omit it, I get the "classic" style progress bar, but the same problem.

Or could it be that in order to do what I want to do, I have to subclass the control, intercept its WM_PAINT messages, etc.? I'm guessing that the problem here may be the sequence of events when I try to alter the DC.

Any help anyone can shed upon this problem would be appreciated!
Assembly language programming should be fun. That's why I do it.

NoCforMe

Aaaaaaargh ... walkin' the walk of shame here: stupid stupid stupid mistake. (Notice how I was putting x & y in registers, then clobbering them with other calls.)

Figured this out. It's ugly but it works: I save the previous text displayed (e.g., "32%"). The next time I display text, I first show the previous text in white, then the new text in black. Works fine.

Sorry to bother y'all with my dumb mistake.
Assembly language programming should be fun. That's why I do it.

jj2007

Hi riomdr,

NoCforMe hasn't been active for a year, but if you post complete code showing your problem, we may be able to help you :thup: