icd
asked on
Simple splash screen code needed
I have a W95/98 32 bit application that uses nothing more complicated in the GUI than MessageBox. The program is a 'front end' to other programs and does some processing for about 10 seconds. Currently, if all goes well, there is no visible change to the desk top to show that my program is running.
I now want to display a 'splash screen' during these 10 seconds which is taken from an image file (bmp or gif etc). The idea is this.
Program starts.
Loads image file.
Displays image file on screen.
Carries out 10 seconds of processing.
Remove image from screen.
program exits.
I would like the simplest code to read, display and remove the image as possible.
I am currently writing my application in MSVC 5.0 (*not* with MFC!)
I now want to display a 'splash screen' during these 10 seconds which is taken from an image file (bmp or gif etc). The idea is this.
Program starts.
Loads image file.
Displays image file on screen.
Carries out 10 seconds of processing.
Remove image from screen.
program exits.
I would like the simplest code to read, display and remove the image as possible.
I am currently writing my application in MSVC 5.0 (*not* with MFC!)
ASKER
As I mentioned, this is *not* an MFC application. I will however accept your answer if there are no other suggestions that do not require MFC.
use the code from this site
http://www.codeguru.com/bitmap/index.shtml
A drolling idiot could do this as long as you remember..
-Add the functions from the page and make sure you replace your dialogs OnPaint with the one one the page
-Import your bitmap into your project and make sure that you replace the IDC_BITMAP from the code with the resource name of your newly imported bitmap.
-remember to write down the dimensions of your image so that you can place the size in the BitBlt function.
-It wouldn't hurt to put a MoveWindow(X,Y,Hieght,Widt h) in your Init Dialog to make sure you dialog will fir the image in.
oh ya, this drooling idiot should know how to make a dialog box and create a class for AND override some functions.
wasn't that fun!.
http://www.codeguru.com/bitmap/index.shtml
A drolling idiot could do this as long as you remember..
-Add the functions from the page and make sure you replace your dialogs OnPaint with the one one the page
-Import your bitmap into your project and make sure that you replace the IDC_BITMAP from the code with the resource name of your newly imported bitmap.
-remember to write down the dimensions of your image so that you can place the size in the BitBlt function.
-It wouldn't hurt to put a MoveWindow(X,Y,Hieght,Widt
oh ya, this drooling idiot should know how to make a dialog box and create a class for AND override some functions.
wasn't that fun!.
ASKER
lucidity
Thanks for that resource however this 'drooling idiot' is NOT using MFC and does not want to impose the overheads of MFC on an application that is quite happily using windows API functions.
All other potential answerers to this question please note.
I DO NOT WANT A SOLUTION THAT REQUIRES MFC
Call me an old fuddy duddy if you wish but windows API functions will be quite sufficient thank you!
Thanks for that resource however this 'drooling idiot' is NOT using MFC and does not want to impose the overheads of MFC on an application that is quite happily using windows API functions.
All other potential answerers to this question please note.
I DO NOT WANT A SOLUTION THAT REQUIRES MFC
Call me an old fuddy duddy if you wish but windows API functions will be quite sufficient thank you!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Here's a quick and dirty non-MFC example that shows a (blank) splash screen and then open the main window:
// splashtest.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
#define MAX_LOADSTRING 100
// Stuff for SPLASH Window
HINSTANCE hSplashInstance, hSplashInst;
HWND hSplashWnd;
LRESULT CALLBACK SplashProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
RECT rt;
GetClientRect(hWnd, &rt);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
BOOL InitSplashInstance(HINSTAN CE hSplashInstance, int nCmdShow)
{
hSplashInst = hSplashInstance; // Store instance handle in our global variable
hSplashWnd = CreateWindow("SplashClass" , NULL, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hSplashInstance, NULL);
if (!hSplashWnd)
{
return FALSE;
}
ShowWindow(hSplashWnd, nCmdShow);
UpdateWindow(hSplashWnd);
return TRUE;
}
ATOM SplashRegisterClass(HINSTA NCE hSplashInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)SplashProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hSplashInstance;
wcex.hIcon = NULL;
wcex.hCursor = NULL;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "SplashClass";
wcex.hIconSm = NULL;
return RegisterClassEx(&wcex);
}
//
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRI NG]; // The title bar text
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Create and display a SPLASH SCREEN
HINSTANCE hSplashInst;
SplashRegisterClass(hSplas hInstance) ;
if(!InitSplashInstance(hSp lashInstan ce, nCmdShow)){
return FALSE;
}
//
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_SPLASHTEST, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance) ;
Sleep(2000);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance , (LPCTSTR)IDC_SPLASHTEST);
// Main message loop:
ShowWindow(hSplashWnd, SW_HIDE);
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg .hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage is only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_SPLASHTEST);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCSTR)IDC_SPLASHTEST;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass , szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
RECT rt;
GetClientRect(hWnd, &rt);
DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
// splashtest.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
#define MAX_LOADSTRING 100
// Stuff for SPLASH Window
HINSTANCE hSplashInstance, hSplashInst;
HWND hSplashWnd;
LRESULT CALLBACK SplashProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
RECT rt;
GetClientRect(hWnd, &rt);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
BOOL InitSplashInstance(HINSTAN
{
hSplashInst = hSplashInstance; // Store instance handle in our global variable
hSplashWnd = CreateWindow("SplashClass"
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hSplashInstance, NULL);
if (!hSplashWnd)
{
return FALSE;
}
ShowWindow(hSplashWnd, nCmdShow);
UpdateWindow(hSplashWnd);
return TRUE;
}
ATOM SplashRegisterClass(HINSTA
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)SplashProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hSplashInstance;
wcex.hIcon = NULL;
wcex.hCursor = NULL;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "SplashClass";
wcex.hIconSm = NULL;
return RegisterClassEx(&wcex);
}
//
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRI
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Create and display a SPLASH SCREEN
HINSTANCE hSplashInst;
SplashRegisterClass(hSplas
if(!InitSplashInstance(hSp
return FALSE;
}
//
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_SPLASHTEST, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance)
Sleep(2000);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance
// Main message loop:
ShowWindow(hSplashWnd, SW_HIDE);
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage is only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_SPLASHTEST);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCSTR)IDC_SPLASHTEST;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
RECT rt;
GetClientRect(hWnd, &rt);
DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
ASKER
jhance
Thanks for that code, I have made some slight changes, I removed the WM_COMMAND case statement from SplashProc (since IDM_EXIT was not defined when I compiled it) and added a DestroyWindow(hSplashWnd) after the 'Sleep' statement in WinMain. Most of the other routines I removed (WndProc, InitInstance, MyRegisterClass). This gave me a minimal splash screen program.
I need to do a little more however.
1. I don't know how to put an image into the window. This image should be from an external file (since the program I am writing does not have any resources of its own).
2. I have experimented with some windows styles for the splash screen, currently I am using WS_DLGFRAME but I can't seem to get rid of the title bar to make it more like a real splash screen.
3. I need to look into how I size the window. Do you know of any on-line resources explaining 'device-units' and how to check the size of the desk-top
Sorry for these additional questions, as I stated before I am not familiar with Windows API. If you feel it is appropriate I will increase the points if you can answer these further points.
Thanks for that code, I have made some slight changes, I removed the WM_COMMAND case statement from SplashProc (since IDM_EXIT was not defined when I compiled it) and added a DestroyWindow(hSplashWnd) after the 'Sleep' statement in WinMain. Most of the other routines I removed (WndProc, InitInstance, MyRegisterClass). This gave me a minimal splash screen program.
I need to do a little more however.
1. I don't know how to put an image into the window. This image should be from an external file (since the program I am writing does not have any resources of its own).
2. I have experimented with some windows styles for the splash screen, currently I am using WS_DLGFRAME but I can't seem to get rid of the title bar to make it more like a real splash screen.
3. I need to look into how I size the window. Do you know of any on-line resources explaining 'device-units' and how to check the size of the desk-top
Sorry for these additional questions, as I stated before I am not familiar with Windows API. If you feel it is appropriate I will increase the points if you can answer these further points.
1. I don't know how to put an image into the window. This image should be from an external file (since the program I am writing does not have any resources of its own).
Use CreateBitmap to create an bitmap and then use BitBlt to draw it into the spash window. It's probably easiest to do this starting with a dialog based bitmap image. They you just need to get it's handle.
2. I have experimented with some windows styles for the splash screen, currently I am using WS_DLGFRAME but I can't seem to get rid of the title bar to make it more like a real splash screen.
3. I need to look into how I size the window. Do you know of any on-line resources explaining 'device-units' and how to check the size of the desk-top
I changed the code as follows to create a non-captioned window and to size it to 320x240:
// splashtest.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
#define MAX_LOADSTRING 100
// Stuff for SPLASH Window
HINSTANCE hSplashInstance, hSplashInst;
HWND hSplashWnd, hMainWnd;
LRESULT CALLBACK SplashProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
RECT rt;
GetClientRect(hWnd, &rt);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
BOOL InitSplashInstance(HINSTAN CE hSplashInstance, int nCmdShow)
{
hSplashInst = hSplashInstance; // Store instance handle in our global variable
hSplashWnd = CreateWindowEx(WS_EX_CLIEN TEDGE | WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE,
"SplashClass", NULL, WS_POPUP,
100, 100, 320, 240, hMainWnd, NULL, hSplashInstance, NULL);
if (!hSplashWnd)
{
MessageBox(NULL, "ERROR", "ERROR", MB_OK);
return FALSE;
}
ShowWindow(hSplashWnd, nCmdShow);
UpdateWindow(hSplashWnd);
return TRUE;
}
ATOM SplashRegisterClass(HINSTA NCE hSplashInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)SplashProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hSplashInstance;
wcex.hIcon = NULL;
wcex.hCursor = NULL;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "SplashClass";
wcex.hIconSm = NULL;
return RegisterClassEx(&wcex);
}
//
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRI NG]; // The title bar text
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Create and display a SPLASH SCREEN
HINSTANCE hSplashInst;
SplashRegisterClass(hSplas hInstance) ;
if(!InitSplashInstance(hSp lashInstan ce, SW_SHOW)){
return FALSE;
}
//
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_SPLASHTEST, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance) ;
// Perform application initialization:
if (!InitInstance (hInstance, SW_HIDE))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance , (LPCTSTR)IDC_SPLASHTEST);
// Main message loop:
Sleep(1000);
ShowWindow(hSplashWnd, SW_HIDE);
ShowWindow(hMainWnd, SW_SHOW);
UpdateWindow(hMainWnd);
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg .hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage is only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_SPLASHTEST);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCSTR)IDC_SPLASHTEST;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
//HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hMainWnd = CreateWindow(szWindowClass , szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hMainWnd)
{
return FALSE;
}
ShowWindow(hMainWnd, nCmdShow);
UpdateWindow(hMainWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
RECT rt;
GetClientRect(hWnd, &rt);
DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
Use CreateBitmap to create an bitmap and then use BitBlt to draw it into the spash window. It's probably easiest to do this starting with a dialog based bitmap image. They you just need to get it's handle.
2. I have experimented with some windows styles for the splash screen, currently I am using WS_DLGFRAME but I can't seem to get rid of the title bar to make it more like a real splash screen.
3. I need to look into how I size the window. Do you know of any on-line resources explaining 'device-units' and how to check the size of the desk-top
I changed the code as follows to create a non-captioned window and to size it to 320x240:
// splashtest.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
#define MAX_LOADSTRING 100
// Stuff for SPLASH Window
HINSTANCE hSplashInstance, hSplashInst;
HWND hSplashWnd, hMainWnd;
LRESULT CALLBACK SplashProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
RECT rt;
GetClientRect(hWnd, &rt);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
BOOL InitSplashInstance(HINSTAN
{
hSplashInst = hSplashInstance; // Store instance handle in our global variable
hSplashWnd = CreateWindowEx(WS_EX_CLIEN
"SplashClass", NULL, WS_POPUP,
100, 100, 320, 240, hMainWnd, NULL, hSplashInstance, NULL);
if (!hSplashWnd)
{
MessageBox(NULL, "ERROR", "ERROR", MB_OK);
return FALSE;
}
ShowWindow(hSplashWnd, nCmdShow);
UpdateWindow(hSplashWnd);
return TRUE;
}
ATOM SplashRegisterClass(HINSTA
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)SplashProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hSplashInstance;
wcex.hIcon = NULL;
wcex.hCursor = NULL;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "SplashClass";
wcex.hIconSm = NULL;
return RegisterClassEx(&wcex);
}
//
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRI
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Create and display a SPLASH SCREEN
HINSTANCE hSplashInst;
SplashRegisterClass(hSplas
if(!InitSplashInstance(hSp
return FALSE;
}
//
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_SPLASHTEST, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance)
// Perform application initialization:
if (!InitInstance (hInstance, SW_HIDE))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance
// Main message loop:
Sleep(1000);
ShowWindow(hSplashWnd, SW_HIDE);
ShowWindow(hMainWnd, SW_SHOW);
UpdateWindow(hMainWnd);
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage is only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_SPLASHTEST);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCSTR)IDC_SPLASHTEST;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
//HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hMainWnd = CreateWindow(szWindowClass
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hMainWnd)
{
return FALSE;
}
ShowWindow(hMainWnd, nCmdShow);
UpdateWindow(hMainWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
RECT rt;
GetClientRect(hWnd, &rt);
DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
ASKER
jhance.
Thanks for those pointers. With a little research/trial/error on my part I think I have a working solution. I would welcome any comments you may make on the solution.
#include <windows.h>
HINSTANCE hSplashInstance;
HINSTANCE hSplashInst;
HWND hSplashWnd;
HBITMAP imgHandle;
BITMAP gBitMap;
LRESULT CALLBACK SplashProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
PAINTSTRUCT ps;
HDC hdc;
HDC hDCMem;
switch (message) {
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
hDCMem = CreateCompatibleDC(hdc);
SelectObject(hDCMem, imgHandle);
SetMapMode(hDCMem, GetMapMode(hdc));
// Draw the bitmap using the BitBlt function
if (BitBlt(
hdc, // The destination device context
0, 0, // Coordinates of the destination rectangle
gBitMap.bmWidth, // Width of the dest. and source rectangle
gBitMap.bmHeight,// Height of the dest. and source rectangle
hDCMem, 0, 0, SRCCOPY)) {
DeleteDC(hDCMem);
}
RECT rt;
GetClientRect(hWnd, &rt);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
BOOL InitSplashInstance(HINSTAN CE hSplashInstance, int nCmdShow) {
imgHandle = (HBITMAP)LoadImage(NULL,"s plash.bmp" ,NULL,NULL ,NULL,LR_L OADFROMFIL E);
if (!imgHandle) {
return FALSE;
}
GetObject(imgHandle, sizeof(BITMAP), &gBitMap);
hSplashInst = hSplashInstance; // Store instance handle in our global variable
hSplashWnd = CreateWindowEx(WS_EX_CLIEN TEDGE | WS_EX_DLGMODALFRAME |
WS_EX_WINDOWEDGE, "SplashClass", NULL, WS_POPUP, 100, 100, gBitMap.bmWidth, gBitMap.bmHeight,
NULL, NULL, hSplashInstance, NULL);
if (!hSplashWnd) {
return FALSE;
}
ShowWindow(hSplashWnd, nCmdShow);
UpdateWindow(hSplashWnd);
return TRUE;
}
ATOM SplashRegisterClass(HINSTA NCE hSplashInstance) {
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)SplashProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hSplashInstance;
wcex.hIcon = NULL;
wcex.hCursor = NULL;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "SplashClass";
wcex.hIconSm = NULL;
return RegisterClassEx(&wcex);
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow) {
// Create and display a SPLASH SCREEN
SplashRegisterClass(hSplas hInstance) ;
if(!InitSplashInstance(hSp lashInstan ce, nCmdShow)){
return FALSE;
}
Sleep(2000);
DestroyWindow(hSplashWnd);
Sleep(2000);
return(0);
}
Thanks for those pointers. With a little research/trial/error on my part I think I have a working solution. I would welcome any comments you may make on the solution.
#include <windows.h>
HINSTANCE hSplashInstance;
HINSTANCE hSplashInst;
HWND hSplashWnd;
HBITMAP imgHandle;
BITMAP gBitMap;
LRESULT CALLBACK SplashProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
PAINTSTRUCT ps;
HDC hdc;
HDC hDCMem;
switch (message) {
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
hDCMem = CreateCompatibleDC(hdc);
SelectObject(hDCMem, imgHandle);
SetMapMode(hDCMem, GetMapMode(hdc));
// Draw the bitmap using the BitBlt function
if (BitBlt(
hdc, // The destination device context
0, 0, // Coordinates of the destination rectangle
gBitMap.bmWidth, // Width of the dest. and source rectangle
gBitMap.bmHeight,// Height of the dest. and source rectangle
hDCMem, 0, 0, SRCCOPY)) {
DeleteDC(hDCMem);
}
RECT rt;
GetClientRect(hWnd, &rt);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
BOOL InitSplashInstance(HINSTAN
imgHandle = (HBITMAP)LoadImage(NULL,"s
if (!imgHandle) {
return FALSE;
}
GetObject(imgHandle, sizeof(BITMAP), &gBitMap);
hSplashInst = hSplashInstance; // Store instance handle in our global variable
hSplashWnd = CreateWindowEx(WS_EX_CLIEN
WS_EX_WINDOWEDGE, "SplashClass", NULL, WS_POPUP, 100, 100, gBitMap.bmWidth, gBitMap.bmHeight,
NULL, NULL, hSplashInstance, NULL);
if (!hSplashWnd) {
return FALSE;
}
ShowWindow(hSplashWnd, nCmdShow);
UpdateWindow(hSplashWnd);
return TRUE;
}
ATOM SplashRegisterClass(HINSTA
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)SplashProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hSplashInstance;
wcex.hIcon = NULL;
wcex.hCursor = NULL;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "SplashClass";
wcex.hIconSm = NULL;
return RegisterClassEx(&wcex);
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow) {
// Create and display a SPLASH SCREEN
SplashRegisterClass(hSplas
if(!InitSplashInstance(hSp
return FALSE;
}
Sleep(2000);
DestroyWindow(hSplashWnd);
Sleep(2000);
return(0);
}
Dialog pop up to choose directory. Choose "Developer Studio Components". There is Splash Screen. Insert it in your project and you have all the needed source.
PS
Your program should be MDI/SDI. if it is not create simple project of SDI ot MDI program insert splash screen and look at inserted code.
hope this helps