The MASM Forum

General => The Campus => Topic started by: Don57 on December 07, 2012, 02:55:45 AM

Title: Just stuck on coloring hyperlink
Post by: Don57 on December 07, 2012, 02:55:45 AM
I was getting a failure on all call in WM_CTLCOLORSTATIC so i added a call to get the DC for the window, now the calls succeed but no color on the text. I am having trouble understanding the paradigm.

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

      LOCAL hdc:HDC                                                           ; handle to hyperlink dc
      LOCAL hdcStatic:HDC                                                     ; handle to device context
      LOCAL ps:PAINTSTRUCT                                                    ; pointer to paint structure

      .IF uMsg==WM_CREATE

          CALL Check_Admin                                                      ; check if program is being run as administrator
          invoke CreateWindowEx,NULL, ADDR sz_Button,ADDR sz_ButtonText,\       ; create window for button
                                WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,\
                                130,110,140,25,hWnd,BUTTON_ID,hInstance,NULL
       mov  hwndButton,eax                                                   ; save handle to button window

          invoke SendMessage, hWnd, WM_SETTEXT,0, ADDR sz_AppName               ; send event to event handler

          invoke CreateWindowEx, NULL, addr sz_AppLink, 0, WS_CHILD or WS_VISIBLE or SS_NOTIFY,\
                               10, 147, 110, 20, hWnd,0, hInstance, NULL                             ; create child window for hyperlink

          mov hStatic, eax                                                      ; handle to window

          invoke CreateFont, -12, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0         ; 12 high 1 = underlined
          invoke SendMessage, hStatic, WM_SETFONT, eax, 1                       ; send message to window to use font
          invoke LoadCursor, 0, IDC_HAND                                        ; cursor to be displayed over hyperlink
          invoke SetClassLong, hStatic, GCL_HCURSOR,eax
          invoke SetWindowText,hStatic,addr sz_Url                              ; display text for hyperlink
   
      .ELSEIF uMsg==WM_CTLCOLORSTATIC

         invoke BeginPaint,hStatic, ADDR ps
          mov    hdcStatic,eax

          invoke SetBkMode,hdcStatic,TRANSPARENT                                      ; transparent background
          invoke SetTextColor,hdcStatic,00FF901Eh                                     ; dodgerblue from css sheet on site 0x00bbggrr
          mov hBrush1,eax                                                       ; save brush

          invoke SelectObject, hdc, hBrush1
         
      .ELSEIF uMsg==WM_PAINT

          invoke BeginPaint,hWnd, ADDR ps
          mov    hdc,eax

          .IF dw_Text_Flag ==0

             invoke TextOut, hdc, TEXT_LEFT, TEXT_TOP, ADDR sz_WarningText, SIZEOF sz_WarningText-1 
             mov dw_Text_Flag, 1

          .ELSE

             invoke TextOut, hdc, TEXT2_LEFT, TEXT_TOP, ADDR sz_ProgressText, SIZEOF sz_ProgressText-1

          .ENDIF
         
          invoke EndPaint,hWnd, ADDR ps

      .ELSEIF uMsg==WM_COMMAND

          mov eax, lParam

          .IF eax==hStatic                                                                         ; if from hypertext window

             invoke ShellExecute, 0, 0, chr$("http://www.shasti.ca"), 0, 0, SW_SHOWDEFAULT    ; goto web site

          .ENDIF

          movzx edx, word ptr wParam+2

          .IF edx==BN_CLICKED

             movzx eax, word ptr wParam

             .IF eax==BUTTON_ID                                               ; was the button pressed     

                 .IF AdminFlaq==1       

                     CALL Get_ELog_List                                       ; creates Event Log text file and dumps to buffer
                     CALL Count_ELogs                                         ; count the number of log files and calcs progress increment
                     CALL Create_Progress_Bar
                 
                     mov  eax,OFFSET Clear_ELogs
                 
                     invoke CreateThread,NULL,NULL,eax,\
                            NULL,NORMAL_PRIORITY_CLASS,\
                            ADDR dw_Clear_ELogs_ID
                               
                     invoke CloseHandle,eax

                     xor eax,eax                                              ; return 0

                 .ELSE

                     invoke MessageBox, NULL,addr sz_MsgBoxAdminText, addr sz_MsgErrorCaption, MB_OK
               
                     invoke PostMessage,hWnd,WM_SYSCOMMAND,SC_CLOSE,NULL                               

                     xor eax,eax                                                               

                 .ENDIF
           
             .ENDIF

          .ENDIF



;==================== need to close brush handle before exit ====================




      .ELSEIF uMsg==WM_FINISH
           
          invoke MessageBox, NULL,addr sz_MsgBoxDoneText, addr sz_MsgDoneCaption, MB_OK

          invoke PostMessage,hWnd,WM_SYSCOMMAND,SC_CLOSE,NULL                         

          xor eax,eax                                                                   

      .ELSEIF uMsg==WM_DESTROY

          invoke PostQuitMessage,NULL

   .ELSE

          invoke DefWindowProc,hWnd,uMsg,wParam,lParam      
          ret

      .ENDIF

      xor eax,eax                                                             ; clear message

      ret

   WndProc ENDP


Title: Re: Just stuck on coloring hyperlink
Post by: jj2007 on December 07, 2012, 03:01:09 AM
You are using the LOCAL hdc for different messages. That won't work. Use
.data?
hdc   dd ?
Title: Re: Just stuck on coloring hyperlink
Post by: dedndave on December 07, 2012, 03:20:15 AM
i don't think you really need to use BeginPaint in WM_CTLCOLORSTATIC, either

you can use SetTextColor, SetBkColor
but - you must also return the background brush handle in EAX at the end of WM_CTLCOLORSTATIC

if you want underlines, that is a font issue
create a font with underline attribute set, then...
        INVOKE  SendMessage,hStatic,WM_SETFONT,hFont,TRUE
Title: Re: Just stuck on coloring hyperlink
Post by: CommonTater on December 07, 2012, 03:30:25 AM
Probably the easiest way around this is to create a brush at global scope and store it's handle.

Then for any of the WM_CTLCOLOR????? messages, you only need to return the brush handle to change the background color.

Also note that brushes are handles, which are actually pointers to structs... if you create a new handle each time, it's going to leak bits of memory when the handle is forgotten.
Title: Re: Just stuck on coloring hyperlink
Post by: Don57 on December 07, 2012, 04:40:14 AM
Needed the DC for the child window with the hyperlink. As soon as I add SendMessage the link appears to change color, hard to tell though because it is flashing very rapidly.


      .ELSEIF uMsg==WM_CTLCOLORSTATIC

          invoke GetDC, hStatic
          mov hdcStatic, eax

          invoke SetBkMode,hdcStatic,TRANSPARENT                                 ; transparent background
          invoke SetTextColor,hdcStatic,00FF901Eh                                ; dodgerblue from css sheet on site 0x00bbggrr
          mov hBrush1,eax                                                        ; save brush

          ; invoke SelectObject, hdcStatic, hBrush1

          invoke SendMessage, hStatic,WM_SETFONT,hLinkFont,TRUE

          mov eax, hBrush1
Title: Re: Just stuck on coloring hyperlink
Post by: dedndave on December 07, 2012, 05:19:16 AM
ok - that's not good, Don   :P

          invoke SetTextColor,hdcStatic,00FF901Eh                                ; dodgerblue from css sheet on site 0x00bbggrr
          mov hBrush1,eax                                                        ; save brush


SetTextColor does not return a brush handle !

CREF_BACKGROUND  EQU 888888h   ;light gray
CREF_FOREGROUND1 EQU 0FF0000h  ;blue
CREF_FOREGROUND2 EQU 0FFh      ;red
;
;
;
        .DATA?

hStatic   HWND   ?
hdcStatic HDC    ?
hBrush1   HBRUSH ?
;
;
        .CODE
;
;
    .if uMsg==WM_CTLCOLORSTATIC
        INVOKE  SetBkColor,hdcStatic,CREF_BACKGROUND
        INVOKE  SetTextColor,hdcStatic,CREF_FOREGROUND1
        mov     eax,hBrush1                                 ;return the background brush handle

    .elseif uMsg==WM_CREATE

;create static control here and store handle as hStatic

        INVOKE  GetDC,hStatic
        mov     hdcStatic,eax
        INVOKE  CreateSolidBrush,CREF_BACKGROUND
        mov     hBrush1,eax
        xor     eax,eax                                     ;return 0

    .elseif uMsg==WM_CLOSE
        INVOKE  ReleaseDC,hStatic,hdcStatic
        INVOKE  DestroyWindow,hWnd
        INVOKE  DeleteObject,hBrush1
        xor     eax,eax                                     ;return 0

    .else
        INVOKE  DefWindowProc,hWnd,uMsg,wParam,lParam       ;return DefWindowProc value

    .endif
    ret
Title: Re: Just stuck on coloring hyperlink
Post by: dedndave on December 07, 2012, 05:30:56 AM
oops - i edited the above to release the static DC before destoying the window   :(

normally, i would name the brush handle variable something like "hbrStatic"
but - hBrush1 will work, of course
Title: Re: Just stuck on coloring hyperlink
Post by: dedndave on December 07, 2012, 06:49:56 AM
ok
i played with it a little bit
i was making a mistake by creating and releasing a DC for the static control

for WM_CTLCOLORxxx messages, you should use the HDC specified in wParam

well - that simplifies our code a little
because we do not have to get/store/release the DC
we just grab wParam   :biggrin:

now - be warned - lol
changing the color of text on a button is a whole different ball of wax
it used to be very similar, before the newer versions of common controls

but, a static control is relatively easy...
Title: Re: Just stuck on coloring hyperlink
Post by: Don57 on December 07, 2012, 07:15:00 AM
The wParam got it. The color is stored as 0x00bbggrr.

Thank You. Do I ever miss the old days of writting right to the device.
Title: Re: Just stuck on coloring hyperlink
Post by: dedndave on December 07, 2012, 07:18:42 AM
in this example, i also created an underline font....

first, i used SystemParametersInfo to fill a NONCLIENTMETRICS structure
this tells us many of the user-selectable settings, including the fonts he has selected for a few things

i grab the user-selected "message" font and modify it to be underlined (simple)
then, i use CreateFontIndirect to create a font for use in the static control
when done, i use DeleteObject to release the font handle

as for the color, you can use a global variable for the foreground color
initialize it to one CREF value
once the user has clicked on the link, set that var to a second color value


EDITED:
i put the underlined font creation in a little PROC so that NONCLIENTMETRICS could be LOCAL   :P
.... without putting the LOCAL in the WndProc
Title: Re: Just stuck on coloring hyperlink
Post by: jj2007 on December 07, 2012, 09:43:47 AM
Looks good, Dave :t
Title: Re: Just stuck on coloring hyperlink
Post by: dedndave on December 07, 2012, 09:54:17 AM
well - i was in a hurry - lol
i just grabbed my little MDI window, because the code is "clean"
overkill, though

and - i didn't size the static when the MDI child is sized, etc
it could use some work - i just wanted to get Don up and running   :P
Title: Re: Just stuck on coloring hyperlink
Post by: hfheatherfox07 on December 07, 2012, 12:36:06 PM
Quote from: dedndave on December 07, 2012, 07:18:42 AM
in this example, i also created an underline font....

first, i used SystemParametersInfo to fill a NONCLIENTMETRICS structure
this tells us many of the user-selectable settings, including the fonts he has selected for a few things

i grab the user-selected "message" font and modify it to be underlined (simple)
then, i use CreateFontIndirect to create a font for use in the static control
when done, i use DeleteObject to release the font handle

as for the color, you can use a global variable for the foreground color
initialize it to one CREF value
once the user has clicked on the link, set that var to a second color value


EDITED:
i put the underlined font creation in a little PROC so that NONCLIENTMETRICS could be LOCAL   :P
.... without putting the LOCAL in the WndProc

EDIT :
I can not seem to download any attachments here .....




@dedndave
I can not seem to download your examples ...it says they are 0bytes ???
Why ?
I tried from different computers and different ways to open them
Title: Re: Just stuck on coloring hyperlink
Post by: dedndave on December 07, 2012, 01:30:29 PM
i had no trouble
perhaps you are bad mojo   :biggrin:

at any rate, you aren't missing much - lol
Title: Re: Just stuck on coloring hyperlink
Post by: hfheatherfox07 on December 07, 2012, 01:47:44 PM
Looks Like An Issue....
the other Day my Avatar disappeared ?
Title: Re: Just stuck on coloring hyperlink
Post by: Donkey on January 08, 2013, 12:58:50 PM
Your probably better off just to write a hyperlink custom control, here's an old masm example I did of a hyperlink control.

Title: Re: Just stuck on coloring hyperlink
Post by: dedndave on January 08, 2013, 01:03:26 PM
you must use environment variables for inc/lib paths   :P
after i set those, it built and ran fine   :t
Title: Re: Just stuck on coloring hyperlink
Post by: Donkey on January 08, 2013, 01:06:59 PM
Thanks Dave,

Many many years ago I wrote in MASM, not sure what the requirements were to assemble it anymore, thanks for pointing that out.
Title: Re: Just stuck on coloring hyperlink
Post by: dedndave on January 08, 2013, 02:27:47 PM
i have thought about setting mine up that way, as well
but - i want to maintain compatibility with other members, for now
Title: Re: Just stuck on coloring hyperlink
Post by: jj2007 on January 08, 2013, 08:32:08 PM
Quote from: dedndave on January 08, 2013, 01:03:26 PM
you must use environment variables for inc/lib paths   :P

That does work indeed but it creates new problems, such as being obliged to do the same for each computer you are using.

The "forum-compatible" solution is to edit Hyperlink.inc as follow:
include \masm32\include\masm32rt.inc
include windows.inc
...
includelib gdi32.lib



P.S.: Remarkably elegant solution, Edgar :t
Title: Re: Just stuck on coloring hyperlink
Post by: hfheatherfox07 on January 08, 2013, 09:41:37 PM
Quote from: dedndave on January 08, 2013, 02:27:47 PM
i have thought about setting mine up that way, as well
but - i want to maintain compatibility with other members, for now


I use RadASM IDE (that I love ),and it compiles with out paths ....
But I use Bach file too so I always add path ...