我正在尝试在屏幕上显示文字,在所有内容上显示文字,而不是可点击,没有任何窗口。这个想法是能够显示通知。我有点接近我想要的东西,但只是表现出一个非常奇怪的问题。这是代码:
#include <Windows.h>
int main(void){
HDC hdc = ::GetDC(0);
RECT rect;
SetTextColor(hdc, RGB(0, 0, 255));
SetBkMode(hdc, TRANSPARENT);
SetBkColor(hdc, RGB(0, 0, 0));
auto hFont = CreateFont(40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, L"Verdana");
auto hTmp = (HFONT)SelectObject(hdc, hFont);
rect.left = 40;
rect.top = 10;
while (true){
DrawText(hdc, L"THIS IS A TEXT", -1, &rect, DT_SINGLELINE | DT_NOCLIP);
Sleep(1);
}
DeleteObject(SelectObject(hdc, hTmp));
::ReleaseDC(0, hdc);
return 0;
}
当我将文字设置从red
更改为blue
并将80
更改为40
时会发生这种情况:
出于某种原因,在重新运行程序后,我仍然可以看到旧文本,这告诉我,我误解了一些东西。有更好,更清洁的方法吗?
编辑:我检查了Windows通知,这不是解决方案。想象一下,你正在玩一个全屏游戏,并想知道是否有电子邮件到达。另一个重要的事情是它无法点击,因此错误点击不会最小化您的游戏。当你接到电话时skype弹出窗口最小化你的应用程序有多烦人?答案 0 :(得分:2)
您已绕过所有窗口/客户端控件,因此系统不知道需要清除此区域。您需要手动告诉它,特别是因为您没有使用Windows消息通知机制。
在绘制之前,您想要使屏幕的那一部分无效并告诉窗口重绘它:
::InvalidateRect (0, &rect, false); // Redraw without erasing. If doesn't help, try true
::UpdateWindow (0);
while (true)...
答案 1 :(得分:2)
我最终遇到了很多问题,同时试图让这项工作成功。如果有人最终访问此页面寻找我遇到的相同问题的答案,我希望你比我更容易。这是对我有用的代码:
#include <Windows.h>
INT WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR lpCmdLine, INT nCmdShow)
{
// Define and initialize variables
HDC hdc;
HDC hdcMem;
HBITMAP hbmMem;
HANDLE hOld;
RECT rect;
SIZE sz;
int win_width = 0;
int win_height = 0;
int font_size = 20;
int location_x = 40;
int location_y = 40;
int border = font_size / 4;
int duration = 10000; // In miliseconds. The notification will always stay up more time
wchar_t* font_face = L"Consolas";
wchar_t message[100];
// Save command-line arguments to message; They are showed by the notification
MultiByteToWideChar(0, 0,
lpCmdLine,
strlen(lpCmdLine),
message,
100
);
message[strlen(lpCmdLine)] = L'\0';
// Acquire screen
hdc = ::GetDC(0);
//Create necessary font
HFONT hFont = CreateFont(font_size, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, font_face);
HFONT hTmp = (HFONT)SelectObject(hdc, hFont);
// Calculate size of the text
GetTextExtentPoint32(hdc, message, wcslen(message), &sz);
win_width = sz.cx;
win_height = sz.cy;
rect = { 0, 0, sz.cx, sz.cx };
// Create an off-screen DC for double-buffering
hdcMem = CreateCompatibleDC(hdc);
hbmMem = CreateCompatibleBitmap(hdc, win_width + 2 * border, win_height + 2 * border);
// Configure off-screen DC
SetBkMode(hdcMem, OPAQUE);
SetTextColor(hdcMem, RGB(125, 125, 255));
SetBkColor(hdcMem, RGB(0, 0, 0));
SelectObject(hdcMem, hFont);
hOld = SelectObject(hdcMem, hbmMem);
// Draw loop
for (int i = 0; i < duration; i++)
{
// Draw into hdcMem
DrawText(hdcMem, message, -1, &rect, DT_SINGLELINE);
// Transfer the off-screen DC to the screen
BitBlt(hdc, location_x, location_y, win_width + 2 * border, win_height + 2 * border, hdcMem, -5, -5, SRCCOPY);
// Don't eat all the cpu!
Sleep(1);
}
// Delete notification right after time expires
::InvalidateRect(0, &rect, false);
::UpdateWindow(0);
// Free-up the off-screen DC
SelectObject(hdcMem, hOld);
DeleteObject(hbmMem);
DeleteDC(hdcMem);
// Release created objects
DeleteObject(SelectObject(hdc, hTmp));
::ReleaseDC(0, hdc);
return 0;
}
它仍然可以改进很多。唯一出现的是带有通知的矩形。
传递给程序的参数将显示为消息。与hdcMem
相关的所有内容都已实施,以避免闪烁。我还无法改变较大矩形的背景。