Fixed: #869 Crash when updating Windows 7 progress bar

This commit is contained in:
kervala 2010-05-22 13:42:13 +02:00
parent 561e3cdbb6
commit b77ca97431
5 changed files with 174 additions and 30 deletions

View file

@ -0,0 +1,51 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NL_SYSTEM_UTILS_H
#define NL_SYSTEM_UTILS_H
#include "types_nl.h"
#include "ucstring.h"
namespace NLMISC
{
/*
* Operating system miscellaneous functions (all methods and variables should be static)
* \author Kervala
* \date 2010
*/
class CSystemUtils
{
static void *s_window;
public:
/// Initialize data which needs it before using them.
static bool init();
/// Uninitialize data when they won't be used anymore.
static bool uninit();
/// Set the window which will be used by some functions.
static void setWindow(void *window);
/// Create/update a progress bar with an appearance depending on system.
static bool updateProgressBar(uint value, uint total);
};
} // NLMISC
#endif // NL_SYSTEM_UTILS_H

View file

@ -1541,6 +1541,14 @@
RelativePath="..\include\nel\misc\inter_window_msg_queue.h" RelativePath="..\include\nel\misc\inter_window_msg_queue.h"
> >
</File> </File>
<File
RelativePath=".\misc\system_utils.cpp"
>
</File>
<File
RelativePath="..\include\nel\misc\system_utils.h"
>
</File>
<File <File
RelativePath="..\include\nel\misc\timeout_assertion_thread.h" RelativePath="..\include\nel\misc\timeout_assertion_thread.h"
> >

View file

@ -0,0 +1,98 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdmisc.h"
#include "nel/misc/system_utils.h"
#ifdef NL_OS_WINDOWS
#define NOMINMAX
#include <windows.h>
#ifdef _WIN32_WINNT_WIN7
// only supported by Windows 7 Platform SDK
#include <ShObjIdl.h>
#define TASKBAR_PROGRESS 1
#endif
#endif
using namespace std;
namespace NLMISC {
void *CSystemUtils::s_window = NULL;
bool CSystemUtils::init()
{
#ifdef NL_OS_WINDOWS
// initialize COM
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (FAILED(hr)) return false;
#endif
return true;
}
bool CSystemUtils::uninit()
{
#ifdef NL_OS_WINDOWS
// uninitialize COM
CoUninitialize();
#endif
return true;
}
void CSystemUtils::setWindow(void *window)
{
s_window = window;
}
bool CSystemUtils::updateProgressBar(uint value, uint total)
{
#ifdef TASKBAR_PROGRESS
if (s_window == NULL)
{
nlwarning("No window has be set with CSystemUtils::setWindow(), progress bar can't be displayed");
return false;
}
ITaskbarList3 *pTaskbarList = NULL;
// instanciate the taskbar control COM object
HRESULT hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pTaskbarList));
// error can be ignored because Windows versions before Windows 7 doesn't support it
if (FAILED(hr) || !pTaskbarList) return false;
if (total)
{
// update the taskbar progress
hr = pTaskbarList->SetProgressValue((HWND)s_window, (ULONGLONG)value, (ULONGLONG)total);
}
else
{
// don't update anymore the progress
hr = pTaskbarList->SetProgressState((HWND)s_window, value == 0 ? TBPF_INDETERMINATE:TBPF_NOPROGRESS);
}
// release the interface
pTaskbarList->Release();
#endif // TASKBAR_PROGRESS
return true;
}
} // NLMISC

View file

@ -33,6 +33,7 @@
#include "nel/misc/class_registry.h" #include "nel/misc/class_registry.h"
#include "nel/misc/system_info.h" #include "nel/misc/system_info.h"
#include "nel/misc/block_memory.h" #include "nel/misc/block_memory.h"
#include "nel/misc/system_utils.h"
// 3D Interface. // 3D Interface.
#include "nel/3d/bloom_effect.h" #include "nel/3d/bloom_effect.h"
#include "nel/3d/u_driver.h" #include "nel/3d/u_driver.h"
@ -899,6 +900,10 @@ void prelogInit()
return; return;
} }
// initialize system utils class
CSystemUtils::init();
CSystemUtils::setWindow(Driver->getDisplay());
CLoginProgressPostThread::getInstance().step(CLoginStep(LoginStep_VideoModeSetupHighColor, "login_step_video_mode_setup_high_color")); CLoginProgressPostThread::getInstance().step(CLoginStep(LoginStep_VideoModeSetupHighColor, "login_step_video_mode_setup_high_color"));
#ifdef NL_OS_WINDOWS #ifdef NL_OS_WINDOWS

View file

@ -23,11 +23,6 @@
#include "nel/3d/u_texture.h" #include "nel/3d/u_texture.h"
#include "game_share/ryzom_version.h" #include "game_share/ryzom_version.h"
#include "nel/misc/i18n.h" #include "nel/misc/i18n.h"
#if defined(NL_OS_WINDOWS) && defined(_WIN32_WINNT_WIN7)
// only supported by Windows 7 Platform SDK
#include <ShObjIdl.h>
#define TASKBAR_PROGRESS 1
#endif
#include "continent.h" #include "continent.h"
#include "weather.h" #include "weather.h"
#include "weather_manager_client.h" #include "weather_manager_client.h"
@ -37,6 +32,7 @@
#include "client_cfg.h" #include "client_cfg.h"
#include "interface_v3/custom_mouse.h" #include "interface_v3/custom_mouse.h"
#include "bg_downloader_access.h" #include "bg_downloader_access.h"
#include "nel/misc/system_utils.h"
using namespace std; using namespace std;
using namespace NLMISC; using namespace NLMISC;
@ -52,10 +48,6 @@ extern uint TipsOfTheDayIndex;
extern ucstring TipsOfTheDay; extern ucstring TipsOfTheDay;
extern bool UseEscapeDuringLoading; extern bool UseEscapeDuringLoading;
#ifdef TASKBAR_PROGRESS
static ITaskbarList3* pTaskbarList = NULL;
#endif
CProgress::CProgress () CProgress::CProgress ()
{ {
_LastUpdate = ryzomGetLocalTime (); _LastUpdate = ryzomGetLocalTime ();
@ -63,22 +55,10 @@ CProgress::CProgress ()
pushCropedValues (0, 1); pushCropedValues (0, 1);
ApplyTextCommands = false; ApplyTextCommands = false;
_TPCancelFlag = false; _TPCancelFlag = false;
#ifdef TASKBAR_PROGRESS
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
// instanciate the taskbar control COM object
// if (SUCCEEDED(hr)) CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pTaskbarList));
#endif // TASKBAR_PROGRESS
} }
CProgress::~CProgress () CProgress::~CProgress ()
{ {
#ifdef TASKBAR_PROGRESS
if (pTaskbarList) pTaskbarList->Release();
CoUninitialize();
#endif // TASKBAR_PROGRESS
} }
void CProgress::setFontFactor(float temp) void CProgress::setFontFactor(float temp)
@ -394,10 +374,15 @@ void CProgress::internalProgress (float value)
CCDBNodeBranch::flushObserversCalls(); CCDBNodeBranch::flushObserversCalls();
//CustomMouse.updateCursor(); //CustomMouse.updateCursor();
#ifdef TASKBAR_PROGRESS // update system dependent progress bar
// update the taskbar progress static uint previousValue = 0;
if (pTaskbarList) pTaskbarList->SetProgressValue((HWND)Driver->getDisplay(), ULONGLONG(value * 1000), 1000); uint currentValue = (uint)(value*100.0f);
#endif // TASKBAR_PROGRESS
if (currentValue != previousValue)
{
CSystemUtils::updateProgressBar(currentValue, 100);
previousValue = currentValue;
}
} }
@ -430,9 +415,6 @@ void CProgress::release()
void CProgress::finish() void CProgress::finish()
{ {
#ifdef TASKBAR_PROGRESS // stop system dependent progress bar
// don't update anymore the progress CSystemUtils::updateProgressBar(1, 0);
if (pTaskbarList && Driver) pTaskbarList->SetProgressState((HWND)Driver->getDisplay(), TBPF_NOPROGRESS);
#endif // TASKBAR_PROGRESS
} }