News:

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

Main Menu

Transparent child window

Started by Don57, February 15, 2013, 07:46:52 AM

Previous topic - Next topic

Don57

Trying to create a transparent background for the hyperlink. SetBkMode to TRANSPARENT  and WS_EX_TRANSPARENT don't work so tried
SetWindowLong and SetLayeredWindowAttributes but no luck.


.IF uMsg==WM_CREATE

         

          INVOKE CreateWindowEx, NULL, ADDR sz_AppLink, 0, WS_CHILD or WS_VISIBLE or SS_NOTIFY,\
                               10, 347, 110, 20, hWnd,0, hInstance, NULL                             
          mov hStatic, eax                                                                                                 

          INVOKE SetWindowLong,hStatic,GWL_EXSTYLE,WS_EX_LAYERED or WS_EX_TOPMOST
          INVOKE SetLayeredWindowAttributes,hStatic,0,0,LWA_ALPHA

          INVOKE CreateSolidBrush,CREF_BACKGROUND
          mov hBrush1,eax

          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

          CALL EnumerateKeys                                                                 ; enumerate uninstall keys

          xor eax,eax

      .ELSEIF uMsg==WM_CTLCOLORSTATIC

          INVOKE SetBkMode,wParam,CREF_BACKGROUND                         ; transparent background - for hyperlink
          INVOKE SetTextColor,wParam,CREF_FOREGROUND                       ; dodgerblue from css sheet on site 0x00bbggrr
          mov eax,hBrush1                                 

dedndave

we don't see how the window class is defined (sz_AppLink)
is it one of the pre-defined system classes ?
or is it a "private" class that you created ?

when you create a child window, hWndParent should be set to the handle of the parent - it seems you have that
but, hMenu should also be a unique child identifier (1 to 65535)

i would think a NULL_BRUSH is what you want if you create the class
you can also accomplish this by returning non-zero for WM_ERASEBKGND messages
it depends on the class definition
the transparent flags may work correctly if you create the window correctly, with a class that supports it

Greenhorn

You can't use WS_EX_LAYERED for child windows below Win8.
I think that a NULL_BRUSH will only work if the parent doesn't have the WS_CLIPSIBLINGS bit in its window style.
If the parent have this bit set, you'll see the desktop pixels.

Do you need "full transparency" or just an unicolor background  ?
Kole Feut un Nordenwind gift en krusen Büdel un en lütten Pint.

Don57

I created sz_AppLink just to display the hyperlink. The hypelink itself works just fine. I have no menu but from what I've read am I correct in thinking that windows will just use it as an identifier, if no menu is present. I have a very small child window with the hyperlink in it and i would like the bitmap from the parent window to come through. It is odd that I can change the color of the hyperlink, but not the background.

qWord

You may try your luck with WM_CTLCOLORSTATIC that returns a pattern brush for the corresponding bitmap region. (by replacing CreateSolidBrush() with CreatePatternBrush(hBmp_static_region)
MREAL macros - when you need floating point arithmetic while assembling!

dedndave

i can create a child window that is invisible   :P

maybe it would help if you posted a minimal example
with a main window, a child window, and the hyperlink
then - tell us what you expect to see (or better yet, google a pic for us to look at)

dedndave

ok - i get it, now
the layered style does not work for child windows, at least not in XP and earlier

i can think of 2 possible work-arounds:
1) make it a top-most parent window (use 0 as parent)   :P
2) don't make it a window at all
copy the parent window client contents into a bitmap and alpha-blend your stuff on top of it

Don57

Actually I was going to try using a bitmap for the child window background, because I have another child window that needs a backgound. I am unsure how to add it though. I added a bitmap for he parent window, using a resource file, but am unsure as how to display the ones for the child windows.

For The Main Window
------------------------

OPENING_SCREEN             EQU 1

===========================================================

      .IF uMsg==WM_CREATE

           invoke LoadBitmap, hInstance, OPENING_SCREEN 

===========================================================

       .ELSEIF uMsg==WM_PAINT

         INVOKE BeginPaint,hWnd, ADDR ps
          mov    hdc,eax
         
          invoke CreateCompatibleDC, hdc                                           ; creates DC with attrib from BeginPaint
          mov  hCompDC,eax                                                              ; save handle to buffer memory
                                                                       
          INVOKE SelectObject, hCompDC, hBitmap                               ; draw bitmap to draw buffer
          INVOKE GetClientRect, hWnd, addr rect                                  ; retrieve co-ordinate of client window area
                                                                           
          INVOKE BitBlt, hdc,0,0,rect.right,\                                         ; transfer to display buffer
                         rect.bottom,hCompDC,\
                         0,0,SRCCOPY

          INVOKE DeleteDC, hCompDC                                                 ; delete the device context
         
          INVOKE EndPaint,hWnd, ADDR ps
          xor eax,eax
          mov hBitmap, eax

===============================================================

Also I would really like some recommended reading concerning the windows event handler, seeing as how it is giving me no end of trouble
understanding what should go where. Thanks.

dedndave

          xor eax,eax
          mov hBitmap, eax

and, you were doing so well, up to that point   :icon_exclaim:
you may want to delete the gdi object handle before zeroing that out   :biggrin:
more than likely, you want to keep that handle until program termination

it would be easier to work with a full program
these snippets leave a lot of unanswered questions

but - basically, if your child is a static, you can set the SS_BITMAP style and
    INVOKE  SendMessage,hStatic,STM_SETIMAGE,IMAGE_BITMAP,hBitmap

http://msdn.microsoft.com/en-us/library/windows/desktop/bb760782%28v=vs.85%29.aspx

static controls automatically size themselves to the image size

EDIT: not sure what you mean by event handler
but, i think you are refering to WndProc, message pump (loop), etc
there is a lot of material to read, but nothing beats experience   :P
i.e., you can read all the stuff, and still not know how it works until you try it - lol

http://msdn.microsoft.com/en-us/library/windows/desktop/ms632586%28v=vs.85%29.aspx

Don57

Oops that last line was left on the clipboard.

The last line should be the xor eax, eax for the return.

It's been 15 years since I worked on a multitasking OS. In those days we would call what is now WndProc an event handler because it handles all the system events or so it seems to me.

Thanks for the answer I just figured that if there was some good reading material, not microsoft data sheets, I would be asking a lot fewer questions.

Thank You.

dedndave

there are a number of easy-to-read documents that will get you started
however, once you get past that, MSDN is probably one of the better sources
even though there is a lot to read, it is well presented, for the most part
there's no getting around the fact that it's a big OS with a lot of ground to cover

try Iczelion's Tutorials for the basics

in DOS days, i used to write a number of SYS drivers
so, WndProc isn't too hard to understand   :P
there are just a lot more "commands" (messages)

MichaelW

#11
At least under Windows 2000 and XP, returning a null brush from the WM_CTLCOLORSTATIC handler, in combination with setting the background mix mode to transparent, will correct the transparent background problem.

;==============================================================================
    include \masm32\include\masm32rt.inc
;==============================================================================
    .data
        hBmp    HBITMAP 0
        hBrush  HBRUSH  0
        bitmap  BITMAP  <>
        state   dd      0
        path    db      "\masm32\examples\exampl01\showdib\apollo11.bmp",0
    .code
;==============================================================================
;---------------------------------------------------------------------
; This procedure sizes the specified window so the client area is the
; specified width and height and returns whatever MoveWindow returns.
; Unlike AdjustWindowRect and AdjustWindowRectEx, this procedure can
; handle the WS_OVERLAPPED style.
;---------------------------------------------------------------------
SetClientSize proc uses ebx hwnd:HWND, pixelWidth:DWORD, pixelHeight:DWORD
    LOCAL rcc:RECT, rcw:RECT
    invoke GetClientRect, hwnd, ADDR rcc
    invoke GetWindowRect, hwnd, ADDR rcw
    mov ecx, rcw.right
    sub ecx, rcw.left       ; ecx = window width - 1
    mov eax, pixelWidth
    dec eax                 ; eax = pixelWidth - 1
    mov ebx, rcc.right      ; ebx = client width - 1
    sub ebx, eax            ; ebx = difference
    sub ecx, ebx            ; adjust width
    mov edx, rcw.bottom
    sub edx, rcw.top        ; edx = window height - 1
    mov eax, pixelHeight
    dec eax                 ; eax = pixelHeight - 1
    mov ebx, rcc.bottom     ; ebx = client height - 1
    sub ebx, eax            ; ebx = difference
    sub edx, ebx            ; adjust height
    invoke MoveWindow, hwnd, rcw.left, rcw.top, ecx, edx, TRUE
    ret
SetClientSize endp
;==============================================================================
DlgProc proc hwndDlg:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
  SWITCH uMsg
    CASE WM_INITDIALOG
        invoke LoadImage, 0, ADDR path, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE
        mov hBmp, eax
        invoke CreatePatternBrush, hBmp
        mov hBrush, eax
        invoke GetObject, hBmp, SIZEOF BITMAP, ADDR bitmap
        invoke SetClientSize, hwndDlg, bitmap.bmWidth, bitmap.bmHeight
    CASE WM_LBUTTONUP
        inc state
        .IF state > 2
            mov state, 0
        .ENDIF
        invoke InvalidateRect, hwndDlg, NULL, 1
    CASE WM_CTLCOLORDLG
        return hBrush
    CASE WM_CTLCOLORSTATIC
        invoke SetTextColor, wParam, 000ffffh
        SWITCH state
          CASE 0
              invoke SetBkMode, wParam, TRANSPARENT
              invoke GetStockObject, NULL_BRUSH
              ret
          CASE 1
              invoke SetBkMode, wParam, TRANSPARENT
          CASE 2
              invoke GetStockObject, NULL_BRUSH
              ret
        ENDSW
    CASE WM_COMMAND
        SWITCH wParam
          CASE IDCANCEL
              invoke DeleteObject, hBrush
              invoke EndDialog, hwndDlg, 0
        ENDSW
      CASE WM_CLOSE
        invoke DeleteObject, hBrush
        invoke EndDialog, hwndDlg, 0
    ENDSW
    return 0
DlgProc endp
;==============================================================================
start:
;==============================================================================
    Dialog "Test", "MS Sans Serif",10, \
           WS_OVERLAPPED or WS_SYSMENU or DS_CENTER, \
           1,0,0,0,0,1024
    DlgStatic "XXXXXX",SS_LEFT,5,10,50,20,1000
    invoke GetModuleHandle, NULL
    CallModalDialog eax,0,DlgProc,NULL
    exit
;==============================================================================
end start



Note that the background mix mode controls the background of the text in the static control, and the returned brush controls the background of the static control beyond the borders of the text.

Edit:

Modified the code so you can click the client area of the window to cycle through the possible combinations of setting the background mix mode to transparent and returning a null brush, to see the effect.


Well Microsoft, here's another nice mess you've gotten us into.

Don57