[C++] GetWindowDC geeft soms invalid handle

Pagina: 1
Acties:
  • 101 views sinds 30-01-2008
  • Reageer

  • Weng
  • Registratie: Juni 2001
  • Laatst online: 11-05-2024

Weng

Are y'all ready kids

Topicstarter
De onderstaande code wordt steeds op volgorde herhaald, maar het probleem is dat ik bij stap 2 soms een ongeldige hDC heb. Dus gaat bij stap 1 de GetWindowDC dus soms fout.

1. Hoe kan dit?
2. Hoe kan ik controleren of ik een geldige hDC heb?

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
31
32
33
34
35
36
37
38
39
//Stap 1: Initialize
    m_hWnd = CreateWWindow();

    if(!m_hWnd)
        ShowMessage("Unable to create window!");

    m_hDC = GetWindowDC(m_hWnd); //Soms invalid

    if(!m_hDC)
        ShowMessage("Unable to get DC!");

//Stap 2: Kies pixel format
    PIXELFORMATDESCRIPTOR pfd;

    //Init pfd
    memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
    pfd.nSize                   = sizeof(PIXELFORMATDESCRIPTOR); 
    pfd.nVersion                = 1; 
    //pfd.enzovoort...

    int iPixelFormat = ChoosePixelFormat(m_hDC, &pfd);

    if(!iPixelFormat){
        //GetLastError geeft ERROR_INVALID_HANDLE
        //Workaround hiervoor:
        m_hDC = GetWindowDC(m_hWnd); //Hier krijg ik dan wel een goeie
        iPixelFormat = ChoosePixelFormat(m_hDC, &pfd);
    }

//Stap 3: UnInitialize
    if(!ReleaseDC(m_hWnd, m_hDC))
        ShowMessage("Unable to release DC!");

    m_hDC = NULL;

    if(!DestroyWindow(m_hWnd))
        ShowMessage("Unable to destroy window!");

    m_hWnd = NULL;


/Edit1: pfd init duidelijker

[ Voor 12% gewijzigd door Weng op 27-02-2004 12:27 ]

Aye aye captain


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Bevinden zich hier threads in het spel?

We adore chaos because we like to restore order - M.C. Escher


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:00

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik zie je dat je het meteen oproept nadat je je CreateWWindow functie hebt aangeroepen. Kan het niet gewoon mogelijk zijn dat de window dan op dat moment nog niet helemaal is geinitialiseerd?

Zet eens een Sleep (1000); tussen het creëren van de window en het aanvragen van de DC. Dit is natuurlijk geen (goede) oplossing, maar geeft misschien wat meer inzicht in de zaak :)

[ Voor 34% gewijzigd door .oisyn op 25-02-2004 19:14 ]

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.


  • Weng
  • Registratie: Juni 2001
  • Laatst online: 11-05-2024

Weng

Are y'all ready kids

Topicstarter
LordLarry schreef op 25 februari 2004 @ 19:11:
Bevinden zich hier threads in het spel?
Nee.

Aye aye captain


  • Weng
  • Registratie: Juni 2001
  • Laatst online: 11-05-2024

Weng

Are y'all ready kids

Topicstarter
.oisyn schreef op 25 februari 2004 @ 19:13:
Ik zie je dat je het meteen oproept nadat je je CreateWWindow functie hebt aangeroepen. Kan het niet gewoon mogelijk zijn dat de window dan op dat moment nog niet helemaal is geinitialiseerd?

Zet eens een Sleep (1000); tussen het creëren van de window en het aanvragen van de DC. Dit is natuurlijk geen (goede) oplossing, maar geeft misschien wat meer inzicht in de zaak :)
Ik heb er een Sleep tussen gegooid maar hij geeft soms nog steeds een invalid handle.

Hoe is het mogelijk dat ik in de workaround een andere hDC waarde terugkrijg dan bij stap 1, terwijl de hWnd waardes in allebei gelijk zijn? :? Het zou idd kunnen zijn wat jij zegt, maar zelfs een Sleep(2000) heeft niet geholpen.

[ Voor 19% gewijzigd door Weng op 25-02-2004 19:40 ]

Aye aye captain


  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 21-05 20:13
Zou ook wel beetje lelijk zijn als je handmatig je code zou moeten laten wachten...

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


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

curry684

left part of the evil twins

.oisyn schreef op 25 februari 2004 @ 19:13:
Ik zie je dat je het meteen oproept nadat je je CreateWWindow functie hebt aangeroepen. Kan het niet gewoon mogelijk zijn dat de window dan op dat moment nog niet helemaal is geinitialiseerd?

Zet eens een Sleep (1000); tussen het creëren van de window en het aanvragen van de DC. Dit is natuurlijk geen (goede) oplossing, maar geeft misschien wat meer inzicht in de zaak :)
Uhm lieve oisyn, sinds wanneer zou een sleep dat oplossen? :) De laatste keer dat ik checkte was het openen en gebruiken van een standaard window nog extreem multithreaded middels een message pump, en zou je hier hoogstens even een flush van de queue moeten doen :D Wat overigens niet het geval is, daar de WM_CREATE nog tijdens de CreateWindow wordt verstuurd en afgehandeld, daarmee het completeren van de constructie aangevend.

Het ziet er overigens erg MFC uit, dus het zou wellicht kunnen schelen om even de message queue te flushen. Ik weet niet hoe dat in MFC gebeurt, maar je doet tussendoor een ShowMessage welke zeker weten een hoop troep flusht.

Professionele website nodig?


  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
Misschien dat je dit soort zaken het best kunt doen nadat je een WM_PAINT hebt ontvangen (of een dergelijk ander "ik-heb-een-window" message)?

Ik noem maar een dwarsstraat hoor, maar Java heeft hier bijvoorbeeld wel last van - de AWT geeft (meestal) pas een non-NULL graphics object als de Paint()-methode wordt aangeroepen.

Verwijderd

Al geprobeerd te kijken wat GetLastError() je teruggeeft?

(en ik zelf zou liever de FAILED() macro gebruiken ipv de ! operator, leest net ietsje makkelijker :-))

btw: Waarom doe je een GetWindowDC() en niet gewoon een GetDC() ??

[ Voor 69% gewijzigd door Verwijderd op 25-02-2004 23:56 ]


  • Korben
  • Registratie: Januari 2001
  • Laatst online: 14-11-2025

Korben

() => {};

Verwijderd schreef op 25 februari 2004 @ 23:51:
btw: Waarom doe je een GetWindowDC() en niet gewoon een GetDC() ??
Omdat GetDC alleen een DC voor de client area van een window geeft, en GetWindowDC een DC voor de hele window geeft.
curry684 schreef op 25 februari 2004 @ 22:28:
[...]

Het ziet er overigens erg MFC uit, dus het zou wellicht kunnen schelen om even de message queue te flushen.
Ik vraag me af waar je dat vandaan haalt, want ShowMessage() is geen Win32 functie, en al helemaal geen MFC-functie. Bovendien (ervan uitgaande dat die code dan in een window-klasse zou worden uitgevoerd), zou het dan ::GetWindowDC(), ::ReleaseDC() en ::DestroyWindow() moeten zijn.
Ik weet niet hoe dat in MFC gebeurt, maar je doet tussendoor een ShowMessage welke zeker weten een hoop troep flusht.
Mjah, die ShowMessage() wordt voor de GetWindowDC alleen aangeroepen als CreateWWindow() mislukt. Bovendien weet je niet wat ShowMessage() doet, het is geen API- of MFC-functie.

[ Voor 7% gewijzigd door Korben op 26-02-2004 04:57 ]

.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:00

.oisyn

Moderator Devschuur®

Demotivational Speaker

curry684 schreef op 25 februari 2004 @ 22:28:
De laatste keer dat ik checkte was het openen en gebruiken van een standaard window nog extreem multithreaded middels een message pump, en zou je hier hoogstens even een flush van de queue moeten doen :D
doh |:(
was er niet helemaal bij
Het ziet er overigens erg MFC uit
:?


Korben schreef op 26 februari 2004 @ 04:56:
Bovendien (ervan uitgaande dat die code dan in een window-klasse zou worden uitgevoerd), zou het dan ::GetWindowDC(), ::ReleaseDC() en ::DestroyWindow() moeten zijn.
Ten eerste weet je dat niet, een using declaration kan daar ook voor zorgen. Ten tweede is het sowieso onzin, want als het classmembers van een window waren geweest dan was die hwnd parameter ook niet nodig geweest ;)

[ Voor 39% gewijzigd door .oisyn op 26-02-2004 15:45 ]

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.


  • staefke
  • Registratie: December 2003
  • Laatst online: 19-05 22:28
ehrm, in welke functie roep je dit alles aan ? het staat mij zo bij dat je dit in de handler wil doen die de WM_INITDIALOG message afhandelt

(uit de docs:

The WM_INITDIALOG message is sent to the dialog box procedure immediately before a dialog box is displayed. Dialog box procedures typically use this message to initialize controls and carry out any other initialization tasks that affect the appearance of the dialog box.

)

volgens mij is dan pas nl. gegarandeerd dat de DC geldig is / bestaat / geinitialiseerd is / whatever..

duh ?


  • Weng
  • Registratie: Juni 2001
  • Laatst online: 11-05-2024

Weng

Are y'all ready kids

Topicstarter
curry684 schreef op 25 februari 2004 @ 22:28:
[...]

Uhm lieve oisyn, sinds wanneer zou een sleep dat oplossen? :) De laatste keer dat ik checkte was het openen en gebruiken van een standaard window nog extreem multithreaded middels een message pump, en zou je hier hoogstens even een flush van de queue moeten doen :D Wat overigens niet het geval is, daar de WM_CREATE nog tijdens de CreateWindow wordt verstuurd en afgehandeld, daarmee het completeren van de constructie aangevend.

Het ziet er overigens erg MFC uit, dus het zou wellicht kunnen schelen om even de message queue te flushen. Ik weet niet hoe dat in MFC gebeurt, maar je doet tussendoor een ShowMessage welke zeker weten een hoop troep flusht.
Het is geen MFC. De functie CreateWWindow() roept gewoon CreateWindowEx() aan en ShowMessage() roept de MessageBox() functie aan.

Aye aye captain


  • Korben
  • Registratie: Januari 2001
  • Laatst online: 14-11-2025

Korben

() => {};

staefke schreef op 26 februari 2004 @ 16:03:
ehrm, in welke functie roep je dit alles aan ? het staat mij zo bij dat je dit in de handler wil doen die de WM_INITDIALOG message afhandelt

...

volgens mij is dan pas nl. gegarandeerd dat de DC geldig is / bestaat / geinitialiseerd is / whatever..
Misschien zou je een kleine message pump kunnen schrijven na die CreateWWindow die checkt of er een WM_INITDIALOG voorbij komt...

C:
1
2
3
4
5
6
7
8
9
MSG msg;
msg.message = 0;

while (msg.message != WM_INITDIALOG)
{
   GetMessage(&msg, m_hWnd, 0, 0);

   DispatchMessage(&msg);
}

.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?


  • Weng
  • Registratie: Juni 2001
  • Laatst online: 11-05-2024

Weng

Are y'all ready kids

Topicstarter
Ik heb gewoon nu in mijn WndProc een case gemaakt die WM_INITDIALOG zou moeten opvangen maar hij komt nooit in die case. Maar in MSDN staat ook dat ie naar een dialog box wordt gestuurd en niet naar een window.

Aye aye captain


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:00

.oisyn

Moderator Devschuur®

Demotivational Speaker

Korben, het is WM_CREATE, WM_INITDIALOG is gewoon voor dialogs zoals Weng al zegt :)

[ Voor 5% gewijzigd door .oisyn op 26-02-2004 19:41 ]

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.


  • Korben
  • Registratie: Januari 2001
  • Laatst online: 14-11-2025

Korben

() => {};

.oisyn schreef op 26 februari 2004 @ 19:19:
Korben, het is WM_CREATE, WM_INITDIALOG is gewoon voor dialogs zoals Weng al zegt :)
Fine, 10 keer op delete drukken en CREATE typen. :|

.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?


  • Weng
  • Registratie: Juni 2001
  • Laatst online: 11-05-2024

Weng

Are y'all ready kids

Topicstarter
Korben schreef op 26 februari 2004 @ 21:34:
[...]
Fine, 10 keer op delete drukken en CREATE typen. :|
Ik heb het nu zo geschreven dat ie pas weer verder gaat, met het halen van de hDC, als hij de WM_CREATE message heeft ontvangen, maar ik heb weer die fout gekregen :( Hij doet het ook maar 1 op de 10 keer ongeveer.

Aye aye captain


Verwijderd

misschien een

ShowWindow(m_hw,SW_SHOWNORMAL);
UpdateWindow(m_hw);

als CreateWWindow() goed ging?

<edit>
ik heb zelf nog nooit met opengl gewerkt..
maar misschien kun je het met een hdc van de desktop proberen
(hdc=CreateDC(0,0,0,0)) (weet niet hoe dat met multimon gaat)?

<reply voor hier beneden>
MoveWindow(0,0,0,0,false); ...; zou dan eventueel kunnen helpen :7
</reply>
</edit>

[ Voor 66% gewijzigd door Verwijderd op 13-03-2004 22:29 ]


  • Weng
  • Registratie: Juni 2001
  • Laatst online: 11-05-2024

Weng

Are y'all ready kids

Topicstarter
Verwijderd schreef op 26 februari 2004 @ 22:42:
misschien een

ShowWindow(m_hw,SW_SHOWNORMAL);
UpdateWindow(m_hw);

als CreateWWindow() goed ging?
Ik wil em dus niet gelijk Showen en hij hoort het ook gewoon te doen, maar soms gaat het dus fout :? Ik heb wel na de CreateWWindow() de UpdateWindow() gedaan maar dat was een beetje nutteloos omdat die functie een WM_PAINT stuurt en ik toch niks wil teken :P En het hielp ook niet :P

Aye aye captain


  • The End
  • Registratie: Maart 2000
  • Laatst online: 20:49

The End

!Beginning

Wat voor een error krijg je (met GetLastError) als de handle invalid is?

Ik zie trouwens dat je 'ChoosePixelFormat' aanroept met een ongeinitialiseerde struct. Je moet op z'n minst alle variabelen leegmaken met b.v.:
memset(&pfd,0,sizeof(PIXELFORMATDESCRIPTOR));
Daarna moet je ook de 'nSize' parameter van de struct setten.
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);

Ik denk dat het hierdoor soms voorkomt.

[ Voor 71% gewijzigd door The End op 27-02-2004 09:04 ]


  • Weng
  • Registratie: Juni 2001
  • Laatst online: 11-05-2024

Weng

Are y'all ready kids

Topicstarter
The End schreef op 27 februari 2004 @ 08:57:
Wat voor een error krijg je (met GetLastError) als de handle invalid is?

Ik zie trouwens dat je 'ChoosePixelFormat' aanroept met een ongeinitialiseerde struct. Je moet op z'n minst alle variabelen leegmaken met b.v.:
memset(&pfd,0,sizeof(PIXELFORMATDESCRIPTOR));
Daarna moet je ook de 'nSize' parameter van de struct setten.
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);

Ik denk dat het hierdoor soms voorkomt.
Als je naar stap 2 kijkt zie je dat ik in commentaar erbij heb geschreven dat GetLastError() een ERROR_INVALID_HANDLE geeft.

En natuurlijk heb ik de pfd wel geinitialiseerd, maar het was een hele zooi om hierbij te pleuren dus heb ik dat maar niet gedaan. Het leek me ook overbodige informatie, maar ik zal het er wel even bij zetten voor de duidelijkheid ;)

[ Voor 10% gewijzigd door Weng op 27-02-2004 12:30 ]

Aye aye captain


  • The End
  • Registratie: Maart 2000
  • Laatst online: 20:49

The End

!Beginning

Weng schreef op 27 februari 2004 @ 12:24:
[...]

Als je naar stap 2 kijkt zie je dat ik in commentaar erbij heb geschreven dat GetLastError() een ERROR_INVALID_HANDLE geeft.

En natuurlijk heb ik de pfd wel geinitialiseerd, maar het was een hele zooi om hierbij te pleuren dus heb ik dat maar niet gedaan. Het leek me ook overbodige informatie, maar ik zal het er wel even bij zetten voor de duidelijkheid ;)
Uit jou verhaaltje maak ik op dat 'ChoosePixelFormat' ERROR_INVALID_HANDLE teruggeeft en niet wat GetWindowDC teruggeeft. Ik vroeg mij namelijk af of die geen error teruggeeft.

  • Weng
  • Registratie: Juni 2001
  • Laatst online: 11-05-2024

Weng

Are y'all ready kids

Topicstarter
The End schreef op 27 februari 2004 @ 13:30:
[...]


Uit jou verhaaltje maak ik op dat 'ChoosePixelFormat' ERROR_INVALID_HANDLE teruggeeft en niet wat GetWindowDC teruggeeft. Ik vroeg mij namelijk af of die geen error teruggeeft.
Hij geeft daar dus geen fout terug. Als ie daar fout zou gaan zou die NULL moeten returnen en dan zou ie opgevangen moeten worden door mijn if(!m_hDC). Bij het uninitializen wordt m_hDC op NULL gezet, maar als hij langs GetWindowDC() komt krijgt hij toch een waarde als het fout gaat. Ik heb het nog met breakpoints gechecked. Ik krijg dan ook een fout bij het releasen van de DC.

[ Voor 6% gewijzigd door Weng op 27-02-2004 14:46 ]

Aye aye captain


  • The End
  • Registratie: Maart 2000
  • Laatst online: 20:49

The End

!Beginning

Zou je kunnen aangeven met welke parameters je 'CreateWindow' aanroept? Ik heb je code gecopy/paste en bij mij werkt het altijd zonder problemen. (Ik heb em in een loopje windows laten aanmaken/verwijderen)

  • Weng
  • Registratie: Juni 2001
  • Laatst online: 11-05-2024

Weng

Are y'all ready kids

Topicstarter
C++:
1
2
3
4
5
6
7
8
9
10
11
12
CreateWindowEx(     m_dwExStyle,    //Verschilt als ik Windowed of Fullscreen doe
                    CLASSNAME,      //Een define
                    m_pWindowInfo->pcTitle,
                    m_dwStyle,      //Verschilt als ik Windowed of Fullscreen doe
                    iXPos,
                    iYPos,
                    m_windowRect.right - m_windowRect.left,
                    m_windowRect.bottom - m_windowRect.top,
                    NULL,
                    NULL,
                    *m_phInst,
                    this    );


Vóór dit wordt dan nog de screensettings geregeld voor windowed of fullscreen mode mbv ChangeDisplaySettings().

/Edit: Als ik de ChangeDisplaySettings() weglaat krijg ik die fout nog steeds.

[ Voor 8% gewijzigd door Weng op 27-02-2004 18:05 ]

Aye aye captain

Pagina: 1