[vc++ & mfc] CStatic en vector gaan niet samen?

Pagina: 1
Acties:

  • bramseltje
  • Registratie: September 2001
  • Laatst online: 23-05 10:13
Misschien een beetje vage topic titel, maar anders past het niet :)

Het probleem is als volgt:

Ik wil op een dialoog-venstertje een aantal cstatics (labels dus) toevoegen. Omdat er geen '=-operator' beschikbaar is voor CStatic is de vector van het type CStatic*.

Wanneer ik de dynamisch aangemaakte CStatics niet in de vector push blijven ze netjes op het dialoogvenster zichtbaar. Maar zodra ik ze in de vector push verdwijnen ze bij het verlaten van de functie.

Dus: Ik maak een CStatic aan. Ik Create() die, SetFont() naar het goede font en push 'm dan in de vector. Aan het eind van de functie, die via een contectmenu wordt aangeroepen, verdwijnt dan het ding van m'n dialoog :s

De volgorde van aanroep voor de functie is als volgt:
dialoog->ContectMenu->Functie

Wanneer de labels niet in een vector gestoken worden (wegcommentaren van dat gedeelte 8)) blijven de labels wel staan. Het lijkt er dus op dat het aan de vector ligt?

stukje header:
C++:
1
2
3
private:
  std::vector<CStatic*> myLabels;
  int iLabels;

een stukje code:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CRect lblSize(TopLeft,BottomRight);
            
CStatic* myLabel = new CStatic();

myLabels.push_back(myLabel);
myLabels.at(iLabels)->Create(_T("Hier toegev\noegd"),
                WS_CHILD|WS_VISIBLE|SS_CENTER,  
                lblSize,
                this);
            
myLabels.at(iLabels)->ShowWindow(SW_SHOW);
myLabels.at(iLabels)->RedrawWindow();
myLabels.at(iLabels)->SetFont(GetFont());
            
iLabels++;
//Sleep(100);
// Als ik dit doe blijft ie nog 100ms langer staan...

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Zo te zien is iLabels verkeerd geinitialiseerd.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • bramseltje
  • Registratie: September 2001
  • Laatst online: 23-05 10:13
Het lag niet aan iLabels, of aan de vector...

Ga ondertussen gewoon door met proberen, maar blijkbaar ligt het aan SetFont()

SetFont heeft een tweede parameter die aangeeft of er opnieuw getekend moet worden. Wanneer deze 'false' is blijft de CStatic wel netjes staan.

Een volgend probleem is dat we in de OnPaint met een iterator door de vector lopen, en elk element opnieuw tekenen. Alleen wordt blijft het tekenen dan elke keer eentje achterlopen. Dus bij het toevoegen van de eerste gebeurt er niks, en bij de tweede wordt de eerste getekend, enzovoort.

Wanneer we deze lus weglaten klopt het wel.
Zou dit kunnen komen omdat er asynchroon de menu-handler gestart wordt, en de OnPaint al wordt aangeroepen als deze nog niet klaar is met uitvoeren (de vector nog niet geupdate)? We programmeren verder niet multithreaded, dus waarom wil MFC dat dan wel zo graag :S

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-05 23:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

Bramseltje schreef op 10 mei 2004 @ 15:21:
Een volgend probleem is dat we in de OnPaint met een iterator door de vector lopen, en elk element opnieuw tekenen. Alleen wordt blijft het tekenen dan elke keer eentje achterlopen. Dus bij het toevoegen van de eerste gebeurt er niks, en bij de tweede wordt de eerste getekend, enzovoort.

Wanneer we deze lus weglaten klopt het wel.
Zou dit kunnen komen omdat er asynchroon de menu-handler gestart wordt, en de OnPaint al wordt aangeroepen als deze nog niet klaar is met uitvoeren (de vector nog niet geupdate)?
C++:
1
2
3
myLabels.at(iLabels)->SetFont(GetFont()); 
             
iLabels++;


De WM_PAINT bypassed de messagequeue, en je OnPaint wordt dus direct aangeroepen. Aangezien je iLabels pas verhoogt na de aanroep van SetFont, heb je in je OnPaint dus nog de verkeerde waarde.

Waarom gebruik je uberhaupt een iLabels variabele? Voldoet myLabels.size () niet gewoon?
We programmeren verder niet multithreaded, dus waarom wil MFC dat dan wel zo graag :S
ik zie de relevantie met multithreading niet helemaal

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • bramseltje
  • Registratie: September 2001
  • Laatst online: 23-05 10:13
.oisyn schreef op 10 mei 2004 onder andere:

[...]

De WM_PAINT bypassed de messagequeue, en je OnPaint wordt dus direct aangeroepen. Aangezien je iLabels pas verhoogt na de aanroep van SetFont, heb je in je OnPaint dus nog de verkeerde waarde.
Hier waren we inderdaad al achter gekomen. Het meegeven van false als tweede parameter (die default true is) levert wel het gewenste resultaat. De tweede parameter geeft aan (ook te zien aan de naam) of er een redraw gedaan moet worden.
.oisyn schreef ook nog:[/message]
Waarom gebruik je uberhaupt een iLabels variabele? Voldoet myLabels.size () niet gewoon?
Ik probeerde het in eerste instantie als volgt:
C++:
1
2
3
4
5
6
7
8
9
10
CStatic* myLabel = new CStatic(); 

myLabels.push_back(myLabel);

(*myLabels.end())->Create(_T("Hier toegev\noegd"), 
                WS_CHILD|WS_VISIBLE|SS_CENTER,     
                lblSize, 
                this); 

//(*myLabels._MyLast)->Create(...) zou ook kunnen...


maar end() levert het laatste element op, net als _MyLast, en die is nog leeg. Dus eentje te ver. iLabels houd gewoon de laatst toegevoegde positie bij. size() heb ik nog niet naar gekeken.

de code is nu als volgt (werkend):
C++:
1
2
3
4
5
6
7
8
9
10
CStatic* myLabel = new CStatic(); 

myLabel->Create(_T("Hier toegev\noegd"), 
                WS_CHILD|WS_VISIBLE|SS_CENTER,     
                lblSize, 
                this); 

myLabel->SetFont(GetFont(), false);

myLabels.push_back(myLabel);

In de OnPaint functie worden de elementen uit de vector ook niet meer opnieuw getekend.
.oisyn schreef als laatste:[/message]
ik zie de relevantie met multithreading niet helemaal
Dat ging erover dat OnPaint werd uitgevoerd tegelijkertijd met de andere functie.

edit:

.oisyn schreef op 10 mei 2004 @ 23:19:
Misschien moet je de handleiding eens gaan lezen. end () retourneert namelijk niet het laatste element, maar 1 voorbij het laatste element. Gebruik back () om het laatste element op te vragen

:+ dat bedoelde ik dus met het volgende:
brammetje zei:
[...] en die is nog leeg. Dus eentje te ver. [...]

[ Voor 15% gewijzigd door bramseltje op 11-05-2004 17:47 . Reden: reply @ .oisyn ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-05 23:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

Bramseltje schreef op 10 mei 2004 @ 22:59:
maar end() levert het laatste element op, net als _MyLast, en die is nog leeg. Dus eentje te ver. iLabels houd gewoon de laatst toegevoegde positie bij. size() heb ik nog niet naar gekeken.
Misschien moet je de handleiding eens gaan lezen. end () retourneert namelijk niet het laatste element, maar 1 voorbij het laatste element. Gebruik back () om het laatste element op te vragen

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1