|
Can I use this to make a splash screen for an .NET application.
ChungPn
|
|
|
|
|
First of thanks for the great class.
For some reason, after introducing the splash screen to my project, the main window would load in the background if another window was open. Calling SetForegroundWindow() did nothing.
Workaround:
Add
AllowSetForegroundWindow(GetCurrentProcessId());
As the last line in
BOOL CSplashWnd::Create()
just before the return statement. This allows the app to bring itself to the foreground then.
|
|
|
|
|
Detected memory leaks!
Dumping objects ->
spltest.cpp(30) : {63} client block at 0x00323090, subtype c0, 232 bytes long.
a CMySplashWnd object at $00323090, 232 bytes long
Object dump complete.
Apparently missing :
delete m_pSplashThread->m_pSplashScreen;
m_pSplashThread->m_pSplashScreen = NULL;
in CSplashFactory::Close() just after :
WaitForSingleObject(m_pSplashThread->m_hThread, INFINITE);
|
|
|
|
|
Thanks for that. I will add this to the TO DO list for the next release.
|
|
|
|
|
Just to let you know that v1.49 has been released on my web site at www.naughter.com which fixes this issue. The way I fix the memory leak is different that your proposed approach above.
|
|
|
|
|
Hi all,
Great little class. I haven't got the updated version, so this may already be there, but I found it useful to add code to make this a stay-on-top window in case the main app window comes up while the splash screen is up.
In CSplashWnd::Create I added the following after the "Create this window" code block:
<br />
CRect rectThisWindow;<br />
GetClientRect(rectThisWindow);<br />
SetWindowPos(&CWnd::wndTopMost, m_nWidth, m_nHeight, rectThisWindow.Width(), rectThisWindow.Height(), SWP_SHOWWINDOW);<br />
This is using MFC 7.1. I'm not sure if all previous versions of MFC support this.
|
|
|
|
|
First ,thank for you great code. But I think splashThread here can't play it's role. We want to use multi-thread here is because Main UI want to do some time-consuming initialization. So we show splash to our user by splashThread. But In your code, the thread is created and resume, then Sleep(5000), so main UI(thread) is block here. It can't go on and do more initialization. I think normal routine should be: splashthread go on but don't sleep.
Benny fun
|
|
|
|
|
|
Hi,
I'm using this class, and I've added two little functionalities that I want to share in case anybody finds them usefull.
First, I use OnSetCursor to show the waiting cursor:
BOOL CSplashWnd::OnSetCursor(CWnd *pWnd, UINT nHitTest, UINT message)
{ ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
return TRUE;
}
And I show my app version in the bitmap, too...
Modified OnPaint:
void CSplashWnd::OnPaint()
{
CPaintDC dc(this);
// Select the palette and bitmap to the DC
CDC memDC;
memDC.CreateCompatibleDC(&dc);
CBitmap *pOldBitmap = memDC.SelectObject(&m_Bitmap);
CPalette *pOldPalette = dc.SelectPalette(&m_Palette, FALSE);
dc.RealizePalette();
dc.BitBlt(0, 0, m_nWidth, m_nHeight, &memDC, 0, 0, SRCCOPY);
memDC.SelectObject(pOldBitmap);
dc.SelectPalette(pOldPalette, FALSE);
DrawVersionInfo(&dc);
}
These two are a bit long... one for getting the file version and the other for painting it...
void CSplashWnd::DrawVersionInfo(CDC *pDC)
{
LOGFONT lf;
ZeroMemory(&lf, sizeof(lf));
lf.lfHeight = -MulDiv(8, pDC->GetDeviceCaps(LOGPIXELSY), 72);
lf.lfWeight = FW_NORMAL;
lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;
// Create and select it
CFont newFont;
if (newFont.CreateFontIndirect(&lf))
{
CFont *pOldFont = pDC->SelectObject(&newFont);
pDC->SetTextColor(RGB(0,0,0));
pDC->SetBkMode(TRANSPARENT);
char szVersion[MAX_TEXT];
if (GetVersionString("raim.exe", szVersion))
{
pDC->TextOut(185, 170, szVersion, strlen(szVersion));
}
pDC->SelectObject(pOldFont);
}
}
BOOL CSplashWnd::GetVersionString(char *pszFileName, char *pszVersion)
{
DWORD dwSize, dwHandle;
dwSize = GetFileVersionInfoSize(pszFileName, &dwHandle);
if (dwSize == 0)
{
return FALSE;
}
unsigned char *lpData = new unsigned char [dwSize];
ASSERT(lpData != NULL);
if (lpData == NULL)
{
return FALSE;
}
ZeroMemory(lpData, dwSize);
GetFileVersionInfo(pszFileName, 0, dwSize, lpData);
VS_FIXEDFILEINFO *lpFixedFileInfo;
unsigned int len;
char szQuery[] = "\\";
VerQueryValue(lpData, szQuery, (LPVOID *)&lpFixedFileInfo, &len);
// 1.2.3.4 means version 1.2, release 3, build 4
char aux[MAX_TEXT];
wsprintf(aux, "%d.%d Release %d",
HIWORD(lpFixedFileInfo->dwFileVersionMS),
LOWORD(lpFixedFileInfo->dwFileVersionMS),
HIWORD(lpFixedFileInfo->dwFileVersionLS));
strcpy(pszVersion, aux);
delete [] lpData;
lpData = NULL;
return TRUE;
}
Isildur.
|
|
|
|
|
You could achieve this in a much more OO approach by deriving a class from CSplashWnd and implement your extensions in it's OnPaint handler. See the s\ample app code for an example of this. Also make sure you get the latest version from my web site at www.naughter.com. Also I've also got an MFC wrapper for version info's which would make your GetVersionString a whole lot simpler.
|
|
|
|
|
Thanks for your advices!
I also have a MFC wrapper for version info, too... But I didn't want to make it so complicated (now I see I failed).
I'm having a look at your web site in this moment... It's full of interesting programming resources!
Thanks again.
|
|
|
|
|
Thanks naughter for his class and Isildur for his functionalities, i incorporated them in the soft .
Although it's not that OO it's easy and it works.
BTW it's better drawing via the MemDC than the WindowDC,
so just before the function BitBlt() call DrawVersionInfo(&memDC) ;
Tout programme dont la fiabilité dépend de l'homme n'est pas fiable
|
|
|
|
|
Plz can anybody help to Flash intro to window application with MFC?
And can any body help me to remove the untitled that appears on the top of the application?
|
|
|
|
|
Hi Abou,
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
cs.style &= ~(LONG) FWS_ADDTOTITLE;
cs.lpszName = "<Put what you want here>";
return TRUE;
}
Regards,
Dan
|
|
|
|
|
Hi,
In your SDI example you close the splash screen after the call to ProcessShellCommand() as shown below
<br />
ParseCommandLine(cmdInfo);<br />
if (!ProcessShellCommand(cmdInfo))<br />
return FALSE;<br />
<br />
pSplashThread->HideSplash();<br />
I was wondering in a Dialog based application how do I know when the main UI is up so that I can close the splash screen.
Thanks,
Melwyn
|
|
|
|
|
Download the latest version from my web site (www.naughter.com). It includes a dialog based sample in addition to the normal SDI / MDI style.
|
|
|
|
|
Hi,
Thanks for the reply.
I went to your site and went to the splasher section (http://www.naughter.com/splasher.html), however I couldn't find the Dialog based sample.
Anyway would the last statement in OnInitDialog() be a good place to close the splash screen?
Regards,
Melwyn
|
|
|
|
|
I was definite there was a dialog based example in that download, but seemly not. Yes, putting the call in Close in your dialog classes OnInitDialog would do the trick nicely.
|
|
|
|
|
There isnt one on my machine....
Appreciate your help,
ns
|
|
|
|
|
This is an MFC library to support Unicode programming. It only gets installed when you do a custom install of Visual Studio. Either do a reinstall of VS or build one of the non unicode build configurations such as "Win32 Debug" or "Win32 Release".
|
|
|
|
|
Thanks for the prompt response!!
Appreciate your help,
ns
|
|
|
|
|
I have an imaging application that I would like to use splasher to display a logo and a progress bar.
It appears the only way a progress bar can be added is to edit the CSplashWnd class. Is this correct?
If I add the CProgressCtrl to the CSplashWnd class, can I update the prog control with out having to call UpdateData.
|
|
|
|
|
Just derive a class from CSplashWnd and add your CProgressCtrl there. You should use DDX_Control instead of UpdateData as UpdateData will update all the controls on the window. BTW, you will want to watch for multithreading issues as remember the splash screen is running in a separate thread so do not "dot into" your progress control from the main thread when you want to update it. Also make sure you have the latest version from my web site which supports end user specification of a derived class.
|
|
|
|
|
Hello,
I writed a MDI application, with a LoginDLG opened before creata MainFrame (something like Initinstance ... do some work ... open LoginDLG modal ... create and show MainFrame). Before integration of Splasher, when I launch my application and after some seconds, Dialog appear - with focus, fine. I try now to add this class into my application: InitInstance ... create & resume splash thread ... do some work ... hide splash ... open LoginDLG modal ... and Login DLG doesn't have focus; focus stay on desktop (or explorer or VC++ depending from where I launch application).
If I doesn't Hide splash, LoginDLG have focus correctly.
I try to add this->SetFocus or this->ShowWindow in InitDialog without any result.
Any idea ?
David D.
|
|
|
|
|
The main application must be visible before you hide the splash screen to allow the ThreadInput to be correctly passed. What you need to do here is hide the splash after the dialog is displayed.
Hope that helps
|
|
|
|