News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Color Button text

Started by ragdog, February 26, 2016, 05:50:23 AM

Previous topic - Next topic

ragdog

Hello

I try to figure out a standart button with colored text like windows calculator. not color background

http://cdn.get-digital-help.com/calc.png

I found this site and this source cpp
https://social.msdn.microsoft.com/Forums/vstudio/en-US/7140c6f0-6c43-409e-a87a-116556d81c40/how-to-change-the-text-color-of-a-checkbox-using-common-controls-60

Here is my code ihave try to figure out but without good results

Main dialog

.elseif uMsg == WM_NOTIFY
       invoke OnNotify,hWnd,wParam,lParam
       ret


Notify code


OnNotify proc uses ebx edi hWnd:HWND,wParam:dword, lParam:dword
LOCAL sBtnText [256]:BYTE
LOCAL nLen:DWORD
LOCAL dimensions:POINT
LOCAL xPos:DWORD
LOCAL yPos:DWORD
mov edi,lParam
mov ecx,[edi].NMHDR.code
.if ecx==NM_CUSTOMDRAW
assume edi: ptr NMLVCUSTOMDRAW
.if [edi].nmcd.dwDrawStage == CDDS_PREPAINT
invoke GetWindowTextLength,[edi].nmcd.hdr.hwndFrom
.if (eax)
mov nLen,eax
invoke GetWindowText,[edi].nmcd.hdr.hwndFrom,addr sBtnText,eax
invoke GetTextExtentPoint32,[edi].nmcd.hdc,addr sBtnText,nLen,addr dimensions
invoke SetWindowText,[edi].nmcd.hdr.hwndFrom,0

;xPos = (custDraw->rc.right - dimensions.cx) / 2;
mov eax,[edi].nmcd.rc.right
mov ebx,dimensions.x
sub ebx,eax
shr ebx,1
mov xPos,eax

;(custDraw->rc.bottom - dimensions.cy) / 2;
mov eax,[edi].nmcd.rc.bottom
mov ebx,dimensions.y
sub ebx,eax
shr ebx,1
mov yPos,eax
invoke SetBkMode,[edi].nmcd.hdc, TRANSPARENT
invoke SetTextColor,[edi].nmcd.hdc,08080FFh
invoke TextOut,[edi].nmcd.hdc,xPos,yPos,addr sBtnText,nLen
.endif
mov eax,CDRF_SKIPDEFAULT
invoke SetWindowLong,hWnd,DWL_MSGRESULT,eax
ret    
.endif
mov     eax, CDRF_DODEFAULT
ret
assume edi: nothing
.endif
ret
OnNotify endp


Any a solution?

MFG,
Ragdog

HSE

To draw button there is BS_OWNERDRAW style, but I never used it. Aparently allow to access the DC.
Equations in Assembly: SmplMath

ragdog

https://msdn.microsoft.com/de-de/library/windows/desktop/bb761847%28v=vs.85%29.aspx
QuoteIf the button control is marked ownerdraw (BS_OWNERDRAW), the NM_CUSTOMDRAW notification code is not sent.

Solved was a mistake in the Subtraction

HSE

Hi ragdog!

With BS_OWNERDRAW the message is WM_DRAWITEM and structure is  DRAWITEMSTRUCT, similar to NM_CUSTOMDRAW but a little older.

Equations in Assembly: SmplMath

TouEnMasm


There is a master demo-program ButBuild.zip here:
http://www.massmind.org/images/www/asmedit/AsmMain.html
Fa is a musical note to play with CL

ragdog

@HSE

This solution works without OwnerDraw buttons


.elseif uMsg == WM_NOTIFY
invoke ColorButtonText_Notify,hWnd,wParam,lParam



ColorButtonText_Notify proc uses ebx edi hWnd:HWND,wParam:dword, lParam:dword
LOCAL sBtnText [256]:BYTE
LOCAL nLen:DWORD
LOCAL dimensions:POINT
LOCAL xPos:DWORD
LOCAL yPos:DWORD
mov edi,lParam
mov ecx,[edi].NMHDR.code
.if ecx==NM_CUSTOMDRAW
assume edi: ptr NMCUSTOMDRAW
.if [edi].dwDrawStage == CDDS_PREPAINT

invoke GetWindowTextLength,[edi].hdr.hwndFrom
.if (eax)
inc eax
mov nLen,eax
invoke GetWindowText,[edi].hdr.hwndFrom,addr sBtnText,eax
invoke GetTextExtentPoint32,[edi].hdc,addr sBtnText,nLen,addr dimensions

;xPos = (custDraw->rc.right - dimensions.cx) / 2;
mov eax,[edi].rc.right
mov ebx,dimensions.x
sub eax,ebx
shr eax,1
mov xPos,eax

;(custDraw->rc.bottom - dimensions.cy) / 2;
mov eax,[edi].rc.bottom
mov ebx,dimensions.y
sub eax,ebx
shr eax,1
mov yPos,eax
invoke SetBkMode,[edi].hdc, TRANSPARENT
invoke SetTextColor,[edi].hdc,00FF0000h
invoke TextOut,[edi].hdc,xPos, yPos,addr sBtnText,nLen
;invoke SetWindowText,[edi].nmcd.hdr.hwndFrom,0
.endif
mov eax,CDRF_SKIPDEFAULT
invoke SetWindowLong,hWnd,DWL_MSGRESULT,eax
ret    
.endif
mov     eax, CDRF_DODEFAULT
assume edi: nothing
.endif
ret
ColorButtonText_Notify endp

TouEnMasm

Works but not really good (with Windows 10)
Fa is a musical note to play with CL

HSE

Yes, I saw you write that was the substraction  :t

Just triyng to clarify things.

Intriguingly, in RadAsm the 2 mechanism are used. Drawitem is there from previous time, or NMHDR have some limitation? I don't know. 

At same time Yves was writing, perhaps DrawItem have less possibilties but it's more robust?
Equations in Assembly: SmplMath

TouEnMasm

The EWAYNE demo use subclass of button and intercept the WM_PAINT message with good results.
Look the text button in the lower left corner
Fa is a musical note to play with CL


HSE

Yves:
I support JJ rquest  :biggrin: You mean the IDE source code?

ButBuild use BS_OWNERDRAW to change background.
Equations in Assembly: SmplMath

TouEnMasm

The path is in one of my precedent post
There is a master demo-program ButBuild.zip here:
http://www.massmind.org/images/www/asmedit/AsmMain.html
direct download:
http://www.massmind.org/images/www/asmedit/files/ButBuild.zip
The button don't use the BS_OWNERDRAW
CONTROL "Text Color",IDC_BUTT04,"button",0x50010000,6,168,52,9,0x00000000
BS_OWNERDRAW   equ   < 00000000Bh>
Subclassing allow to get a dc and play with that see:

;=============================================================================
; Creates various appearances of Buttons
;=============================================================================
ButtonType  PROC hButt:DWORD, hFontT, BackClr, TextClr, szText, Bor
LOCAL     rect:RECT
LOCAL     hOldFont:DWORD, hBR, hDC

      INVOKE     GetDC, hButt
         mov     hDC, eax
         mov     eax, hButt
      .if Bor == 2 && eax == hButt4
;            mov     BackClr, 00ffffe9h
;         INVOKE     CreateSolidBrush, BackClr
         INVOKE     CreateHatchBrush, HS_DIAGCROSS, 00008000h
      .elseif Bor == 2
            mov     BackClr, 00929292h
         INVOKE     CreateSolidBrush, BackClr
      .else
         INVOKE     CreateSolidBrush, BackClr
      .endif
         mov     hBR, eax
      INVOKE     GetClientRect, hButt, addr rect
      INVOKE     FillRect, hDC, addr rect, hBR
      INVOKE     DeleteObject, hBR             ; Delete the brush handle
         mov     eax, hButt

      .if Bor == 1 && eax != hButt2 && eax != hButt4
         INVOKE     DrawEdge, hDC, addr rect, BDR_RAISEDOUTER, BF_TOPLEFT
         INVOKE     DrawEdge, hDC, addr rect, BDR_RAISEDOUTER, BF_BOTTOMRIGHT
      .elseif Bor == 2
         INVOKE     DrawEdge, hDC, addr rect, EDGE_SUNKEN, BF_RECT
      .endif
      INVOKE     SelectObject, hDC, hFontT     ; Select the font into the dc
         mov     hOldFont, eax
         mov     eax, hButt
      .if  Bor == 2 && eax == hButt4
         INVOKE     SetTextColor, hDC, 000000ffh
      .else
         INVOKE     SetTextColor, hDC, TextClr ; Set the text color
      .endif
      INVOKE     SetBkMode, hDC, TRANSPARENT   ; Set the text background to transparent
      INVOKE     DrawText, hDC, szText, -1, addr rect, DT_CENTER or DT_VCENTER or DT_SINGLELINE
      INVOKE     SelectObject, hDC, hOldFont
      INVOKE     ReleaseDC, hButt, hDC         ; Release the control dc

         xor    eax, eax
         ret
ButtonType  ENDP




Fa is a musical note to play with CL

HSE

You are wright!

The code that ButBuild generate use BS_OWNERDRAW, but ButBuild itself no. Very interesting.
Equations in Assembly: SmplMath

ragdog

Quote
Posted by: ToutEnMasm
Works but not really good (with Windows 10)

Can you make a screenshot?

Yes under xp too try to change this

invoke GetWindowTextLength,[edi].hdr.hwndFrom
.if (eax)
mov nLen,eax
inc eax
invoke GetWindowText,[edi].hdr.hwndFrom,addr sBtnText,eax

TouEnMasm

image of the button,text shown : BOUTON
Fa is a musical note to play with CL