The MASM Forum

General => The Campus => Topic started by: jj2007 on August 03, 2012, 04:41:39 AM

Title: ShowWindow before entering message loop?
Post by: jj2007 on August 03, 2012, 04:41:39 AM
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 (http://masm32.com/board/index.php?topic=463.msg4198#msg4198) 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  (http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548%28v=vs.85%29.aspx)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
Title: Re: ShowWindow before entering message loop?
Post by: Ryan on August 03, 2012, 05:03:53 AM
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.
Title: Re: ShowWindow before entering message loop?
Post by: jj2007 on August 03, 2012, 05:12:25 AM
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)
Title: Re: ShowWindow before entering message loop?
Post by: dedndave on August 03, 2012, 05:30:32 AM
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
Title: Re: ShowWindow before entering message loop?
Post by: Antariy on August 03, 2012, 09:32:11 AM
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.
Title: Re: ShowWindow before entering message loop?
Post by: jj2007 on August 03, 2012, 04:38:57 PM
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:
Title: Re: ShowWindow before entering message loop?
Post by: dedndave on August 03, 2012, 08:43:56 PM
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 (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
Title: Re: ShowWindow before entering message loop?
Post by: jj2007 on August 03, 2012, 08:56:24 PM
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.
Title: Re: ShowWindow before entering message loop?
Post by: dedndave on August 04, 2012, 12:37:21 AM
yes - but - if that is the user's intent....
Title: Re: ShowWindow before entering message loop?
Post by: mywan on August 05, 2012, 05:43:09 AM
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.