auf Desktop zeichnen



  • Hallo Spezialisten!

    In den letzten Tagen habe ich ein kleines Grafikprogramm geschrieben.
    Nun bin ich auf den Zweig gekommen das man dies doch eigentlich nicht nur auf eine Form zeichnen könnte, sondern auch direkt als bewegstes Bild auf den Desktop... 🙂

    Deshalb habe ich mich hier im Forum mal umgesehen, habe alber nichts konkretes für die VCL gefunden. Evtl. liegt das aber auch daran, das mir kein gescheites Lemma unter dem ich suchen soll einfällt.

    Hat jemand von euch da schon mal was vetsucht oder ne Erfahrung?
    Ich danke schonmal!

    MfG
    Tippo



  • gleich sry wegen dem doppelpost. aber mich interessiert das thema wirklich!

    Vlt kann mir jemand ja ein besseres Lemma zur Suche nennen!
    Danke!

    Tippo



  • Was genau meinst du mit "bewegtes Bild auf dem Desktop"?
    Du könntest ein rahmenloses Fenster erzeugen, und dort dann deine Sachen reinzeichnen.



  • DC(0) aber bei deiner Frage bist du besser im WinAPI Forum aufgehoben



  • Dieser Thread wurde von Moderator/in akari aus dem Forum VCL/CLX (Borland C++ Builder) in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • DC(0) ???

    Ich denke mal man kann sich die Grafik am besten als Radar vorstellen. Und das möchte ich am liebsten nicht mehr mit Canvas->Form1 auf das Form sondern auf den Desktop zeichnen.
    Aber das Bild verändert sich halt.

    Wie kann ich sowas realisieren?

    MfG
    Tippo



  • Das Fenster für den Desktop bekommst du so:

    GetDesktopWindow()
    ➡ http://msdn2.microsoft.com/en-us/library/ms633504.aspx

    Aber wie du darauf zeichnest, kann ich dir nicht sagen,
    aber die oben genannte Funktion müsste eigentlich ausreichen.

    Poste mal bitte deine Lösung.

    viele grüße
    supersass1



  • GetDesktopWindow Function

    The GetDesktopWindow function returns a handle to the desktop window. The desktop window covers the entire screen. The desktop window is the area on top of which other windows are painted.

    Syntax

    HWND GetDesktopWindow(VOID);

    Return Value

    The return value is a handle to the desktop window.

    Naja, mit den handle kann ich arbeiten, aber davon weiss ich ja nicht wo ich hinzeichnen soll 😞



  • Willst du, dass das Bild auf dem Desktop-Hintergrund gezeichnet werden soll, die Icons also im Vordergrund bleiben sollen? Oder einfach über den Desktop?



  • ich denke mal, er möchte über den Icons malen:

    case WM_PAINT:
    	{
    		HDC hDC;
    		PAINTSTRUCT ps;
    
    		HDC hDesktopDC = GetDC(hDesktop);
    		hDC = BeginPaint(hWnd, &ps);
    
    // malen
    
    		EndPaint(hWnd, &ps);
    		ReleaseDC(hDesktop, hDesktopDC);
    
    		return 0;
    	}
    

    ➡ http://msdn2.microsoft.com/en-us/library/ms533241.aspx

    das sollte weiterhelfen,

    viele grüße
    supersass1



  • Also eigentlich würde ich es schon gerne so einrichten, dass die Icons noch sichtbar / zu betätigen sind,
    also mein Form sozusagen als Wallpaper.

    Läuft das dann in etwa so:

    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
        case WM_PAINT:
        {
            HDC hDC;
            PAINTSTRUCT ps;
    
            HDC hDesktopDC = GetDC(hDesktop);
            hDC = BeginPaint(hWnd, &ps);
    
        // malen
    
            EndPaint(hWnd, &ps);
            ReleaseDC(hDesktop, hDesktopDC);
    
            return 0;
        }
    }
    //---------------------------------------------------------------------------
    

    Edit: So funzt es net, aber wie gesagt sowas hab ich noch nie gemacht und suche deshalb eure Hife 🙂



  • Ja versuch es doch erstma so.

    Edit: So funzt es net, aber wie gesagt sowas hab ich noch nie gemacht und suche deshalb eure Hife 🙂

    Poste den ganzen Code, bzw. deine Fehler. Was hast du genau gemacht?
    Versuch erstma was einfaches darzustellen, und wenn das klappt, ersetz dies mit deiner Grafik (oder was auch immer)

    grüße
    supersass1



  • Unit1.cpp eines ganz leeren Forms, zum testen neu erstellt:

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
      case WM_PAINT:
        {
            HDC hDC;
            PAINTSTRUCT ps;
    
            HDC hDesktopDC = GetDC(hDesktop);
            hDC = BeginPaint(hWnd, &ps);
    
        // malen
    
            EndPaint(hWnd, &ps);
            ReleaseDC(hDesktop, hDesktopDC);
    
            return 0;
        }
    }
    //---------------------------------------------------------------------------
    

    [C++ Fehler] Unit1.cpp(15): E2128 case-Marke außerhalb der switch-Anweisung
    [C++ Fehler] Unit1.cpp(15): E2188 Ausdruckssyntax
    [C++ Fehler] Unit1.cpp(31): E2379 In Anweisung fehlt ;

    @supersass1: BIst du sicher, dass TForm1::TForm1 der richtige Platz für den Code ist?

    Ich kenne die Case-Struktur ja, aber was di an der Stelle soll, und nur dieser Teil davon, das kann ich nicht nachvollziehen an dem gepostetem Code.

    Wie gesagt, das Form ist leer, beste Vorraussetzung zum Testen, meine Grafik kommt dann erst wenn das hier funzt 😉

    Ich danke schon mal das ihr euch die Mühe macht! Echt super hier im Forum!
    MfG
    Tippo



  • du hast den thread im Forum winAPI gepostet, also bin ich davon ausgegangen, dass deine Grundstruktur wie folgt lautet:

    #define STRICT
    
    #include <windows.h>
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    
    const char szAppName[] = "Ein eigenes Fenster";
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
                       PSTR szCmdLine, int iCmdShow)
    {
    
       HWND       hWnd;
       MSG        msg;
       WNDCLASS   wc;
    
       wc.style         =  CS_HREDRAW | CS_VREDRAW;
       wc.lpfnWndProc   =  WndProc;
       wc.cbClsExtra    =  0;
       wc.cbWndExtra    =  0;
       wc.hInstance     =  hInstance;
       wc.hCursor       =  LoadCursor(NULL,IDC_ARROW);
       wc.hIcon         =  LoadIcon(NULL,IDI_APPLICATION);
       wc.hbrBackground =  (HBRUSH)GetStockObject(WHITE_BRUSH);
       wc.lpszClassName =  szAppName;
       wc.lpszMenuName  =  NULL;
       RegisterClass(&wc);
       hWnd = CreateWindow(szAppName,
                           "Titelleiste",
                           WS_OVERLAPPEDWINDOW,
                           CW_USEDEFAULT,          /* X-Position auf dem Monitor */
                           CW_USEDEFAULT,          /* Y-Position auf dem Monitor */
                           CW_USEDEFAULT,          /* Fensterbreite              */
                           CW_USEDEFAULT,          /* Fensterhoehe               */
                           NULL,
                           NULL,
                           hInstance,
                           NULL);
    
       ShowWindow(hWnd, iCmdShow);
       UpdateWindow(hWnd);
       while (GetMessage(&msg, NULL, 0, 0))
       {
          TranslateMessage(&msg);
          DispatchMessage(&msg);
       }
       return msg.wParam;
    }
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
       switch (message)
       {
     //----------------------------------->
     // siehe unten
       case WM_DESTROY:
          {
             PostQuitMessage(0);
             return 0;
          }
       }
       return DefWindowProc(hWnd, message, wParam, lParam);
    }
    

    dies sollte/ist der StandartCode einer WinAPI-anwedung.

    nun fügst du in die switch-Anweisung folgendes ein:

    case WM_PAINT:
        {
            HDC hDC;
            PAINTSTRUCT ps;
    
            HDC hDesktopDC = GetDC(hDesktop);
            hDC = BeginPaint(hWnd, &ps);
    
    // malen
    
            EndPaint(hWnd, &ps);
            ReleaseDC(hDesktop, hDesktopDC);
    
            return 0;
        }
    

    dort wo malen steht, muss natürlich das hin, was du zeichnen willst...

    Bei deiner vorgeschlagenen Lösung müsstet du eigentlich nur das case entfernen, etwas so:

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
     // case WM_PAINT:
     //   {
            HDC hDC;
            PAINTSTRUCT ps;
    
            HDC hDesktopDC = GetDC(hDesktop);
            hDC = BeginPaint(hWnd, &ps);
    
        // malen
    
            EndPaint(hWnd, &ps);
            ReleaseDC(hDesktop, hDesktopDC);
    
            return 0;
      //  }
    }
    //---------------------------------------------------------------------------
    

    //Edit:
    Achja, nich vergessen:

    include <windows.h>
    


  • Hallo supersass1 und alle anderen!
    Ich begrüße den einen Herrn mal zuerst, weil er schon so viel für mich gepostet hat.

    Leider hat das für mich einige Klippen mit denen ich nicht so leicht umgehe kann wie ich das gerne könnte. Ich muss zugeben das es meine erste Anwendung sein soll die WinApi nutzen soll, und ich keine Ahnung habe... Nur zum Verständnis.

    Soweit ich das sehe, muss ich ersteinmal mit

    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                       PSTR szCmdLine, int iCmdShow)
    

    einige Veriablen besorgen und "bescheid geben" das was mit Api kommen soll, richtig?

    hWnd = CreateWindow(szAppName,
                           "Titelleiste",
                           WS_OVERLAPPEDWINDOW,
                           CW_USEDEFAULT,          /* X-Position auf dem Monitor */
                           CW_USEDEFAULT,          /* Y-Position auf dem Monitor */
                           CW_USEDEFAULT,          /* Fensterbreite              */
                           CW_USEDEFAULT,          /* Fensterhoehe               */
                           NULL,
                           NULL,
                           hInstance,
                           NULL);
    

    Das verwirrt mich, CreateWindow erstellt doch ein normales Fenster so wie ich es von "Form1" gewöhnt bin. Aber ich will doch auf den Desktop kommen.

    Nun also hab ich das mal versucht, und habe an der im code von superass gekennzeichneten Stelle den WM_PAINT Teil eingefügt.

    Da kam ein Fehler mit hDesktop, das ich dann als

    HWND hDesktop=GetDesktopWindow();
    

    vereinbart habe.

    Aber dann muss ich ja auch noch was zeichnen. Gut, ok, eine Ellipse, kein Problem, aber wohin? Form1->Canvas->Ellipse(...) aber Form1 muss ich ja iwi mit dem Desktop vertauschen, oder?

    Gut, wenn ich den Code nun ausführe gibt es keine Fehler mehr, aber ein normales Fenster öffnet sich, und nichts wird gezeichnet, egal was ich bei //malen reinschreibe.

    Für die ganz harten nun noch mein ganzer QT: (kann ich auf Wunsch auch wieder wegeditieren, wenn zu lang)

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #include <windows.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    #define STRICT
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    
    const char szAppName[] = "Ein eigenes Fenster";
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                       PSTR szCmdLine, int iCmdShow)
    {
    
       HWND       hWnd;
       MSG        msg;
       WNDCLASS   wc;
    
       wc.style         =  CS_HREDRAW | CS_VREDRAW;
       wc.lpfnWndProc   =  WndProc;
       wc.cbClsExtra    =  0;
       wc.cbWndExtra    =  0;
       wc.hInstance     =  hInstance;
       wc.hCursor       =  LoadCursor(NULL,IDC_ARROW);
       wc.hIcon         =  LoadIcon(NULL,IDI_APPLICATION);
       wc.hbrBackground =  (HBRUSH)GetStockObject(WHITE_BRUSH);
       wc.lpszClassName =  szAppName;
       wc.lpszMenuName  =  NULL;
       RegisterClass(&wc);
       hWnd = CreateWindow(szAppName,
                           "Titelleiste",
                           WS_OVERLAPPEDWINDOW,
                           CW_USEDEFAULT,          /* X-Position auf dem Monitor */
                           CW_USEDEFAULT,          /* Y-Position auf dem Monitor */
                           CW_USEDEFAULT,          /* Fensterbreite              */
                           CW_USEDEFAULT,          /* Fensterhoehe               */
                           NULL,
                           NULL,
                           hInstance,
                           NULL);
    
       ShowWindow(hWnd, iCmdShow);
       UpdateWindow(hWnd);
       while (GetMessage(&msg, NULL, 0, 0))
       {
          TranslateMessage(&msg);
          DispatchMessage(&msg);
       }
       return msg.wParam;
    }
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
       switch (message)
       {
       //----------------------------------->
       // siehe unten
       case WM_PAINT:
       {
            HDC hDC;
            PAINTSTRUCT ps;
    
            HWND hDesktop=GetDesktopWindow(); 
            HDC hDesktopDC = GetDC(hDesktop);
            hDC = BeginPaint(hWnd, &ps);
    
            // malen
            Form1->Canvas->Brush->Color = clRed;
            Form1->Canvas->Ellipse(0,0,Form1->ClientWidth,Form1->ClientHeight); 
    
            EndPaint(hWnd, &ps);
            ReleaseDC(hDesktop, hDesktopDC);
    
            return 0;
       }
       case WM_DESTROY:
          {
             PostQuitMessage(0);
             return 0;
          }
       }
       return DefWindowProc(hWnd, message, wParam, lParam);
    }
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    

    Jedenfalls kann ich mir bei der Sache nicht selber weiterhelfen. Was läuft falsch. Sicher mache ich etwas grundlegendes falsch...

    MfG
    Tippo



  • hi Tippo,

    ich habe grad nicht viel Zeit, deshalb ist der Post nicht so ausführlich.

    Jedenfalls kann ich mir bei der Sache nicht selber weiterhelfen. Was läuft falsch. Sicher mache ich etwas grundlegendes falsch...

    Ja in der Tat, du musst dich entscheiden, zwischen winApi oder deinem TForm-"kram".

    Möchtest du weiter wie gewohnt arbeiten, müsstest du dies im andern Thread posten, bleibst du hierbei, müsstest du dich mit WinApi anvertrauen.

    Kurzes Tutorial: http://www.win-api.de/tutorials.php?tutid=3
    Das Ist außerderm der Quelltext, den ich dir als Grundlage vorgeschlagen habe.

    dWie du zeichnen kannst steht hier:
    http://win-api.de/tutorials.php?tutid=9

    Doch das ist für dich wohl zu un-umfassend.
    Ich werde dir später (habe wenig Zeit grade) noch ausführlicherer Infos schicken.

    übrigens:
    Steht dein "Radar" schon oder was du zeichnen wolltest?
    Also kannst du es in deinem Fesnter zeichnen?

    viele liebe grüße
    supersass1

    //Edit1:

    Form1->Canvas->Brush->Color = clRed;
            Form1->Canvas->Ellipse(0,0,Form1->ClientWidth,Form1->ClientHeight);
    

    das erinnert mich an Delphi, ich könnte dir erklären wie man in Delphi zeichnent, das ist recht einfach.

    //Edit2:
    ich habe etwas interessantes gefunden ➡ http://www.bytesandmore.de/rad/index.htm?http://www.bytesandmore.de/rad/cpp/snipp/sc03027.php
    Das sollte auch für dich ansrpechenen, wenn man den Handle dementsprechen verändert.



  • Evtl kannst du das Desktopfenster hooken (Boardsuche nach SetWindowsHookEx) und beim Hintergrund-zeichnen dein Fenster draufzeichnen lassen?



  • supersass1 schrieb:

    hi Tippo,

    Form1->Canvas->Brush->Color = clRed;
            Form1->Canvas->Ellipse(0,0,Form1->ClientWidth,Form1->ClientHeight);
    

    das erinnert mich an Delphi, ich könnte dir erklären wie man in Delphi zeichnent, das ist recht einfach.

    Wenn du mir das evtl für Delphi zeigen kannst, dann wäre das sicher nen Versuch wert! Dann könnte ich das auch weiter mit der VCL machen. Denn ich kann nur ehrlich sagen das ich mich jetzt nicht noch so tief in die WinAPI einarbeiten will, und auch nicht kann.

    Vlt können wir das ja so lösen?!

    PS: Ja, die Grafik ist eigentlich fertig, habs zu angucken mal auf meinen Server gepackt als exe, da kann man sich das vlt besser vorstellen.

    http://tippo.webnerd.de/radar.exe

    Wie gesagt, ist kein Virus oder so drauf, ist ja von mir und auch auf meinem Server.



  • Tippokrates schrieb:

    Wie gesagt, ist kein Virus oder so drauf, ist ja von mir und auch auf meinem Server.

    Freiheit statt Angst - Für die Grundrechte - und wenn du keinen Virus verbreiten willst, lad ich mir auch nix von deinem Server. Informatikstudenten sind mir eh ein Greuel.



  • könntest du zu dem radar noch den source code stellen bitte?


Log in to reply