*/
#include "StdAfx.h"
+#include "sf_windows.h"
#include "icon.h"
namespace sf {
-icon::icon()
-{
-}
-icon::~icon()
-{
-}
+
+ icon::icon(icon_holder& ic)
+ {
+ icon_.reset(::CopyIcon(ic.get()));
+ analyze();
+ }
+
+ icon::icon(icon_holder&& ic)
+ {
+ std::swap(ic,icon_);
+ analyze();
+ }
+
+ icon::icon(bitmap_holder& bmp_color,int width,int height)
+ : width_(width),height_(height)
+ {
+ bitmap_holder hmb(::CreateBitmap(width,height,1,1,NULL));
+ BITMAP bmp;
+ ::GetObjectW(bmp_color.get(),sizeof(BITMAP),&bmp);
+ bits_per_pixel_ = bmp.bmBitsPixel;
+
+ ICONINFO ii;
+ ii.fIcon = TRUE;
+ ii.xHotspot = 0;
+ ii.yHotspot = 0;
+ ii.hbmMask = hmb.get();
+ ii.hbmColor = bmp_color.get();
+ icon_.reset(::CreateIconIndirect(&ii));
+ }
+
+ icon::icon(ID2D1BitmapPtr& ptr)
+ {
+ ID2D1FactoryPtr factory;
+ ptr->GetFactory(&factory);
+
+ D2D1_SIZE_U size(ptr->GetPixelSize());
+ // \83r\83b\83g\83}\83b\83v\83w\83b\83_\82Ì\83Z\83b\83g\83A\83b\83v
+ BITMAPV5HEADER bi = {0};
+ bi.bV5Size = sizeof(BITMAPV5HEADER);
+ bi.bV5Width = size.width;
+ bi.bV5Height = size.height;
+ bi.bV5Planes = 1;
+ bi.bV5BitCount = 32;
+ bi.bV5Compression = BI_BITFIELDS;
+ bi.bV5RedMask = 0x00FF0000;
+ bi.bV5GreenMask = 0x0000FF00;
+ bi.bV5BlueMask = 0x000000FF;
+ bi.bV5AlphaMask = 0xFF000000;
+
+ // \83f\83X\83N\83g\83b\83vHDC\82Ì\8eæ\93¾
+ get_dc dc(NULL);
+
+ // DIB\83Z\83N\83V\83\87\83\93\82Ì\8dì\90¬
+ void *bits;// \93¾\82ç\82ê\82é\83r\83b\83g\83}\83b\83v
+ bitmap_holder bmp(
+ ::CreateDIBSection(
+ dc.get(),reinterpret_cast<BITMAPINFO *>(&bi),DIB_RGB_COLORS,&bits,NULL,0));
+ {
+ // \8cÝ\8a·DC\82Ì\8dì\90¬
+ compatible_dc cdc(dc.get());
+ {
+ // \95`\89æ\90æ\82Ö\82Ì\90Ø\82è\91Ö\82¦
+ select_object s(cdc.get(),bmp.get());
+
+ // DC\8cÝ\8a·\83\8c\83\93\83_\81[\83^\81[\83Q\83b\83g\82Ì\83Z\83b\83g\83A\83b\83v
+ D2D1_RENDER_TARGET_PROPERTIES
+ props = D2D1::RenderTargetProperties(
+ D2D1_RENDER_TARGET_TYPE_DEFAULT,
+ D2D1::PixelFormat(
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ D2D1_ALPHA_MODE_PREMULTIPLIED),
+ 0,
+ 0,
+ D2D1_RENDER_TARGET_USAGE_NONE,
+ D2D1_FEATURE_LEVEL_DEFAULT
+ );
+
+ ID2D1DCRenderTargetPtr dcr;
+ throw_if_err<>()(factory->CreateDCRenderTarget(&props,&dcr));
+ RECT rect = {0,0,size.width,size.height};
+ // \8cÝ\8a·DC\82Ö\82Ì\83o\83C\83\93\83h
+ throw_if_err<>()(dcr->BindDC(cdc.get(),&rect));
+ dcr->DrawBitmap(ptr);
+ }
+ }
+ icon(bmp,size.width,size.height);
+ };
+
+
+ icon::icon(boost::filesystem3::wpath& path)
+ {
+ icon_.reset(
+ reinterpret_cast<HICON>(
+ LoadImageW(NULL,path.native().c_str(),IMAGE_ICON,0,0,LR_DEFAULTSIZE | LR_LOADFROMFILE)));
+ }
+
+ icon::~icon()
+ {
+
+ }
+
+ void icon::analyze()
+ {
+ ::ICONINFOEXW info;
+ ::GetIconInfoExW(icon_.get(),&info);
+ BITMAP bmp;
+ ::GetObjectW(info.hbmColor,sizeof(BITMAP),&bmp);
+ width_ = bmp.bmWidth;
+ height_ = bmp.bmHeight;
+ bits_per_pixel_ = bmp.bmBitsPixel;
+ }
+
+ icon& icon::operator= (icon& i)
+ {
+ BOOST_ASSERT(icon_ != i.icon_);
+ if(icon_ == i.icon_) return *this;
+ icon_.reset(::CopyIcon(i.icon_.get()));
+ width_ = i.width_;
+ height_ = i.height_;
+ bits_per_pixel_ = i.bits_per_pixel_;
+ return *this;
+ }
+
+ //icon_ptr icon::create_icon()
+ //{
+
+ // // \83r\83b\83g\83}\83b\83v\83w\83b\83_\82Ì\83Z\83b\83g\83A\83b\83v
+ // BITMAPV5HEADER bi = {0};
+ // bi.bV5Size = sizeof(BITMAPV5HEADER);
+ // bi.bV5Width = width_;
+ // bi.bV5Height = height_;
+ // bi.bV5Planes = 1;
+ // bi.bV5BitCount = 32;
+ // bi.bV5Compression = BI_BITFIELDS;
+ // bi.bV5RedMask = 0x00FF0000;
+ // bi.bV5GreenMask = 0x0000FF00;
+ // bi.bV5BlueMask = 0x000000FF;
+ // bi.bV5AlphaMask = 0xFF000000;
+
+ // // \83f\83X\83N\83g\83b\83vHDC\82Ì\8eæ\93¾
+ // get_dc dc(NULL);
+
+ // // DIB\83Z\83N\83V\83\87\83\93\82Ì\8dì\90¬
+ // void *bits;// \93¾\82ç\82ê\82é\83r\83b\83g\83}\83b\83v
+ // gdi_object<HBITMAP> bmp(
+ // ::CreateDIBSection(
+ // dc.get(),reinterpret_cast<BITMAPINFO *>(&bi),DIB_RGB_COLORS,&bits,NULL,0));
+ // {
+ // // \8cÝ\8a·DC\82Ì\8dì\90¬
+ // compatible_dc cdc(dc.get());
+ // {
+ // // \95`\89æ\90æ\82Ö\82Ì\90Ø\82è\91Ö\82¦
+ // select_object s(cdc.get(),bmp);
+
+ // // DC\8cÝ\8a·\83\8c\83\93\83_\81[\83^\81[\83Q\83b\83g\82Ì\83Z\83b\83g\83A\83b\83v
+ // D2D1_RENDER_TARGET_PROPERTIES
+ // props = D2D1::RenderTargetProperties(
+ // D2D1_RENDER_TARGET_TYPE_DEFAULT,
+ // D2D1::PixelFormat(
+ // DXGI_FORMAT_B8G8R8A8_UNORM,
+ // D2D1_ALPHA_MODE_PREMULTIPLIED),
+ // 0,
+ // 0,
+ // D2D1_RENDER_TARGET_USAGE_NONE,
+ // D2D1_FEATURE_LEVEL_DEFAULT
+ // );
+
+ // ID2D1DCRenderTargetPtr dcr;
+ // throw_if_err<>()(factory_->CreateDCRenderTarget(&props,&dcr));
+ // RECT rect = {0,0,w,h};
+ // // \8cÝ\8a·DC\82Ö\82Ì\83o\83C\83\93\83h
+ // throw_if_err<>()(dcr->BindDC(cdc.get(),&rect));
+
+ // // \83u\83\89\83V\82Ì\83Z\83b\83g\83A\83b\83v(\94w\8ci\82Ì\90Ô\8aÛ\81j
+ // ID2D1SolidColorBrushPtr brush_e;
+ // throw_if_err<>()(
+ // dcr->CreateSolidColorBrush(
+ // D2D1::ColorF(D2D1::ColorF::Red,0.8f), &brush_e));
+
+ // // \83A\83C\83R\83\93\82É\95`\89æ\82·\82é\95¶\8e\9a\82Ì\90¶\90¬
+ // std::wstring t(L"S.F.\nTimer");
+ // D2D1_RECT_F l = D2D1::RectF(0.0f,0.0f,width_,height_);
+ // // Text Format\82Ì\8dì\90¬
+ // IDWriteTextFormatPtr f;
+ // write_factory_->CreateTextFormat(
+ // L"\83\81\83C\83\8a\83I", // Font family name.
+ // NULL, // Font collection (NULL sets it to use the system font collection).
+ // DWRITE_FONT_WEIGHT_REGULAR,
+ // DWRITE_FONT_STYLE_NORMAL,
+ // DWRITE_FONT_STRETCH_NORMAL,
+ // 10.0f,
+ // L"ja-jp",
+ // &f
+ // );
+ // f->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);
+ // f->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);
+
+ // // \95¶\8e\9a\95`\89æ\97p\83u\83\89\83V\82Ì\83Z\83b\83g\83A\83b\83v
+ // ID2D1SolidColorBrushPtr brush;
+ // dcr->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black), &brush);
+ // // \95`\89æ\8aJ\8en
+ // dcr->BeginDraw();
+ // // \83r\83b\83g\83}\83b\83v\83N\83\8a\83A
+ // dcr->Clear(D2D1::ColorF(D2D1::ColorF::Black,0.0f));
+ // // \90Ô\8aÛ\82ð\95`\82
+ // dcr->FillEllipse(D2D1::Ellipse(D2D1::Point2F(16.0f,16.0f),14,14),brush_e);
+ // // \83e\83L\83X\83g\82ð\95\\8e¦\82·\82é
+ // dcr->DrawTextW(t.c_str(),t.size(),f,&l,brush);
+ // // \95`\89æ\8fI\97¹
+ // dcr->EndDraw();
+ // }
+ // }
+ //}
}
*/
namespace sf {
+
+struct icon_deleter {
+ typedef HICON pointer;
+ void operator ()(HICON handle) {
+ if (handle) {
+ ::DestroyIcon(handle);
+ }
+ }
+};
+
+typedef std::unique_ptr<HICON,icon_deleter> icon_holder;
+
+/**
+
+*/
struct icon
{
public:
- icon();
+ icon(){};
+ explicit icon(icon_holder& ic);
+ explicit icon(icon_holder&& ic);
+ icon(bitmap_holder& bmp_color,int width = ::GetSystemMetrics(SM_CXICON),int height = ::GetSystemMetrics(SM_CYICON));
+ icon(ID2D1BitmapPtr& ptr);
+ icon(boost::filesystem3::wpath& path);
+
virtual ~icon();
+
+ HICON get() {return icon_.get();};
+
+ icon(icon& i) : width_(i.width_),height_(i.height_),bits_per_pixel_(i.bits_per_pixel_)
+ {
+ icon_.reset(::CopyIcon(i.icon_.get()));
+ }
+
+ icon(icon&& i) : width_(i.width_),height_(i.height_),bits_per_pixel_(i.bits_per_pixel_)
+ {
+ std::swap(icon_,i.icon_);
+ }
+
+ icon& operator= (icon&& i)
+ {
+ BOOST_ASSERT(icon_ != i.icon_);
+ if(icon_ == i.icon_) return *this;
+ std::swap(icon_,i.icon_);
+ width_ = i.width_;
+ height_ = i.height_;
+ bits_per_pixel_ = i.bits_per_pixel_;
+ return *this;
+ }
+
+ icon& operator= (icon& i);
+
+ void swap(icon& i)
+ {
+ std::swap(icon_,i.icon_);
+ std::swap(width_,i.width_);
+ std::swap(height_,i.height_);
+ std::swap(bits_per_pixel_,i.bits_per_pixel_);
+ }
+
private:
-};
+
+ void analyze();
+ //ID2D1DCRenderTargetPtr dcr_;
+ //ID2D1BitmapPtr bitmap_;
+ int width_;
+ int height_;
+ int bits_per_pixel_;
+ icon_holder icon_;
+ };
}
void operator()(HRESULT hr) {if(hr != S_OK){throw Exc(hr);}}
};
+ /* inline template <class Exc = win32_error_exception> void throw_if_err<>()(HRESULT hr)
+ {
+ if(hr != S_OK){throw Exc(hr);}
+ };*/
+
ID2D1BitmapPtr load_bitmap_from_file(
ID2D1HwndRenderTargetPtr render_target,
//};
+
struct handle_deleter {
typedef HANDLE pointer;
void operator ()(HANDLE handle) {
}
};
+ struct HBITMAP_deleter {
+ typedef HBITMAP pointer;
+ void operator ()(HBITMAP handle) {
+ if (handle) {
+ ::DeleteObject(handle);
+ }
+ }
+ };
+
//template <typename Handle,typename Handle_Deleter>
//struct handle_holder {
// typedef boost::unique_ptr<Handle,Handle_Deleter> holder_type;
//};
typedef std::unique_ptr<HANDLE,handle_deleter> handle_holder;
+ typedef std::unique_ptr<HBITMAP,HBITMAP_deleter> bitmap_holder;
typedef device_context<d2_dc> d2_dc_type;
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/convenience.hpp>
+#include <boost/filesystem/fstream.hpp>
#include "sf_com.h"
//#include <d3d10_1.h>
//#include <d3d10.h>
#include <boost/foreach.hpp>
#include "toplevel_window.h"
#include "sf_windows.h"
+#include "icon.h"
#include "timer.h"
#include "exception.h"
safe_release(write_factory_);
};
- // äº\92æ\8f\9bã\83\93ã\83\83ã\83\88ã\83\9eã\83\83ã\83\97ã\81«Direct2Dã\81«描画し、
+ // äº\92æ\8f\9bã\83\93ã\83\83ã\83\88ã\83\9eã\83\83ã\83\97ã\81«Direct2Dã\81§描画し、
// アイコンにして返すメソッド
- HICON create_icon()
+ icon create_icon()
{
// アイコンサイズの取得
- uint32_t w(::GetSystemMetrics(SM_CXICON))
- ,h(::GetSystemMetrics(SM_CYICON));
-
+ icon_size_ = D2D1::SizeU(::GetSystemMetrics(SM_CXICON),::GetSystemMetrics(SM_CYICON));
// ビットマップヘッダのセットアップ
BITMAPV5HEADER bi = {0};
bi.bV5Size = sizeof(BITMAPV5HEADER);
- bi.bV5Width = w;
- bi.bV5Height = h;
+ bi.bV5Width = icon_size_.width;
+ bi.bV5Height = icon_size_.height;
bi.bV5Planes = 1;
bi.bV5BitCount = 32;
bi.bV5Compression = BI_BITFIELDS;
bi.bV5AlphaMask = 0xFF000000;
// デスクトップHDCの取得
- get_dc dc(NULL);
+ {
+ get_dc dc(NULL);
- // DIBセクションの作成
- void *bits;// 得られるビットマップ
- gdi_object<HBITMAP> bmp(
- ::CreateDIBSection(
- dc.get(),reinterpret_cast<BITMAPINFO *>(&bi),DIB_RGB_COLORS,&bits,NULL,0));
- {
- // 互換DCの作成
- compatible_dc cdc(dc.get());
- {
- // 描画先への切り替え
- select_object s(cdc.get(),bmp);
+ // DIBセクションの作成
+ bmp_.reset(
+ ::CreateDIBSection(
+ dc.get(),reinterpret_cast<BITMAPINFO *>(&bi),DIB_RGB_COLORS,0,NULL,0));
+ {
// DC互換レンダーターゲットのセットアップ
D2D1_RENDER_TARGET_PROPERTIES
D2D1_FEATURE_LEVEL_DEFAULT
);
- ID2D1DCRenderTargetPtr dcr;
- throw_if_err<>()(factory_->CreateDCRenderTarget(&props,&dcr));
- RECT rect = {0,0,w,h};
- // 互換DCへのバインド
- throw_if_err<>()(dcr->BindDC(cdc.get(),&rect));
-
- // ブラシのセットアップ(背景の赤丸)
- ID2D1SolidColorBrushPtr brush_e;
- throw_if_err<>()(
- dcr->CreateSolidColorBrush(
- D2D1::ColorF(D2D1::ColorF::Red,0.8f), &brush_e));
-
- // アイコンに描画する文字の生成
- std::wstring t(L"S.F.\nTimer");
- D2D1_RECT_F l = D2D1::RectF(0.0f,0.0f,w,h);
- // Text Formatの作成
- IDWriteTextFormatPtr f;
- write_factory_->CreateTextFormat(
- L"メイリオ", // Font family name.
- NULL, // Font collection (NULL sets it to use the system font collection).
- DWRITE_FONT_WEIGHT_REGULAR,
- DWRITE_FONT_STYLE_NORMAL,
- DWRITE_FONT_STRETCH_NORMAL,
- 10.0f,
- L"ja-jp",
- &f
- );
- f->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);
- f->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);
-
- // 文字描画用ブラシのセットアップ
- ID2D1SolidColorBrushPtr brush;
- dcr->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black), &brush);
- // 描画開始
- dcr->BeginDraw();
- // ビットマップクリア
- dcr->Clear(D2D1::ColorF(D2D1::ColorF::Black,0.0f));
- // 赤丸を描く
- dcr->FillEllipse(D2D1::Ellipse(D2D1::Point2F(16.0f,16.0f),14,14),brush_e);
- // テキストを表示する
- dcr->DrawTextW(t.c_str(),t.size(),f,&l,brush);
- // 描画終了
- dcr->EndDraw();
+ throw_if_err<>()(factory_->CreateDCRenderTarget(&props,&dcr_));
}
}
- // HBITMAPからアイコンを作成する
+ draw_icon();
+ return std::move(icon(bmp_,icon_size_.width,icon_size_.height));
+ };
+
+ void draw_icon()
+ {
+ get_dc dc(NULL);
+ // 互換DCの作成
+ compatible_dc cdc(dc.get());
+ {
+ // 描画先への切り替え
+ select_object s(cdc.get(),bmp_.get());
+ RECT rect = {0,0,icon_size_.width,icon_size_.height};
+ // 互換DCへのバインド
+ dcr_->BindDC(cdc.get(),&rect);
+ //// ブラシのセットアップ(背景の赤丸)
+ //ID2D1SolidColorBrushPtr brush_e;
+ //throw_if_err<>()(
+ // dcr->CreateSolidColorBrush(
+ // D2D1::ColorF(D2D1::ColorF::Red,0.8f), &brush_e));
+
+ // アイコンに描画する文字の生成
+ std::wstring t((boost::wformat(L"%s\n%02d:%02d") % (status_ == active?L"活動中":L"休憩中") % (result_time_ / 60) % (result_time_ % 60)).str());
+ D2D1_RECT_F l = D2D1::RectF(0.0f,0.0f,icon_size_.width,icon_size_.height);
+ // Text Formatの作成
+ IDWriteTextFormatPtr f;
+ write_factory_->CreateTextFormat(
+ L"メイリオ", // Font family name.
+ NULL, // Font collection (NULL sets it to use the system font collection).
+ DWRITE_FONT_WEIGHT_REGULAR,
+ DWRITE_FONT_STYLE_NORMAL,
+ DWRITE_FONT_STRETCH_NORMAL,
+ 10.0f,
+ L"ja-jp",
+ &f
+ );
+
+ f->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);
+ f->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);
+
+ // 文字描画用ブラシのセットアップ
+ ID2D1SolidColorBrushPtr brush;
+ dcr_->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black), &brush);
+ // 描画開始
+ dcr_->BeginDraw();
+ // ビットマップクリア
+ dcr_->Clear(D2D1::ColorF(D2D1::ColorF::Black,0.0f));
+ //// 赤丸を描く
+ //dcr_->FillEllipse(D2D1::Ellipse(D2D1::Point2F(16.0f,16.0f),14,14),brush_e);
+ // テキストを表示する
+ dcr_->DrawTextW(t.c_str(),t.size(),f,&l,brush);
+ // 描画終了
+ dcr_->EndDraw();
+ }
+
+
+ }
- // 空のモノクロビットマップを作成する。
- gdi_object<HBITMAP> hmb(::CreateBitmap(w,h,1,1,NULL));
- ICONINFO ii;
- ii.fIcon = TRUE;
- ii.xHotspot = 0;
- ii.yHotspot = 0;
- ii.hbmMask = hmb;
- ii.hbmColor = bmp;
- return CreateIconIndirect(&ii);
- };
// -------------------------------------------------------------------
// ウィンドウプロシージャ
// -------------------------------------------------------------------
switch (status_)
{
case active:
+ {
+ --result_time_;
+ taskbar_.progress_value(*this,result_time_,INTERVAL_SEC1);
- --result_time_;
- taskbar_.progress_value(*this,result_time_,INTERVAL_SEC1);
+ if(result_time_ == 0)
+ {
+ ::MessageBeep(MB_ICONEXCLAMATION);
+ status_ = sleep;
+ result_time_ = INTERVAL_SEC2;
+ taskbar_.progress_state(*this,taskbar::paused);
+ taskbar_.progress_value(*this,result_time_,INTERVAL_SEC2);
+ text(std::wstring(L"ミニタイマー(休憩中)"));
+ }
- if(result_time_ == 0)
- {
- ::MessageBeep(MB_ICONEXCLAMATION);
- status_ = sleep;
- result_time_ = INTERVAL_SEC2;
- taskbar_.progress_state(*this,taskbar::paused);
- taskbar_.progress_value(*this,result_time_,INTERVAL_SEC2);
- text(std::wstring(L"ミニタイマー(休憩中)"));
+ draw_icon();
+ icon_ = icon(bmp_,icon_size_.width,icon_size_.height);
+ icon_holder ic_backup((HICON)::SetClassLongPtrW(hwnd,GCLP_HICON,(LONG_PTR)icon_.get()));
+ invalidate_rect();
}
- invalidate_rect();
break;
case sleep:
{
taskbar_.progress_value(*this,result_time_,INTERVAL_SEC1);
text(std::wstring(L"ミニタイマー(活動中)"));
}
+
+ draw_icon();
+ icon_ = icon(bmp_,icon_size_.width,icon_size_.height);
+ icon_holder ic_backup((HICON)::SetClassLongPtrW(hwnd,GCLP_HICON,(LONG_PTR)icon_.get()));
invalidate_rect();
}
break;
virtual void create(){
create_device_independent_resources();
- register_class(this->name_.c_str(),CS_HREDRAW | CS_VREDRAW,0,create_icon());
+ icon_ = create_icon();
+ register_class(this->name_.c_str(),CS_HREDRAW | CS_VREDRAW,0,icon_.get());
create_window();
// 半透明ウィンドウを有効にする。
layout_rect_,
brush);
THROW_IFERR(render_target_->EndDraw());
+
} catch(sf::win32_error_exception& err)
{
if(err.hresult() == D2DERR_RECREATE_TARGET)
timer_status status_;
IDWriteTextFormatPtr write_text_format_;
D2D1_RECT_F layout_rect_;
+
+ icon icon_;
+ D2D1_SIZE_U icon_size_;
+ bitmap_holder bmp_;
+ ID2D1DCRenderTargetPtr dcr_;
+
};
//
#include "stdafx.h"
#include "application.h";
-
/** WinMain */
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,