Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

03.12.2011, 20:19

CWnd::UpdateLayeredWindow (MFC,C++,GDI+) Fehler

Hallo Community,
Ich versuche auf ein "layered" Window mit GDI+ zu zeichnen!
Das ganze hab ich schon mit der API umgesetzt, doch nun steh ich vor dem Problem das sich das nicht so einfach ins MFC umwandeln lässt! Das Fenster bleibt "leer", obwohl es eingefärbt werde sollte! ?(

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <afxwin.h>
#include <gdiplus.h>

#pragma comment( lib, "gdiplus.lib" )
using namespace Gdiplus;


class Button :public CFrameWnd
{
public:
    // Konstruktor
    Button()
    {
        const char *cWndClass = AfxRegisterWndClass( CS_HREDRAW|CS_VREDRAW , NULL,CreateSolidBrush(RGB(0,0,0)) ,NULL);
        CreateEx(WS_EX_LAYERED| WS_EX_TOPMOST /*|WS_EX_TOOLWINDOW*/ ,cWndClass ,_T(""),WS_VISIBLE|WS_POPUP, 0,0,200,200,NULL, NULL, NULL );
    }

};

class FWinApp :public CWinApp
{
   Button *wnd; 
public:
   BOOL InitInstance()
   {
        // Start GDI+
        GdiplusStartupInput gdiplusStartupInput;
        ULONG_PTR           gdiplusToken;  
        GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

        wnd = new Button();
        wnd->ShowWindow(1);

        // Blend Structur
        BLENDFUNCTION hBlend;
        hBlend.BlendFlags = 0;
        hBlend.BlendOp = AC_SRC_OVER;
        hBlend.SourceConstantAlpha = 255;
        hBlend.AlphaFormat = AC_SRC_ALPHA;

        // Create Graphics and Bitmaps
        CDC hScreen = CDC();
        CDC hCDC;
        hCDC.CreateCompatibleDC(&hScreen);
        HBITMAP hBitmap = CreateCompatibleBitmap(hScreen,200,200);
        SelectObject(hCDC,hBitmap ); 

        // Draw
        Graphics *hGraphics = Graphics::FromHDC(hCDC);
        hGraphics->Clear(Color(255,200,0,255));
        

        // Set Position/Size
        POINT hPoint = {0, 0};  // Screen Position
        SIZE hSize = {200,200}; // Window Size
        POINT pptSrc = {0,0};   // 

        // Display
        wnd->UpdateLayeredWindow(&hScreen,&hPoint,&hSize,&hCDC,&pptSrc,0,&hBlend,ULW_ALPHA);
        
        while (true) {};
        return TRUE;

     }

};

FWinApp theApp;


Zusätzliche Links:
UpdateLayeredWindow Example (C++) (das ganze mit der API)
http://msdn.microsoft.com/en-us/library/613c3691.aspx (CWnd::UpdateLayeredWindow MSDN)

Da hab ich wohl ihrgentwas mit der Klasse "CDC" ganz falsch verstanden! :(
Wäre cool, wenn jemand sich das kurz anschauen könnte, den ich verzweifle nun schon nach 3 Tagen stundenlangem googlen und ausprobieren...
Mit freundlichen Grüßen
Faweyr

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Faweyr« (03.12.2011, 23:33)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

03.12.2011, 20:38

Den Code solltest Du in irgendeiner Draw-Routine ausführen, aber im Konstruktor zweifle ich an, dass das funktioniert.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

3

03.12.2011, 23:35

Ok, hab den Code aus dem Konstruktor rausgenommen, doch es zeigt keine Wirkung :(

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

04.12.2011, 07:49

Wohin hast Du ihn denn jetzt gepackt?
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

5

04.12.2011, 08:36

Naja, ich hab die "UpdateLayeredWindow"-Methode aus dem Konstruktor rausgenommen und in die "InitInstance" Methode gesteckt. Davor wurde der Konstruktor von meinem CFrameWnd schon vollständig auggerufen! Das erzeugte Fenster wird einmal neu gezeichnet (muss auch nicht dauerhaft erneuert werden).

Wenn mir jemand aber sagen könnte, ob das Zeichnen normalerweise funktionieren sollte und der Fehler nicht darin liegt:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
 // Create Graphics and Bitmaps
        CDC hScreen = CDC();
        CDC hCDC;
        hCDC.CreateCompatibleDC(&hScreen);
        HBITMAP hBitmap = CreateCompatibleBitmap(hScreen,200,200);
        SelectObject(hCDC,hBitmap ); 

        // Draw
        Graphics *hGraphics = Graphics::FromHDC(hCDC);
        hGraphics->Clear(Color(255,200,0,255));

dann könnte ich ja weiter ausprobieren, aber so weiß ich leider nicht weiter! ?(

Code: siehe erster Post ;)

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Faweyr« (04.12.2011, 08:51)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

04.12.2011, 09:13

Wie ich schon sagte:
Pack es in eine Draw-Methode. Es macht auch in InitInstance keinen Sinn und ich sehe auch nicht, wieso das Fenster nur einmal gezeichnet werden sollte. Ohne das Default-Rendering zu unterbinden, wirst Du nichts sehen.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

7

04.12.2011, 10:23

Okeey! Hab nun das ganze in eine eigene Methode gesteckt und lass diese dauerthaft über eine While-Schleife aufrufen! Das mit dem "Default-Rendering" hab noch nciht verstanden!
Das dauerhafte Neuzeichnen ist auch normaler bei der UpdatelayeredWindow Funktion nicht notwendig, deshalb verstehe ich auch nicht wieso sie bei MFC das Fenster öfters gezeichnet werden sollte.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <afxwin.h>
#include <gdiplus.h>

#pragma comment( lib, "gdiplus.lib" )
using namespace Gdiplus;


class Button :public CFrameWnd
{
    
public:
    // Konstruktor, Destruktor
    Button() {
        const char *cWndClass = AfxRegisterWndClass( CS_HREDRAW|CS_VREDRAW , NULL,CreateSolidBrush(RGB(0,0,0)) ,NULL);
        CreateEx(WS_EX_LAYERED| WS_EX_TOPMOST /*|WS_EX_TOOLWINDOW*/ ,cWndClass ,_T(""),WS_VISIBLE|WS_POPUP, 0,0,200,200,NULL, NULL, NULL );
    }

    void Button::Draw() {
        // Blend Structur
        BLENDFUNCTION hBlend;
        hBlend.BlendFlags = 0;
        hBlend.BlendOp = AC_SRC_OVER;
        hBlend.SourceConstantAlpha = 255;
        hBlend.AlphaFormat = AC_SRC_ALPHA;

        // Create Graphics and Bitmaps
        CDC hScreen = CDC();
        CDC hCDC;
        hCDC.CreateCompatibleDC(&hScreen);
        HBITMAP hBitmap = CreateCompatibleBitmap(hScreen,200,200);
        SelectObject(hCDC,hBitmap ); 

        // Draw
        Graphics *hGraphics = Graphics::FromHDC(hCDC);
        hGraphics->Clear(Color(255,200,0,255));
        

        // Set Position/Size
        POINT hPoint = {0, 0};  // Screen Position
        SIZE hSize = {200,200}; // Window Size
        POINT pptSrc = {0,0};   // 

        // Display
        UpdateLayeredWindow(&hScreen,&hPoint,&hSize,&hCDC,&pptSrc,0,&hBlend,ULW_ALPHA);
    }


};

class FWinApp :public CWinApp
{
   Button *wnd; 
public:
   BOOL InitInstance()
   {
        // Start GDI+
        GdiplusStartupInput gdiplusStartupInput;
        ULONG_PTR           gdiplusToken;  
        GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

        wnd = new Button();
        wnd->ShowWindow(1);
        
        while (true) {
            wnd->Draw();
        };
        return TRUE;

     }

};

FWinApp theApp;


Grüße Faweyr

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

8

04.12.2011, 10:34

Argh! Nein, so war das sicher nicht gemeint, das ist weder performant, noch sinnvoll. Vielleicht solltest Du Dich doch noch etwas belesen, bevor Du an solche Aufgaben herangehst.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

9

04.12.2011, 11:03

Hehe :D yep! Das merkte ich auch schon! Aber trotzdem reitzt es mich, das nun auf die Reihe zu bekommen, da ich eher ein Freund von "Learning by Doing" bin!
Aber so schnell geb ich nicht auf :D Es geht mir auch gar nicht darum das es performant ist, sondern das es überhaupt funktioniert.

Hab das ganze jetzt mit einer OnTimer Methode versucht!!!

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <afxwin.h>
#include <gdiplus.h>

#pragma comment( lib, "gdiplus.lib" )
using namespace Gdiplus;


class Button :public CFrameWnd
{
public:
    // Konstruktor, Destruktor
    Button() 
    {
        const char *cWndClass = AfxRegisterWndClass( CS_HREDRAW|CS_VREDRAW , NULL,CreateSolidBrush(RGB(0,0,0)) ,NULL);
        CreateEx(WS_EX_LAYERED| WS_EX_TOPMOST |WS_EX_TOOLWINDOW ,cWndClass ,_T(""),WS_VISIBLE|WS_POPUP, 0,0,200,200,NULL, NULL, NULL );

        SetTimer(1,270,NULL);
    }

    ~Button() {}

    void Button::OnTimer (UINT n) 
    {

        // Blend Structur
        BLENDFUNCTION hBlend;
        hBlend.BlendFlags = 0;
        hBlend.BlendOp = AC_SRC_OVER;
        hBlend.SourceConstantAlpha = 255;
        hBlend.AlphaFormat = AC_SRC_ALPHA;

        // Create Graphics and Bitmaps
        CDC hScreen = CDC();
        CDC hCDC;
        hCDC.CreateCompatibleDC(&hScreen);
        HBITMAP hBitmap = CreateCompatibleBitmap(hScreen,200,200);
        SelectObject(hCDC,hBitmap ); 

        // Draw
        Graphics *hGraphics = Graphics::FromHDC(hCDC);
        hGraphics->Clear(Color(255,200,0,255));
        

        // Set Position/Size
        POINT hPoint = {0, 0};  // Screen Position
        SIZE hSize = {200,200}; // Window Size
        POINT pptSrc = {0,0};   // 

        // Display
        UpdateLayeredWindow(&hScreen,&hPoint,&hSize,&hCDC,&pptSrc,0,&hBlend,ULW_ALPHA);
    }

    DECLARE_MESSAGE_MAP()
};

BEGIN_MESSAGE_MAP(Button,CFrameWnd)
    ON_WM_TIMER()
    END_MESSAGE_MAP()


class FWinApp :public CWinApp
{
   Button *wnd; 
public:
   BOOL InitInstance()
   {
        // Start GDI+
        GdiplusStartupInput gdiplusStartupInput;
        ULONG_PTR           gdiplusToken;  
        GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

        wnd = new Button();
        wnd->ShowWindow(SW_SHOW);
        
        return TRUE;
   }

    BOOL ExitInstance() {
        return TRUE;
    }

};

FWinApp theApp;


Aber es wäre nett, wenn du mit 2-3 Stichwörter nennen könntest wie DU es gemeint hast! 8|
Grüße Faweyr

Werbeanzeige