The MASM Forum

General => The Campus => Topic started by: ragdog on February 26, 2016, 05:50:23 AM

Title: Color Button text
Post by: ragdog on February 26, 2016, 05:50:23 AM
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
Title: Re: Color Button text
Post by: HSE on February 26, 2016, 06:32:27 AM
To draw button there is BS_OWNERDRAW style, but I never used it. Aparently allow to access the DC.
Title: Re: Color Button text
Post by: ragdog on February 26, 2016, 06:43:32 PM
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
Title: Re: Color Button text
Post by: HSE on February 27, 2016, 01:39:33 AM
Hi ragdog!

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

Title: Re: Color Button text
Post by: TouEnMasm on February 27, 2016, 05:30:43 AM

There is a master demo-program ButBuild.zip here:
http://www.massmind.org/images/www/asmedit/AsmMain.html
Title: Re: Color Button text
Post by: ragdog on February 28, 2016, 12:58:01 AM
@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
Title: Re: Color Button text
Post by: TouEnMasm on February 28, 2016, 04:16:59 AM
Works but not really good (with Windows 10)
Title: Re: Color Button text
Post by: HSE on February 28, 2016, 04:32:00 AM
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?
Title: Re: Color Button text
Post by: TouEnMasm on February 28, 2016, 04:37:49 AM
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
Title: Re: Color Button text
Post by: jj2007 on February 28, 2016, 04:54:27 AM
Quote from: ToutEnMasm on February 28, 2016, 04:37:49 AM
The EWAYNE demo

Path?
Title: Re: Color Button text
Post by: HSE on February 28, 2016, 05:04:11 AM
Yves:
I support JJ rquest  :biggrin: You mean the IDE source code?

ButBuild use BS_OWNERDRAW to change background.
Title: Re: Color Button text
Post by: TouEnMasm on February 28, 2016, 05:20:57 AM
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




Title: Re: Color Button text
Post by: HSE on February 28, 2016, 06:33:26 AM
You are wright!

The code that ButBuild generate use BS_OWNERDRAW, but ButBuild itself no. Very interesting.
Title: Re: Color Button text
Post by: ragdog on February 29, 2016, 01:50:45 AM
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
Title: Re: Color Button text
Post by: TouEnMasm on February 29, 2016, 03:50:01 AM
image of the button,text shown : BOUTON
Title: Re: Color Button text
Post by: ragdog on February 29, 2016, 04:40:56 AM
Under Xp and Win7 looks good
Try to delete the original button Text

Title: Re: Color Button text
Post by: TouEnMasm on February 29, 2016, 05:25:40 AM
Here a perfect result even with Windows 10 (even better look than the standard button):
The code is mine.


; .if uMsg == WM_CREATE
; mov ebx,lParam
; invoke CreateWindowEx,0,ADDR bouton,NULL,50010000h,
; 50,50,100,30,hwnd,NULL,hInstance,NULL
; mov xHcontrole,eax
; invoke SetWindowLong,xHcontrole,GWL_WNDPROC,Event_xHcontrole
; mov Prev_Event_xHcontrole, eax       ;retourne l'adresse de la premiere procédure
; ButtonState dd EDGE_RAISED
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Event_xHcontrole proc hwnd:DWORD, uMsg, wParam, lParam
Local retour:DWORD,hdc:DWORD,rect:RECT
Local Ps:PAINTSTRUCT
mov retour,0 ;la plus commune des valeurs de retour

.if uMsg == WM_PAINT
invoke BeginPaint,hwnd,ADDR Ps     
mov hdc, eax
INVOKE     GetClientRect, xHcontrole, addr rect
INVOKE     SetTextColor, hdc,00FF8000h ;blue
INVOKE     SetBkMode, hdc, TRANSPARENT  ; Set the text background to transparent
INVOKE     DrawText, hdc, TXT("BOUTON"), -1, addr rect, DT_CENTER or DT_VCENTER or DT_SINGLELINE
INVOKE     DrawEdge, hdc, addr rect, ButtonState,BF_RECT
invoke EndPaint,hwnd,ADDR Ps

.else
.if uMsg == WM_LBUTTONDOWN
mov ButtonState,EDGE_SUNKEN
.endif
.if uMsg == WM_LBUTTONUP
mov ButtonState,EDGE_RAISED
.endif
invoke CallWindowProc,Prev_Event_xHcontrole,hwnd,uMsg,wParam,lParam
mov retour,eax
.endif
mov eax,retour
ret
Event_xHcontrole endp

Title: Re: Color Button text
Post by: HSE on February 29, 2016, 06:50:42 AM
Here a test of ragdog's last code, that look good in win7:

(this is compiled with MASM32 SDK, perhaps some difference with Yves' own SDK).
Title: Re: Color Button text
Post by: ragdog on March 01, 2016, 04:30:53 AM
Hello i think my code have under windows 10 a calculate rect problem
I have only test under Xp and 7 and it works perfect and i have no windows 10 to test and find a result to works on
all windows.