Avatar billede tax Nybegynder
16. oktober 2001 - 11:02 Der er 18 kommentarer og
1 løsning

Optegning indefra en klasse.

Jeg arbejder på et modulopbygget system, der skal kunne simulere et simpelt væskeflow. Til dette har vi lavet en klasse med grundegenskaberne for disse moduler, og nedarvet denne i 4 afledede klasser. (Pumper, junctions, ventiler og rør).

Problemet er nu at vi skal have dem til at optegne sig selv i vores vindue. Vi har prøvet at gøre dette tidligere, ved at give klassen HWND til vinduet, for derefter at lade klassen indhente HDC og forsøge en optegning. Men dette gav ingen optegning. Det var som om at klassen ikke kunne bruge hwnd til noget. (Jeg prøvede at kaste nogle messageboxes til det, men forgæves)

Hvordan optegner man i et vindue fra en klasse???

Avatar billede tax Nybegynder
16. oktober 2001 - 11:02 #1
Jeg skal lige tilføje at det er et Windowsprogram vi udvikler i VC++
:)
Avatar billede jpk Nybegynder
16. oktober 2001 - 11:06 #2
Er det dialogbaseret eller doc/view eller?
Avatar billede tax Nybegynder
16. oktober 2001 - 11:09 #3
Det originale design er baseret på at tegne direkte i client-området på et MDI vindue, men lige nu under udviklingen af dette her sæt klasser tegner vi i clientområdet på et standardvindue.

(Fra simple \"hello world\" application templaten)
Avatar billede jpk Nybegynder
16. oktober 2001 - 11:17 #4
Bare en designovervejelse: Har i overvejet at lave et mellemlag, således objekterne ikke skal tegne sig selv (for at adskille data og visning)?

Men... Ellers vil jeg foreslå, at draw-metoderne i objekterne får en CDC* som argument og så tegner sig selv på dette (device context). Herved kan i lettere understøtte fx print (da man i MFC typisk vil oprette et CDC for en printer ligeledes)
Avatar billede soepro Nybegynder
16. oktober 2001 - 11:31 #5
C++ Builder (der var den igen) har et eksempel, hvor man lader tre forskellige tråde (TThreads) tegne sine data på en og samme client. Den eneste challenge her, er at sikre exclusivitet, dvs. at to forskellige tråde ikke tilgår den samme client på een gang. I deres eksempel gjorde man dette vha. Synchronize() metoden.

Humlen i deres løsning var imidlertid det at klasserne ikke tegnede noget selv, men derimod kaldte en hovedmetode til tegning, men navnet på trådens (= klassens) egen tegne metode som parameter. Hermed er både exclusivitet og uafhængighed sikret.
Avatar billede soepro Nybegynder
16. oktober 2001 - 11:37 #6
De to vigtigste methods er sådan her ud:

void __fastcall TSortThread::DoVisualSwap()
{
  // Her hægter vi os på hoved canvas\'en (Borland\'s navn for en Device Context)
  TCanvas *canvas;
  canvas = FBox->Canvas;
  canvas->Pen->Color = TColor(clBtnFace);

  // Her tegner vi så vha. lokale/klassespecifikke
  // metoder.
  PaintLine(canvas, FI, FA);
  PaintLine(canvas, FJ, FB);
  canvas->Pen->Color = clRed;
  PaintLine(canvas, FI, FB);
  PaintLine(canvas, FJ, FA);
}
void __fastcall TSortThread::VisualSwap(int A, int B, int I, int J)
{
  // Wrapper variabler til parameter overførsel
  // til den parameterløses synchronize metode.
  FA = A;
  FB = B;
  FI = I;
  FJ = J;

  Synchronize(DoVisualSwap);
}

(Synchronize metoden kræver navnet på en void function(void) metode.) Pointeren til hoved canvas\'et får tråden i sin constructor:

__fastcall TSortThread::TSortThread(TPaintBox *Box)
    : TThread(False)
{
  FBox = Box;
  FreeOnTerminate = True;
}
Avatar billede jpk Nybegynder
16. oktober 2001 - 11:39 #7
Med stikordene Pumper, junctions, ventiler og rør tror jeg man kan forvente en del objekter og at lade hver af disse objekter tegne sig selv i en seperat tråd er vist lige i overkanten...
Avatar billede tax Nybegynder
16. oktober 2001 - 11:50 #8
JPK -> Hvad mener du med et mellemlag?
Avatar billede soepro Nybegynder
16. oktober 2001 - 11:51 #9
jpk >> Jeg foreslog nu ikke trådning - ovenstående kan også bruges direkte på alm. klasser, som ikke er trådet.
Avatar billede jpk Nybegynder
16. oktober 2001 - 11:53 #10
Et lag der gør, at dine data ikke behøver at have noget med grafisk repræsentation at gøre og at dit vindue ikke behøver at kende til strukturen i dine data.
Avatar billede tax Nybegynder
16. oktober 2001 - 11:57 #11
Jeg har lidt svært ved at forestille mig hvordan vi skal kunne få den lagdeling ind i designet.

Men anyways.

Vi regner med at lave et CDC i hukommelsen og optegne i dette. Al optegningen foregår via rekursive kald ind igennem flow-netværket, så vi er sikre på at der ikke tegnes samtidigt.

Derefter vil vi forsøge at anvende BitBlt til at overføre billedet til brugergrænsefladen.

Er der nogen der synes det her lyder helt åndsvagt?
:)
Avatar billede tax Nybegynder
16. oktober 2001 - 11:59 #12
Hvad bruger man normalt til at tegne på i baggrunden? CDC eller et bitmap?
Avatar billede jpk Nybegynder
16. oktober 2001 - 12:12 #13
Begge...
Man tegner via CDC\'ets metoder, men på et bitmap der er valgt \'ind\' i CDC\'et
Avatar billede jpk Nybegynder
16. oktober 2001 - 12:14 #14
Bagefter kan du kalde CDC::BitBlt(...) for at overføre hele billedet til skærmen
Avatar billede tax Nybegynder
16. oktober 2001 - 12:21 #15
Vi sidder netop og diskuterer om det ville være smart at lave et statisk public
bitmap i vores moderklasse. (Den der er forælder til alt der skal tegnes) For at alle de afledede klasser kunne tegne i den. På den måde kunne man via en getHandleTilBitmap() funktion blitte bare man havde adgang til et enkelt af netobjekterne.
Avatar billede tax Nybegynder
16. oktober 2001 - 12:45 #16
Jeg sidder og er kommet i tvivl om hvordan jeg skal oprette et bitmap i et objekt.

Hvis jeg vil anvende CreateCompatibleBitmap, kræver det at jeg har et HDC, til et andet hdc, men det har jeg ikke set indefra mit objekt.

Derfor vil jeg så bruge CreateBitmap, men den skal bruge et array af colordata, jeg ikke helt ved hvor jeg kan skaffe.

Kan man ikke skaffe et standardcolordata objekt eller lign?
Avatar billede soepro Nybegynder
16. oktober 2001 - 13:04 #17
Jeg forstår ikke hvorfor du først vil tegne dit objekt på en lokal bitmap, for derefter at tegne den (bitmappen) på en central bitmap. Er det ikke unødvendig dobbeltkonfekt ?
Avatar billede jpk Nybegynder
16. oktober 2001 - 13:06 #18
Var lige til frokost...

Jeg bryder mig ikke om ideen med et statisk bitmap! Lad dog være med at lave jeres design mere kompliceret end nødvendig!!!

Her er hvad jeg forestiller mig/har forstået på jer:

I skal kunne repræsentere et væskeflow grafisk. Forestil jer en klasse CFluidFlow, der ligner denne:

class CFluidFlow
{
public:
    CFluidFlow();
    AddModule(CModule Module);
    Draw(CDC* pDC); // Denne klasse har ligeledes en draw-metode, der gennemløber vectoren og kalder hver objekt\'s Drawmetode
    // Altså kan man tegne hele sit flow med et enkelt kald til CFluidFlow objektets Draw-metode

protected:
    vector<CModule*> m_Modules;
}

En instans af CFluidFlow indeholder alle de moduler der indgår i et flow.
Jeres specifikke moduler nedarver alle fra en fælles baseklasse CModule. dette muliggør, at man i en datastruktur som fx vector eller list kan have samtlige moduler

class CModule // Baseklasse
{
    virtual void Draw(CDC* pDC) = 0; // Skal implementeres i alle nedarvinger
}

class CPump : public CModule
{
public:
    // Methods
    void Draw(CDC* pDC); // Denne metode tegner objektet på dc\'et (man kan således kalde Draw() med andre typer af dc\'s, fx for en printer og man har udskrivning uden extra arbejde)

protected:
    // Attributes
}
Avatar billede jpk Nybegynder
16. oktober 2001 - 13:30 #19
CFluidFlow\'s Draw-metode kan jo gøre noget lign. dette:

CDC dcMem;
dcMem.CreateCompatibleDC(pDC); // pDC er en pointer til skærmens dc
BITMAP bm;
CBitmap bitmap;
bitmap.GetBitmap(&bm);
CBitmap* pOldBitmap = dcMem.SelectObject(&bitmap);

// Kald så hvert moduls Draw-metode med &dcMem som argument

// Til sidst kaldes pDC->BitBlt (også med &dcMem som argument) for at overføre det tegnede til skærmen
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester