2014-12-03 135 views
1

我試圖在屏幕上顯示文本,在任何情況下都不可點擊,而沒有任何窗口。這個想法是能夠顯示通知。我與我想要的有點接近,但是一個真正奇怪的問題剛剛顯示。這是代碼:如何在沒有窗口的情況下繪製文本

#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; 

} 

,這是當我改變了文本設置從redblue和大小8040會發生什麼:

buggz

出於某種原因,我仍然可以看到舊的文本,重新運行程序後,這告訴我,我誤解了一些東西。有沒有更好,更乾淨的方法來做到這一點?

編輯:我檢查了Windows通知,這不是一個解決方案。想象一下,你正在玩一個全屏遊戲,並想知道一封電子郵件是否到達。另一個重要的事情是它不能點擊,所以誤點擊不會最小化你的遊戲。當你打電話時,如何讓你的應用程序最小化的Skype彈出窗口令人討厭?

+0

您正在主設備上下文中繪圖。 – mudasobwa 2014-12-03 11:58:56

+0

@mudasobwa你能否澄清你的評論?那是什麼意思? – SlySherZ 2014-12-03 12:00:09

+0

「這個想法是能夠顯示通知。」自定義通知系統非常糟糕,最好不要收到任何通知。當你的操作系統支持一個內置的系統通知機制(如Windows 10)就可以使用它。 – bames53 2014-12-03 12:01:57

回答

2

您已繞過所有的窗口/客戶端控件,因此係統不知道該區域需要清除。你需要手動告訴它,特別是因爲你沒有使用Windows消息通知機制。

之前繪製它,你想無效屏幕的一部分,告訴窗口重繪:

​​
+0

謝謝,這工作!還有一件事:有沒有辦法讓這項工作通過全屏應用程序? – SlySherZ 2014-12-03 12:56:10

+2

如果有人正在使用全屏應用,那麼他們不想看到通知。不要進入最高級別的比賽。 – 2014-12-03 13:06:06

1

我結束了運行到很多的問題,同時努力使這項工作。如果有人最終訪問此頁面尋找對我遇到的同樣問題的答案,我希望你比我有更容易的時間。這是我的代碼:

#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相關的所有內容都已實施,以避免閃爍。我還不能改變更大矩形的背景。

相關問題