bild auf dem desktop ausgeben



  • hoi 🙂

    ist es möglich ein bild auszugeben ohne grosartig fenster erstellen
    zu müssen und so? also ich möchte einfach nur ein bild auf bestimmten
    koordinaten ausgeben.

    meine frage wäre nicht nur ob es möglich wäre sondern auch wie es geht 😉
    vieleicht hab ihr ja ein gutes tut zur hand oder ein beispiel!

    thx, babel



  • Einfach das Bild als Wallpaper setzen - ansonsten: Warum willst du kein eigenes Fenster dazu erzeugen 😕



  • Vielleicht meint er ja ein unsichtbares fenster... wie es oft bei desktopscherztools angewandt wird^^

    also einfach ein Fenster mit WS_POPUP erstellen... und bei der wndclassex kein hbrBackground (also NULL da)



  • du kannst ja dein fenster unsichtbar machen und dann auf den desktop malen

    also mit GetDC(NULL) bekommst du den desktop und da dann einfach ne bmp drauf zeichnen



  • Moin, Moin...

    Als Beispiel, wie man auf den Desktop rummalt, poste ich hier ein kleines Programm aus dem Petzold:

    /*------------------------------------------------
       SCRAMBLE.C -- Scramble (and Unscramble) Screen
                     (c) Charles Petzold, 1998
      ------------------------------------------------*/
    
    #include <windows.h>
    
    #define NUM 300
    
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                        PSTR szCmdLine, int iCmdShow)
    {
         static int iKeep [NUM][4] ;
         HDC        hdcScr, hdcMem ;
         int        cx, cy ;
         HBITMAP    hBitmap ;
         HWND       hwnd ;
         int        i, j, x1, y1, x2, y2 ;
    
         if (LockWindowUpdate (hwnd = GetDesktopWindow ()))
         {
              hdcScr  = GetDCEx (hwnd, NULL, DCX_CACHE | DCX_LOCKWINDOWUPDATE) ;
              hdcMem  = CreateCompatibleDC (hdcScr) ;
              cx      = GetSystemMetrics (SM_CXSCREEN) / 10 ;
              cy      = GetSystemMetrics (SM_CYSCREEN) / 10 ;
              hBitmap = CreateCompatibleBitmap (hdcScr, cx, cy) ;
    
              SelectObject (hdcMem, hBitmap) ;
    
              srand ((int) GetCurrentTime ()) ;
    
              for (i = 0 ; i < 2   ; i++)
              for (j = 0 ; j < NUM ; j++)
              {
                   if (i == 0)
                   {
                        iKeep [j] [0] = x1 = cx * (rand () % 10) ;
                        iKeep [j] [1] = y1 = cy * (rand () % 10) ;
    
                        iKeep [j] [2] = x2 = cx * (rand () % 10) ;
                        iKeep [j] [3] = y2 = cy * (rand () % 10) ;
                   }
                   else
                   {
                        x1 = iKeep [NUM - 1 - j] [0] ;
                        y1 = iKeep [NUM - 1 - j] [1] ;
                        x2 = iKeep [NUM - 1 - j] [2] ;
                        y2 = iKeep [NUM - 1 - j] [3] ;
                   }
                   BitBlt (hdcMem,  0,  0, cx, cy, hdcScr, x1, y1, SRCCOPY) ;
                   BitBlt (hdcScr, x1, y1, cx, cy, hdcScr, x2, y2, SRCCOPY) ;
                   BitBlt (hdcScr, x2, y2, cx, cy, hdcMem,  0,  0, SRCCOPY) ;
    
                   Sleep (10) ;
              }
    
              DeleteDC (hdcMem) ;
              ReleaseDC (hwnd, hdcScr) ;
              DeleteObject (hBitmap) ;
    
              LockWindowUpdate (NULL) ;
         }
         return FALSE ;
    }
    

    Es zeigt, wie man das Handle für den Desktop erhält und den Desktop sperrt(!!) bevor man darauf rummalt.

    Ciao....



  • Wenn man z.b. auf dem Desktop ein Bild anzeigen will, dass immer im vordergrund bleibt, also auch wenn ein Fenster darübergemalt wird, müsste man ja sozusagen die WM_PAINT nachricht für den desktop mitbekommmen. gibt es die überhaupt? und wie fängt man sie ab?



  • Wenn es auch über allen Fenstern liegen soll, dann wäre es ja nich mehr auf dem Desktop (denn der wird ja von Fenstern überdeckt) 😕



  • stimmt..hab mal wieder nicht nachgedacht.
    Allerdings wäre folgendes auch ganz interessant:
    wie kann man text immer im vordergrund anzeigen, also immer in dem fenster, das sich momentan an dieser stelle befindet.
    aber das nur nebenbei...
    was ich meinte ist folgendes:
    wie finde ich heraus, dass ein fenster gerade verkleinert wurde, also der desktop neu gezeichnet werden muss, und man sozusagen seinen text wieder drüberschreiben muss?



  • Warum nimmst du nicht ein eigenes Fenster und platzierst es mit HWND_BOTTOM bzw. HWND_TOPMOST 🙄
    Ansonsten müsstest du wohl mit Sub-Classing arbeiten oder das ganze einfach als Desktop-Hintergrundbild machen 🙂



  • McFarmer schrieb:

    ...
    wie finde ich heraus, dass ein fenster gerade verkleinert wurde, also der desktop neu gezeichnet werden muss, und man sozusagen seinen text wieder drüberschreiben muss?

    Stichwort: Hook

    HHOOK SetWindowsHookEx(
    
        int idHook,	// "WH_CALLWNDPROCRET"  Hooktyp der Installiert wird
        HOOKPROC lpfn,	// Adresse zur Hookprocedure
        HINSTANCE hMod,	// HInstance des Programms
        DWORD dwThreadId 	// 0=alle oder halt entsprechende id
       );
    //-----
    LRESULT CALLBACK CallWndRetProc(
    
        int nCode,	// Hookcode (siehe MSDN WH_)
        WPARAM wParam,	// kennste
        LPARAM lParam 	// kennste auch
       );
    

    Nachrichten abfangen nachdem die Clienten die Nachricht erhalten haben.
    Auswerten und neuzeichnen.

    *****************

    Wenn du sowas wie OSD realisieren willst, also Text einblenden und später wieder aus.
    reicht folgendes:

    Text einblenden:

    char Text[] = "OSD Anzeige"; 
                     HDC dc = GetDC(NULL);
                     HFONT hFont = CreateFont(36,0,0,0,700,0,0,0,0,0,0,0,FIXED_PITCH,"Arial");
                     HGDIOBJ OldObject = SelectObject(dc,hFont);
                     SetBkMode(dc,TRANSPARENT);
                     SetTextColor(dc,RGB(0,0,0)); // schwarzer Rand
                     TextOut(dc, 41, 51, Text, strlen(Text)); // für Rand
                     TextOut(dc, 39, 51, Text, strlen(Text)); // dito
                     TextOut(dc, 41, 49, Text, strlen(Text)); // dito
                     TextOut(dc, 39, 49, Text, strlen(Text)); // dito
                     SetTextColor(dc,RGB(255,255,0)); // Textfarbe
                     TextOut(dc, 40, 50, Text, strlen(Text));
                     SelectObject(dc, OldObject);
                     ReleaseDC(NULL,dc);
    

    Ausblenden:

    RECT rc; 
                     rc.left = 35;
                     rc.right = 250;
                     rc.top = 40;
                     rc.bottom = 100;
                     RedrawWindow(NULL,&rc,NULL,RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);
    

    Wenn das Einblenden über längere Zeit statt finden soll, lass es in einer schleife

    Pseudocode:

    while (an) {
        /* PeekMessage() schleife um Nachrichten zu Verarbeiten */
        ClearDesktop() // Das Ausblenden (RedrawWindow() )
        CaptureDesktop() // GetDC(NULL) und in eine Bitmap blitten
        TextOutBitmap() // Text in Bitmap
        DrawBitmap() // Backbuffer Bitmap auf Desktop zeichnen
    }
    


  • Äh, help please:

    //hier passier der Fehler. Warum gehts net ?
    HDC dc = GetDC(NULL);

    error C2660: 'CWnd::GetDC': Funktion akzeptiert keine 1 Argumente



  • Hast du es in deinem Code auch so geschrieben wie hier, den so ist es Richtig.



  • Hallo,
    ja genau so hab ich es auch übernommen.
    Hab ich vergessen was zu includen ?
    Bekomme den Fehler wie beschrieben und bei

    ReleaseDC(NULL,dc);
    error C2660: 'CWnd::ReleaseDC': Funktion akzeptiert keine 2 Argumente
    😕



  • Entschuldigt, hat sich erledigt!

    ::GetDC(NULL)
    ::ReleaseDC(NULL,dc);



  • Ist aber Merkwürdig das du ::Funktion schreiben muß, kann es sein das du was includet hast was nicht notwendig ist?



  • Keine Ahnung. Hab sonst nichts weiter gemacht.
    Wollte nur mal den Code testen weil ich es
    sehr interessant fand. Komisch warum es nur
    so geht 😕 Aber vielen Dank 🙂



  • Du scheinst MFC zu verwenden - rufst du denn den Code innerhalb einer Klasse auf, oder hast du irgendwie ein using namespace o.ä. verwendet 😕


Anmelden zum Antworten