Sign in to follow this  
fabry

[SOLVED] problem while changing windowed/fullscreen mode

Recommended Posts

fabry    100
Hi, I'm developing a 2d game engine with directx and cpp language. By pressing the F2 key the player can switch between fullscreen and windowed mode. I correctly use the TestCooperativeLevel and device Reset, releasing and reacquiring all textures, I obtain the switch between the two modes but i have a problem when i change the window style. The code, (inside an Update function called every window main loop) after device reset and objects reallocation is as follow:
if(this->full_screen_mode){
   ::SetWindowLongPtr(this->hWnd, GWL_EXstyle, 0);
   ::SetWindowLongPtr(this->hWnd, GWL_style, WS_EX_TOPMOST | WS_VISIBLE | WS_POPUP);
}
else{
   ::SetWindowLongPtr(this->hWnd, GWL_EXstyle, 256);
   ::SetWindowLongPtr(this->hWnd, GWL_style, WS_OVERLAPPEDWINDOW);
}

::SetWindowPos(this->hWnd, NULL, CW_USEDEFAULT, CW_USEDEFAULT, this->Get_screen_width(), 
    this->Get_screen_height(), SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_SHOWWINDOW);


I start in windowed mode and send to a text file the GWL_style and GWL_EXstyle by using getWindowLong, the value of GWL_EXstyle is 256 as set by the initial CreateWindow winapi. After switching to full screen mode i find the correct value for GWL_style but the value 8 for GWL_EXstyle in place of 0. Then, switching to windowed mode again i find inside the logfile the GWL_style with the correct value but the GWL_EXstyle with value 264 (=256 + 8 (00001000 binary coded)) in place of 256. Why are my settings ignored by windows? A collateral effect is that after switching from the initial windowed mode to fullscreen and windowed mode again, the fps drops from 60fps to 34fps, my window remains always on top and if i press ALT-TAB my window loose focus but the other windows remains always behind it. I've tryed lots of changes without having the right result. I'm coming crazy! Thank you for your help (i'm sorry, this problem was formerly posted in the wrong section "General Programming", now i moved it into the more appropriate Directx section; i've tried to find between other posts but anyone seems to have the same problem) [Edited by - fabry on June 25, 2009 4:53:52 AM]

Share this post


Link to post
Share on other sites
Evil Steve    2017
8 in the extended style is WS_EX_TOPMOST. That explains why your window is always on top. As for why you get a lower FPS; is the window the correct size? You'll probably have to resize the window when going to windowed mode, since you'll need to account for the window borders (Much like how you need to use AdjustWindowRectEx when you create the window).

Also, this looks wrong to me:
::SetWindowLongPtr(this->hWnd, GWL_style, WS_EX_TOPMOST | WS_VISIBLE | WS_POPUP);
You can't mix extended and non-extended styles like that.

Share this post


Link to post
Share on other sites
fabry    100
Hi Steve, thank you very much for your quickly answer.

mmmhhhh the size should be correct, i use the same variables, screen_width and screen_height, used inside the initialization function (the one which contains the CreateWindow). I sent the two values to the log file and seem to be ok (1024x768).
I've also tryed to reduce the size of the window with ::SetWindowPos(.......,screen_width - 200, screen_height - 200,....) to see what happens but i still obtain a maximized window. Windows simply ignore the setting.

Is the ::SetWindowPos ok for resizing the window? Or it must be replaced by the AdjustWindowRectEx api?

I'll take a deeper look at the ::SetWindowLongPtr api documentation

What sounds strange to me is that while toggling to windowed mode, I change the GWL_EXstyle to 256 to avoid the flag WS_EX_TOPMOST but the log reports to me that the GWL_EXstyle is still 264 so the flag i set

Share this post


Link to post
Share on other sites
Evil Steve    2017
Quote:
Original post by fabry
Hi Steve, thank you very much for your quickly answer.

mmmhhhh the size should be correct, i use the same variables, screen_width and screen_height, used inside the initialization function (the one which contains the CreateWindow). I sent the two values to the log file and seem to be ok (1024x768).
I've also tryed to reduce the size of the window with ::SetWindowPos(.......,screen_width - 200, screen_height - 200,....) to see what happens but i still obtain a maximized window. Windows simply ignore the setting.

Is the ::SetWindowPos ok for resizing the window? Or it must be replaced by the AdjustWindowRectEx api?
SetWindowPos is fine; but if your window has borders (I.e. has the WS_OVERLAPPED style) you should be using AdjustWindowRectEx to determine the correct window size to use - If you pass 1024,768 to CreateWindowEx, the window is 1024x768, but the client area will be something like 1018x742 because of the size of the borders and title bar. That means that if your backbuffer is 1024x768, you don't have a 1 to 1 mapping of backbuffer pixels to window pixels, which can give you weird effects, and totally breaks picking.
When you're specifying the size for the window with SetWindowPos(), you are removing the SWP_NOSIZE flag, right?

Quote:
Original post by fabry
What sounds strange to me is that while toggling to windowed mode, I change the GWL_EXstyle to 256 to avoid the flag WS_EX_TOPMOST but the log reports to me that the GWL_EXstyle is still 264 so the flag i set
Why do you set it to 256? You should be using WS_EX_WINDOWEDGE or nothing at all - depending on what you want.

My fullscreen toggle code is:

// Change window style to remove border in fullscreen mode
DWORD dwStyle;
if(m_thePresentParams.Windowed)
dwStyle = (WS_OVERLAPPEDWINDOW | WS_VISIBLE) & ~WS_THICKFRAME;
else
dwStyle = WS_POPUP;
SetWindowLongPtr(m_hWnd, GWL_STYLE, dwStyle);

// Make sure the changes are flushed
SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);

I never touch the extended style, because my code doesn't need any extended style bits set.

Share this post


Link to post
Share on other sites
fabry    100
Hi Steve, I have no need in my code to change the size of the window. I have a resolution of 1024x768 and i'd like to use the same resolution as for fullscreen as for the size of the window; the size is initially set in the winmain CreateWindow and i'd like that the winodowed mode maintains the same size (borders and titlebar included). I call the SetWindowPos only for having the changes made by SetWindowLongPtr flushed.

I changed my code according to your advices and now the style changing during toggle is made as you do in your engine but I always have the same problem with some important changes:

1° case: start in windowed mode, 60fps, the window is 1024x768 and hides the win taskbar, it's big as the entire screen. If I press ALT-TAB another window get the focus and correctly covers my window. I ALT-TAB to gain focus again and I double-click on the titlebar of my window. At this point the win taskbar appears at the bottom of the screen cutting the bottom of my, the fps drops from 60 to 34 but ALT-TAB works, my window is covered by another window. I regain focus and i double-click again on my titlebar, my window covers the win taskbar and the frame rate come back from 34 to 60fps. I've also noticed, placing a timer that starts before the device->Present() and stops just after the device->Preset() to calculate the swap time between the front and backbuffer, that when 60fps the swap time is 13ms, when 34fps it raises to 25ms. I don't know the reason because the Presentation interval is always the same.

When at 34fps the sprite objects have a jerkily movements and anyway I have a better fluid motion in windowed mode at initial 60fps than in fullscreen at 50fps.

2° case: start in windowed mode at 60fps, toggle to fullscreen at 50fps and back to windowed mode again with a drop to 34fps with a swap buffers time raised from 13ms to 25ms. In this case, the window remains always on top, if I ALT-TAB the other windows stay behind my window. I formerly changed the extended style (now removed from my code) just for this reason, hoping to prevent this behaviour, unsetting the topmost flag, but as i told, it didn't work, my window was still on top. Now if I'm in windowed mode and I drag my window with one or two borders out of the screen the image starts to flicker and the flickering amount is as more as a bigger portion of the window is outside the edges of the screen (The weird effects you were talking about in your previous post?). It seems like at every frame swap, the images in the front and backbuffer are not aligned.

This is what happens in details during the toggle, I used alt-tab to minimize the window and use Win Spy++ to watch the style and extended style of the window (I cut the WS_MINIMIZE flag because it's due to the alt-tab to watch the Spy++)
- start in winmode with 60fps:
style: 34cb 0000 (WS_CAPTION, WS_VISIBLE, WS_CLIPSIBLING, WS_SYSMENU, WS_OVERLAPPED, WS_MINIMIZEBOX, WS_MAXIMIZEBOX)
ex_style: 0000 0100 (WS_EX_LEFT, WS_LTRREADING, WS_EX_RIGHTSCROLLBAR, WS_EX_WINDOWEDGE)
- hit F2 to toggle to full screen mode with 50fps:
style: b400 0000 (WS_POPUP, WS_VISIBLE, WS_CLIPSIBILINGS)
ex_style: 0000 0008 (WS_EX_LEFT, WS_LTRREADING, WS_EX_RIGHTSCROLLBAR, WS_EX_TOPMOST)
- hit F2 to come back to windowed mode, 34fps, here the problem starts:
style: 34cb 0000 (WS_CAPTION, WS_VISIBLE, WS_CLIPSIBLING, WS_SYSMENU, WS_OVERLAPPED, WS_MINIMIZEBOX, WS_MAXIMIZEBOX)
ex_style: 0000 0108 (WS_EX_LEFT, WS_LTRREADING, WS_EX_RIGHTSCROLLBAR, WS_EX_TOPMOST, WS_EX_WINDOWEDGE)
NOTE: also without change the extended style I find the WS_EX_TOPMOST flag set

I post some code hoping you could help me to understand

winmain.cpp:

int WINAPI WinMain(....){
MSG msg; WNDCLASSEX wc; HWND hWnd; DWORD dw_style;

//RegisterClass(hInstance);
wc.cbSize=sizeof(WNDCLASSEX);
wc.style=CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc=(WNDPROC)WinProc;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hInstance=hInstance;
wc.hIcon=NULL;
wc.hCursor=LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground=NULL;
wc.lpszMenuName=NULL;
wc.lpszClassName=g_engine->GetWinTitle();
wc.hIconSm=NULL;
RegisterClassEx(&wc);

//at the beginning g_engine->Get_full_screen_mode() returns false, we start always in windowed mode
if(g_engine->Get_full_screen_mode())
dw_style = WS_POPUP;
else
dw_style = (WS_OVERLAPPEDWINDOW | WS_VISIBLE) & ~WS_THICKFRAME;

//window creation
hWnd=CreateWindow(
g_engine->GetWinTitle(), //win class
g_engine->GetWinTitle(), //title bar
dw_style, //style
CW_USEDEFAULT, //win x pos
CW_USEDEFAULT, //win y pos
g_engine->Get_screen_width(), //width
g_engine->Get_screen_height(), //height
NULL, //parent win
NULL, //menu
hInstance, //istanza applicazione
NULL); //win parameters

if(hWnd==NULL)
return 0;

//display win
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

//Create an instance of Engine class called g_engine
g_engine = new Engine();

//Game initialization
if(!g_engine->Init(hWnd))
return 0;

bGame_Over=false;
//Message Loop
while( !bGame_Over )
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

g_engine->Update(); //Process game loop

} //end while true

g_engine->End(); //Game cleanup
delete g_engine;
return msg.wParam;
} //WinMain end




Engine class:

Engine::Engine()
{
..........
this->deviceLost = false;
this->toggling_WinFullScreenMode = false;
}
void Engine::Shutdown(void)
{
bGame_Over = true;
}
int Engine::Init(HWND hWnd) //D3D Initialization
{
D3DDISPLAYMODE dm; this->hWnd = hWnd;
......
this->d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &dm);

//this->p_d3dpp_windowedMode holds Presentation_parameters for windowed mode
ZeroMemory(&(this->p_d3dpp_windowedMode), sizeof(this->p_d3dpp_windowedMode));
this->p_d3dpp_windowedMode.Windowed = true;
this->p_d3dpp_windowedMode.SwapEffect = D3DSWAPEFFECT_DISCARD;
this->p_d3dpp_windowedMode.BackBufferFormat=D3DFMT_UNKNOWN;
this->p_d3dpp_windowedMode.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
this->p_d3dpp_windowedMode.hDeviceWindow = this->hWnd;

//and this->p_d3dpp_fullScreenMode for fullscreen mode
ZeroMemory(&(this->p_d3dpp_fullScreenMode), sizeof(this->p_d3dpp_fullScreenMode));
this->p_d3dpp_fullScreenMode.Windowed = false;
this->p_d3dpp_fullScreenMode.SwapEffect = D3DSWAPEFFECT_DISCARD;
this->p_d3dpp_fullScreenMode.BackBufferFormat=dm.Format;
this->p_d3dpp_fullScreenMode.BackBufferCount = 1;
this->p_d3dpp_fullScreenMode.BackBufferWidth = this->screen_width;
this->p_d3dpp_fullScreenMode.BackBufferHeight = this->screen_height;
this->p_d3dpp_fullScreenMode.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
this->p_d3dpp_fullScreenMode.hDeviceWindow = this->hWnd;

//this->p_d3dpp holds the parameters for device->Reset and device->CreateDevice
if(this->full_screen_mode){ //FULL screen mode
::ShowCursor(FALSE);
this->p_d3dpp = this->p_d3dpp_fullScreenMode;
}
else
this->p_d3dpp = this->p_d3dpp_windowedMode;

//Create device D3D device
this->d3d->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
this->hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&this->p_d3dpp,
&(this->d3ddev));
if(this->d3ddev==NULL){
MessageBox(NULL, "Engine::Init - Error creating D3D Device", "ERROR", MB_OK);
return 0;
}
....
}

void Engine::ToggleScreenMode(void)
{ //function called if F2 key hit by user to toggle between windowed and fullcreen mode
this->full_screen_mode = !this->full_screen_mode;
this->deviceLost = true;
this->toggling_WinFullScreenMode = true;
if(this->full_screen_mode)
this->p_d3dpp = this->p_d3dpp_fullScreenMode;
else
this->p_d3dpp = this->p_d3dpp_windowedMode;
}

void Engine::Update()
{ //Called in the window main loop at every frame
HRESULT result;

//Check if the device is lost (ALT-TAB in fullscreen mode) or user hits F2 for toggling
if(this->deviceLost)
{
result = this->d3ddev->TestCooperativeLevel();
if(result == D3DERR_DEVICELOST){
::Sleep(100);
return; //leave Update method and go to the win main loop
} //endif(result == D3DERR_DEVICELOST)

if( (result == D3DERR_DEVICENOTRESET) || (this->toggling_WinFullScreenMode) ){
//device->Reset can be tried or user hits F2 key

//Release of all resources and call device->Reset
this->onLostDevice();

result = this->d3ddev->Reset(&this->p_d3dpp);
if(result == D3D_OK){ //Reset is OK
this->deviceLost = false;

//Try to reacquire all resources previously released
if( !this->onResetDevice() ) {
this->Shutdown(); //something wrong, shutdown and kill the application
}

if(this->toggling_WinFullScreenMode) { //if true the user press F2 for toggling mode
this->toggling_WinFullScreenMode = false;
DWORD dwStyle;
if(this->full_screen_mode){ //change style for full screen mode
dwStyle = WS_POPUP;
::ShowCursor(FALSE);
}
else{ //change win style for windowed mode
dwStyle = (WS_OVERLAPPEDWINDOW | WS_VISIBLE) & ~WS_THICKFRAME;
::ShowCursor(TRUE);
}
//change the win style and flush changes
::SetWindowLongPtr(this->hWnd, GWL_STYLE, dwStyle);
::SetWindowPos(this->hWnd, NULL, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
} //endif(this->toggling_WinFullScreenMode)
}
else{ //the device->Reset goes wrong, return, leave Update method and go back to the win main loop
return;
} //endif(result == D3D_OK)
}//endif(result == D3DERR_DEVICENOTRESET)

if(result != D3D_OK){
////something wrong, shutdown and kill the application
this->Shutdown();
} //endif(result != D3D_OK)
} //endif(this->deviceLost) --- end of section that manages the devicelost and the toggle mode

//Call the extern function Game_Run() wich update 2d objects position according to the keys hit by user
Game_Run(); //it updates objects not managed by the Engine class but managed by the extern functions

//automatically update the objects managed by the Engine class contained inside a std::list object
this->Update2D_Entities();

//Perform collision detection testing, I omitted the code

//update with 60fps timing using a stopwatch of 14ms. If from the previous call the time passed is less than
//14ms sleep(1) and jump the code below
if (!timedUpdate.stopwatch(14)) {
Sleep(1);
}
else { //more than 14ms passed before last call, I can write on backbuffer and present the scene
//update input devices and audio system, code omitted

//Render objects
if(this->Start_Render()) //execute this->d3ddev->BeginScene();
{
this->d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 200), 1.0f, 0); //Clear the scene
this->Start_Render2d(); //execute D3DXSprite->Begin(D3DXSPRITE_ALPHABLEND))
this->Draw2D_Entities(); //execute the D3DXSprite->Draw() for the objects managed by the Engine class contained inside a std::list object
Game_Render2d(); //extern function that does the D3DXSprite->Draw() for the objects not managed by the Engine class but managed by the extern functions
this->Stop_Render2d(); //execute D3DXSprite->End();
this->Stop_Render(); //execute the this->d3ddev->EndScene() and the this->d3ddev->Present(NULL, NULL, NULL, NULL);
//if the d3ddev->Present() get back a D3DERR_DEVICELOST =====> this->deviceLost = true;
}

//automatically remove the dead objects managed by the Engine class and contained inside a std::list object
this->Bury2D_Entities();
} //endelse
} //End of Engine::Update




[Edited by - fabry on June 23, 2009 2:57:39 AM]

Share this post


Link to post
Share on other sites
fabry    100
Hi,
also tryed leaving the screen res to 1024x768 but change the game res to 800x600.
I always start in win mode, toggle to fullscreen and go back to window mode: the fps is ok(60) but the window is always on top (i have no code portion for it).

Also tryed to drag the window outside the screen edge. This causes some weird effects, the image flickers and the center of the image is not aligned with the bottom and the top. It doesn't happen when i first start the game but only after coming back to win mode after double toggling from the first win mode and the second full screen mode. Maybe something wrong with the backbuffer? I've tryed different solutions but without a good result.

I posted the code in the previous post.

I hope you can help, thanks in advance...

Share this post


Link to post
Share on other sites
Evil Steve    2017
What CPU, GPU and OS do you have? In windowed mode, Present() causes a BitBlt() from the backbuffer to the window client area, but only if the client area size matches the backbuffer. If the sizes differ, Present() will be forced to call StretchBlt(), which will obviously be slower - perhaps substantially.

So - have you checked that the size of your client area (From GetClientRect()) is always the same as your backbuffer size?

Share this post


Link to post
Share on other sites
fabry    100
It's a notebook with an Intel Pentium M (centrino running at 1.7Ghz), an integrated GPU Intel 82855 GME Graphics controller running Windows XP Pro.

Between the window mode at the beginning (where all is ok, fps is good, there is no flickering and no weird effects) and the window mode after double toggling, there's no change of the size of the client area and backbuffer, i always use the same variables and I restore the same win styles and d3d settings, for this reason this fact sounds so strange to me.
Anyway i try to send to logfile these details and check again.

Thank you

Share this post


Link to post
Share on other sites
Evil Steve    2017
Quote:
Original post by fabry
It's a notebook with an Intel Pentium M (centrino running at 1.7Ghz), an integrated GPU Intel 82855 GME Graphics controller running Windows XP Pro.

Between the window mode at the beginning (where all is ok, fps is good, there is no flickering and no weird effects) and the window mode after double toggling, there's no change of the size of the client area and backbuffer, i always use the same variables and I restore the same win styles and d3d settings, for this reason this fact sounds so strange to me.
Anyway i try to send to logfile these details and check again.

Thank you
That's exactly the sort of spec where I'd expect to see a difference between BitBlt and StretchBlt performance. You could also try explicitly specifying a backbuffer size for windowed mode, in case the backbuffer is being created at say 1024x768 when re-entering windowed mode, but then the window is resized to 1024x768 which will make the client area smaller than that.

Share this post


Link to post
Share on other sites
fabry    100
Quote:

That's exactly the sort of spec where I'd expect to see a difference between BitBlt and StretchBlt performance. You could also try explicitly specifying a backbuffer size for windowed mode, in case the backbuffer is being created at say 1024x768 when re-entering windowed mode, but then the window is resized to 1024x768 which will make the client area smaller than that

Great!!!!!! The second time i switch to win mode i have the backbuffer at 800x600 and the client area size of 794x575.
Why does it happen if i use the same identical style used in CreateWindow?

Share this post


Link to post
Share on other sites
Evil Steve    2017
Quote:
Original post by fabry
Quote:

That's exactly the sort of spec where I'd expect to see a difference between BitBlt and StretchBlt performance. You could also try explicitly specifying a backbuffer size for windowed mode, in case the backbuffer is being created at say 1024x768 when re-entering windowed mode, but then the window is resized to 1024x768 which will make the client area smaller than that

Great!!!!!! The second time i switch to win mode i have the backbuffer at 800x600 and the client area size of 794x575.
Why does it happen if i use the same identical style used in CreateWindow?
If you have a window that is 800x600, then the window will be that size. The client area will be smaller (794x575), since that includes the space for the window borders, menus, etc.

I'd assume this is because when the device is reset, the window style is WS_POPUP, which means the client area is 800x600. You then change the window style to WS_OVERLAPPEDWINDOW, which reduces the client area to 794x575.

I'd use GetClientRect() to get the size of the client area, and manually specify that for the backbuffer width and height in windowed mode, instead of letting D3D handle it.

Share this post


Link to post
Share on other sites
fabry    100
Great!! The problem was the size of backbuffer that was not equal to the size of the client area.

I've still a problem when going back to window mode from fullscreen. The window remains always on top. I've checked with WInSpy++ and the extended styles has the flag WS_EX_TOPMOST set but after toggling i only changed the style, no change to EX_style. There's no call in my code that set the window EX_style.
Here is my code:


//Change D3D parameters and do Reset

if(this->toggling_WinFullScreenMode) { //if true the user press F2 for toggling mode
this->toggling_WinFullScreenMode = false;
DWORD dwStyle;
if(this->full_screen_mode){ //change style for full screen mode
dwStyle = WS_POPUP;
::ShowCursor(FALSE);
}
else{ //change win style for windowed mode
dwStyle = (WS_OVERLAPPEDWINDOW | WS_VISIBLE) & ~WS_THICKFRAME;
::ShowCursor(TRUE);
}
//change the win style and flush changes
::SetWindowLongPtr(this->hWnd, GWL_STYLE, dwStyle);
::SetWindowPos(this->hWnd, NULL, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
} //endif(this->toggling_WinFullScreenMode)



I hope you can help, thanks in advance...

Share this post


Link to post
Share on other sites
Evil Steve    2017
You could try changing your SetWindowPos call to:

::SetWindowPos(this->hWnd, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);

I.e. explicitly move the window to the top of the Z order (and clear the topmost flag) when moving it.

Share this post


Link to post
Share on other sites
fabry    100
Hi Steve,
I tryed your code:
::SetWindowPos(this->hWnd, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
but it doesn't work :(

I also try to force off the TOPMOST bit


::SetWindowLongPtr(this->hWnd, GWL_EXSTYLE, (::GetWindowLongPtr(this->hWnd, GWL_EXSTYLE)) & ~ WS_EX_TOPMOST);

//Flush the change
::SetWindowPos(.....);



But it's always on top

Share this post


Link to post
Share on other sites
y2kiah    2031
I'm getting the same problem. The dwstyle and dwExstyle flags that I'm trying to set via SetWindowsLongPtr do not agree with the resulting flags that are set after the call to SetWindowPos, which I obtain from GetWindowsLongPtr. Problems start appearing with the window after a switch from fullscreen back to windowed - it's always on top yet I can't click it or do anything with it.

Share this post


Link to post
Share on other sites
y2kiah    2031
I wanted to let you know that I figured it out.

First, you need to explicitly set HWND_TOPMOST or HWND_NOTOPMOST in the SetWindowPos call, and take away the SWP_NOZORDER flag - you can't rely on the style or exstyle settings when it comes to topmost because it seems SetWindowPos ignores those and uses its own.

Next, to get my window responsive again, I had to call ShowWindow(SW_NORMAL); after calling SetWindowPos. For some reason the window was displaying but could not be clicked, the mouse would bleed right through to whatever was behind. Re-showing the window seems to solve it.

Share this post


Link to post
Share on other sites
fabry    100
Quote:

First, you need to explicitly set HWND_TOPMOST or HWND_NOTOPMOST in the SetWindowPos call, and take away the SWP_NOZORDER flag - you can't rely on the style or exstyle settings when it comes to topmost because it seems SetWindowPos ignores those and uses its own.

Next, to get my window responsive again, I had to call ShowWindow(SW_NORMAL); after calling SetWindowPos. For some reason the window was displaying but could not be clicked, the mouse would bleed right through to whatever was behind. Re-showing the window seems to solve it.


Hi, thank you very much for your help, i've tryed so many different solution but without having a good result. And the behaviour of the win32 api that set/unset these flags has really no sense!
I'll change my code according to your advices as soon as I can and i'll let you know
Thank you again

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this