News:

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

Changing background in TrackBar Control?

Started by axus, January 30, 2006, 05:14:34 PM

Previous topic - Next topic

axus

 :8) How changed background color in TrackBar Control?

P1


msmith

axus,

Actually, it is similar to changing the background color of a static, edit, radiobuttons, or checkboxes. Without going into all of the details, I set flags in each control's descriptor that are monitored in the event handler. A portion of the event handler follows:


cmp ebx,WM_CTLCOLORSTATIC
je !CtlColorChange
cmp ebx,WM_CTLCOLOREDIT
je !CtlColorChange
cmp ebx,WM_CTLCOLORBTN
je !CtlColorChange
cmp ebx,WM_CTLCOLORSCROLLBAR
je !CtlColorChange
cmp ebx,WM_CTLCOLORLISTBOX
je !CtlColorChange
cmp ebx,WM_CTLCOLORDLG
je !CtlColorChange
.
.
.
invoke CreateSolidBrush,[!dsBackColor]
mov [!Brush],eax
invoke SetBkColor,[wparam],[!dsBackColor]
mov eax,[!Brush]


After this, you may need to do an invalidaterect or setwindowpos for the change to "take" Since I am sending all 6 ctlcolor messages to the same place, I don't know which one affects the trackbar, but I believe it is the scrollbar one.

So, unlike some controls where you can just send a message to change the color, this set of controls makes it much more involved to do so.

Mike

axus

Quote from: msmith on January 30, 2006, 11:36:10 PM
axus,

Actually, it is similar to changing the background color of a static, edit, radiobuttons, or checkboxes. Without going into all of the details, I set flags in each control's descriptor that are monitored in the event handler. A portion of the event handler follows:


cmp ebx,WM_CTLCOLORSTATIC
je !CtlColorChange
cmp ebx,WM_CTLCOLOREDIT
je !CtlColorChange
cmp ebx,WM_CTLCOLORBTN
je !CtlColorChange
cmp ebx,WM_CTLCOLORSCROLLBAR
je !CtlColorChange
cmp ebx,WM_CTLCOLORLISTBOX
je !CtlColorChange
cmp ebx,WM_CTLCOLORDLG
je !CtlColorChange
.
.
.
invoke CreateSolidBrush,[!dsBackColor]
mov [!Brush],eax
invoke SetBkColor,[wparam],[!dsBackColor]
mov eax,[!Brush]


After this, you may need to do an invalidaterect or setwindowpos for the change to "take" Since I am sending all 6 ctlcolor messages to the same place, I don't know which one affects the trackbar, but I believe it is the scrollbar one.

So, unlike some controls where you can just send a message to change the color, this set of controls makes it much more involved to do so.

Mike


Thank you very much!!!
Thanks!!!!


msmith

axus,

Quote
After this, you may need to do an invalidaterect or setwindowpos for the change to "take" Since I am sending all 6 ctlcolor messages to the same place, I don't know which one affects the trackbar, but I believe it is the scrollbar one.

I did some testing and found that the sure way to get the color change to "take" is to do a SetFocus on the trackbar after doing the change. The other controls colored this way do not seem to require the SetFocus. The invalidaterect or setwindowpos do not always work.

Mike

zooba

InvalidateRect is the most correct way to do it. Don't supply a rectangle, just the control handle (that will mark the entire control to be redrawn) and make sure that you pass TRUE as the third parameter (to erase the background).

Cheers,

Zooba

msmith

Hi Zooba,

InvalidateRect just doesn't work here consistantly. SetFocus does... every time.

Mike


zcoder

msmith ,
are you sure? I use it in zeta32 to change the controls color
after you use Invalidaterect windows may or may not do it at
that time is is put on a Que, you can force it to do it NOW
by using UpdateWindow right after InvalidateRect


Zcoder....
Back in 1979, My computer ran so fine.
And there was no such thing,
As a Microsoft Crashed Machine.
http://zcoder.110mb.com
http://www.dietzel.com/partner/idevaffiliate.php?id=345_6  Free Domain Names

msmith

zcoder,

I think I see the problem between what you and zooba say and what I see here.

The problem is that my code is generated by my compiler and the user of the compiler can't be concerned with how the color really is changed. My mechanism allows it to appear to the user that all color changes are "equal". As you must be aware, changing the color of a static, for example, is much more involoved than changing the color of a progressbarr. In the following code snippets I show a progressbar, an edit, and a slider having their color changed. In the case of the progressbar it is as simple as sending 1 message. In the case of the edit and slider, I set up flag bits in the control's descriptor status word that will be examined later in the event processor. If the event processor sees these bits set a certain way, it will create a brush etc. I don't do the InvalidateRect there. I do it earlier before the event processor is entered as shown below. Maybe if I would do the InvalidateRect later afer the brush is used, it would work fine for sliders also. Since what I have is working fine already, I will just leave it as is. The statics, buttons, combos, and edits all work fine as the edit shown below, but the slider only works with the SetFocus as shown.



; LN:34 pb.backcolor=$ffff
mov edi,!pb
mov eax,65535
invoke SendMessage, dword [edi+HandleOffs],PBM_SETBKCOLOR,0,eax

; LN:150 TextBox.BACKCOLOR=$800080
mov edi,!TextBox
mov eax,8388736
bts dword [edi+StatusOffs],WinChangeBackColor
mov dword [edi+BackColorOffs],eax
invoke InvalidateRect, dword [edi+HandleOffs],NULL,TRUE

; LN:179 sl1.backcolor=$ff0080
mov edi,!sl1
mov eax,16711808
bts dword [edi+StatusOffs],WinChangeBackColor
mov dword [edi+BackColorOffs],eax
invoke SetFocus, dword [edi+HandleOffs]


With all of that considered, zooba is likely correct (as usual) <g>.

Thanks,

Mike

zooba

There should be little need to worry about the code generated. If I were working on this project (and I presently am working on a similar one) I would create control specific functions (contained in a table with the offset based on the control type) which do all the work required to change the colour.

That way, simple ones are easily dealt with (and ones that work the same can all use the same function) whereas the more complicated ones can contain the extra required calls. InvalidateRect followed by UpdateWindow should be sufficient in all cases to redraw the control. Using SetFocus is asking for trouble - what happens if the colour changes based on what a user types in a textbox? Every keypress could redirect the focus to the trackbar :eek

BTW: or DWORD [edi+StatusOffs], (1 SHL WinChangeBackColor) will be far more efficient than using BTS, mostly good practice rather than optimisation. GUI stuff can't really by optimised by 3rd party developers (ie. not Microsoft)
(your constants could also be modified to represent a single bit <ie. 0001h, 0002h, 0004h, 0008h, 0010h, etc> to simplify their behaviour - you can use and <operand>, NOT WinChangeBackColor to clear a bit :U)

msmith

zooba,

Quote
There should be little need to worry about the code generated. If I were working on this project (and I presently am working on a similar one) I would create control specific functions (contained in a table with the offset based on the control type) which do all the work required to change the colour.

I have multilevel indirect tables to drive my function selection for code generation. This is the mechanism that makes color selection (and every other function) look more like VB than the API, which is what my users expect and want.

Quote
That way, simple ones are easily dealt with (and ones that work the same can all use the same function) whereas the more complicated ones can contain the extra required calls. InvalidateRect followed by UpdateWindow should be sufficient in all cases to redraw the control. Using SetFocus is asking for trouble - what happens if the colour changes based on what a user types in a textbox? Every keypress could redirect the focus to the trackbar

I have tried every way I can thaink of to prove you right about "InvalidateRect followed by UpdateWindow should be sufficient...". It just isn't so for tarackbar. I even set a timer to 500MS and then did the InvalidateRect followed by UpdateWindow after setting the color. No good. I put in a manual SetFocus either before or after the timeout and it works evey time. You should be able to prove this for yourself. I had a similar discussion with Donkey on another forum over 2 years ago. I believe he thought that SetWindowPos might help. I did sometimes but not all times. I'm thinking about doing a GetFocus-Setfocus (trackbar)-SetFocus(saved value), but this would change the textbox cursor position.

Quote
BTW: or DWORD [edi+StatusOffs], (1 SHL WinChangeBackColor) will be far more efficient than using BTS, mostly good practice rather than optimisation. GUI stuff can't really by optimised by 3rd party developers (ie. not Microsoft)
(your constants could also be modified to represent a single bit <ie. 0001h, 0002h, 0004h, 0008h, 0010h, etc> to simplify their behaviour - you can use and <operand>, NOT WinChangeBackColor to clear a bit

My constants are single bit so I could go either way. Apparently the relative timings of the X86 processors are a moving target based on the generation. I have seen somewere that on the P4 processors are faster at mul 256 then shl 8. This must mean that there is no barrel shifter in the newer processor or that there is a lookup table for MUL. In the old days, multiply was done by a shift/add algorithm in a loop and was ALWAYS slower than shift n bits. With a barrel shifter the shift would win hands down.

Regards,

Mike


Note: It just occured to me what you meant by single bit constants. Are you referring to one bit per entity (byte word, dword)?  My constants are NOT single bit in that sense. My descriptors are already growing to fast to suit me. If I go to single bit constants in the way I think you mean, the descriptor size will grow even faster.

zooba

I wasn't at any point inferring that your end-users would have more to worry about. I was suggesting that as part of your generated code you could include a static library containing 'property let/set' functions. On compilation only modules which are used are actually included and your code generation then comes down to "call the method for <control type here> to do <action type here>". IMHO this will be more expandable then inline code generation, however it is your project and your decision.

With regards to bit manipulation commands I appear to have been mistaken. BTS is in fact faster than OR. The same with BTC and AND NOT. With a memory operand as the destination (to have it's bit set/cleared) they are the same. (This was a contrived example I tested though of 32-consecutive BTS or OR instructions, so perhaps BTS pairs better) In any case, what you are currently doing with your status constants is fine. I'll just go hide in the corner now :wink :U

msmith

zooba,

No need to hide in the corner! I always appreciate your help and that of others. Maybe, just maybe, someday I can return the favor and help you too.

Compared to my 35 years experience with mainframes, minicomputers, and other microcomputers, the documentation of the Intel processors and especially the Windows API are inconsistant at best. If the processor itself and the API were orthagonal, this would not be such a big problem. In my opinion, much of the traffic on this great forum as well as others is a byproduct of this inconsistancy. Since this is the processor and operating system that the public is using, we all have to make the best of it.

Regards,

Mike