15,980
社区成员
发帖
与我相关
我的任务
分享
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
static LRESULT CALLBACK MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK LyricsWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK ToolWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
static HWND gs_hwndLyrics = NULL; // 歌词窗口
static HWND gs_hwndTools = NULL; // 辅助窗口
static HFONT gs_hFont = NULL;
//#define USE_WIN32_CONSOLE
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpszCmdLine, int iCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASS wndcls;
#ifdef USE_WIN32_CONSOLE
AllocConsole();
_tfreopen(TEXT("CONOUT$"), TEXT("w"), stdout);
#endif
// 这是主窗口,相当于播放器窗口
wndcls.style = CS_HREDRAW | CS_VREDRAW;
wndcls.lpfnWndProc = &MainWndProc;
wndcls.cbClsExtra = 0;
wndcls.cbWndExtra = 0;
wndcls.hInstance = hInstance;
wndcls.hIcon = NULL;
wndcls.hCursor = LoadCursor(NULL, IDC_ARROW);
wndcls.hbrBackground = NULL;
wndcls.lpszMenuName = NULL;
wndcls.lpszClassName = TEXT("TestWindow");
if (!RegisterClass(&wndcls))
{
return 0;
}
hwnd = CreateWindowEx(0, wndcls.lpszClassName, TEXT("TestWindow"),
WS_POPUP | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX,
0, 0, 200, 200,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
#ifdef USE_WIN32_CONSOLE
fclose(stdout);
FreeConsole();
#endif
return (int)msg.wParam;
}
// 主窗口回调函数
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
RECT screenRect;
int x, y, width = 900, height = 150;
WNDCLASS wndcls;
gs_hFont = CreateFont(64, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE,
GB2312_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, FF_MODERN, TEXT("黑体"));
// 歌词窗口跟辅助窗口共用一个类
wndcls.style = CS_HREDRAW | CS_VREDRAW;
wndcls.lpfnWndProc = &DefWindowProc; // 先用一下默认回调函数
wndcls.cbClsExtra = 0;
wndcls.cbWndExtra = 0;
wndcls.hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
wndcls.hIcon = NULL;
wndcls.hCursor = LoadCursor(NULL, IDC_SIZEALL);
wndcls.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); // 黑色背景
wndcls.lpszMenuName = NULL;
wndcls.lpszClassName = TEXT("LyricsWindow");
RegisterClass(&wndcls);
// 计算坐标,将两窗口放在桌面底部
SystemParametersInfo(SPI_GETWORKAREA, 0, &screenRect, 0);
x = (screenRect.right - screenRect.left - width) >> 1;
y = screenRect.bottom - screenRect.top - height;
// 创建歌词窗口
gs_hwndLyrics = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST,
wndcls.lpszClassName, NULL,
WS_POPUP | WS_CLIPSIBLINGS,
x, y, width, height, NULL, NULL, wndcls.hInstance, NULL);
// 设置新回调函数
SetWindowLong(gs_hwndLyrics, GWL_WNDPROC, (LONG)&LyricsWndProc);
// 显示歌词窗口,以得到一条WM_PAINT消息
ShowWindow(gs_hwndLyrics, SW_SHOWNORMAL);
// 设置上WS_EX_LAYERED扩展风格,如果创建时就已设置,那么就收不到WM_PAINT消息了
SetWindowLong(gs_hwndLyrics, GWL_EXSTYLE, (LONG)
(WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW));
// 设置黑色为透明色
SetLayeredWindowAttributes(gs_hwndLyrics, RGB(0, 0, 0), 0, LWA_COLORKEY);
// 创建辅助窗口
gs_hwndTools = CreateWindowEx(WS_EX_TOPMOST | WS_EX_LAYERED | WS_EX_TOOLWINDOW,
wndcls.lpszClassName, NULL,
WS_POPUP | WS_CLIPSIBLINGS | WS_THICKFRAME,
x, y, width, height, NULL, NULL, wndcls.hInstance, NULL);
// 设置新回调函数
SetWindowLong(gs_hwndTools, GWL_WNDPROC, (LONG)&ToolWndProc);
// 设置透明度
SetLayeredWindowAttributes(gs_hwndTools, 0, 64, LWA_ALPHA);
}
return 0;
case WM_PAINT:
{
static TCHAR str[] = TEXT("这是主窗口");
HDC hdc;
PAINTSTRUCT paintStruct;
hdc = BeginPaint(hwnd, &paintStruct);
SetTextColor(hdc, RGB(0xFF, 0, 0));
SetBkMode(hdc, TRANSPARENT);
TextOut(hdc, 0, 0, str, _tcslen(str));
EndPaint(hwnd, &paintStruct);
}
return 0;
case WM_DESTROY:
DeleteObject(gs_hFont);
DestroyWindow(gs_hwndLyrics);
DestroyWindow(gs_hwndTools);
PostQuitMessage(0);
return 0;
default:
break;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
// 歌词窗口回调函数
LRESULT CALLBACK LyricsWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static TCHAR str[] = TEXT("这是歌词窗口");
switch (message)
{
case WM_PAINT:
{
HDC hdc;
PAINTSTRUCT paintStruct;
hdc = BeginPaint(hwnd, &paintStruct);
SetTextColor(hdc, RGB(0, 0, 0xFF));
SetBkMode(hdc, TRANSPARENT);
SelectObject(hdc, gs_hFont);
TextOut(hdc, 160, 20, str, _tcslen(str));
EndPaint(hwnd, &paintStruct);
}
return 0;
case WM_MOUSEMOVE: // 检测到鼠标移动,就将辅助窗口显示出来
ShowWindow(gs_hwndTools, SW_SHOWNORMAL);
return 0;
case WM_SIZE:
case WM_MOVE: // 手动重绘
{
HDC hdc = GetDC(hwnd);
SetTextColor(hdc, RGB(0, 0, 0xFF));
SetBkMode(hdc, TRANSPARENT);
SelectObject(hdc, gs_hFont);
TextOut(hdc, 160, 20, str, _tcslen(str));
ReleaseDC(hwnd, hdc);
}
return 0;
case WM_CLOSE:
ShowWindow(hwnd, SW_HIDE);
return 0;
case WM_DESTROY:
return 0;
default:
break;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
// 辅助窗口回调函数
LRESULT CALLBACK ToolWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static TRACKMOUSEEVENT mouseEvent = { sizeof(TRACKMOUSEEVENT), 0, NULL, HOVER_DEFAULT };
static int iTrackedFlag = 0; // -1 客户区 0 无 1 非客客户区
switch (message)
{
case WM_LBUTTONDOWN: // 欺骗windows,让它以为在标题栏上,从而可以移动窗口
return DefWindowProc(hwnd, WM_SYSCOMMAND, (WPARAM)(SC_MOVE | HTCAPTION), 0);
case WM_NCMOUSEMOVE:
if (iTrackedFlag == -1) // 取消监测客户区
{
//printf("cancel track c\n");
mouseEvent.hwndTrack = hwnd;
mouseEvent.dwFlags = TME_LEAVE | TME_CANCEL;
TrackMouseEvent(&mouseEvent);
iTrackedFlag = 0;
}
if (iTrackedFlag == 0) // 监测非客户区
{
//printf("start track c\n");
mouseEvent.hwndTrack = hwnd;
mouseEvent.dwFlags = TME_LEAVE | TME_NONCLIENT;
TrackMouseEvent(&mouseEvent);
SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, NULL, 0);
iTrackedFlag = 1;
}
return 0;
case WM_MOUSEMOVE:
if (iTrackedFlag == 1) // 取消监测非客户区
{
//printf("cancel track nc\n");
mouseEvent.hwndTrack = hwnd;
mouseEvent.dwFlags = TME_LEAVE | TME_NONCLIENT | TME_CANCEL;
TrackMouseEvent(&mouseEvent);
iTrackedFlag = 0;
}
if (iTrackedFlag == 0) // 监测客户区
{
//printf("start track c\n");
mouseEvent.hwndTrack = hwnd;
mouseEvent.dwFlags = TME_LEAVE;
TrackMouseEvent(&mouseEvent);
SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, NULL, 0);
iTrackedFlag = -1;
}
return 0;
case WM_MOUSELEAVE: // 离开客户区
// 监测非客户区
//printf("start track nc\n");
mouseEvent.hwndTrack = hwnd;
mouseEvent.dwFlags = TME_LEAVE | TME_NONCLIENT;
TrackMouseEvent(&mouseEvent);
SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, NULL, 0);
iTrackedFlag = 1;
return 0;
case WM_NCMOUSELEAVE: // 离开非客户区
//printf("end track nc\n");
ShowWindow(hwnd, SW_HIDE); // 隐藏辅助窗口
SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, FALSE, NULL, 0);
iTrackedFlag = 0;
return 0;
case WM_MOVING: // 移动
case WM_SIZING: // 缩放
{
LPCRECT pRect = (LPCRECT)lParam;
// 使得正在移动/缩放时,辅助窗口不要隐藏
ShowWindow(hwnd, SW_SHOWNORMAL);
// 使歌词窗口随辅助窗口一起移动/缩放
MoveWindow(gs_hwndLyrics, pRect->left, pRect->top,
pRect->right - pRect->left,
pRect->bottom - pRect->top, TRUE);
}
return TRUE;
case WM_KILLFOCUS: // 失去焦点,则隐藏辅助窗口
ShowWindow(hwnd, SW_HIDE);
return 0;
case WM_CLOSE:
ShowWindow(hwnd, SW_HIDE);
return 0;
default:
break;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}