fix a notifier error that can't set icon from its exe file

This commit is contained in:
Jinhao 2016-06-05 02:36:38 +08:00
parent 108a31d907
commit 5ab0cfdd17
5 changed files with 84 additions and 61 deletions

View File

@ -1,7 +1,7 @@
/* /*
* Definition of Notifier * Definition of Notifier
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at

View File

@ -28,24 +28,9 @@
#include <nana/system/platform.hpp> #include <nana/system/platform.hpp>
#endif #endif
namespace nana{ #include "../../paint/image_accessor.hpp"
namespace paint
{
class image_accessor
{
public:
#if defined(NANA_WINDOWS)
static HICON icon(const nana::paint::image& img)
{
auto ico = dynamic_cast<paint::detail::image_ico*>(img.image_ptr_.get());
if(ico && ico->ptr())
return *(ico->ptr());
return nullptr;
}
#endif
};
}
namespace nana{
namespace detail{ namespace detail{
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)

View File

@ -1,17 +1,17 @@
/* /*
* Implementation of Notifier * Implementation of Notifier
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt) * http://www.boost.org/LICENSE_1_0.txt)
* *
* @file: nana/gui/notifier.cpp * @file: nana/gui/notifier.cpp
* @contributors: * @contributors:
* Jan * Jan
* Benjamin Navarro(pr#81) * Benjamin Navarro(pr#81)
*/ */
#include <nana/deploy.hpp> #include <nana/deploy.hpp>
#include <nana/gui/programming_interface.hpp> #include <nana/gui/programming_interface.hpp>
#include <nana/gui/notifier.hpp> #include <nana/gui/notifier.hpp>
@ -33,9 +33,11 @@
#include <iostream> #include <iostream>
#endif #endif
#include "../paint/image_accessor.hpp"
namespace nana namespace nana
{ {
typedef std::lock_guard<std::recursive_mutex> lock_guard; using lock_guard = std::lock_guard<std::recursive_mutex>;
struct notifier::implement struct notifier::implement
{ {
@ -47,13 +49,15 @@ namespace nana
detail::notifier_events events; detail::notifier_events events;
bool icon_added = false; bool icon_added = false;
std::size_t play_index; std::size_t play_index;
#if defined(NANA_WINDOWS)
HICON icon_handle = nullptr;
std::vector<HICON> icons;
void set_icon(HICON icon) paint::image icon;
::std::vector<paint::image> icons;
void set_icon(const paint::image& ico)
{ {
if (icon_handle) #if defined(NANA_WINDOWS)
auto ico_handle = paint::image_accessor::icon(ico);
if (ico_handle)
{ {
NOTIFYICONDATA icon_data; NOTIFYICONDATA icon_data;
memset(&icon_data, 0, sizeof icon_data); memset(&icon_data, 0, sizeof icon_data);
@ -62,13 +66,13 @@ namespace nana
icon_data.uID = id; icon_data.uID = id;
icon_data.uFlags = NIF_MESSAGE | NIF_ICON; icon_data.uFlags = NIF_MESSAGE | NIF_ICON;
icon_data.uCallbackMessage = nana::detail::messages::tray; icon_data.uCallbackMessage = nana::detail::messages::tray;
icon_data.hIcon = icon; icon_data.hIcon = ico_handle;
::Shell_NotifyIcon(icon_added ? NIM_MODIFY : NIM_ADD, &icon_data); ::Shell_NotifyIcon(icon_added ? NIM_MODIFY : NIM_ADD, &icon_data);
icon_added = true; icon_added = true;
} }
}
#endif #endif
}
}; };
arg_notifier::operator nana::arg_mouse() const arg_notifier::operator nana::arg_mouse() const
@ -287,12 +291,6 @@ namespace nana
icon_data.hWnd = reinterpret_cast<HWND>(impl_->native_handle); icon_data.hWnd = reinterpret_cast<HWND>(impl_->native_handle);
icon_data.uID = impl_->id; icon_data.uID = impl_->id;
::Shell_NotifyIcon(NIM_DELETE, &icon_data); ::Shell_NotifyIcon(NIM_DELETE, &icon_data);
if (impl_->icon_handle)
::DestroyIcon(impl_->icon_handle);
for (auto handle : impl_->icons)
::DestroyIcon(handle);
#endif #endif
API::umake_event(impl_->evt_destroy); API::umake_event(impl_->evt_destroy);
notifications::instance().cancel(impl_->native_handle, impl_->id); notifications::instance().cancel(impl_->native_handle, impl_->id);
@ -321,30 +319,23 @@ namespace nana
void notifier::icon(const std::string& icon_file) void notifier::icon(const std::string& icon_file)
{ {
#if defined(NANA_WINDOWS) paint::image image_ico{ icon_file };
auto pre_icon = impl_->icon_handle; auto icon_handle = paint::image_accessor::icon(image_ico);
auto ico = (HICON)::LoadImageW(0, to_wstring(icon_file).data(), IMAGE_ICON, 0, 0, LR_LOADFROMFILE); if (icon_handle)
if (ico)
{ {
impl_->icon_handle = ico;
impl_->ani_timer.stop(); impl_->ani_timer.stop();
impl_->play_index = 0; impl_->play_index = 0;
impl_->set_icon(impl_->icon_handle); impl_->set_icon(image_ico);
::DestroyIcon(pre_icon); impl_->icon = image_ico;
} }
#else
static_cast<void>(icon_file); //to eliminate unused parameter compiler warning
#endif
} }
void notifier::insert_icon(const std::string& icon_file) void notifier::insert_icon(const std::string& icon_file)
{ {
#if defined(NANA_WINDOWS) paint::image image_ico{ icon_file };
auto icon = (HICON)::LoadImage(0, to_wstring(icon_file).data(), IMAGE_ICON, 0, 0, LR_LOADFROMFILE); auto icon_handle = paint::image_accessor::icon(image_ico);
impl_->icons.push_back(icon); if (icon_handle)
#else impl_->icons.emplace_back(static_cast<paint::image&&>(image_ico));
static_cast<void>(icon_file); //to eliminate unused parameter compiler warning.
#endif
} }
void notifier::period(unsigned ms) void notifier::period(unsigned ms)

View File

@ -34,10 +34,27 @@
#include "detail/image_bmp.hpp" #include "detail/image_bmp.hpp"
#include "detail/image_ico.hpp" #include "detail/image_ico.hpp"
#include "image_accessor.hpp"
namespace nana namespace nana
{ {
namespace paint namespace paint
{ {
#if defined(NANA_WINDOWS)
HICON image_accessor::icon(const nana::paint::image& img)
{
auto ico = dynamic_cast<paint::detail::image_ico*>(img.image_ptr_.get());
if (ico && ico->ptr())
return *(ico->ptr());
return nullptr;
}
#else
int image_accessor::icon(const image&)
{
return 0;
}
#endif
namespace detail namespace detail
{ {
//class image_ico //class image_ico

View File

@ -0,0 +1,30 @@
/*
* Paint Image Accessor
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file nana/paint/image_accessor.hpp
* @brief A declaration of class image_accessor. It is used to access image private data, internal use.
*/
#ifndef NANA_PAINT_IMAGE_ACCESS_HEADER_INCLUDED
#define NANA_PAINT_IMAGE_ACCESS_HEADER_INCLUDED
namespace nana
{
namespace paint
{
class image_accessor
{
public:
#if defined(NANA_WINDOWS)
static HICON icon(const image&);
#else
static int icon(const image&);
#endif
};
}
}
#endif