News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

ShowWindow before entering message loop?

Started by jj2007, August 03, 2012, 04:41:39 AM

Previous topic - Next topic

jj2007

A straightforward way to create a window:

   invoke CreateWindowEx, WS_EX_OVERLAPPEDWINDOW,
     ADDR szClassName, ADDR szDisplayName,
     WS_OVERLAPPEDWINDOW or WS_VISIBLE,
     Wtx,Wty,Wwd,Wht,
     NULL, rv(LoadMenu, hInst, 600),
     hInst, NULL

   mov hWnd, eax  ; copy return value into handle DWORD
;   invoke ShowWindow, eax, SW_SHOWNORMAL      ; display the window
;   invoke UpdateWindow,hWnd                  ; update the display

   .While 1
      invoke GetMessage, ADDR msg, 0, 0, 0
      .Break .if !eax
      invoke TranslateMessage, ADDR msg           ; translate it
      invoke DispatchMessage,  ADDR msg           ; send it to message proc
   .Endw
   return msg.wParam

You can either set the WS_VISIBLE style, or the two lines commented out.
At least, that's what I thought until mywan pushed me on a problem with SciTe launching the proggie and no display, in spite of the WS_VISIBLE style.

So I wonder what's going on there. I have never seen a need for the two grey lines above, but effectively the SciTe launch started working when I added the ShowWindow (the UpdateWindow is not needed).

Any explanation?

One interesting quote from MSDN for ShowWindow:
QuotenCmdShow [in]
    Type: int
    Controls how the window is to be shown. This parameter is ignored the first time an application calls ShowWindow, if the program that launched the application provides a STARTUPINFO structure

Ryan

I saw that on MSDN, but I dismissed it because you don't call ShowWindow normally, so I would think you wouldn't be affected.

jj2007

Actually, it seems that is the cause. I added a test for the StartupInfo structure, and while my own MasmBasic Launch macro uses SW_SHOWNORMAL by default, SciTe does something else: it passes SW_HIDE aka zero!

StartupInfo from SciTe: sinfo.wShowWindow 0

So it seems that it overrides the WS_VISIBLE style ::)

On the positive side, this means that by specifying the WS_VISIBLE style and not using ShowWindow before the message loop, as in the snippet above, you can steer the behaviour of your window from the launching app. Interesting 8)

dedndave

if i have a program that i want to allow multiple instances.....
i use CW_USEDEFAULT for the X position...
QuoteIf an overlapped window is created with the WS_VISIBLE style bit set and the x parameter
is set to CW_USEDEFAULT, then the y parameter determines how the window is shown.
and SW_SHOW for the Y position

also - to test the various possibilities, you can create shortcuts to open the program
then - modify the shortcut properties - minimized, normal, maximized
to test how it behaves with different startup info

Antariy

MS imposes a "proper style" of window creation/showing with using of STARTUPINFO.wShowWindow as a parameter for the ShowWindow. I.e., the "proper code" of almost every Windows GUI app uses the code sequence similar following:

start:
invoke GetStartupInfo,addr startupInfo
movzx eax,startupinfo.wShowWindow
push eax

invoke GetCommandLine
push eax
push 0
invoke GetModuleHandle,0
push eax
call WinMain


...


WinMain proc hInstance, hPrevInstance, lpCmdLine, nCmdShow

...

invoke CreateWindowEx ...
mov hWnd,eax
invoke ShowWindow,eax,nCmdShow
invoke UpdateWindow ...

...



I.e., this deemed as a de-facto "standard". So, we could freely assume that if the programmer uses WS_VISIBLE as a style of a window, the Windows uses this standard scheme of the window displaying behaviour, i.e. it does the same sequence of actions (GetStartupInfo/ShowWindow,HWND,STARTUPINFO.wShowWindow) just instead of the programmer.

jj2007

That sounds logical, Alex :t, although instead of forcing us poor developers to "freely assume", M$ might have explained that in the manual :eusa_boohoo:

dedndave

i don't think you have to do all that

MSDN ShowWindow
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548%28v=vs.85%29.aspx
QuoteThis parameter is ignored the first time an application calls ShowWindow, if the program that launched the application provides a STARTUPINFO structure. Otherwise, the first time ShowWindow is called, the value should be the value obtained by the WinMain function in its nCmdShow parameter.

if you create a shortcut that specifies the window size on startup...
or if you use CreateProcess...
a STARTUPINFO structure is passed to the process
whether you call ShowWindow after creating the main window or use the method i mentioned above
(which does not require the call to ShowWindow), the kernel uses the value specified in the STARTUPINFO structure

clicking on the EXE in explorer seems to create one, as well
it uses the last state of the window for that EXE

jj2007

Dave,

That quote was already in the first post. The issue is that if you use this feature, there are good and bad news:
- the good news is you can control the initial window state of your app from outside (a launcher, a shortcut, explorer, ...)
- the bad news is that you will never see your window if the launcher (like SciTe) decides to use WM_HIDE.

To prevent the latter, you must use both the WS_VISIBLE style and a separate ShowWindow call.

dedndave

yes - but - if that is the user's intent....

mywan

Quote from: dedndave on August 04, 2012, 12:37:21 AM
yes - but - if that is the user's intent....
In the case of SciTe it's not the users intent. SciTe can't know up front whether it's dealing with a console, such that hidden makes perfect sense as the output is redirected anyway, or a window app which the user needs to be visible for interaction. This is not normally a problem, because standard window apps invoke ShowWindow which makes it visible in spite of SciTe setting it not visible. Console apps, which don't need to be visible do not. So it only breaks when a window app fails to invoke ShowWindow.