/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
Mere windowsprogrammering
Fra : Jacob Jensen


Dato : 22-01-05 22:04

Jeg har stjålet en lille skal til et program som viser et vindue og wm_paint
beskedsektionen af windowproc ser sådan ud:

case WM_PAINT:
hDC = BeginPaint(hWnd, &PaintSt);
GetClientRect(hWnd, &aRect);
SetBkMode(hDC, TRANSPARENT);
DrawText(hDC, "TESTING", -1, &aRect, DT_SINGLELINE|DT_CENTER|DT_VCENTER);
EndPaint(hWnd, &PaintSt);
return 0;

Jeg har prøvet at søge lidt på msdn efter noget winapi og så tilføjet:

case WM_LBUTTONDOWN:
hDC = BeginPaint(hWnd, &PaintSt);
GetClientRect(hWnd, &aRect);
SetBkMode(hDC, TRANSPARENT);
DrawText(hDC, "TESTING THIS", -1, &aRect,
DT_SINGLELINE|DT_CENTER|DT_VCENTER);
EndPaint(hWnd, &PaintSt);
return 0;

Burde programmet nu ikke skrive "THIS" efter "TESTING" når jeg klikker i
vinduet? Hvad er der galt (det sker ikke)?

I øvrigt står der at jeg ikke bør bruge beginpaint bortset fra når der
kommer en WM_PAINT besked. Hvad er den "rigtige" måde at gøre det her på?

Jacob



 
 
Jacob Jensen (22-01-2005)
Kommentar
Fra : Jacob Jensen


Dato : 22-01-05 22:50

I forlængelse af tråden "windowsprogrammering" er det jeg vil ende op med
noget med at når der bliver klikket på venstre museknap skal der oprettes en
instans af klassen "linje" som indeholder et punkt (også en instans af en
klasse) som er netop det punkt hvor man klikkede. Herefter skal linjen så
tegnes og så har jeg tænkt mig at få den til at flytte sig lidt senere, men
nu skal jeg lige have den tegnet først.

Da det eneste jeg har lige nu er en winmain og en windowsprocfunktion er jeg
lidt på herrens mark. Skal jeg oprette en global variabel som ligesom ER
vinduet og så kan jeg så have en funktion heri som opretter linjer (og
kommer dem i en liste f.eks.), eller hvordan gør man?

Jacob



Jacob Jensen (22-01-2005)
Kommentar
Fra : Jacob Jensen


Dato : 22-01-05 23:40

aha

Jeg kan tilsyneladende slet ikke bruge BeginPaint uden for WM_PAINT i
windowproc. Hvis jeg bruger GetDC virker det som det skal. Er det slet ikke
muligt at ruge BeginPaint? Hvorfor bruger man egentligt den og ikke GetDC
inde i WM_PAINT?

Jacob



Bertel Brander (23-01-2005)
Kommentar
Fra : Bertel Brander


Dato : 23-01-05 00:01

Jacob Jensen wrote:
> aha
>
> Jeg kan tilsyneladende slet ikke bruge BeginPaint uden for WM_PAINT i
> windowproc. Hvis jeg bruger GetDC virker det som det skal. Er det slet ikke
> muligt at ruge BeginPaint? Hvorfor bruger man egentligt den og ikke GetDC
> inde i WM_PAINT?

Når der popper et andet vindue op foran dit, eller hvis du selv kalder
InvalidateRect markeres nogle regioner som "invalide" hviket betyder
at de skal tegnes, og windows sender så en WM_PAINT hvor man "validerer"
disse regioner, dvs tegner dem.
Windows vil blive ved med at sende WM_PAINT beskeder indtil du kalder
BeginPaint og EndPaint, så når det er WM_PAINT skal du bruge BeginPaint
og EndPaint, for at fortælle at regionerne er valide.
Normalt (hvis man er lidt doven eller det ikke er for langsomt) tegner
man hele vinduet når der kommer en WM_PAINT, men den PAINTSTRUCT som man
kan få ved WM_PAINT fortæller hvilke regioner der skal opdateres.

--
"We learned more from a three minute record, baby
than we ever learned in school"
- Bruce Springsteen

Bertel Brander (22-01-2005)
Kommentar
Fra : Bertel Brander


Dato : 22-01-05 23:54

Jacob Jensen wrote:
> I forlængelse af tråden "windowsprogrammering" er det jeg vil ende op med
> noget med at når der bliver klikket på venstre museknap skal der oprettes en
> instans af klassen "linje" som indeholder et punkt (også en instans af en
> klasse) som er netop det punkt hvor man klikkede. Herefter skal linjen så
> tegnes og så har jeg tænkt mig at få den til at flytte sig lidt senere, men
> nu skal jeg lige have den tegnet først.
>
> Da det eneste jeg har lige nu er en winmain og en windowsprocfunktion er jeg
> lidt på herrens mark. Skal jeg oprette en global variabel som ligesom ER
> vinduet og så kan jeg så have en funktion heri som opretter linjer (og
> kommer dem i en liste f.eks.), eller hvordan gør man?
>

Man kunne lave en class der er applikationen og en anden der er
hoved vinduet, og hvis du har flere undervinduer kunne de hver
være en instans af en tredie class. De to sidste typer class
kunne arve fra samme base klasse.
Når man har dette oppe at stå, har man (stort set) det samme
"framwork" som for din MFC app og man kunne lave stort set det
samme. Man kunne bruge en std::list til at holde styr på alle
linierne.

Du kan måske finde lidt inspiration i denne:
http://home20.inet.tele.dk/midgaard/jdraw-1.zip

Det er en Win32Api application lavet med class'er, den kan
vise og manipulere jpg og bmp billeder.

--
"We learned more from a three minute record, baby
than we ever learned in school"
- Bruce Springsteen

Jacob Jensen (23-01-2005)
Kommentar
Fra : Jacob Jensen


Dato : 23-01-05 01:08

> Man kunne lave en class der er applikationen og en anden der er
> hoved vinduet, og hvis du har flere undervinduer kunne de hver
> være en instans af en tredie class. De to sidste typer class
> kunne arve fra samme base klasse.
> Når man har dette oppe at stå, har man (stort set) det samme
> "framwork" som for din MFC app og man kunne lave stort set det
> samme. Man kunne bruge en std::list til at holde styr på alle
> linierne.
>
> Du kan måske finde lidt inspiration i denne:
> http://home20.inet.tele.dk/midgaard/jdraw-1.zip

Tak. Det vil jeg se på i morgen. Nu har jeg lige fået noget til faktisk at
bevæge sig (med SetTimer).

Lige en ting mere selvom det er lidt sent: Når jeg har brugt LineTo flyttes
position til endepunktet. Hvordan flytter jeg den tilbage igen? Der er ikke
en MoveTo så vist jeg kan se. Lige nu beder jeg om en ny DC men det er da
lidt unødvendigt ikke?

Jacob



Bertel Brander (23-01-2005)
Kommentar
Fra : Bertel Brander


Dato : 23-01-05 01:17

Jacob Jensen wrote:
> Lige en ting mere selvom det er lidt sent: Når jeg har brugt LineTo flyttes
> position til endepunktet. Hvordan flytter jeg den tilbage igen? Der er ikke
> en MoveTo så vist jeg kan se. Lige nu beder jeg om en ny DC men det er da
> lidt unødvendigt ikke?
>

Der er en MoveToEx.

--
"We learned more from a three minute record, baby
than we ever learned in school"
- Bruce Springsteen

Jacob Jensen (23-01-2005)
Kommentar
Fra : Jacob Jensen


Dato : 23-01-05 01:19

> Man kunne lave en class der er applikationen og en anden der er
> hoved vinduet, og hvis du har flere undervinduer kunne de hver
> være en instans af en tredie class. De to sidste typer class
> kunne arve fra samme base klasse.
> Når man har dette oppe at stå, har man (stort set) det samme
> "framwork" som for din MFC app og man kunne lave stort set det
> samme. Man kunne bruge en std::list til at holde styr på alle
> linierne.

Jeg kunne ikke helt lade være at kigge på programmet. Jeg kan slet ikke
overskue det for at være helt ærlig :) Jeg forstår princippet i ovenstående
med at have en klasse som ligesom er vinduet (kalder man det ikke for et
"view"?) men jeg forstår ikke det med en klasse der er applikationen. Hvad
mener du? I MFC har jeg kun prøvet at lave noget hvor der var en "doc"
klasse og en "view" klasse. "doc" fordi man havde mulighed for at åbne
"undervinduer" og tegne i dem. Det er som jeg ser det et helt andet princip
end det jeg har gang i nu hvor jeg kun har 1 vindue at lege med hele tiden.

Bare for lige at være sikker på at jeg er med:
Den liste du omtaler skulle så være placeret i den klasse som "er" vinduet
ikke?
Vil winmain og windowproc stadig bare ligge uden for klasser og daske rundt?
Hvad skal applikationsklassen indeholde?

I skal nok høre en masse fra mig endnu. Jeg har først lige fået det til at
bevæge sig.

Jacob



Bertel Brander (23-01-2005)
Kommentar
Fra : Bertel Brander


Dato : 23-01-05 02:11

Jacob Jensen wrote:
>>Man kunne lave en class der er applikationen og en anden der er
>>hoved vinduet, og hvis du har flere undervinduer kunne de hver
>>være en instans af en tredie class. De to sidste typer class
>>kunne arve fra samme base klasse.
>>Når man har dette oppe at stå, har man (stort set) det samme
>>"framwork" som for din MFC app og man kunne lave stort set det
>>samme. Man kunne bruge en std::list til at holde styr på alle
>>linierne.
>
>
> Jeg kunne ikke helt lade være at kigge på programmet. Jeg kan slet ikke
> overskue det for at være helt ærlig :) Jeg forstår princippet i ovenstående
> med at have en klasse som ligesom er vinduet (kalder man det ikke for et
> "view"?) men jeg forstår ikke det med en klasse der er applikationen. Hvad
> mener du? I MFC har jeg kun prøvet at lave noget hvor der var en "doc"
> klasse og en "view" klasse. "doc" fordi man havde mulighed for at åbne
> "undervinduer" og tegne i dem. Det er som jeg ser det et helt andet princip
> end det jeg har gang i nu hvor jeg kun har 1 vindue at lege med hele tiden.
>
> Bare for lige at være sikker på at jeg er med:
> Den liste du omtaler skulle så være placeret i den klasse som "er" vinduet
> ikke?
> Vil winmain og windowproc stadig bare ligge uden for klasser og daske rundt?
> Hvad skal applikationsklassen indeholde?

En lidt lang forklaring, den baserer sig på dit program som ligner
alle andre MFC multi dokument baserede applikationer.

I dit MFC program har du i Sketcher.h en CSketcherApp der arver
fra CWinApp, dette er applikationen. Det vigtigste for denne class
er InitInstance funktionen der bliver kaldt én gang når applikationen
starter, her laves hoved vinduet.

Hoved vinduet er af typen CMainFrame der arver fra CMDIFrameWnd.
Hovedvinduet holder styr på toolbar, statusbar og alle child-vinduerne.

Det vindue du tegner i består af tre dele:
- Et child-vindue, der er rammen udenom og title baren (der hvor navnet
på filen står, når dette vindue ikke er maksimeret. Dette er
CChildFrame der arver fra CMDIChildWnd.
- Et view, CSketcherView der arver fra CView. Dette er egentlig bare et
vindue (Window), MFC kalder det for et view, måske fordi det er her data
bliver vist. Det er her du tegner dine figurer.
- Et dokument, der er den class der læser og skriver "dokumenterne",
og som gemmer data. Dette er CSketcherDoc der arver fra CDocument.

I den model jeg beskrev i før vil jeg lave tre class'er:

- En applikation, denne skal indkapsle Instance handlen, som man
får fra WinMain. WinMain laver en instans af applikation's class'en.
Applikations class'en laver hoved vinduet. Applikations klassen
kan også holde styr på "globale" data, der skal være tilgængelige
for alle andre altid, f.ex. data der gemmes i registry.
- Et hoved vindue, indkapsler handlen til hoved vinduet, har
menu'en, og laver under vinduerne/undervinduet.
- Et eller flere undervinduer, denne class tager sig af
både view-delen og doc-delen, men man kan godt dele det
i to (eller tre om man vil).

Listen over linier og andre objekter, skulle være placeret
i undervinduet.
windowproc bør ligge i class'en, men du kan godt bruge samme
windowproc for alle vinduer (der kan arve fra samme
base class).
Bemærk at du ikke kan bruge en normal funktion i en class
som windowproc; det skal være en global funktion eller en
static memberfunktion.
At få fat i objektet i denne funktion kan være lidt af en
udfordring, men kan løses ved at have en global std::map
der mapper en HWND til et objekt.

I JDraw som jeg linkede til før, er applikationen og
hoved vinduet samme class, men den arver fra en app-class
og en window-class.
Undervinduet har en image-class der holder styr på data.

--
"We learned more from a three minute record, baby
than we ever learned in school"
- Bruce Springsteen

Jacob Jensen (23-01-2005)
Kommentar
Fra : Jacob Jensen


Dato : 23-01-05 12:55

> I dit MFC program har du i Sketcher.h en CSketcherApp der arver
> fra CWinApp, dette er applikationen. Det vigtigste for denne class
> er InitInstance funktionen der bliver kaldt én gang når applikationen
> starter, her laves hoved vinduet.

Jeg kan bare ikke se CSketcherApp implementationen :) Men jeg stoler på dig.

> Hoved vinduet er af typen CMainFrame der arver fra CMDIFrameWnd.
> Hovedvinduet holder styr på toolbar, statusbar og alle child-vinduerne.

Det var jeg vist med på.

> Det vindue du tegner i består af tre dele:
> - Et child-vindue, der er rammen udenom og title baren (der hvor navnet
> på filen står, når dette vindue ikke er maksimeret. Dette er
> CChildFrame der arver fra CMDIChildWnd.
> - Et view, CSketcherView der arver fra CView. Dette er egentlig bare et
> vindue (Window), MFC kalder det for et view, måske fordi det er her data
> bliver vist. Det er her du tegner dine figurer.

Ja viewet er vel sådan set clientarea-delen af child-vinduet ikke?

> - Et dokument, der er den class der læser og skriver "dokumenterne",
> og som gemmer data. Dette er CSketcherDoc der arver fra CDocument.

Ja

> I den model jeg beskrev i før vil jeg lave tre class'er:
>
> - En applikation, denne skal indkapsle Instance handlen, som man
> får fra WinMain. WinMain laver en instans af applikation's class'en.
> Applikations class'en laver hoved vinduet.

ok, istedet for at winmain gør det nu? Winmain skal altså faktisk kun
indeholde en instans af applikationsklassen og message-loopet?

> Applikations klassen
> kan også holde styr på "globale" data, der skal være tilgængelige
> for alle andre altid, f.ex. data der gemmes i registry.
> - Et hoved vindue, indkapsler handlen til hoved vinduet, har
> menu'en, og laver under vinduerne/undervinduet.

Men jeg har ingen undervinduer så jeg i mit tilfælde vil der bare kun være
et hovedvindue.

> - Et eller flere undervinduer, denne class tager sig af
> både view-delen og doc-delen, men man kan godt dele det
> i to (eller tre om man vil).
>
> Listen over linier og andre objekter, skulle være placeret
> i undervinduet.

Ja.

> windowproc bør ligge i class'en, men du kan godt bruge samme
> windowproc for alle vinduer (der kan arve fra samme
> base class).

Den skal jeg lige have igen. Windowproc kan vel være global og bare sende
beskederne videre til min applikationsklasse? Hvilken klasse ville du lægge
den i? Du kom til bare at skrive "class'en" ovenfor.

> Bemærk at du ikke kan bruge en normal funktion i en class
> som windowproc; det skal være en global funktion eller en
> static memberfunktion.

Ok.

> At få fat i objektet i denne funktion kan være lidt af en
> udfordring, men kan løses ved at have en global std::map
> der mapper en HWND til et objekt.

Det må jeg også lige have uddybet.

Tak for hjælpen. Jeg vil lige kigge på det.

Jacob



Jacob Jensen (23-01-2005)
Kommentar
Fra : Jacob Jensen


Dato : 23-01-05 12:58

> ok, istedet for at winmain gør det nu? Winmain skal altså faktisk kun
> indeholde en instans af applikationsklassen og message-loopet?

Hov jamen hvis jeg opretter instansen af applikationsklassen inde i winmain
er den vel ikke tilgængelig uden for winmain. Den skal vel være global ikke?

Jacob



Bertel Brander (23-01-2005)
Kommentar
Fra : Bertel Brander


Dato : 23-01-05 22:43

Jacob Jensen wrote:
>>ok, istedet for at winmain gør det nu? Winmain skal altså faktisk kun
>>indeholde en instans af applikationsklassen og message-loopet?
>
>
> Hov jamen hvis jeg opretter instansen af applikationsklassen inde i winmain
> er den vel ikke tilgængelig uden for winmain. Den skal vel være global ikke?
>

Jo, applikationen skal være globalt tilgængelig.
Man kan løse det ved at lave en static member funktion
i app-classen der returnerer en pointer til en static
member variabel der peger på applikations instansen, denne
pointer sættes i constructoren i applikations classen.
Dette vil virke da der altid kun vil kunne være én
instans af applikations classen
Jeg tror at C++ eksperterne vil kalde dette for en
"singleton class".

--
"We learned more from a three minute record, baby
than we ever learned in school"
- Bruce Springsteen

Bertel Brander (23-01-2005)
Kommentar
Fra : Bertel Brander


Dato : 23-01-05 22:32

Jacob Jensen wrote:
>
> Jeg kan bare ikke se CSketcherApp implementationen :) Men jeg stoler på dig.

I sketcher.cpp har du CSketcherApp::InitInstance()

> Ja viewet er vel sådan set clientarea-delen af child-vinduet ikke?

Viewet _fylder_ clientarea delen af child-vinduet. View'et er et
vindue, lige som child-vinduet er et vindue.

>
>
>>I den model jeg beskrev i før vil jeg lave tre class'er:
>>
>>- En applikation, denne skal indkapsle Instance handlen, som man
>>får fra WinMain. WinMain laver en instans af applikation's class'en.
>>Applikations class'en laver hoved vinduet.
>
>
> ok, istedet for at winmain gør det nu? Winmain skal altså faktisk kun
> indeholde en instans af applikationsklassen og message-loopet?

Ja, eller man kunne (hvilket jeg foretrækker) lade applikation's
class'en lave lave message-loopen.

>
>>Applikations klassen
>>kan også holde styr på "globale" data, der skal være tilgængelige
>>for alle andre altid, f.ex. data der gemmes i registry.
>>- Et hoved vindue, indkapsler handlen til hoved vinduet, har
>>menu'en, og laver under vinduerne/undervinduet.
>
>
> Men jeg har ingen undervinduer så jeg i mit tilfælde vil der bare kun være
> et hovedvindue.

Ja, du kan godt nøjes med at tegne på clientarea delen af hovedvinduet.
Det er dog min erfaring at det er lettere at styre placering af
toolbar, statusbar og resten hvis man laver et seperat vindue til
at tegne på (og lave det som to class'er).

>
>
>>windowproc bør ligge i class'en, men du kan godt bruge samme
>>windowproc for alle vinduer (der kan arve fra samme
>>base class).
>
>
> Den skal jeg lige have igen. Windowproc kan vel være global og bare sende
> beskederne videre til min applikationsklasse? Hvilken klasse ville du lægge
> den i? Du kom til bare at skrive "class'en" ovenfor.

Det jeg mener er at WindowProc'en bør ligge i den class der
implementerer vinduet. Man kan godt nøjes med én WindowProc for
hele applikationen, dette kan man gøre ved at implementere
WindowProc'en i en base class som alle de vinduer der vil
bruge denne WindowProc arver fra (det er måske en idé at
have en seperart WindowProc for dialogbox'e).

>
>>At få fat i objektet i denne funktion kan være lidt af en
>>udfordring, men kan løses ved at have en global std::map
>>der mapper en HWND til et objekt.
>
>
> Det må jeg også lige have uddybet.

Din WindowProc modtager en hwnd, men du skal finde den
instans af den class der skal modtage beskeden, dvs.
det objekt der implementerer vinduet.

Hvis du kun har et vindue er der ikke noget problem i at
sende beskeden videre til ejeren, men hvis du har flere
bliver du nødt til at lave en mapping mellem et hwnd og
et objekt.
Denne mapping kunne man lave med en std::map.
Når man opretter et vindue med CreateWindow kan man som
sidste parameter angive en "window-creation data", dette
kunne være en pointer til den class der implementerer
vinduet. Når WindowProcen modtager WM_CREATE kan den få
fat i denne parameter gennem den CREATESTRUCT der sendes
med. Der ved kan man tilføje et entry til mappen.

--
"We learned more from a three minute record, baby
than we ever learned in school"
- Bruce Springsteen

Jacob Jensen (23-01-2005)
Kommentar
Fra : Jacob Jensen


Dato : 23-01-05 14:05

Nu sidder jeg i suppedasen:

Jeg har en main.cpp som indeholder winmain og windowproc (på globalt
niveau). Her oprettes en instans af klassen "program" på globalt niveau, og
inde i winmain kaldes program's init funktion som sætter hInstance variablen
i program-klassen.

Program indeholder en instans af klassen MainWindow, og MainWIndow's
constructor udfører følgende:

static char szAppName[] = "Mini_Win_Program";
WindowClass.style = CS_HREDRAW | CS_VREDRAW;
WindowClass.lpfnWndProc = WindowProc;
WindowClass.cbClsExtra = 0;
WindowClass.cbWndExtra = 0;
WindowClass.hInstance = hInstance;
WindowClass.hIcon = LoadIcon(0, IDI_APPLICATION);
WindowClass.hCursor = LoadCursor(0, IDC_ARROW);
WindowClass.hbrBackground =
static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
WindowClass.lpszMenuName = 0;
WindowClass.lpszClassName = szAppName;
RegisterClass(&WindowClass);
hWnd = CreateWindow(szAppName, "Mini Windows Program", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance,
0);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

Men problemet er at MainWindow ikke kender til WindowProc så linje 3 fejler.
Hvad gør jeg?

Jacob



Bertel Brander (23-01-2005)
Kommentar
Fra : Bertel Brander


Dato : 23-01-05 22:47

Jacob Jensen wrote:
> Nu sidder jeg i suppedasen:
>
> Jeg har en main.cpp som indeholder winmain og windowproc (på globalt
> niveau). Her oprettes en instans af klassen "program" på globalt niveau, og
> inde i winmain kaldes program's init funktion som sætter hInstance variablen
> i program-klassen.
>
> Program indeholder en instans af klassen MainWindow, og MainWIndow's
> constructor udfører følgende:
>
> static char szAppName[] = "Mini_Win_Program";
> WindowClass.style = CS_HREDRAW | CS_VREDRAW;
> WindowClass.lpfnWndProc = WindowProc;
....
>
> Men problemet er at MainWindow ikke kender til WindowProc så linje 3 fejler.
> Hvad gør jeg?
>

Da WindowProc er en global funktion skal du vel bare tilføje en
prototype til denne. Hvis den findes i en anden cpp fil
bør den laves i en .h fil, ellers lave du den bare i starten
af cpp filen.


--
"We learned more from a three minute record, baby
than we ever learned in school"
- Bruce Springsteen

Jacob Jensen (24-01-2005)
Kommentar
Fra : Jacob Jensen


Dato : 24-01-05 13:19

> Da WindowProc er en global funktion skal du vel bare tilføje en
> prototype til denne. Hvis den findes i en anden cpp fil
> bør den laves i en .h fil, ellers lave du den bare i starten
> af cpp filen.

Nu er jeg godt nok kommet ud over det her ved bare at have en main.cpp som
indeholder winmain og winproc. i denne fil oprettes en instans af klassen
"state" (tilstand) på globalt niveau som skal være det objekt der "styrer"
hvad der foregår. I state-objektet har jeg samlingen af objekter og
funktioner som kan flytte disse på skærmen osv.

....men jeg kunne nu godt tænke mig at prøve at få det andet til at fungere.
Altså have winmain i en fil for sig, og så en applikationsklasse (med
windowproc) som skal inkapsle hovedvinduet (men som vi snakkede om skal
hovedvindueklassen selv stå for at vise vinduet på skærmen). hovedvinduet
skal tilmed indeholde noglelunde det samme som min "state" ovenfor. Men jeg
har brug for hjælp til dette, derfor får i lige 4 spørgsmål:

(hele programmet findes her:
http://home20.inet.tele.dk/omo/mini_win_program_failed.rar)

Først og fremmest fatter jeg altså ikke .h filer - ligenu har jeg ingen af
dem. Hvad gør jeg og hvorfor? :)

Da det er vindueklassen der selv skal stå for at lave vinduet skal den bruge
hInstance og adressen på windowproc i denne linje: "WindowClass.lpfnWndProc
= " og denne linje: "hWnd = CreateWindow(... " Hvordan kan den kende dem?
Skal jeg fra applikationsklassen give vinduesklassen en pointer til
windowprocfunktionen og hInstance-variablen? Er vi så ikke lige vidt? Kunne
applikationsklassen ikke ligeså godt vise vinduet så?

Hvis jeg skal gøre ovenstående hvordan giver jeg så vinduesklassen den
pointer til windowproc?

Hvis jeg laver windowproc statisk i applikationsklassen kan jeg ikke kalde
funktioner fra den. Eksempel: Jeg har oprettet en instans af vindueklassen i
applikationsklassen og når der kommer en WM_LBUTTONDOWN besked vil jeg så
fra windowproc kalde en funktion, test, i vindueklassen:

case WM_LBUTTONDOWN:
MainWindow.test();
return 0;

Jeg får denne fejl: error C2228: left of '.test' must have
class/struct/union type

MainWindow er defineret længere oppe:

private:
MainWindow MainWindow;

Hvis windowproc ikke er statisk får jeg ikke fejlen (og den SKAL være
statisk hvis den er i en klasse ikke?)

Tak for al hjælpen indtil nu.
Jacob



Bertel Brander (24-01-2005)
Kommentar
Fra : Bertel Brander


Dato : 24-01-05 23:19

Hoved problemet er at WindowProc er en static member
funktion i class'en. Det skal den være da man ikke
kan bruge ikke-static member funktioner som Window proc.
En static member funktion kan kun tilgå andre static
member funktioner og variable i class'en. At
de er static betyder ca. at der kun kan findes en af dem.
MainWindow er en ikke-static member variabel og det går
således ikke. Da der kun er ét MainWindow kan et hurtigt
fix være at lave MainWindow static også.

Jeg har lavet denne rettelse og nogle få andre
og lagt koden her:
http://home20.inet.tele.dk/midgaard/mini_win_program_compiles.zip

Jeg har flyttet lidt rundt på koden, lavet nogle
..h filer, så man ikke inkluderer .cpp filer.
Jeg har ændret et par navne på classer så de
ikke hedder det samme som objekterne.

--
"We learned more from a three minute record, baby
than we ever learned in school"
- Bruce Springsteen

Bertel Brander (22-01-2005)
Kommentar
Fra : Bertel Brander


Dato : 22-01-05 23:42

Jacob Jensen wrote:
> I øvrigt står der at jeg ikke bør bruge beginpaint bortset fra når der
> kommer en WM_PAINT besked. Hvad er den "rigtige" måde at gøre det her på?

Man bør og kan ikke bruge bruge BeginPaint og EndPaint til andet
end WM_PAINT.

I andre tilfælde bruger man GetDC til at få fat på DC'en og
ReleaseDC til at frigive den efter brug.

--
"We learned more from a three minute record, baby
than we ever learned in school"
- Bruce Springsteen

Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408929
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste