Toon posts:

[win32/C++] Programma sluit niet af

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb dus een proggy gescheven die de Windows API gebruikt,
ook de WM_CLOSE messages goed en zo.
Bij mij sluit hij normaal af, maar bij twee vrienden van mij is hij niet af te sluiten.
Ik kan me vaag iets herrinneren dat bij Windows XP de message nogmaals vertaald moet worden, maar ik kan er niets over vinden.

Is iemand die hier meer van weet?

bvd,

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12:16

.oisyn

Moderator Devschuur®

Demotivational Speaker

Hoe reageer je dan op die WM_CLOSE? En hoe ziet je message pump eruit? Laat je code eens zien

[ Voor 24% gewijzigd door .oisyn op 14-01-2004 17:28 ]

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.


Verwijderd

Topicstarter
dit is de messageloop
code:
1
2
3
4
5
6
        if(PeekMessage(&msg,wHandle,0,0,PM_REMOVE))
        {
            TranslateMessage(&msg);

            DispatchMessage(&msg);
        }

edit: dit staat natuurlijk in een loop ^^

en dit is de WinProc:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
LRESULT CALLBACK wP(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
    case WM_CLOSE:
        {
            PostQuitMessage(0);
            return 0;
        }
    
    case WM_KEYDOWN:
        {
            keys[wParam] = true;
            return 0;
        }
    }
    return DefWindowProc(windowHandle,message,wParam,lParam);
}


maar het rare is dat hij bij mij, en op windows 98 systemen wel gewoon afsluiten.

als je de gehele code wilt zien moet je het maar even aangeven.

bvd

[ Voor 5% gewijzigd door Verwijderd op 14-01-2004 17:34 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12:16

.oisyn

Moderator Devschuur®

Demotivational Speaker

wat is de conditie van die loop waarin je PeekMessage aanroept? PostQuitMessage () zal natuurlijk een WM_QUIT genereren, test je daar wel op?

En ik weet niet of je wat anders zinnigs in je loop doet, maar zo niet dan kun je er natuurlijk beter een while (GetMessage (...)) { translate; dispatch; } van maken

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.


Verwijderd

Topicstarter
.oisyn schreef op 14 januari 2004 @ 17:42:
wat is de conditie van die loop waarin je PeekMessage aanroept? PostQuitMessage () zal natuurlijk een WM_QUIT genereren, test je daar wel op?

En ik weet niet of je wat anders zinnigs in je loop doet, maar zo niet dan kun je er natuurlijk beter een while (GetMessage (...)) { translate; dispatch; } van maken
C++:
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
    MSG msg;

    do
    {
        if(PeekMessage(&msg,wHandle,0,0,PM_REMOVE))
        {
            TranslateMessage(&msg);

            DispatchMessage(&msg);
        }
        if(keys[VK_ESCAPE])
        {
            SendMessage(wHandle,WM_CLOSE,0,0);
            keys[VK_ESCAPE] = false;
        }
        if(keys[VK_RIGHT])
        {
            SendMessage(winamp,WM_COMMAND,40048,0);
            keys[VK_RIGHT] = false;
        }
        if(keys[VK_LEFT])
        {
            SendMessage(winamp,WM_COMMAND,40044,0);
            keys[VK_LEFT] = false;
        }

        GetWindowText(winamp,title,sizeof(title));
        SetWindowText(wHandle,title);

    } while(msg.message != WM_QUIT);


dit is de loop zelf.
Ik zal dat voorbeeld van jou even proberen zo.
bedankt

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22-05 16:53
C++:
1
2
3
4
5
......
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
.......

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12:16

.oisyn

Moderator Devschuur®

Demotivational Speaker

farlane: waarom? Op het kruisje drukken geeft een WM_CLOSE, en die geeft een WM_QUIT. Moet dus gewoon normaal werken.

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.


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22-05 16:53
.oisyn schreef op 14 januari 2004 @ 20:50:
farlane: waarom? Op het kruisje drukken geeft een WM_CLOSE, en die geeft een WM_QUIT. Moet dus gewoon normaal werken.
Hm, idd. Was in de veronderstelling dat je op een WM_DESTROY moest quitten, maar op WM_CLOSE doet ie het ook. ( Je krijgt dan geen WM_DESTROY meer trouwens )

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Misschien een gek idee of zo, maar vind je het echt tactisch dat je programma permanent 100% CPU-tijd trekt? Je yield nergens en zo....

Professionele website nodig?


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22-05 16:53
curry684 schreef op 15 januari 2004 @ 10:22:
Misschien een gek idee of zo, maar vind je het echt tactisch dat je programma permanent 100% CPU-tijd trekt? Je yield nergens en zo....
Dat doet PeekMessage toch voor je ?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • SWfreak
  • Registratie: Juni 2001
  • Niet online
farlane schreef op 15 januari 2004 @ 12:24:
[...]


Dat doet PeekMessage toch voor je ?
Nope, PeekMessage returnt altijd meteen, of er nu wel of geen message is...

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

farlane schreef op 15 januari 2004 @ 12:24:
[...]
Dat doet PeekMessage toch voor je ?
GetMessage yield alleen, indien er geen messages staan. Zijn message loop yield nooit en zal dus zeker onder 98 het hele systeem starven.

Professionele website nodig?


Verwijderd

Topicstarter
curry684 schreef op 15 januari 2004 @ 10:22:
Misschien een gek idee of zo, maar vind je het echt tactisch dat je programma permanent 100% CPU-tijd trekt? Je yield nergens en zo....
dit is eigenlijk een goede veronderstelling
had ik zelf nog niet aan gedacht.

de mensen bij wie hij niet af wil sluiten zeggen ook dat het programma "vastloopt"

dus ik moet gewoon die loop een paar keer per seconde laten lopen neem ik aan.

ik ga het meteen proberen.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Ik snap je message pump sowieso niet... waarom gebruik je geen standaard GetMsg/Translate/Dispatch loop waarin je WM_KEYDOWN en WM_PAINT correct afhandelt ipv die troep hier op een volstrekt foute plaats af te handelen?

[edit]
Het probleem van het vastlopen is trouwens wel duidelijk, je processed maximaal 1 message per iteratie, en SetWindowText produceert er minimaal 1 (WM_PAINT). Met de muis bewegen zorgt er dus al voor dat de message queue binnen de kortste keren overloopt.

[ Voor 39% gewijzigd door curry684 op 15-01-2004 13:47 ]

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12:16

.oisyn

Moderator Devschuur®

Demotivational Speaker

curry: wordt de WM_PAINT niet direct aan de windowproc gegeven ipv eerst door de messagequeue te gaan? UpdateWindow () en RedrawWindow doen dat iig wel (en bovendien is het volgens mij een WM_NCPAINT)

Ik zat idd ook te denken aan het overlopen van de queue door SetWindowText, maar ik zie zo snel niet waardoor. Het is natuurlijk wel gewoon lompe code, zo elke iteratie de windowtext aanpassen :)

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.


Verwijderd

Een minimale message loop hoort er zo uit te zien...
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
BOOL bRet;

while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{ 
    if (bRet == -1)
    {
        // handle the error and possibly exit
    }
    else
    {
        TranslateMessage(&msg); 
        DispatchMessage(&msg); 
    }
}

De rest van de troep moet je in je window procedure afhandelen.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

.oisyn schreef op 15 januari 2004 @ 15:46:
curry: wordt de WM_PAINT niet direct aan de windowproc gegeven ipv eerst door de messagequeue te gaan? UpdateWindow () en RedrawWindow doen dat iig wel (en bovendien is het volgens mij een WM_NCPAINT)

Ik zat idd ook te denken aan het overlopen van de queue door SetWindowText, maar ik zie zo snel niet waardoor. Het is natuurlijk wel gewoon lompe code, zo elke iteratie de windowtext aanpassen :)
WM_PAINT en WM_NCPAINT gaan wel via de queue, maar op een speciale manier: er kan nooit meer dan 1 WM_*PAINT message in de queue staan (de eerste), en die trekt met BeginPaint alle pending rectangles open.

UpdateWindow en RedrawWindow zijn functies die juist bedoeld zijn om respectievelijk alle pending paints af te handelen en een immediate repaint te doen, en bypassen dus idd de message queue (en flushen eventueel aanwezige WM_*PAINT's).

SetWindowText is alleen een NCPAINT indien wHandle een overlapped window is, als wHandle een button of edit control is een gewone PAINT :)

En die queue loopt dus gewoon over, je krijgt iedere iteratie een WM_PAINT plus eventuele inputmessages. Als je dus tussen PeekMessage en SetWindowText erin slaagt om 2 toetsen in te drukken zal de bijbehorende WM_KEYDOWN van de 2e dus al nooit aankomen, en een WM_CHAR zal al helemaal nooit in de queue komen schat ik zo.

Professionele website nodig?

Pagina: 1