News:

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

Main Menu

Help Plz

Started by mabdelouahab, October 24, 2013, 12:16:15 PM

Previous topic - Next topic

dedndave

very cool, qWord   :t

i suppose that could be done with an icon or cursor, as well

mabdelouahab

Thank qWord  ;Gunther;jj2007;avcaballero;vertograd;Farabi;dedndave;all..
very nice example, qWord  ,Thank ... :eusa_clap:
I will complete my project
After that I will respond

Gunther

qWord,

rock solid.  :t

Gunther
You have to know the facts before you can distort them.

qWord

Quote from: vertograd on October 25, 2013, 08:03:29 PMwhat if to add some (color / transparency / shape) animation  to it ?
as said, recall UpdateLayeredWindow() if you wish to change the window's content. The Shape depends on the window region and what you draw with GDI+.
In the attachment the modified example with an animated "red point"  :biggrin:
include \masm32\include\masm32rt.inc
include \masm32\include\gdiplus.inc
includelib \masm32\lib\gdiplus.lib
.686
.mmx
.xmm

TIMER_INTERVAL      EQU 40 ; ms
TIMER_ID            EQU 100
INTERPOLATION_STEPS EQU 100
ANIMATION_COLOR     EQU 0ff0000h

ARGB1 MACRO alpha, red, green, blue
  EXITM % (alpha SHL 24) OR (red SHL 16) OR (green SHL 8) OR blue
ENDM

WAVE_2D struct
    n               DWORD ? ; number of interpolation steps
    lambda          REAL4 ? ; wavelength in pixels
    alpha_offset    REAl4 ? ;
    alpha_range     REAL4 ? ;
    rcp_c           REAl4 ? ; 1/c
    rcp_n           REAl4 ? ; 1/n
    omega           REAl4 ? ; 2*pi*f = 2*pi*(c/lambda)
WAVE_2D ends

.data?
    g_hInstance HINSTANCE ?
    g_ptZero    POINT <>
    g_wave      WAVE_2D <>
    g_t         DWORD ?
   
.const
    align 4
    ;/* play with the following 4 values ;-) */
    ss_lambda   REAl4 40.0  ; wavelength in pixels
    ss_c        REAL4 20.0  ; phase velocity in pixels/s
   
    ss_range    REAl4 90.0  ; linear gradient for alpha values (from center to border):
    ss_offset   REAl4 120.0 ; alpha(r,t) = ss_offset + ss_range * wave_function(r,t)
   
    ss_1        REAl4 1.0
    ss_2pi      REAl4 6.2831853071796
    ss_1Em3     REAl4 1.0E-3
   
    ClassName   db "foo xyz",0
    AppName     db "layered window, per-pixel alpha",0
.code
main proc
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL gsi:GdiplusStartupInput
LOCAL gtkn:PULONG

    mov gsi.GdiplusVersion,1
    mov gsi.DebugEventCallback,0
    mov gsi.SuppressBackgroundThread,0
    mov gsi.SuppressExternalCodecs,0
    invoke GdiplusStartup,ADDR gtkn,ADDR gsi,0

    mov wc.hInstance,rvx(g_hInstance=GetModuleHandle,0)
    mov wc.cbSize,WNDCLASSEX
    mov wc.style,CS_HREDRAW or CS_VREDRAW
    mov wc.lpfnWndProc,WndProc
    mov wc.cbClsExtra,0
    mov wc.cbWndExtra,0
    mov wc.hbrBackground,0
    mov wc.lpszMenuName,0
    mov wc.lpszClassName,OFFSET ClassName
    mov wc.hIconSm,rvx(wc.hIcon=LoadIcon,0,IDI_APPLICATION)
    mov wc.hCursor,rv(LoadCursor,0,IDC_ARROW)
    fn RegisterClassEx,&wc
    fn CreateWindowEx,WS_EX_LAYERED or WS_EX_TOPMOST,&ClassName,&AppName,WS_VISIBLE OR WS_POPUP,100,100,200,200,0,0,wc.hInstance,0

    .while TRUE
        .break .if !rv(GetMessage,&msg,0,0,0)
        fn TranslateMessage,&msg
        fn DispatchMessage,&msg
    .endw
    invoke GdiplusShutdown,gtkn
    invoke ExitProcess,msg.wParam

main endp

update_layer proc uses ebx esi edi hWnd:HWND,t:REAL4,pWave:ptr WAVE_2D
LOCAL hdc:HDC,memDC:HDC
LOCAL bitmap:PVOID
LOCAL hBmp:HBITMAP
LOCAL graphics:PVOID,path:PVOID,brush:PVOID
LOCAL blend:BLENDFUNCTION
LOCAL rect:RECT
LOCAL nx:DWORD,nxh:DWORD

    mov ebx,pWave
   
    invoke GetWindowRect,hWnd,ADDR rect
    mov edx,rect.right
    mov ecx,rect.bottom
    sub edx,rect.left
    sub ecx,rect.top
    mov rect.right,edx
    mov rect.bottom,ecx

    invoke GdipCreateBitmapFromScan0,ecx,edx,0,PixelFormat32bppPARGB,0,ADDR bitmap
    invoke GdipGetImageGraphicsContext,bitmap,ADDR graphics
    invoke GdipGraphicsClear,graphics,ARGB1(0,0,0,0)
   
    invoke GdipCreatePath,FillModeAlternate,ADDR path
    mov eax,rect.right
    .if eax > rect.bottom
        mov eax,rect.bottom
    .endif
    mov nx,eax
    shr eax,1
    mov nxh,eax
    invoke GdipAddPathEllipseI,path,0,0,nx,nx
    invoke GdipCreatePathGradientFromPath,path,ADDR brush

    mov eax,[ebx].WAVE_2D.n
    lea edi,[eax*DWORD+DWORD]
    mov esi,alloc(edi)
    mov edi,alloc(edi)

    ;/**
    ; * calculate interpolation points (alpha+color, position)
    ; * used formular:
    ; *    alpha(x,t) = A*sin(omega*(x/c+t)) + offset
    ; *             A = x/(nx/2)
    ; *         omega = 2*pi*f = 2*pi*c/lambda
    ; * [x] = pixel
    ; * [t] = s
    ; * [c] = pixel/s
    ; * [lambda] = pixel
    ; */
    cvtsi2ss xmm6,nxh
    movss xmm7,ss_1
    divss xmm7,xmm6
    mulss xmm6,[ebx].WAVE_2D.rcp_n
    xorps xmm0,xmm0
    xor ecx,ecx
    .while ecx <= [ebx].WAVE_2D.n
        movss xmm1,xmm0
        mulss xmm1,xmm7
        .if ecx == [ebx].WAVE_2D.n
            mrm REAl4 ptr [esi+ecx*REAL4],ss_1 ; ensures that the last position is 1.0
        .else
            movss REAl4 ptr [esi+ecx*REAL4],xmm1
        .endif
        movss xmm1,xmm0
        mulss xmm1,[ebx].WAVE_2D.rcp_c
        movss xmm2,xmm7
        mulss xmm2,xmm0
        addss xmm1,t
        mulss xmm1,[ebx].WAVE_2D.omega
        movss REAl4 ptr [esp-REAl4],xmm1
        fld REAl4 ptr [esp-REAL4]
        fsin
        fstp REAl4 ptr [esp-REAL4]
        movss xmm1,REAl4 ptr [esp-REAL4]
        mulss xmm1,[ebx].WAVE_2D.alpha_range
        addss xmm1,[ebx].WAVE_2D.alpha_offset
        mulss xmm1,xmm2
        cvtss2si eax,xmm1
        shl eax,24
        or eax,ANIMATION_COLOR
        mov DWORD ptr [edi+ecx*DWORD],eax
        addss xmm0,xmm6; x = x + step
        add ecx,1
    .endw

    mov eax,[ebx].WAVE_2D.n
    add eax,1
    invoke GdipSetPathGradientPresetBlend,brush,edi,esi,eax
   
    invoke GdipFillEllipseI,graphics,brush,0,0,nx,nx
    invoke GdipDeleteGraphics,graphics
    invoke GdipDeleteBrush,brush
    invoke GdipDeletePath,path
   
    free edi
    free esi
   
    mov blend.BlendOp,AC_SRC_OVER
    mov blend.BlendFlags , 0
    mov blend.AlphaFormat,AC_SRC_ALPHA
    mov blend.SourceConstantAlpha, 255
   
    fnx memDC = CreateCompatibleDC,rvx(hdc=GetDC,rv(GetDesktopWindow))
    invoke ReleaseDC,rv(GetDesktopWindow),hdc
    invoke GdipCreateHBITMAPFromBitmap,bitmap,ADDR hBmp,0
    fnx hBmp = SelectObject,memDC,hBmp

    invoke UpdateLayeredWindow,hWnd,0,ADDR rect,ADDR rect.right, memDC,addr g_ptZero, 0,addr blend, ULW_ALPHA
    invoke DeleteObject,rv(SelectObject,memDC,hBmp)
    invoke DeleteDC,memDC
    invoke GdipDisposeImage,bitmap
   
    ret
   
update_layer endp

WndProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL t:REAL4

    .if uMsg == WM_DESTROY
        invoke PostQuitMessage,NULL
    .elseif uMsg == WM_CREATE
       
        ;/* fill WAVE_2D structure (could be done before assembling) */
        mov g_wave.n,INTERPOLATION_STEPS
        mrm g_wave.lambda,ss_lambda
        mrm g_wave.alpha_offset,ss_offset
        mrm g_wave.alpha_range,ss_range
        movss xmm0,ss_c
        divss xmm0,ss_lambda
        mulss xmm0,ss_2pi
        movss g_wave.omega,xmm0
        movss xmm1,ss_1
        divss xmm1,ss_c
        movss g_wave.rcp_c,xmm1
        movss xmm0,ss_1
        cvtsi2ss xmm1,g_wave.n
        divss xmm0,xmm1
        movss g_wave.rcp_n,xmm0
       
        ;/* set layer (t=0) */
        fn update_layer,hWnd,0,&g_wave
       
        ;/* start timer */
        invoke SetTimer,hWnd,TIMER_ID,TIMER_INTERVAL,0
        mov g_t,rv(GetTickCount)
   
    .elseif uMsg == WM_TIMER && wParam == TIMER_ID
       
        ;/* update */
        invoke GetTickCount
        sub eax,g_t
        cvtsi2ss xmm0,eax
        mulss xmm0,ss_1Em3
        movss t,xmm0
        fn update_layer,hWnd,t,&g_wave

    .elseif uMsg == WM_LBUTTONDOWN
        invoke  SendMessage,hWnd,WM_NCLBUTTONDOWN,HTCAPTION,lParam
    .elseif uMsg == WM_RBUTTONUP
        invoke PostMessage,hWnd,WM_CLOSE,0,0
    .else
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam       
        ret
    .endif
    xor eax,eax
    ret
WndProc endp
end main
MREAL macros - when you need floating point arithmetic while assembling!

GoneFishing

qWord
Thank you for providing new , animated example  :t
you're very experienced in coding the  layered windows  ...
Interestingly that they (i.e. LWs) are invisible for ALT-TAB / toolbar   
May I use your source code for further experiments ?

Force

That's Great qWord,

:t

Force

qWord

Quote from: vertograd on October 26, 2013, 10:27:31 PMInterestingly that they (i.e. LWs) are invisible for ALT-TAB / toolbar
for Win7 the program appears in the task bar. However, this depends on the windows styles and if the window has an owner- or parent window.
Quote from: vertograd on October 26, 2013, 10:27:31 PMMay I use your source code for further experiments ?
yes, of course.
MREAL macros - when you need floating point arithmetic while assembling!

GoneFishing

Thanks,
I just checked out LW.EXE and it appeared in the task bar ( sorry , I made the  mistake  in my previous post  )
while GTdi01.EXE DID NOT  (Win8)

qWord

I somehow loved that example and therefore extend it a bit: now the window size, wave parameters, number of interpolation points and the color can be changed while runtime.
Be warned, at some configurations the animation will get a bit "psychedelic"  :biggrin:
Quote from: usageusage:
                     mouse wheel -> change size of window
   CONTROL         + mouse wheel -> change phase velocity
   SHIFT           + mouse wheel -> change wavelength
   CONTROL + SHIFT + mouse wheel -> change number of interpolation points (GDI+ path gradient)
   C               + mouse wheel -> change color
   SPACE                         -> show parameters
A right mouse click close the application.
MREAL macros - when you need floating point arithmetic while assembling!

dedndave

 :biggrin:
hypnotic, even
subliminal messages "send money to qWord - send money to qWord"   :P

GoneFishing

#25
...

avcaballero

Quote from: dedndave on October 29, 2013, 10:48:45 AM
hypnotic, even
subliminal messages "send money to qWord - send money to qWord"
Ha ha ha. Plz, wait a moment Dave, don't send all your money yet to qWord, that I will code another hypnotic spiral...  :greensml:

dedndave

better hurry - i have him on auto-pay, now   :biggrin:

GoneFishing

Quote from: avcaballero on October 29, 2013, 08:59:27 PM
Quote from: dedndave on October 29, 2013, 10:48:45 AM
hypnotic, even
subliminal messages "send money to qWord - send money to qWord"
Ha ha ha. Plz, wait a moment Dave, don't send all your money yet to qWord, that I will code another hypnotic spiral...  :greensml:

I suppose , sadly you'll have to include the complete source code to strengthen the psychic magnetism of the demo  ;)

qWord:

unfortunately I currently don't have all required knowledge and skills to code it myself (quickly enough)

so here're all my ideas about how to enhance this simple demo  :

  • it would be better to have a parent window (preferably full-screen with customizable background color)   for running  as many "spheres" as one may like  (let's call it the "playground"  ;) )
  • DXUT-like stuff (DirectX framework) comes to my mind  but I don't want to mention it here  ;)
  • ...

First LW tutorial
-Launch 2 instances of LW
-move the later one a few pixels to the left / right   , up / down
-enjoy 

Gunther

Very cool, qWord.  :t

Gunther
You have to know the facts before you can distort them.