使 win32 window 对消息透明(点击、触摸、键盘)
Make a win32 window transparent to messages (click, touch, keyboard)
我使用本次讨论(由 wilkie 发布)中的源代码创建了一个半透明 window:
How to make an OpenGL rendering context with transparent background?
它有效,但我希望我的 window 不接收鼠标、触摸和键盘点击消息。
但最重要的是,我希望位于透明 window.
下方的应用程序能够接收到这些消息(点击、触摸、键盘)
示例:
我的透明 window (TOP_MOST) 位于 NotePad++ 之上。如果我点击我的透明 window,我希望 NotePad++ 接收到这次点击,而不是我的透明 window.
我没有在 Internet 上找到有效的答案。
我看到两种可能性:
_ 让我的 window 对所有消息透明
_ 或者我的透明 window 必须接收消息,而不是通过将它们发送到位于下面的 window 来响应和重定向它们。
这两种情况,我都不知道该怎么做:)
可能吗?
此致,
使用代码编辑:
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <windowsx.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <dwmapi.h>
#pragma comment (lib, "opengl32.lib")
#pragma comment (lib, "glu32.lib")
#pragma comment (lib, "dwmapi.lib")
#include <assert.h>
#include <tchar.h>
#ifdef assert
#define verify(expr) if(!expr) assert(0)
#else verify(expr) expr
#endif
const TCHAR szAppName[] = _T("TransparentGL");
const TCHAR wcWndName[] = _T("TransparentGL");
HDC hDC;
HGLRC m_hrc;
int w = 240;
int h = 240;
BOOL initSC() {
glEnable(GL_ALPHA_TEST);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0, 0, 0, 0);
return 0;
}
void resizeSC(int width, int height) {
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
BOOL renderSC() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glColor3f(0, 1, 1);
glBegin(GL_TRIANGLES); // Drawing Using Triangles
glColor3f(1.0f, 0.0f, 0.0f); // Set The Color To Red
glVertex3f(0.0f, 1.0f, 0.0f); // Top
glColor3f(0.0f, 1.0f, 0.0f); // Set The Color To Green
glVertex3f(-1.0f, -1.0f, 0.0f); // Bottom Left
glColor3f(0.0f, 0.0f, 1.0f); // Set The Color To Blue
glVertex3f(1.0f, -1.0f, 0.0f); // Bottom Right
glEnd();
glPopMatrix();
glFlush();
return 0;
}
BOOL CreateHGLRC(HWND hWnd) {
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_SUPPORT_COMPOSITION | // Format Must Support Composition
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
32, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
8, // An Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
24, // 16Bit Z-Buffer (Depth Buffer)
8, // Some Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
HDC hdc = GetDC(hWnd);
int PixelFormat = ChoosePixelFormat(hdc, &pfd);
if (PixelFormat == 0) {
assert(0);
return FALSE;
}
BOOL bResult = SetPixelFormat(hdc, PixelFormat, &pfd);
if (bResult == FALSE) {
assert(0);
return FALSE;
}
m_hrc = wglCreateContext(hdc);
if (!m_hrc) {
assert(0);
return FALSE;
}
ReleaseDC(hWnd, hdc);
return TRUE;
}
LRESULT CALLBACK WindowFunc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_CREATE:
break;
case WM_DESTROY:
if (m_hrc) {
wglMakeCurrent(NULL, NULL);
wglDeleteContext(m_hrc);
}
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR str, int nWinMode) {
WNDCLASSEX wc;
memset(&wc, 0, sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WindowFunc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hThisInst;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)CreateSolidBrush(0x00000000);
wc.lpszClassName = szAppName;
if (!RegisterClassEx(&wc)) {
MessageBox(NULL, _T("RegisterClassEx - failed"), _T("Error"), MB_OK | MB_ICONERROR);
return FALSE;
}
HWND hWnd = CreateWindowEx(WS_EX_APPWINDOW | WS_EX_TOPMOST | WS_EX_TRANSPARENT, szAppName, wcWndName,
WS_VISIBLE | WS_POPUP, 200, 150, w, h,
NULL, NULL, hThisInst, NULL);
if (!hWnd) {
MessageBox(NULL, _T("CreateWindowEx - failed"), _T("Error"), MB_OK | MB_ICONERROR);
return FALSE;
}
DWM_BLURBEHIND bb = { 0 };
HRGN hRgn = CreateRectRgn(0, 0, -1, -1);
bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
bb.hRgnBlur = hRgn;
bb.fEnable = TRUE;
DwmEnableBlurBehindWindow(hWnd, &bb);
CreateHGLRC(hWnd);
HDC hdc = GetDC(hWnd);
wglMakeCurrent(hdc, m_hrc);
initSC();
resizeSC(w, h);
ReleaseDC(hWnd, hdc);
MSG msg;
while (1) {
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
HDC hdc = GetDC(hWnd);
wglMakeCurrent(hdc, m_hrc);
renderSC();
SwapBuffers(hdc);
ReleaseDC(hWnd, hdc);
}
}
return (FALSE);
}
您可以添加WS_EX_LAYERED
style when creating the form, and set the opacity of the window through the SetLayeredWindowAttributes
功能。
HWND hWnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_APPWINDOW | WS_EX_TOPMOST | WS_EX_TRANSPARENT, szAppName, wcWndName,
WS_VISIBLE | WS_POPUP, 200, 150, w, h,
NULL, NULL, hThisInst, NULL);
if (!hWnd) {
MessageBox(NULL, _T("CreateWindowEx - failed"), _T("Error"), MB_OK | MB_ICONERROR);
return FALSE;
}
SetLayeredWindowAttributes(hWnd, 0, 255, LWA_ALPHA);
那么对我有用:
感谢 Zhu Song - MSFT 和 David Heffernan,这是修改后示例的完整源代码 post 在此 post 中编辑:
How to make an OpenGL rendering context with transparent background?
透明显示 OpenGL 三角形 Window 并支持点击:
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <windowsx.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <dwmapi.h>
#pragma comment (lib, "opengl32.lib")
#pragma comment (lib, "glu32.lib")
#pragma comment (lib, "dwmapi.lib")
#include <assert.h>
#include <tchar.h>
#ifdef assert
#define verify(expr) if(!expr) assert(0)
#else verify(expr) expr
#endif
const TCHAR szAppName[] = _T("TransparentGL");
const TCHAR wcWndName[] = _T("TransparentGL");
HDC hDC;
HGLRC m_hrc;
int w = 240;
int h = 240;
BOOL initSC() {
glEnable(GL_ALPHA_TEST);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0, 0, 0, 0);
return 0;
}
void resizeSC(int width, int height) {
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
BOOL renderSC() {
static float angle = 0.0f;
angle = (angle < 360.0f ) ? angle + 0.01f : 0.0f;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(angle, 0.0f, 0.0f, 1.0f);
glColor3f(0, 1, 1);
glBegin(GL_TRIANGLES); // Drawing Using Triangles
glColor4f(1.0f, 0.0f, 0.0f,0.5f); // Set The Color To Red
glVertex3f(0.0f, 1.0f, 0.0f); // Top
glColor4f(0.0f, 1.0f, 0.0f, 0.5f); // Set The Color To Green
glVertex3f(-1.0f, -1.0f, 0.0f); // Bottom Left
glColor4f(0.0f, 0.0f, 1.0f, 0.5f); // Set The Color To Blue
glVertex3f(1.0f, -1.0f, 0.0f); // Bottom Right
glEnd();
glPopMatrix();
glFlush();
return 0;
}
BOOL CreateHGLRC(HWND hWnd) {
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_SUPPORT_COMPOSITION | // Format Must Support Composition
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
32, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
8, // An Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
24, // 16Bit Z-Buffer (Depth Buffer)
8, // Some Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
HDC hdc = GetDC(hWnd);
int PixelFormat = ChoosePixelFormat(hdc, &pfd);
if (PixelFormat == 0) {
assert(0);
return FALSE;
}
BOOL bResult = SetPixelFormat(hdc, PixelFormat, &pfd);
if (bResult == FALSE) {
assert(0);
return FALSE;
}
m_hrc = wglCreateContext(hdc);
if (!m_hrc) {
assert(0);
return FALSE;
}
ReleaseDC(hWnd, hdc);
return TRUE;
}
LRESULT CALLBACK WindowFunc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
PAINTSTRUCT ps;
switch (msg) {
case WM_CREATE:
break;
case WM_DESTROY:
if (m_hrc) {
wglMakeCurrent(NULL, NULL);
wglDeleteContext(m_hrc);
}
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR str, int nWinMode) {
WNDCLASSEX wc;
memset(&wc, 0, sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WindowFunc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hThisInst;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)CreateSolidBrush(0x00000000);
wc.lpszClassName = szAppName;
if (!RegisterClassEx(&wc)) {
MessageBox(NULL, _T("RegisterClassEx - failed"), _T("Error"), MB_OK | MB_ICONERROR);
return FALSE;
}
HWND hWnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_APPWINDOW | WS_EX_TOPMOST | WS_EX_TRANSPARENT, szAppName, wcWndName,
WS_VISIBLE | WS_POPUP, 200, 150, w, h,
NULL, NULL, hThisInst, NULL);
if (!hWnd) {
MessageBox(NULL, _T("CreateWindowEx - failed"), _T("Error"), MB_OK | MB_ICONERROR);
return FALSE;
}
SetLayeredWindowAttributes(hWnd, 0, 255, LWA_ALPHA);
DWM_BLURBEHIND bb = { 0 };
HRGN hRgn = CreateRectRgn(0, 0, -1, -1);
bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
bb.hRgnBlur = hRgn;
bb.fEnable = TRUE;
DwmEnableBlurBehindWindow(hWnd, &bb);
CreateHGLRC(hWnd);
HDC hdc = GetDC(hWnd);
wglMakeCurrent(hdc, m_hrc);
initSC();
resizeSC(w, h);
ReleaseDC(hWnd, hdc);
MSG msg;
while (1) {
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
HDC hdc = GetDC(hWnd);
wglMakeCurrent(hdc, m_hrc);
renderSC();
SwapBuffers(hdc);
ReleaseDC(hWnd, hdc);
}
}
return (FALSE);
}
如果它可以帮助其他人,如果你想用QT做同样的事情:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
_glWidget = new MyOpenGLWidget(this); // derived from: public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core
setAttribute(Qt::WA_InputMethodTransparent);
setAttribute(Qt::WA_TranslucentBackground, true);
setAttribute(Qt::WA_TransparentForMouseEvents);
SetForegroundWindow((HWND)winId());
setWindowFlags(Qt::Window | Qt::FramelessWindowHint |Qt::WindowStaysOnTopHint);
ui->verticalLayout->addWidget(_glWidget);
}
我使用本次讨论(由 wilkie 发布)中的源代码创建了一个半透明 window: How to make an OpenGL rendering context with transparent background?
它有效,但我希望我的 window 不接收鼠标、触摸和键盘点击消息。 但最重要的是,我希望位于透明 window.
下方的应用程序能够接收到这些消息(点击、触摸、键盘)示例: 我的透明 window (TOP_MOST) 位于 NotePad++ 之上。如果我点击我的透明 window,我希望 NotePad++ 接收到这次点击,而不是我的透明 window.
我没有在 Internet 上找到有效的答案。 我看到两种可能性: _ 让我的 window 对所有消息透明 _ 或者我的透明 window 必须接收消息,而不是通过将它们发送到位于下面的 window 来响应和重定向它们。
这两种情况,我都不知道该怎么做:) 可能吗?
此致,
使用代码编辑:
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <windowsx.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <dwmapi.h>
#pragma comment (lib, "opengl32.lib")
#pragma comment (lib, "glu32.lib")
#pragma comment (lib, "dwmapi.lib")
#include <assert.h>
#include <tchar.h>
#ifdef assert
#define verify(expr) if(!expr) assert(0)
#else verify(expr) expr
#endif
const TCHAR szAppName[] = _T("TransparentGL");
const TCHAR wcWndName[] = _T("TransparentGL");
HDC hDC;
HGLRC m_hrc;
int w = 240;
int h = 240;
BOOL initSC() {
glEnable(GL_ALPHA_TEST);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0, 0, 0, 0);
return 0;
}
void resizeSC(int width, int height) {
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
BOOL renderSC() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glColor3f(0, 1, 1);
glBegin(GL_TRIANGLES); // Drawing Using Triangles
glColor3f(1.0f, 0.0f, 0.0f); // Set The Color To Red
glVertex3f(0.0f, 1.0f, 0.0f); // Top
glColor3f(0.0f, 1.0f, 0.0f); // Set The Color To Green
glVertex3f(-1.0f, -1.0f, 0.0f); // Bottom Left
glColor3f(0.0f, 0.0f, 1.0f); // Set The Color To Blue
glVertex3f(1.0f, -1.0f, 0.0f); // Bottom Right
glEnd();
glPopMatrix();
glFlush();
return 0;
}
BOOL CreateHGLRC(HWND hWnd) {
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_SUPPORT_COMPOSITION | // Format Must Support Composition
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
32, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
8, // An Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
24, // 16Bit Z-Buffer (Depth Buffer)
8, // Some Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
HDC hdc = GetDC(hWnd);
int PixelFormat = ChoosePixelFormat(hdc, &pfd);
if (PixelFormat == 0) {
assert(0);
return FALSE;
}
BOOL bResult = SetPixelFormat(hdc, PixelFormat, &pfd);
if (bResult == FALSE) {
assert(0);
return FALSE;
}
m_hrc = wglCreateContext(hdc);
if (!m_hrc) {
assert(0);
return FALSE;
}
ReleaseDC(hWnd, hdc);
return TRUE;
}
LRESULT CALLBACK WindowFunc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_CREATE:
break;
case WM_DESTROY:
if (m_hrc) {
wglMakeCurrent(NULL, NULL);
wglDeleteContext(m_hrc);
}
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR str, int nWinMode) {
WNDCLASSEX wc;
memset(&wc, 0, sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WindowFunc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hThisInst;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)CreateSolidBrush(0x00000000);
wc.lpszClassName = szAppName;
if (!RegisterClassEx(&wc)) {
MessageBox(NULL, _T("RegisterClassEx - failed"), _T("Error"), MB_OK | MB_ICONERROR);
return FALSE;
}
HWND hWnd = CreateWindowEx(WS_EX_APPWINDOW | WS_EX_TOPMOST | WS_EX_TRANSPARENT, szAppName, wcWndName,
WS_VISIBLE | WS_POPUP, 200, 150, w, h,
NULL, NULL, hThisInst, NULL);
if (!hWnd) {
MessageBox(NULL, _T("CreateWindowEx - failed"), _T("Error"), MB_OK | MB_ICONERROR);
return FALSE;
}
DWM_BLURBEHIND bb = { 0 };
HRGN hRgn = CreateRectRgn(0, 0, -1, -1);
bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
bb.hRgnBlur = hRgn;
bb.fEnable = TRUE;
DwmEnableBlurBehindWindow(hWnd, &bb);
CreateHGLRC(hWnd);
HDC hdc = GetDC(hWnd);
wglMakeCurrent(hdc, m_hrc);
initSC();
resizeSC(w, h);
ReleaseDC(hWnd, hdc);
MSG msg;
while (1) {
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
HDC hdc = GetDC(hWnd);
wglMakeCurrent(hdc, m_hrc);
renderSC();
SwapBuffers(hdc);
ReleaseDC(hWnd, hdc);
}
}
return (FALSE);
}
您可以添加WS_EX_LAYERED
style when creating the form, and set the opacity of the window through the SetLayeredWindowAttributes
功能。
HWND hWnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_APPWINDOW | WS_EX_TOPMOST | WS_EX_TRANSPARENT, szAppName, wcWndName,
WS_VISIBLE | WS_POPUP, 200, 150, w, h,
NULL, NULL, hThisInst, NULL);
if (!hWnd) {
MessageBox(NULL, _T("CreateWindowEx - failed"), _T("Error"), MB_OK | MB_ICONERROR);
return FALSE;
}
SetLayeredWindowAttributes(hWnd, 0, 255, LWA_ALPHA);
那么对我有用:
感谢 Zhu Song - MSFT 和 David Heffernan,这是修改后示例的完整源代码 post 在此 post 中编辑: How to make an OpenGL rendering context with transparent background?
透明显示 OpenGL 三角形 Window 并支持点击:
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <windowsx.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <dwmapi.h>
#pragma comment (lib, "opengl32.lib")
#pragma comment (lib, "glu32.lib")
#pragma comment (lib, "dwmapi.lib")
#include <assert.h>
#include <tchar.h>
#ifdef assert
#define verify(expr) if(!expr) assert(0)
#else verify(expr) expr
#endif
const TCHAR szAppName[] = _T("TransparentGL");
const TCHAR wcWndName[] = _T("TransparentGL");
HDC hDC;
HGLRC m_hrc;
int w = 240;
int h = 240;
BOOL initSC() {
glEnable(GL_ALPHA_TEST);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0, 0, 0, 0);
return 0;
}
void resizeSC(int width, int height) {
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
BOOL renderSC() {
static float angle = 0.0f;
angle = (angle < 360.0f ) ? angle + 0.01f : 0.0f;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(angle, 0.0f, 0.0f, 1.0f);
glColor3f(0, 1, 1);
glBegin(GL_TRIANGLES); // Drawing Using Triangles
glColor4f(1.0f, 0.0f, 0.0f,0.5f); // Set The Color To Red
glVertex3f(0.0f, 1.0f, 0.0f); // Top
glColor4f(0.0f, 1.0f, 0.0f, 0.5f); // Set The Color To Green
glVertex3f(-1.0f, -1.0f, 0.0f); // Bottom Left
glColor4f(0.0f, 0.0f, 1.0f, 0.5f); // Set The Color To Blue
glVertex3f(1.0f, -1.0f, 0.0f); // Bottom Right
glEnd();
glPopMatrix();
glFlush();
return 0;
}
BOOL CreateHGLRC(HWND hWnd) {
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_SUPPORT_COMPOSITION | // Format Must Support Composition
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
32, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
8, // An Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
24, // 16Bit Z-Buffer (Depth Buffer)
8, // Some Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
HDC hdc = GetDC(hWnd);
int PixelFormat = ChoosePixelFormat(hdc, &pfd);
if (PixelFormat == 0) {
assert(0);
return FALSE;
}
BOOL bResult = SetPixelFormat(hdc, PixelFormat, &pfd);
if (bResult == FALSE) {
assert(0);
return FALSE;
}
m_hrc = wglCreateContext(hdc);
if (!m_hrc) {
assert(0);
return FALSE;
}
ReleaseDC(hWnd, hdc);
return TRUE;
}
LRESULT CALLBACK WindowFunc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
PAINTSTRUCT ps;
switch (msg) {
case WM_CREATE:
break;
case WM_DESTROY:
if (m_hrc) {
wglMakeCurrent(NULL, NULL);
wglDeleteContext(m_hrc);
}
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR str, int nWinMode) {
WNDCLASSEX wc;
memset(&wc, 0, sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WindowFunc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hThisInst;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)CreateSolidBrush(0x00000000);
wc.lpszClassName = szAppName;
if (!RegisterClassEx(&wc)) {
MessageBox(NULL, _T("RegisterClassEx - failed"), _T("Error"), MB_OK | MB_ICONERROR);
return FALSE;
}
HWND hWnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_APPWINDOW | WS_EX_TOPMOST | WS_EX_TRANSPARENT, szAppName, wcWndName,
WS_VISIBLE | WS_POPUP, 200, 150, w, h,
NULL, NULL, hThisInst, NULL);
if (!hWnd) {
MessageBox(NULL, _T("CreateWindowEx - failed"), _T("Error"), MB_OK | MB_ICONERROR);
return FALSE;
}
SetLayeredWindowAttributes(hWnd, 0, 255, LWA_ALPHA);
DWM_BLURBEHIND bb = { 0 };
HRGN hRgn = CreateRectRgn(0, 0, -1, -1);
bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
bb.hRgnBlur = hRgn;
bb.fEnable = TRUE;
DwmEnableBlurBehindWindow(hWnd, &bb);
CreateHGLRC(hWnd);
HDC hdc = GetDC(hWnd);
wglMakeCurrent(hdc, m_hrc);
initSC();
resizeSC(w, h);
ReleaseDC(hWnd, hdc);
MSG msg;
while (1) {
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
HDC hdc = GetDC(hWnd);
wglMakeCurrent(hdc, m_hrc);
renderSC();
SwapBuffers(hdc);
ReleaseDC(hWnd, hdc);
}
}
return (FALSE);
}
如果它可以帮助其他人,如果你想用QT做同样的事情:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
_glWidget = new MyOpenGLWidget(this); // derived from: public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core
setAttribute(Qt::WA_InputMethodTransparent);
setAttribute(Qt::WA_TranslucentBackground, true);
setAttribute(Qt::WA_TransparentForMouseEvents);
SetForegroundWindow((HWND)winId());
setWindowFlags(Qt::Window | Qt::FramelessWindowHint |Qt::WindowStaysOnTopHint);
ui->verticalLayout->addWidget(_glWidget);
}