c++ - Win32 window freezes after the first draw (directx 11) -
i have standard win32 window, draw on d2d1
. responsive , runs smoothly. problem follows: after window created, calls wm_paint
once , gets "stuck" waiting user input (ex. mouse move or click in window area). receives input, runs without further problems. while doesn't render program nonfunctional, seems highly unprofessional and... ugly. oh, , mean "stuck" background processes still run without problems, loop runs intended - however, wm_paint
isn't called reason.
here current code:
header file:
#define program_fps 30 #define gwindow_style (ws_overlapped | ws_caption | ws_sysmenu | ws_minimizebox | ws_clipchildren | ws_clipsiblings) class application { public: application(); ~application(); // register window class , call methods instantiating drawing resources hresult initialize(); // process , dispatch messages void runmessageloop(); static inline void saferelease(iunknown * _x) { if(_x != null) _x->release(); }; hresult setfullscreen(bool); private: // time (ms) between frames of application // initiation: m_appfps_div( (dword)1000.0 / (dword)program_fps ) const dword m_appfps_div; // initialize device-independent resources. hresult createdeviceindependentresources(); // initialize device-dependent resources. hresult createdeviceresources(); // release device-dependent resource. void discarddeviceresources(); // draw content. hresult onrender(); hresult loadbitmapfromfile( id2d1rendertarget*, pcwstr, uint, uint, id2d1bitmap ** ); // windows procedure. static lresult callback wndproc( hwnd hwnd, uint message, wparam wparam, lparam lparam ); hwnd m_hwnd; id2d1factory * m_pdirect2dfactory; id2d1hwndrendertarget * m_prendertarget; iwicimagingfactory *m_piwicfactory; id2d1solidcolorbrush * m_pwhitebrush; id2d1solidcolorbrush * m_pgraybrush; id2d1lineargradientbrush * m_plineargradientbrush; id2d1bitmap *m_loadingpicture; };
parts of .cpp file
void application::runmessageloop() { haccel hacceltable = loadaccelerators(hinst, makeintresource(idc_win32app)); dword screen_last_refresh = 0; msg msg; for(bool applicationrunning = true; applicationrunning;) { while(peekmessage(&msg, null, 0, 0, pm_remove)) { if(msg.message == wm_quit) { applicationrunning = false; } if(!translateaccelerator(msg.hwnd, hacceltable, &msg)) { translatemessage(&msg); dispatchmessage(&msg); } } /*** here run various background processes ***/ while((gettickcount() - screen_last_refresh) < m_appfps_div) sleep(2); invalidaterect(msg.hwnd, null, false); screen_last_refresh = gettickcount(); } } lresult callback application::wndproc(hwnd hwnd, uint message, wparam wparam, lparam lparam) { lresult result = 0; if (message == wm_create) { lpcreatestruct pcs = (lpcreatestruct)lparam; application *papp = (application *)pcs->lpcreateparams; ::setwindowlongptrw(hwnd, gwlp_userdata, ptrtoulong(papp) ); invalidaterect(hwnd, null, false); result = 1; } else { application *papp = reinterpret_cast<application *>(static_cast<long_ptr>( ::getwindowlongptrw( hwnd, gwlp_userdata ))); bool washandled = false; if (papp) { switch (message) { case wm_size: { uint width = loword(lparam); uint height = hiword(lparam); papp->onresize(width, height); } result = 0; washandled = true; break; case wm_displaychange: { invalidaterect(hwnd, null, false); } result = 0; washandled = true; break; case wm_paint: { papp->onrender(); validaterect(hwnd, null); } result = 0; washandled = true; break; case wm_destroy: { postquitmessage(0); } result = 1; washandled = true; break; } } if (!washandled) { result = defwindowproc(hwnd, message, wparam, lparam); } } return result; } hresult application::onrender() { hresult hr = s_ok; hr = createdeviceresources(); if (succeeded(hr)) { m_prendertarget->begindraw(); m_prendertarget->settransform(d2d1::matrix3x2f::identity()); /** here handle opening animation **/ hr = m_prendertarget->enddraw(); } if (hr == d2derr_recreate_target) { hr = s_ok; discarddeviceresources(); } return hr; }
so, i've tested on 2 computers (both using win 8.1) vs 2012 ultimate , vs 2013 professional, run debug tests , forth, stripping parts of program, searched mdsn, google , stackexchange - no avail. freeze happens when handle wm_command
of child window. there no such issue when tried implementing gdi+, proved highly ineffective, hence switch directx. aside that, program runs flawlessly. hope i've provided enough information.
you have not been clear doing run "various background processes." "stuck" issue comes from. suggestion move out of message loop. instead, call settimer during window initialization , bit of background process work each time wm_timer message comes in.
and, when want wm_paint come in call invalidaterect().
Comments
Post a Comment