IonicWind Software
February 04, 2012, 11:20:28 AM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: IonicWind Network Client/Server Library 2.0 released!
 
   Home   Help Login Register  
Pages: [1]
  Print  
Author Topic: A window with transparent caption  (Read 1146 times)
0 Members and 1 Guest are viewing this topic.
sapero
Senior Developer
Hero Member
*****
Offline Offline

Posts: 1292



« on: February 17, 2010, 01:08:29 PM »

This is a tricky code example showing the simplest method to have a window with transparent areas (using alpha channel).
The main window is layered (WS_EX_LAYERED), and opaque (alpha=255). The WS_EX_LAYERED extended styles makes possible to copy pixels from the desktop, but not including our window.
We copy the desktop pixels from a rectangle where our window resides into temporary device context, per pixel alpha-blend it with previously saved window pixels, and then the result is copied on main window.

If you add a grow (caption text) and blur (caption) effects, it will be a real aero Smiley

Code:
$include "windowssdk.inc"
$use "msimg32.lib"
$define CLIENT_ALPHA 255
$define NONCLIENT_ALPHA 128

main()
end


sub width(pointer rc),int
settype rc,WINRECT
return *rc.right - *rc.left
endsub

sub height(pointer rc),int
settype rc,WINRECT
return *rc.bottom - *rc.top
endsub

sub DrawMe(HWND hwnd, HDC hdcOrigin, HDC hdcTemp)

WINRECT rc
BLENDFUNCTION bf
HDC hdcDesktop = GetDC(0)
HDC hdcWindow =  GetWindowDC(hwnd)

bf.BlendOp = AC_SRC_OVER
bf.BlendFlags = 0
bf.AlphaFormat = AC_SRC_ALPHA
bf.SourceConstantAlpha = 255

GetWindowRect(hwnd, &rc)
int w = width(&rc)
int h = height(&rc)
' copy from desktop bitmap to temporary bitmap
BitBlt(hdcTemp, 0, 0, w, h, hdcDesktop, rc.left, rc.top, SRCCOPY)
' blend the original window bitmap onto temporary bitmap
AlphaBlend(hdcTemp, 0, 0, w, h, hdcOrigin, 0, 0, w, h, bf)
' show the result
BitBlt(hdcWindow, 0, 0, w, h, hdcTemp, 0, 0, SRCCOPY)

ReleaseDC(hwnd, hdcWindow)
ReleaseDC(0, hdcDesktop)
endsub

sub MyWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam),BOOL

HDC _hdcOrigin = GetProp(hwnd, "_hdcOrigin")' window bitmap with alpha pixels
HDC _hdcTemp = GetProp(hwnd, "_hdcTemp")

select (uMsg)

case WM_WINDOWPOSCHANGED:
pointer pos = *<WINDOWPOS>lParam
settype pos,WINDOWPOS
' if the window is showing and the variables are not initialized yet
if ((*pos.flags & SWP_SHOWWINDOW) and !_hdcOrigin)

WINDOWINFO wi
BITMAPINFOHEADER bh
pointer pixels
settype pixels, RGBQUAD
POINT pt
HDC hdc = GetWindowDC(hwnd)

wi.cbSize = len(wi)
GetWindowInfo(hwnd, wi)

ZeroMemory(&bh, len(bh))
bh.biSize     = len(bh)
bh.biWidth    = width(&wi.rcWindow)
bh.biHeight   = height(&wi.rcWindow)
bh.biPlanes   = 1
bh.biBitCount = 32

' create window bitmap
_hdcOrigin = CreateCompatibleDC(hdc)
DeleteObject(SelectObject(_hdcOrigin, CreateDIBSection(_
hdc, &bh, DIB_RGB_COLORS, &pixels, 0, 0)))
' remember current window bits
BitBlt(_hdcOrigin, 0, 0, width(&wi.rcWindow), height(&wi.rcWindow), hdc, 0, 0, SRCCOPY)

' temporary bitmap for drawing
_hdcTemp = CreateCompatibleDC(hdc)
DeleteObject(SelectObject(_hdcTemp, CreateCompatibleBitmap(_
hdc, width(&wi.rcWindow), height(&wi.rcWindow))))

ReleaseDC(0, hdc)
SetProp(hwnd, "_hdcOrigin", _hdcOrigin)
SetProp(hwnd, "_hdcTemp", _hdcTemp)

' initialize alpha pixels
int left = wi.rcClient.left - wi.rcWindow.left
int top  = wi.rcClient.top - wi.rcWindow.top
SetRect(&wi.rcClient, left, top, left+width(&wi.rcClient), top+height(&wi.rcClient))

for pt.y=0 to bh.biHeight-1

int y = bh.biHeight - pt.y - 1
pointer lineptr = &*pixels[y * bh.biWidth]
settype lineptr, RGBQUAD

for pt.x=0 to bh.biWidth-1
*lineptr[pt.x].rgbReserved = IIF(PtInRect(&wi.rcClient, pt), CLIENT_ALPHA, NONCLIENT_ALPHA)
next pt.x
next pt.y
endif
DrawMe(hwnd, _hdcOrigin, _hdcTemp)

case WM_CLOSE
DestroyWindow(hwnd)

case WM_DESTROY:
if (_hdcOrigin)
DeleteDC(_hdcOrigin)
DeleteDC(_hdcTemp)
RemoveProp(hwnd, "_hdcOrigin")
RemoveProp(hwnd, "_hdcTemp")
endif
PostQuitMessage(0)

case WM_MOVE
case& WM_NCACTIVATE
case& WM_ACTIVATE
case& WM_ACTIVATEAPP
case& WM_MOUSEACTIVATE
case& WM_NCLBUTTONDOWN
case& 0x02A2
case& WM_SIZING
DrawMe(hwnd, _hdcOrigin, _hdcTemp)
endselect
return FALSE
endsub

sub main()

MSG msg
' open invisible dialog
HWND hwnd = CreateWindowExA(WS_EX_LAYERED, WC_DIALOG, "Transparent Caption", WS_CAPTION|WS_SYSMENU|WS_BORDER,0,0,0,0,0,0,0,0)
' make it opaque
SetLayeredWindowAttributes(hwnd, 0, 255, LWA_ALPHA)
' set message callback function
SetWindowLong(hwnd, DWL_DLGPROC, &MyWndProc)
' show it
SetWindowPos(hwnd,0,200,200,400,300,SWP_NOZORDER|SWP_SHOWWINDOW)

while (GetMessage(&msg, 0, 0, 0))
TranslateMessage(&msg)
DispatchMessage(&msg)
endwhile
return 0
endsub
« Last Edit: February 17, 2010, 05:59:46 PM by sapero » Logged

pistol350
Paid Subscriber
Hero Member
*****
Offline Offline

Posts: 615



« Reply #1 on: February 17, 2010, 04:16:49 PM »

Hi Sapero!
I keep getting this message whenever i try to compile the code

"no appropriate conversion exists - )"

The message is related to the line 67 :
Code:
GetWindowInfo(hwnd, &wi)
Logged

Regards,

Peter B.
sapero
Senior Developer
Hero Member
*****
Offline Offline

Posts: 1292



« Reply #2 on: February 17, 2010, 05:57:24 PM »

Maybe I have updated my headers without uploading them, one of the old defines it (winuser.inc) as
Code:
declare import,GetWindowInfo(HWND hwnd,WINDOWINFO pwi),BOOL

So you can replace the line with
Code:
GetWindowInfo(hwnd, wi)
Logged

Haim
Paid Subscriber
Sr. Member
*****
Offline Offline

Posts: 376


« Reply #3 on: February 17, 2010, 11:39:34 PM »

Hi
It works fine on my laptop without any change.
Thanks for sharing this,
Haim
Logged
ZeroDog
Sr. Member
****
Offline Offline

Posts: 304


« Reply #4 on: February 17, 2010, 11:51:29 PM »

I wanted to try this out... but the windowssdk.inc is like 10megs and im on dial up.... lol. 
Logged
Copex
Paid Subscriber
Full Member
*****
Offline Offline

Posts: 218



« Reply #5 on: February 18, 2010, 06:17:38 AM »

I wanted to try this out... but the windowssdk.inc is like 10megs and im on dial up.... lol. 

PM your address and i will pop it on a cd and post it to you, if there is anything else you are after just let me know ill happily download and fill CD :-)
Logged

-
I really should learn how to use a spell checker! though im not sure how it will help someone who can not spell?
-
Except where otherwise noted, content Posted By Copex is
licensed under a Creative Commons Attribution 3.0 License

http://creativecommons.org/licenses/by/3.0/
pistol350
Paid Subscriber
Hero Member
*****
Offline Offline

Posts: 615



« Reply #6 on: February 18, 2010, 06:55:31 AM »

Maybe I have updated my headers without uploading them, one of the old defines it (winuser.inc) as
Code:
declare import,GetWindowInfo(HWND hwnd,WINDOWINFO pwi),BOOL

So you can replace the line with
Code:
GetWindowInfo(hwnd, wi)

This worked!
Thanks!
Logged

Regards,

Peter B.
ZeroDog
Sr. Member
****
Offline Offline

Posts: 304


« Reply #7 on: February 18, 2010, 03:11:20 PM »

Quote
PM your address and i will pop it on a cd and post it to you, if there is anything else you are after just let me know ill happily download and fill CD :-)

That is very generous of you, however,  I can either wait till im back on highspeed, or leave it downloading for an hour an a half on dial up.  I was just surprised at the size of the windowssdk.inc... whats in that thing anyways?  must be quite a bit to fill up 10 megs of source code...
Logged
sapero
Senior Developer
Hero Member
*****
Offline Offline

Posts: 1292



« Reply #8 on: February 18, 2010, 05:02:25 PM »

For today, include directory is 31MB (after a fresh cleanup), additional static libs 29MB (28,5 MB from Microsoft).
Let's see how it grows after adding dxsdk from february 2010 Smiley
« Last Edit: February 18, 2010, 05:04:26 PM by sapero » Logged

ckoehn
Full Member
***
Offline Offline

Posts: 181


« Reply #9 on: February 19, 2010, 09:57:34 AM »

sapero,

The link that I am sent to is only 11.4MB.   Is there a different one that is the latest?

Thanks,
Clint
Logged
sapero
Senior Developer
Hero Member
*****
Offline Offline

Posts: 1292



« Reply #10 on: February 19, 2010, 10:52:45 AM »

The latest pak is from 11 july 2009. I have a queued update with the latest DirectX, old directx media, and some bugfixes.
Logged

Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.15 | SMF © 2011, Simple Machines Valid XHTML 1.0! Valid CSS!


Google visited last this page January 14, 2012, 04:42:01 PM