Как создать приложение Win11 Task-Bare, аналогичное TrafficMonitor, 360 и Taskbar-Monitor?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как создать приложение Win11 Task-Bare, аналогичное TrafficMonitor, 360 и Taskbar-Monitor?

Сообщение Anonymous »

Я заинтересован только в Win11 и выше, и реализация Win10 и ниже не находится в рамках обсуждения. https://github.com/leandrosa81/taskbar-monitorобразное/> 360: https://weishi.360.cn/clear/xfjsq/
В настоящее время я создал самое основное окно. Даже если окно установлено как верхнее окно, оно все равно будет покрыто панелью задач. < /P>

Код: Выделить всё

#include 
#include 
#include 

// The structure stores the boundaries of all displays
typedef struct {
int left;
int top;
int right;
int bottom;
} MonitorBounds;

// Callback function: Calculate the total area of all displays
BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
MonitorBounds* bounds = (MonitorBounds*)dwData;

// Update the minimum/maximum boundaries of all displays
bounds->left = min(bounds->left, lprcMonitor->left);
bounds->top = min(bounds->top, lprcMonitor->top);
bounds->right = max(bounds->right, lprcMonitor->right);
bounds->bottom = max(bounds->bottom, lprcMonitor->bottom);

return TRUE; // Continue enumerating
}

// Limit window movement within all screens and allow coverage of taskbar
void ClampWindowPosition(HWND hwnd, WINDOWPOS* wp) {
RECT windowRect;
GetWindowRect(hwnd, &windowRect);

int windowWidth = windowRect.right - windowRect.left;
int windowHeight = windowRect.bottom - windowRect.top;

// Get the regions of all displays
MonitorBounds screenBounds = { INT_MAX, INT_MAX, INT_MIN, INT_MIN };
EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)&screenBounds);

// Limit the left and top of the window
if (wp->x < screenBounds.left) {
wp->x = screenBounds.left;
}
if (wp->y < screenBounds.top) {
wp->y = screenBounds.top;
}

// Limit the right and bottom of the window (allow to overwrite the taskbar)
if (wp->x + windowWidth > screenBounds.right) {
wp->x = screenBounds.right - windowWidth;
}
if (wp->y + windowHeight > screenBounds.bottom) {
wp->y = screenBounds.bottom - windowHeight;
}
}

COLORREF transparentColor = RGB(255, 255, 255);
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
char text[100];
static int i = 0;
sprintf_s(text, "WindowProc %d\n", i++);
OutputDebugStringA(text);
switch (uMsg)
{
case WM_CREATE:
{
LONG_PTR exStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
exStyle |= WS_EX_NOPARENTNOTIFY;
exStyle |= WS_EX_LAYERED;
exStyle |= WS_EX_TOPMOST;
exStyle |= WS_EX_LEFT;
exStyle |= WS_EX_NOACTIVATE;
//exStyle |= WS_EX_TOOLWINDOW; // Set as a tool window so that icons do not appear on the taskbar
SetWindowLong(hWnd, GWL_EXSTYLE, exStyle);
SetLayeredWindowAttributes(hWnd, transparentColor, 255, LWA_COLORKEY | LWA_ALPHA);
break;
}
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);

// Text to be displayed
LPCWSTR text = TEXT("");
wchar_t buffer[1024] = { 0 };

for (int i = 0; i < 4; i++) {
wcscat_s(buffer, 1024, TEXT("This is a line of lyrics    This is a line of lyrics\n"));
}

text = buffer;

// Create Font
HFONT hFont = CreateFont(20, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, TEXT("Consolas"));
HFONT oldFont = (HFONT)SelectObject(hdc, hFont);

// Calculate text size
RECT textRect = { 0, 0, 800, 600 };
DrawText(hdc, text, -1, &textRect, DT_CALCRECT | DT_WORDBREAK);  // Only calculate size, do not draw

// Set window size
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, textRect.right - textRect.left,
textRect.bottom - textRect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);

// Set Text Color
SetTextColor(hdc, RGB(255, 0, 0));
SetBkMode(hdc, TRANSPARENT);

// Draw text (centered)
DrawText(hdc, text, -1, &textRect, DT_WORDBREAK);

// clean
SelectObject(hdc, oldFont);
DeleteObject(hFont);

EndPaint(hWnd, &ps);
break;
}
case WM_SIZE:
{
break;
}
case WM_COMMAND:
{
break;
}
case WM_LBUTTONDOWN:
{
PostMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, lParam);
break;
}
case WM_LBUTTONDBLCLK:
{
break;
}
case WM_RBUTTONDOWN:
{
int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam);
TCHAR buffer[256];
StringCchPrintf(buffer, 256, TEXT("xPos: %d, yPos: %d\nThe window is about to close"), xPos, yPos);
MessageBox(hWnd, buffer, TEXT("tip"), MB_OK);
PostMessage(hWnd, WM_CLOSE, 0, 0);
break;
}
case WM_MOUSEMOVE:
{
SetLayeredWindowAttributes(hWnd, NULL, 255, LWA_COLORKEY);
// Track the mouse and check if it moves out of the window
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = hWnd;
tme.dwHoverTime = 0;
TrackMouseEvent(&tme);
break;
}
case WM_MOUSELEAVE:
{
OutputDebugString(TEXT("The mouse has been moved out of the window!"));
SetLayeredWindowAttributes(hWnd, transparentColor, 255, LWA_COLORKEY);
break;
}
case WM_KEYDOWN:
{
break;
}
case WM_CLOSE:
{
DestroyWindow(hWnd);
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
break;
}
default:
break;
}
LPCTSTR lpWindowplace = TEXT("./WinConfig.ini");
if (uMsg == WM_CREATE) {
// Window place
WINDOWPLACEMENT wp = { 0 };
GetPrivateProfileStruct(TEXT("MainFrame"), TEXT("WindowPlace"), &wp, sizeof(wp), lpWindowplace);
SetWindowPlacement(hWnd, &wp);
}
else if (uMsg == WM_DESTROY) {
// Window place
WINDOWPLACEMENT wp = { 0 };
GetWindowPlacement(hWnd, &wp);
WritePrivateProfileStruct(TEXT("MainFrame"), TEXT("WindowPlace"), &wp, sizeof(wp), lpWindowplace);
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wcex = { 0 };
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hbrBackground = CreateSolidBrush(transparentColor);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hInstance = hInstance;
wcex.lpfnWndProc = WindowProc;
wcex.lpszClassName = TEXT("MainClass");
wcex.lpszMenuName = NULL;
wcex.style = CS_HREDRAW | CS_VREDRAW;

RegisterClassEx(&wcex);

HWND hWnd = CreateWindowEx(
WS_EX_LAYERED | WS_EX_TOPMOST,
wcex.lpszClassName, TEXT("MainFrame"), WS_OVERLAPPEDWINDOW,
1000,1350,100,100,
NULL, NULL, hInstance, NULL);
if (hWnd == NULL)
{
return 0;
}
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);

MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}

Я рассмотрел следующие соли:

. Чтобы сделать окно сверху < /li>
< /ol>
DWORD WINAPI ThreadFunction(LPVOID lpParam)
{
while (1)
{
HWND hWnd = (HWND)lpParam;
if (hWnd)
{
OutputDebugStringA("ThreadFunction");
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
Sleep(100);
}
return 0;
}
< /code>

Используйте таймер, чтобы сделать окно сверху < /p>
< /li>
Установить клавиатуру и крючки для мыши, чтобы сделать окно сверху, если есть событие, но это идеал. После долгого размышлений я до сих пор не нашел подходящего решения. Разное. Поскольку TrafficMonitor довольно сложный, я не понимаю принципов реализации ключей. Если у кого -то есть соответствующий опыт или реализовал аналогичные приложения, предоставьте некоторые идеи или пример кода, большое спасибо!

Подробнее здесь: https://stackoverflow.com/questions/795 ... 60-and-tas
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»