winapi - Windows API: write to screen as on screen display -
i writing (very) small application performs minor things @ start , should write message on screen similar on-screen-display: big letters, without window, above everything, visible moment , fade away.
if possible not want create window it.
what right way this?
(i hope there no special toolkits directx, direct graphics access etc. required)
as pointed out in comments, can draw directly screen. getdc offers return appropriate device context:
hwnd [in]
a handle window dc retrieved. if value null, getdc retrieves dc entire screen.
rendering directly screen poses @ least 2 problems need addressed:
- the screen dc shared resource. whenever else renders screen (e.g. when window displayed), portion of screen gets overwritten.
- rendering destructive. when rendering device context, original contents overwritten. implement fade-out effect have save original contents (and update them dynamically other windows displayed).
both issues can solved creating window instead. window not required have border, caption bar, system menu or minimize/maximize/close buttons. appropriate window styles ws_popup | ws_visible
.
to make window show in front of else, needs marked topmost (using ws_ex_topmost
extended window style). note, places window above other non-topmost windows in z-order. still have fight other topmost windows (an arms race cannot win).
to implement transparency window must have ws_ex_layered
extended window style create layered window. alpha transparency enabled calling setlayeredwindowattributes. keep window background transparent regardless of window's alpha transparency need enable color keying. simple way set hbrbackground
member of wndclassex structure (hbrush)getstockobject(black_brush)
, , specify rgb(0, 0, 0)
crkey
argument in call setlayeredwindowattributes
.
proof of concept (error checking elided brevity):
#define strict 1 #define win32_lean_and_mean #include <sdkddkver.h> #include <windows.h> // forward declarations lresult callback wndproc( hwnd, uint, wparam, lparam ); // entry point int apientry wwinmain( hinstance hinstance, hinstance /*hprevinstance*/, lptstr /*lpcmdline*/, int ncmdshow ) {
first registering main application window class. important piece hbrbackground
member. controls background rendering, , made transparent.
const wchar_t k_wndclassname[] = l"overlaywindowclass"; // register window class wndclassexw wcex = { 0 }; wcex.cbsize = sizeof( wcex ); wcex.style = cs_hredraw | cs_vredraw; wcex.lpfnwndproc = wndproc; wcex.hinstance = hinstance; wcex.hcursor = ::loadcursorw( null, idc_arrow ); wcex.hbrbackground = (hbrush)::getstockobject( black_brush ); wcex.lpszclassname = k_wndclassname; ::registerclassexw( &wcex );
this setup code required instantiate window, , adjust it's attributes. alpha transparency enabled prepare fade-out effect, while color keying masks out areas of window aren't rendered to.
hwnd hwnd = ::createwindowexw( ws_ex_topmost | ws_ex_layered, k_wndclassname, l"overlay window", ws_popup | ws_visible, cw_usedefault, cw_usedefault, 800, 600, null, null, hinstance, null ); // make window semi-transparent, , mask out background color ::setlayeredwindowattributes( hwnd, rgb( 0, 0, 0 ), 128, lwa_alpha | lwa_colorkey );
the remainder of wwinmain
boilerplate windows application code.
::showwindow( hwnd, ncmdshow ); ::updatewindow( hwnd ); // main message loop: msg msg = { 0 }; while ( ::getmessagew( &msg, null, 0, 0 ) > 0 ) { ::translatemessage( &msg ); ::dispatchmessagew( &msg ); } return (int)msg.wparam; }
the window procedure performs simple rendering. demonstrate both alpha , key color transparency code renders white ellipse client area bounding rectangle. in addition, wm_nchittest message handled, provide simple way dragged window accross screen using mouse or pointing device. note mouse input passed window underneath areas transparent.
lresult callback wndproc( hwnd hwnd, uint message, wparam wparam, lparam lparam ) { switch ( message ) { case wm_paint: { paintstruct ps = { 0 }; hdc hdc = ::beginpaint( hwnd, &ps ); rect rc = { 0 }; ::getclientrect( hwnd, &rc ); hbrush hbrold = (hbrush)::selectobject( hdc, ::getstockobject( white_brush ) ); ::ellipse( hdc, rc.left, rc.top, rc.right, rc.bottom ); ::selectobject( hdc, hbrold ); ::endpaint( hwnd, &ps ); } return 0; case wm_nchittest: return htcaption; case wm_destroy: ::postquitmessage( 0 ); return 0; default: break; } return ::defwindowproc( hwnd, message, wparam, lparam ); }
alternative
wm_paint
handler, outputs text. it's important use text color different key color. if want use black text have use different key color. case wm_paint: { paintstruct ps = { 0 }; hdc hdc = ::beginpaint( hwnd, &ps ); rect rc = { 0 }; ::getclientrect( hwnd, &rc ); ::settextcolor( hdc, rgb( 255, 255, 255 ) ); ::setbkmode( hdc, transparent ); ::drawtextexw( hdc, l"hello, world!", -1, &rc, dt_singleline | dt_center | dt_vcenter, null ); ::endpaint( hwnd, &ps ); } return 0;
Comments
Post a Comment