div*_*ivB 1 windows winapi screen
我正在写一个(非常)小的应用程序,它只是在开始时执行一些小的操作,应该在屏幕上写一条消息,类似于屏幕显示:大字母,没有任何窗口,高于一切,可见一段时间和然后逐渐消失.
如果可能的话我不想为它创建一个窗口.
这样做的正确方法是什么?
(我希望没有像DirectX这样的特殊工具包,需要直接图形访问等)
正如评论中指出的那样,您可以直接绘制到屏幕上.GetDC提供返回适当的设备上下文:
hWnd [in]
要检索其DC的窗口的句柄.如果此值为NULL,则GetDC将检索整个屏幕的DC.
直接渲染到屏幕会产生至少两个需要解决的问题:
这两个问题都可以通过创建一个窗口来解决.窗口不需要具有边框,标题栏,系统菜单或最小化/最大化/关闭按钮.适当的窗口样式是WS_POPUP | WS_VISIBLE.
要使窗口显示在其他所有内容之前,需要将其标记为最顶层(使用WS_EX_TOPMOST 扩展窗口样式).请注意,这会将窗口置于Z顺序中所有其他非最顶层窗口的上方.你仍然需要与其他最顶级的窗户战斗(你无法赢得的军备竞赛).
要实现透明度,窗口必须具有WS_EX_LAYERED扩展窗口样式以创建分层窗口.然后调用SetLayeredWindowAttributes启用Alpha透明度.为了使窗口背景完全透明,无论窗口的Alpha透明度如何,您还需要启用颜色键控.一种简单的方法是hbrBackground将WNDCLASSEX结构的成员设置为(HBRUSH)GetStockObject(BLACK_BRUSH),并在调用中指定RGB(0, 0, 0)为crKey参数SetLayeredWindowAttributes.
#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 ) {
Run Code Online (Sandbox Code Playgroud)
首先是注册主应用程序窗口类.重要的是hbrBackground会员.它控制背景渲染,最终将完全透明.
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 );
Run Code Online (Sandbox Code Playgroud)
这是实例化窗口所需的所有设置代码,并调整其属性.启用Alpha透明度以准备淡出效果,而颜色键控屏蔽窗口中未渲染的那些区域.
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, and mask out background color
::SetLayeredWindowAttributes( hWnd, RGB( 0, 0, 0 ), 128, LWA_ALPHA | LWA_COLORKEY );
Run Code Online (Sandbox Code Playgroud)
其余部分wWinMain是样板窗口应用程序代码.
::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;
}
Run Code Online (Sandbox Code Playgroud)
窗口过程执行简单渲染.为了演示alpha和键颜色透明度,代码呈现一个白色椭圆,客户区域为边界矩形.此外,还处理WM_NCHITTEST消息,以提供使用鼠标或其他指示设备在屏幕上拖动窗口的简单方法.请注意,鼠标输入将传递到下面的窗口,以用于完全透明的所有区域.
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 );
}
Run Code Online (Sandbox Code Playgroud)
WM_PAINT处理程序,输出文本.使用与键颜色不同的文本颜色非常重要.如果要使用黑色文本,则必须使用不同的键颜色.
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;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2552 次 |
| 最近记录: |