The MASM Forum

General => The Laboratory => Topic started by: hutch-- on August 19, 2019, 04:08:27 AM

Title: A prototype that needs testing on different OS versions
Post by: hutch-- on August 19, 2019, 04:08:27 AM
Could I impose on a few folks to test this simple app for me, its a prototype for a splash screen that shows the screen fading in to a full image then it disappears before the main window appears. The main window is just a can to test the splash screen but the help menu will also run the same splash screen. Its working OK here but there are many other variables from different human language OS versions and OS versions.

The splash screen window runs in a separate thread from the main app so it can be handled in a modular manner and it uses a normal timer for its duration. The idea is to have a simple function call that specifies a resource ID for a JPG image and a duration in milliseconds for it to be displayed.
Title: Re: A prototype that needs testing on different OS versions
Post by: LiaoMi on August 19, 2019, 04:48:42 AM
Hi hutch,

Win 10 - OK
Win 7   - OK
WinXP  - nothing is displayed, but then the program works (Perhaps due to the fact that the visual styles of Windows are disabled.)
Title: Re: A prototype that needs testing on different OS versions
Post by: felipe on August 19, 2019, 05:03:07 AM
I like it! works fine in windows 8.1  :thumbsup:
Title: Re: A prototype that needs testing on different OS versions
Post by: avcaballero on August 19, 2019, 06:06:20 AM
W10 works fine
Title: Re: A prototype that needs testing on different OS versions
Post by: HSE on August 19, 2019, 06:48:59 AM
Is intended behaviour to see the splash when selecting "about"?
Title: Re: A prototype that needs testing on different OS versions
Post by: Biterider on August 19, 2019, 06:50:45 AM
Works OK with Win10/64
Biterider
Title: Re: A prototype that needs testing on different OS versions
Post by: sinsi on August 19, 2019, 09:51:45 AM
2000(after installing gdiplus.dll)/XP/XP64/Vista64 - main window shows, splash shows in the taskbar but not on screen
7/8.1/10 - works OK
Title: Re: A prototype that needs testing on different OS versions
Post by: hutch-- on August 19, 2019, 11:35:57 AM
Thanks guys, its pointed at win7 upwards and uses GDI+ to handle a JPG stored in the resource section. I think it will be a reasonably easy port to Win64 and it should be useful for UI apps.
Title: Re: A prototype that needs testing on different OS versions
Post by: daydreamer on August 19, 2019, 07:10:05 PM
works ok on this build of W10,wonder if reporting build number for W10 ,should make it more helpful for all kinds of future tests?
separate thread for GDI+ drawing ,example would be nice  and useful for smoother and better drawing on newer computer than make messagepump laggy
Title: Re: A prototype that needs testing on different OS versions
Post by: FORTRANS on August 19, 2019, 10:50:04 PM
Hi,

Win 2000 Grayed window, but runs and exits.

Win 98 Complained of missing gdi+ dll.
When supplied DLL, aborted with an illegal instruction.

Win XP Grayed window, but runs and exits.

Win 8.1 Shows splash screen then grayed window.
Clicking Help => About shows a splash screen somewhat
wider and shorter than the window.


Cheers,

Steve N.
Title: Re: A prototype that needs testing on different OS versions
Post by: aw27 on August 19, 2019, 11:16:27 PM
Just tested in Windows Server 2019 and it works fine too.
Title: Re: A prototype that needs testing on different OS versions
Post by: hutch-- on August 20, 2019, 07:13:45 PM
I have done the 64 bit MASM version and it seems to work OK here. It has been a pain to get the start splash screen going as Win64 instantly displays the window without needing to use ShowWindow() so I have used an old technique of starting the window off screen, displaying the splash screen then using MoveWindow() to display the main window. No such problem once the main window is displayed, the Help/About menu displays a different image with a single call. This one has the full 64 bit MASM code and a directory that builds the test library for the splash module. Once I am happy with it, the module goes into the 64 bit library.
Title: Re: A prototype that needs testing on different OS versions
Post by: jj2007 on August 20, 2019, 08:43:56 PM
Quote from: hutch-- on August 20, 2019, 07:13:45 PMas Win64 instantly displays the window without needing to use ShowWindow()

Did you try without WS_VISIBLE?

    invoke CreateWindowEx,WS_EX_LEFT or WS_EX_ACCEPTFILES, \
                          ADDR classname,ADDR caption, \
                          WS_OVERLAPPEDWINDOW or WS_VISIBLE,\
                          -1000,-1000,wid,hgt,0,0,hInstance,0   ; start off screen
Title: Re: A prototype that needs testing on different OS versions
Post by: hutch-- on August 20, 2019, 09:26:19 PM
It works but at the price that the main window no longer has the focus after the splash screen is finished.
Title: Re: A prototype that needs testing on different OS versions
Post by: jj2007 on August 20, 2019, 09:45:39 PM
Do you main focus (->SetFocus) or z-order (->SetWindowPos)?
Title: Re: A prototype that needs testing on different OS versions
Post by: hutch-- on August 20, 2019, 09:52:55 PM
Both, it no longer had the focus AND it was not on the top of the Z order. Starting it off screen minimised did the job and when the splash screen was finished and the ShowWindow restoired it, MoveWindow() put it at the right location. The mess was because the splash screen was done in a separate thread that took the original focus. It was a lot less problematic in Win32.
Title: Re: A prototype that needs testing on different OS versions
Post by: TimoVJL on August 20, 2019, 09:59:02 PM
Perhaps sequence: start splash thread, create window, show window works.
Title: Re: A prototype that needs testing on different OS versions
Post by: hutch-- on August 21, 2019, 12:43:23 AM
Timo,

That was the original idea but if the splash thread is the first thread the main app window is then not the main thread and it does not gain the keyboard focus when it starts. I tried all of the combinations and starting the main window first minimised was the only one that safely worked. As in the about box, once the main thread has started everything works normally.
Title: Re: A prototype that needs testing on different OS versions
Post by: TimoVJL on August 21, 2019, 01:00:46 AM
In one example was used SetForegroundWindow(hFrame); in splash thread at the end of it.
Title: Re: A prototype that needs testing on different OS versions
Post by: hutch-- on August 21, 2019, 01:24:11 AM
The thread does not know what the main window handle is and you would have to pass the handle to the splash thread to try it. I have tried both SetActiveWindow() and SetForegroundWindow() and neither brought the main window to the top. The library module works fine so I don't see any point to changing how its called. Starting off screen has always worked well and a call to MoveWindow()) does the job.

LATER : Had a quick play with an old API, BringWindowToTop() and it works OK with the window starting minimised, running the splash screen then setting the Z order with this API.
Title: Re: A prototype that needs testing on different OS versions
Post by: aw27 on August 21, 2019, 02:43:13 AM
This is an example of splash screen of 2 seconds made without using a second thread. It is made in C, 90% of it copied straight from the internet.


#include <windows.h>
#include "resource.h"

const char ClassName[] = "MainWindowClass";
const char SplashClassName[] = "SplashWindowClass";

HWND hMainWnd;
HBITMAP hSplashBMP;

HDC hSplashDC;
HDC hMemoryDC;

LONG BitmapWidth, BitmapHeight;

LRESULT CALLBACK WndProc(HWND    hWnd,

UINT    Msg,
WPARAM  wParam,
LPARAM  lParam)
{

switch (Msg)

{
case WM_CLOSE:

DestroyWindow(hWnd);
break;

case WM_DESTROY:
PostQuitMessage(0);
break;

default:

return (DefWindowProc(hWnd, Msg, wParam, lParam));
}

return 0;
}

LRESULT CALLBACK SplashWndProc(HWND    hWnd,

UINT    Msg,
WPARAM  wParam,
LPARAM  lParam)
{
switch (Msg)
{

case WM_ERASEBKGND:
BitBlt((HDC)wParam, 0, 0, BitmapWidth, BitmapHeight, hMemoryDC, 0, 0, SRCCOPY);
break;

case WM_TIMER:
DeleteObject(hSplashBMP);
ReleaseDC(hWnd, hSplashDC);
ReleaseDC(hWnd, hMemoryDC);
DestroyWindow(hWnd);
ShowWindow(hMainWnd, SW_SHOW);
UpdateWindow(hMainWnd);
SetForegroundWindow(hMainWnd);

break;
default:

return (DefWindowProc(hWnd, Msg, wParam, lParam));
}

return 0;
}

INT WINAPI WinMain(HINSTANCE  hInstance,
HINSTANCE  hPrevInstance,
LPSTR      lpCmdLine,
INT        nCmdShow)
{
WNDCLASSEX    wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON));
wc.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = ClassName;

if (!RegisterClassEx(&wc))
{
MessageBox(NULL, "Failed To Register The Window Class.", "Error", MB_OK | MB_ICONERROR);
return 0;
}

WNDCLASSEX    splashwc;

splashwc.cbSize = sizeof(WNDCLASSEX);
splashwc.style = 0;
splashwc.lpfnWndProc = (WNDPROC)SplashWndProc;
splashwc.cbClsExtra = 0;
splashwc.cbWndExtra = 0;
splashwc.hInstance = hInstance;
splashwc.hIcon = NULL;
splashwc.hIconSm = NULL;
splashwc.hCursor = LoadCursor(NULL, IDC_ARROW);
splashwc.hbrBackground = NULL;
splashwc.lpszMenuName = NULL;
splashwc.lpszClassName = SplashClassName;

if (!RegisterClassEx(&splashwc))
{
MessageBox(NULL, "Failed To Register The Splash Window Class.", "Error", MB_OK | MB_ICONERROR);
return 0;
}

RECT DesktopRect;
GetWindowRect(GetDesktopWindow(), &DesktopRect);

hMainWnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
ClassName,
"Splash Screen",
WS_OVERLAPPEDWINDOW,
(DesktopRect.right - 340) / 2,
(DesktopRect.bottom - 200) / 2,
340,
200,
NULL,
NULL,
hInstance,
NULL);

if (!hMainWnd)
{
MessageBox(NULL, "Window Creation Failed.", "Error", MB_OK | MB_ICONERROR);
return 0;
}

hSplashBMP = LoadBitmap(hInstance, MAKEINTRESOURCE(BITMAP_ID));
if (!hSplashBMP)
{
MessageBox(NULL, "Failed To Load Bitmap", "Error", MB_OK | MB_ICONERROR);
return 0;
}

BITMAP Bitmap;
GetObject(hSplashBMP, sizeof(BITMAP), &Bitmap);
BitmapWidth = Bitmap.bmWidth;
BitmapHeight = Bitmap.bmHeight;

HWND hSplashWnd = CreateWindowEx(
0,
SplashClassName,
"Splash Screen",
WS_POPUP,
(DesktopRect.right - BitmapWidth) / 2,
(DesktopRect.bottom - BitmapHeight) / 2,
Bitmap.bmWidth,
Bitmap.bmHeight,
NULL,
NULL,
hInstance,
NULL);

if (!hSplashWnd)
{
MessageBox(NULL, "Splash Window Creation Failed.", "Error", MB_OK | MB_ICONERROR);
return 0;
}

hSplashDC = GetDC(hSplashWnd);
hMemoryDC = CreateCompatibleDC(hSplashDC);
SelectObject(hMemoryDC, (HGDIOBJ)hSplashBMP);

SetTimer(hSplashWnd, 0, 2000, (TIMERPROC)NULL);

ShowWindow(hSplashWnd, SW_SHOW);
UpdateWindow(hSplashWnd);

MSG    Msg;

while (GetMessage(&Msg, NULL, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}


Title: Re: A prototype that needs testing on different OS versions
Post by: hutch-- on August 21, 2019, 03:21:48 AM
They can be coded inline but I was after a separate module that could be called without complex setup and use a JPG image to keep the app size down.
Title: Re: A prototype that needs testing on different OS versions
Post by: TimoVJL on August 21, 2019, 07:12:14 AM
Better to use thread, as it don't disturb main thread, a simple test.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#define USE_THREAD

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
ULONG ShowSplash(void *p);

char *szAppName = "WinFrame";
char *szFrameClass = "cWinFrame";
HWND hFrame;
HANDLE hInst;

void __cdecl WinMainCRTStartup(void)
{
ExitProcess(WinMain(GetModuleHandle(NULL), 0, 0, SW_NORMAL));
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wcx;
MSG msg;

wcx.cbSize = sizeof(WNDCLASSEX);
GetClassInfoEx(hInstance, MAKEINTRESOURCE(32770), &wcx);
wcx.lpfnWndProc = (WNDPROC) WndProc;
wcx.hInstance = hInstance;
wcx.hbrBackground= (HBRUSH)COLOR_APPWORKSPACE+1;
wcx.lpszClassName= szFrameClass;

if (!RegisterClassEx(&wcx))
return 0;
hInst = hInstance;
#ifndef USE_THREAD
ShowSplash();
#else
CreateThread(0, 0, ShowSplash, 0, 0, NULL);
#endif
hFrame = CreateWindowEx(0, szFrameClass, szAppName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInst, NULL);
if(!hFrame) return 0;
ShowWindow(hFrame, nCmdShow);
//UpdateWindow(hFrame);

while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
switch(wMsg) {
case WM_CREATE:
Sleep(1000);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, wMsg, wParam, lParam);
}

void WINAPI TimerProc1(HWND hwnd, UINT uMsg, UINT timerId, DWORD dwTime)
{
SetForegroundWindow(hFrame);
KillTimer(hwnd, timerId);
DestroyWindow(hwnd);
}

ULONG ShowSplash(void *p)
{
int x = GetSystemMetrics(SM_CXFULLSCREEN) / 2 - 250;
int y = GetSystemMetrics(SM_CYFULLSCREEN) / 2 - 250;
HWND hWnd =  CreateWindowEx(0, "STATIC", "#8001",
WS_POPUP | WS_BORDER | WS_VISIBLE | SS_BITMAP
, x, y, 500, 500, 0,
(HMENU)0, hInst, NULL);
SetTimer(hWnd, 1, 2000, TimerProc1);
#ifdef USE_THREAD
MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
#endif
return (ULONG)hWnd;
}
8001 BITMAP "WFSplash.bmp"
EDIT: using thread don't add much code#ifndef USE_THREAD
ShowSplash(8001);
#else
CreateThread(0, 0, ShowSplash, (void*)8001, 0, NULL);
#endif