CRgn als Wert zurückgeben
-
Hallo!
Ich habe eine Funktion geschrieben die mir einer CRgn Klasse als Wert zurückgibt.
CRgn BorderRgn(CRgn &rgn)
{
CRgn MeineRegion;...
return MeineRegion;
}aber es lässt sich nicht kompilieren,
der Compiler meldet ...error C2558: class 'CRgn' : Kein Kopierkonstruktor verfuegbar
Was soll ich tun ?
Vielen Dank für Eure Hilfe.
Gruß Ronny
-
gib die Region als Zeiger zurück, oder benutze HRGN
-
return *MeineRegion
???
Ist das so korrekt ?
und wie muss dann die Funktion deklariert sein ?
Danke

-
Sagt der Standard nicht, dass es immer einen Copy-Konstruktor gibt? Und in den entsprechenden Headern ist er nicht explizit private oder protected deklariert...
Wie auch immer. Wenn du einen Pointer zurückgeben willst, musst du das Objekt auf dem Heap anlegen, also:
CRgn *BorderRgn(CRgn &rgn) { CRgn *MeineRegion = new CRgn(); //... (MeineRegion ist jetzt ein Pointer, also alle member über -> ansprechen) return MeineRegion; }Allerdings musst du dann nachher höllisch aufpassen, dass du den Speicher wieder freigibst, außen rum müsste das also so aussehen:
CRgn param, *border_reg; //... param createn usw. border_reg = BorderRgn(param); //... damit arbeiten delete border_reg;Sinnvoller wäre wohl:
CRgn &BorderRgn(CRgn &rgn, CRgn &MeineRegion) { //... return MeineRegion; }Das sieht zwar sehr nach C aus, hat aber den Vorteil, dass du keinen Speicher leckst. Der Aufruf sähe dann so aus:
CRgn param, border_reg; //... param createn usw. BorderRgn(param, border_reg); //... damit arbeiten //nachher ist kein delete nötigWenn du dir beide Möglichkeiten offen halten willst:
CRgn *BorderRgn(CRgn &rg, CRgn *MeineRegion = NULL) { if(MeineRegion = NULL) { MeineRegion = new CRgn(); //Createn usw. } //... return MeineRegion; }Dann sähe der Aufruf im zweiten Fall (wenn du delete vermeiden willst) allerdings so aus:
BorderRgn(param, &border_reg); //Adresse übergebenweil in diesem Fall eine Referenz nicht ausreicht.
-
//entweder CRgn* Proc(/*...*/) { return &CRgn(); } //oder HRGN Proc(/*...*/);edit:
ein Objekt auf dem Heap anzulegen braucht man nicht (unbedingt), ein lokales Objekt kann man als static deklarieren.
-
Das beste ist, als HRGN zurückzugeben. Man erspart sich 'ne menge Ärger.
HRGN GetRgn() { CRgn rgn; ... return (HRGN) rgn.Detach(); } CRgn rgn = GetRgn();@Shlo:
return &CRgn(...) ist aus zwei Gründen schlecht:a) Du gibst die Adresse eines temporären Objekts zurück. Die kann zwar (mit COPY-Semanti) zugewiesen werden, aber da brauch man ja wieder einen Copy-CTor, und ist generell schlechtes Design für eine Funktionssignatur.
b) Der Destructor von CGdiObject (von dem CRgn abgeleitet ist) ruft DeleteObject() auf - deine gekapselte HRGN ist also schon lange über den Jordan.Und noch ein Dritter - die Adresse eines static-Members zurückzugeben geht nur solange gut, wie GetRgn auch nur mit einer Region arbeitet.
m.e. sind MFC's GDI-Objekt - Wrapperklassen eh' total verhunztund bereiten mehr Kopfschmerzen als vergnügen.
-
Danke für Eure Hilfe!
Meine Funktion sieht jetzt so aus..
HRGN BorderRgn(CRgn *SourceRgn) { CRgn DestRgn; // ... return (HRGN) DestRgn.Destach(); }soweit so gut.
nun möchte ich diese Region mit einer schon vorhandenen Region kombinieren...
CRgn MeineRegion, ZielRegion; MeineRegion.CreateRectRgn(50, 50, 100, 100); ZielRegion.CombineRgn(&MeineRegion, BorderRgn(&MeineRegion), RGN_OR);Aber der Compiler streigt und sagt ...
error C2664: 'CombineRgn' : Konvertierung des Parameters 2 von 'struct HRGN__ *' in 'class CRgn *' nicht moeglich
Kann mir jemmand weiterhelfen

Danke

-
ZielRegion.CombineRgn(&MeineRegion, &CRgn(BorderRgn(&MeineRegion)), RGN_OR);Genau wegen diesem gefummel bevorzuge ich gleich mit HRGN's zu arbeiten..
-
CRgn *CBorder::BorderRgn(CRgn *rgn) { CRgn *DestRgn = new CRgn(), SourceRgn; long i, n, x, y, size; bool foundTop, foundBottom, foundLeft, foundRight; RECT rect, checkrect; RGNDATA *RegionData; RECT *pArray; size = GetRegionData(*rgn, sizeof(RGNDATA), NULL); // Regiongröße ermitteln RegionData = (RGNDATA*) malloc(size); // Speicher reservieren GetRegionData(*rgn, size, RegionData); // Daten über Region ermitteln pArray = new RECT[(long)RegionData->rdh.nCount]; for(i = 0; i < (long)RegionData->rdh.nCount; i++) { memcpy( // RECT in Array speichern &pArray[i], &RegionData->Buffer[i * sizeof(RECT)], sizeof(RECT) ); } DestRgn->CreateRectRgn(0,0,0,0); // leere Region erzeugen // Alle Rechtecke prüfen for(i = 0; i < (long)RegionData->rdh.nCount; i++) { checkrect = pArray[i]; // X-Achse for(x = checkrect.left; x < checkrect.right; x++) { foundTop = false; foundBottom = false; for(n = 0; n < (long)RegionData->rdh.nCount; n++) { rect = pArray[n]; // Prüfen ob rect auf x liegt if(rect.left + 1 <= x && rect.right - 2 >= x) { // Prüfen ob rect auf MyRect.top - 1 liegt if(rect.top <= checkrect.top - 1 && rect.bottom - 1 >= checkrect.top - 1) { foundTop = true; } // Prüfen ob rect auf MyRect.bottom + 1 liegt if(rect.top <= checkrect.bottom + 1 && rect.bottom >= checkrect.bottom + 1) { foundBottom = true; } } } if(!foundTop) { SourceRgn.CreateRectRgn(x, checkrect.top, x + 1, checkrect.top + 1); DestRgn->CombineRgn(DestRgn, &SourceRgn, RGN_OR); } if(!foundBottom) { // SourceRgn.CreateRectRgn(x, checkrect.bottom, x + 1, checkrect.bottom - 1); // DestRgn->CombineRgn(DestRgn, &SourceRgn, RGN_OR); } } // Y-Achse for(y = checkrect.top; y < checkrect.bottom; y++) { foundLeft = false; foundRight = false; for(n = 0; n < (long)RegionData->rdh.nCount; n++) { rect = pArray[n]; // Prüfen ob rect auf y liegt if(rect.top <= y && rect.bottom - 1 >= y) { // Prüfen ob rect auf MyRect.left - 1 liegt if(rect.left <= checkrect.left - 1 && rect.right - 1 >= checkrect.left - 1) { foundLeft = true; } // Prüfen ob rect auf MyRect.right + 1 liegt if(rect.left <= checkrect.right + 1 && rect.right - 1 >= checkrect.right + 1) { foundRight = true; } } } if(!foundLeft) { //SourceRgn.CreateRectRgn(checkrect.left, y, checkrect.left + 1, y + 1); //DestRgn->CombineRgn(DestRgn, &SourceRgn, RGN_OR); } if(!foundRight) { //SourceRgn.CreateRectRgn(checkrect.right, y, checkrect.right - 1, y + 1); //DestRgn->CombineRgn(DestRgn, &SourceRgn, RGN_OR); } } } // DeleteObject(SourceRgn); delete [] pArray; return DestRgn; }Warum stürtzt wenn ich diese Funktion aufrufe immer mein Programm ab ?
Hab schon alles ausprobiert aber es stürtzt immer ab.
-
wo stürzt es ab, wie, und schon mal mit dem Debugger eingekreist???
-
SourceRgn.CreateRectRgn(x, checkrect.top, x + 1, checkrect.top + 1);
es passiert weil ich die SourceRgn mehrmals verwende!
Ich habe Sie in einer for-Schleife und setze sie jeweils auf ein neues Rechteck.Als ich alles mit HRGN's gemacht hab, hat es funktioniert.
Nur jetzt mit CRgn funktioniert es nicht mehr.Weißt du wie ich diesen Fehler beheben kann ?