OSDN Git Service

サムネイル・ツールバーを実装してみた。 master
authorSFPGMR <sfpg@git.sourceforge.jp>
Thu, 5 May 2011 08:01:41 +0000 (17:01 +0900)
committerSFPGMR <sfpg@git.sourceforge.jp>
Thu, 5 May 2011 08:01:41 +0000 (17:01 +0900)
20 files changed:
wintimer/application.cpp
wintimer/application.h
wintimer/base_window.h
wintimer/code_converter.h
wintimer/exception.cpp
wintimer/icon.cpp
wintimer/icon.h
wintimer/logger.cpp
wintimer/logger.h
wintimer/sf_com.h
wintimer/sf_windows.cpp
wintimer/sf_windows.h
wintimer/taskbar.cpp
wintimer/taskbar.h
wintimer/timer.cpp
wintimer/timer.h
wintimer/toplevel_window.cpp
wintimer/toplevel_window.h
wintimer/wintimer.vcxproj
wintimer/wintimer.vcxproj.filters

index ecfba3a..bb9db46 100644 (file)
   ==============================================================================
 */
 #include "StdAfx.h"
-#include "toplevel_window.h"
+
+#if _DEBUG
+#define _CRTDBG_MAP_ALLOC
+#include <crtdbg.h>
+#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
+#endif
+
 #include "sf_windows.h"
+#include "icon.h"
+#include "toplevel_window.h"
 #include "message_loop.h"
 #include "sf_com.h"
 #include "application.h"
 
+#ifndef HINST_THISCOMPONENT
+EXTERN_C IMAGE_DOS_HEADER __ImageBase;
+#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
+#endif
+
+
+
 namespace sf {
 #ifdef _DEBUG
   std::wstring application::app_id_(L"SF.MiniTimerDebug");
 #else
   std::wstring application::app_id_(L"SF.MiniTimer");
 #endif
+application::application()
+{
+  instance_handle_ = HINST_THISCOMPONENT;
+}
 
 int application::execute(HINSTANCE hInstance,
                      HINSTANCE hPrevInstance,
                      LPTSTR    lpCmdLine,
                      int       nCmdShow)
 {
+#ifdef _DEBUG
+  ::_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF);
+#endif
   UNREFERENCED_PARAMETER(hPrevInstance);
        UNREFERENCED_PARAMETER(lpCmdLine);
-
   std::wcout.imbue(std::locale(""));
 
   // 2\8fd\8bN\93®\82Ì\96h\8e~
@@ -69,7 +90,6 @@ int application::execute(HINSTANCE hInstance,
   // \83A\83v\83\8a\83P\81[\83V\83\87\83\93ID\82Ì\93o\98^
   sf::throw_if_err<application::exception>()(SetCurrentProcessExplicitAppUserModelID(app_id_.c_str()));
   
-
   // \83E\83B\83\93\83h\83E\82Ì\8dì\90¬
   sf::toplevel_window_ptr 
     window(
@@ -82,3 +102,4 @@ int application::execute(HINSTANCE hInstance,
 }
 
 }
+
index 6f3a2e2..36ca352 100644 (file)
@@ -34,7 +34,7 @@ public:
     exception() : win32_error_exception() {} ;
   };
 
-  application(){};
+  application();
   ~application(){};
   
   int execute(HINSTANCE hInstance,
@@ -44,6 +44,7 @@ public:
   
 
   std::wstring& app_id(){return app_id_;};
+  HINSTANCE instance_handle() {return instance_handle_;};
 
 private:
   static std::wstring app_id_;
index e6a3a50..0168469 100644 (file)
   ==============================================================================
 */
 namespace sf {
-   /** window \83x\81[\83X\83N\83\89\83X */
+/** window \83x\81[\83X\83N\83\89\83X */
+
+struct rect {
+  uint32_t width;
+  uint32_t height;
+};
+
 struct base_window : boost::noncopyable
 {
   typedef boost::signals2::signal<void ()> on_render_type;
 
   on_render_type on_render;
-    
-  virtual void * raw_handle() = 0;
+  
+  // \90\82ÌWindow\83n\83\93\83h\83\8b\82ð\95Ô\82·\81B
+  virtual void * raw_handle() const = 0;
+  // \83E\83B\83\93\83h\83E\82ð\90\90¬\82·\82é
   virtual void create() = 0;
-  virtual void show(uint32_t show_flag) = 0;
+//  virtual void show(uint32_t show_flag) = 0;
+  // \83E\83B\83\93\83h\83E\82ð\95\\8e¦\82·\82é
+  virtual void show() = 0;
+  // \83E\83B\83\93\83h\83E\82ª\8d¡\95\\8e¦\82³\82ê\82Ä\82¢\82é\82©\82ð\95Ô\82·
+  virtual bool is_show() = 0;
+  // \83E\83B\83\93\83h\83E\82ð\89B\82·
+  virtual void hide() = 0;
+  //virtual void activate() = 0;
+  //virtual bool is_activate() = 0;
+  //virtual void deactivate() = 0;
+  //virtual void 
+  //virtual void size(uint32_t width,uint32_t height); 
+  //virtual rect size(); 
+
   virtual void text(std::wstring& text) = 0;
+  //virtual std::wstring text() = 0;
+
   virtual void update() = 0;
 
 protected:
index d9c398c..0132f8e 100644 (file)
@@ -1,21 +1,21 @@
-#pragma once
+#pragma once
 
 
 /** @file
  *  @author S.F. (Satoshi Fujiwara)
- *  @brief wchar_t <--> char \82Ì\95Ï\8a·\83\86\81[\83e\83B\83\8a\83e\83B
- *  \88ø\90\94\82Æ\82µ\82Ä\95\8e\9a\97ñ\82ð\88ø\82«\93n\82·\8dÛ\81A\95Ï\8a·\82ª\95K\97v\82È\8fê\8d\87\81A\89º\8bL\82Ì\82æ\82¤\82É\83A\83_\83v\83^\93I\82É\8eg\97p\82·\82é\82±\82Æ\82ð\91z\92è\82µ\82Ä\82¢\82é\81B
+ *  @brief wchar_t <--> char の変換ユーティリティ
+ *  引数として文字列を引き渡す際、変換が必要な場合、下記のようにアダプタ的に使用することを想定している。
  *  std::wstring a(L"abcd");
  *  std::wstring b((sf::code_converter<wcha_t,char>(a)));
  *
- *\81@\8cã\81AATL\83R\81[\83h\8d·\82µ\91Ö\82¦\97p\82Ìtypedef\82à\97p\88Ó\82µ\82Ä\82¢\82é\81B
- *  \82±\82ê\82Í\81A\83A\83_\83v\83^\82Æ\82µ\82Ä\82Ì\97\98\97p\82Ì\82Ý\82É\8cÀ\92è\82³\82ê\82é\81B
- *  sf::ct2a hoge_(L"abcef"); // \91z\92è\82µ\82Ä\82¢\82È\82¢\81i\93®\8dì\82·\82é\8fê\8d\87\82à\82 \82é\82µ\81A\83_\83\81\82È\8fê\8d\87\82à\82 \82é\81j
+ * 後、ATLコード差し替え用のtypedefも用意している。
+ *  これは、アダプタとしての利用のみに限定される。
+ *  sf::ct2a hoge_(L"abcef"); // 想定していない(動作する場合もあるし、ダメな場合もある)
  */
 
 namespace sf 
 {
-    /** \90\97\8c` */
+    /** 雛形 */
     template <typename SrcChar,typename DestChar>
     struct code_converter
     {
@@ -25,7 +25,7 @@ namespace sf
         operator DestChar*();
     };
 
-    /** char -> wchar_t\82Ö\82Ì\95Ï\8a· */
+    /** char -> wchar_tへの変換 */
     template <>
     struct code_converter<char,wchar_t>
     {
@@ -48,29 +48,29 @@ namespace sf
         boost::scoped_array<char> m_dest;
     };
 
-    /** ATL\83R\81[\83h\8d·\82µ\91Ö\82¦\82Ì\82½\82ß\82Ì\83G\83C\83\8a\83A\83X */
+    /** ATLコード差し替えのためのエイリアス */
     typedef sf::code_converter<char,wchar_t> ca2w;
 
-    /** ATL\83R\81[\83h\8d·\82µ\91Ö\82¦\82Ì\82½\82ß\82Ì\83G\83C\83\8a\83A\83X */
+    /** ATLコード差し替えのためのエイリアス */
     typedef sf::code_converter<wchar_t,char> cw2a;
 
     #ifdef _UNICODE
 
-        /** ATL\83R\81[\83h\8d·\82µ\91Ö\82¦\82Ì\82½\82ß\82Ì\83G\83C\83\8a\83A\83X */
+        /** ATLコード差し替えのためのエイリアス */
         typedef sf::code_converter<char,wchar_t> ca2t;
-        /** ATL\83R\81[\83h\8d·\82µ\91Ö\82¦\82Ì\82½\82ß\82Ì\83G\83C\83\8a\83A\83X */
+        /** ATLコード差し替えのためのエイリアス */
         typedef sf::code_converter<wchar_t,char> ct2a;
 
-        /** ATL\83R\81[\83h\8d·\82µ\91Ö\82¦\82Ì\82½\82ß\82Ì\83G\83C\83\8a\83A\83X */
+        /** ATLコード差し替えのためのエイリアス */
         inline const wchar_t* ct2w(const wchar_t* p) { return p;};
-        /** ATL\83R\81[\83h\8d·\82µ\91Ö\82¦\82Ì\82½\82ß\82Ì\83G\83C\83\8a\83A\83X */
+        /** ATLコード差し替えのためのエイリアス */
         inline const wchar_t* cw2t(const wchar_t* p) { return p;};
 
     #else
 
-        /** ATL\83R\81[\83h\8d·\82µ\91Ö\82¦\82Ì\82½\82ß\82Ì\83G\83C\83\8a\83A\83X */
+        /** ATLコード差し替えのためのエイリアス */
         inline const char* ct2a(const char* p) { return p;};
-        /** ATL\83R\81[\83h\8d·\82µ\91Ö\82¦\82Ì\82½\82ß\82Ì\83G\83C\83\8a\83A\83X */
+        /** ATLコード差し替えのためのエイリアス */
         inline const char* ca2t(const char* p) { return p;};
 
     #endif
index cfcb15f..3030979 100644 (file)
 #include <boost/assign/ptr_list_of.hpp>
 #include <boost/assign/ptr_list_inserter.hpp>
 #include <boost/foreach.hpp>
+
+#if _DEBUG
+#define _CRTDBG_MAP_ALLOC
+#include <crtdbg.h>
+#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
+#endif
+
 #include "sf_memory.h"
 
 using namespace boost;
index bdf925c..b03c446 100644 (file)
@@ -1,4 +1,4 @@
-/*
+/*
   ==============================================================================
 
    This file is part of the mini timer
 */
 
 #include "StdAfx.h"
+
+#if _DEBUG
+#define _CRTDBG_MAP_ALLOC
+#include <crtdbg.h>
+#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
+#endif
+
 #include "sf_windows.h"
 #include "icon.h"
+#include "application.h"
 
 namespace sf {
+  bitmap_holder icon::default_mono_bitmap(CreateBitmap(32,32,1,1,NULL));
+
+  icon::icon(uint32_t id) 
+    : icon_((HICON)::LoadImageW(application::instance()->instance_handle(),MAKEINTRESOURCE(id),IMAGE_ICON,0,0,LR_DEFAULTCOLOR))
+  {
+
+  };
 
   icon::icon(icon_holder& ic)
   {
@@ -42,18 +57,25 @@ namespace sf {
   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;
+    ICONINFO ii;
     ::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));
+
+    if(width == 32 && height == 32){
+      ii.hbmMask = default_mono_bitmap.get();
+      icon_.reset(::CreateIconIndirect(&ii));
+    } else {
+      bitmap_holder hmb(::CreateBitmap(width,height,1,1,NULL));
+      ii.hbmMask = hmb.get();
+      icon_.reset(::CreateIconIndirect(&ii));
+    }
+
   }
 
   icon::icon(ID2D1BitmapPtr& ptr)
@@ -62,7 +84,7 @@ namespace sf {
     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;
@@ -75,22 +97,22 @@ namespace sf {
     bi.bV5BlueMask  =  0x000000FF;
     bi.bV5AlphaMask =  0xFF000000; 
 
-    // \83f\83X\83N\83g\83b\83vHDC\82Ì\8eæ\93¾
+    // デスクトップHDCの取得
     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
+    // DIBセクションの作成
+    void *bits;// 得られるビットマップ
     bitmap_holder bmp(
       ::CreateDIBSection(
         dc.get(),reinterpret_cast<BITMAPINFO *>(&bi),DIB_RGB_COLORS,&bits,NULL,0));
     { 
-      // \8cÝ\8a·DC\82Ì\8dì\90¬
+      // 互換DCの作成
       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
+        // DC互換レンダーターゲットのセットアップ
         D2D1_RENDER_TARGET_PROPERTIES 
           props = D2D1::RenderTargetProperties(
           D2D1_RENDER_TARGET_TYPE_DEFAULT,
@@ -106,7 +128,7 @@ namespace sf {
         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
+        // 互換DCへのバインド
         throw_if_err<>()(dcr->BindDC(cdc.get(),&rect));
         dcr->DrawBitmap(ptr);
       }
@@ -152,7 +174,7 @@ namespace sf {
   //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_;
@@ -165,22 +187,22 @@ namespace sf {
   //  bi.bV5BlueMask  =  0x000000FF;
   //  bi.bV5AlphaMask =  0xFF000000; 
 
-  //  // \83f\83X\83N\83g\83b\83vHDC\82Ì\8eæ\93¾
+  //  // デスクトップHDCの取得
   //  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
+  //  // DIBセクションの作成
+  //  void *bits;// 得られるビットマップ
   //  gdi_object<HBITMAP> bmp(
   //    ::CreateDIBSection(
   //      dc.get(),reinterpret_cast<BITMAPINFO *>(&bi),DIB_RGB_COLORS,&bits,NULL,0));
   //  { 
-  //    // \8cÝ\8a·DC\82Ì\8dì\90¬
+  //    // 互換DCの作成
   //    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
+  //      // DC互換レンダーターゲットのセットアップ
   //      D2D1_RENDER_TARGET_PROPERTIES 
   //        props = D2D1::RenderTargetProperties(
   //        D2D1_RENDER_TARGET_TYPE_DEFAULT,
@@ -196,22 +218,22 @@ namespace sf {
   //      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
+  //      // 互換DCへのバインド
   //      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¬
+  //      // Text Formatの作成
   //      IDWriteTextFormatPtr f;
   //      write_factory_->CreateTextFormat(
-  //      L"\83\81\83C\83\8a\83I",                // Font family name.
+  //      L"メイリオ",                // Font family name.
   //      NULL,                       // Font collection (NULL sets it to use the system font collection).
   //      DWRITE_FONT_WEIGHT_REGULAR,
   //      DWRITE_FONT_STYLE_NORMAL,
@@ -223,18 +245,18 @@ namespace sf {
   //      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();
   //    }
   //  }
index 4602b96..35a77e5 100644 (file)
@@ -42,6 +42,7 @@ struct icon
 {
 public:
   icon(){};
+  explicit icon(uint32_t id);
   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));
@@ -50,7 +51,7 @@ public:
   
   virtual ~icon();
 
-  HICON get() {return icon_.get();};
+  HICON get() const {return icon_.get();};
 
   icon(icon& i) : width_(i.width_),height_(i.height_),bits_per_pixel_(i.bits_per_pixel_)
   {
@@ -92,6 +93,7 @@ private:
   int height_;
   int bits_per_pixel_;
   icon_holder icon_;
+  static bitmap_holder default_mono_bitmap; 
  };
 }
 
index 60f9922..01e33b7 100644 (file)
@@ -25,7 +25,11 @@ Boston, MA 02111-1307 USA
 */
 
 #include "stdafx.h"
-
+#if _DEBUG
+#define _CRTDBG_MAP_ALLOC
+#include <crtdbg.h>
+#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
+#endif
 namespace sf {
 
   struct logger::impl 
index 8d6a396..dd0b08c 100644 (file)
@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
 
 #include "boost/date_time/gregorian/gregorian.hpp"
 #include "boost/date_time/posix_time/posix_time.hpp"
@@ -17,7 +17,7 @@ namespace sf {
     void write(const std::wistream & st);
   private:
     struct impl;
-    boost::shared_ptr<impl> m_impl;
+    std::shared_ptr<impl> m_impl;
   };
 
   void debug_out(const char * file_name,const int line,boost::wformat& fmt);
index c1e8265..8aab1f1 100644 (file)
@@ -42,7 +42,7 @@ namespace sf
         com_initialize(void * reserved = NULL,unsigned int init = multi_threaded);
         ~com_initialize() {};
     private:
-        boost::shared_ptr<impl> m_impl;
+        std::shared_ptr<impl> m_impl;
     };
 
        template <typename ComClass,typename ComInterface> 
index 04df552..3d74e70 100644 (file)
@@ -4,9 +4,18 @@
 #include <boost/assign/ptr_list_of.hpp>
 #include <boost/assign/ptr_list_inserter.hpp>
 #include <boost/foreach.hpp>
+
+#if _DEBUG
+#define _CRTDBG_MAP_ALLOC
+#include <crtdbg.h>
+#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
+#endif
+
 #include "sf_windows.h"
 #include "exception.h"
 
+
+
 #define THROW_IFERR(hres) \
   if (FAILED(hres)) { throw sf::win32_error_exception(hres); }
 
@@ -113,7 +122,7 @@ namespace sf
     //
     // Because the CreateWindow function takes its size in pixels, we
     // obtain the system DPI and use it to scale the window size.
-    FLOAT dpiX, dpiY;
+    //FLOAT dpiX, dpiY;
     //factory_->GetDesktopDpi(&dpiX, &dpiY);
 
 
@@ -124,33 +133,36 @@ namespace sf
       WS_OVERLAPPEDWINDOW,
       CW_USEDEFAULT,
       CW_USEDEFAULT,
-      static_cast<uint32_t>(ceil(width_ /** dpiX / 96.f*/)),
-      static_cast<uint32_t>(ceil(height_ /** dpiY / 96.f*/)),
+      static_cast<uint32_t>(dpi_.scale_x(width_)),
+      static_cast<uint32_t>(dpi_.scale_y(height_)),
       NULL,
       NULL,
       HINST_THISCOMPONENT,
       this
       );
+    ::GetWindowPlacement(hwnd_,&wp_);
   }
 
-  void base_win32_window::show(uint32_t show_flag) 
-  {
-    //HRESULT hr = S_OK;
-    //BOOL enable;
-    //DwmIsCompositionEnabled (&enable);
-    //if(enable){
-    //   //Create and populate the BlurBehind structre
-    //   DWM_BLURBEHIND bb = {0};
-    //   //Enable Blur Behind and Blur Region;
-    //   bb.dwFlags = DWM_BB_ENABLE;
-    //   bb.fEnable = true;
-    //   bb.hRgnBlur = NULL;
-
-    //   //Enable Blur Behind
-    //   hr = DwmEnableBlurBehindWindow(hwnd_, &bb);
-    //}
-    ::ShowWindow(hwnd_,show_flag);
-  }
+  //void base_win32_window::show() 
+  //{
+  //  //HRESULT hr = S_OK;
+  //  //BOOL enable;
+  //  //DwmIsCompositionEnabled (&enable);
+  //  //if(enable){
+  //  //   //Create and populate the BlurBehind structre
+  //  //   DWM_BLURBEHIND bb = {0};
+  //  //   //Enable Blur Behind and Blur Region;
+  //  //   bb.dwFlags = DWM_BB_ENABLE;
+  //  //   bb.fEnable = true;
+  //  //   bb.hRgnBlur = NULL;
+
+  //  //   //Enable Blur Behind
+  //  //   hr = DwmEnableBlurBehindWindow(hwnd_, &bb);
+  //  //}
+  //  ::ShowWindow(hwnd_,SW_SHOW);
+  //  ::GetWindowPlacement(&wp_);
+  //}
+
 
   void base_win32_window::update() {::UpdateWindow(hwnd_);}
 
@@ -162,6 +174,8 @@ namespace sf
   base_win32_window::base_win32_window(const std::wstring& title,const std::wstring& name,bool fit_to_display,float width,float height)
     : title_(title),name_(name),fit_to_display_(fit_to_display),width_(width),height_(height),thunk_(this,base_win32_window::WndProc),hwnd_(0)
   {
+    memset(&wp_,0,sizeof(wp_));
+    wp_.length = sizeof(WINDOWPLACEMENT);
     thunk_proc_ = (WNDPROC)thunk_.getCode();
     //create_device_independent_resources();
   }
index d563900..072c6c7 100644 (file)
@@ -4,6 +4,7 @@
 // Windows Header Files:
 #include "exception.h"
 #include "base_window.h"
+#include "dpi.h"
 #define XBYAK64
 #include "xbyak.h"
 // DLLのリンク
@@ -174,7 +175,7 @@ namespace sf{
     ~device_context() {}
     operator HDC(){return holder_->get();}
   private:
-    boost::scoped_ptr<Holder> holder_;
+    std::unique_ptr<Holder> holder_;
   };
 
   //struct handle_holder : boost::noncopyable
@@ -293,10 +294,30 @@ namespace sf{
     typedef boost::signals2::signal<LRESULT (HWND,uint32_t,WPARAM, LPARAM) > on_message_type;
     on_message_type on_message;
     
-    operator HWND() {return hwnd_;};
+    operator HWND() const {return hwnd_;};
     
-    virtual void * raw_handle(){return hwnd_;};
-    virtual void show(uint32_t show_flag);
+    virtual void * raw_handle() const {return hwnd_;};
+//    virtual void show(uint32_t show_flag);
+
+    virtual void show() {
+      ::ShowWindow(hwnd_,SW_SHOW);
+      ::GetWindowPlacement(hwnd_,&wp_);
+    }
+
+    // Window を画面から隠す
+    virtual bool is_show() {
+      return ( wp_.showCmd == SW_SHOWMAXIMIZED 
+        || wp_.showCmd == SW_SHOWMINIMIZED
+        || wp_.showCmd == SW_SHOWNORMAL );
+    };
+
+    //
+    virtual void hide()
+    {
+      ::ShowWindow(hwnd_,SW_HIDE);
+      ::GetWindowPlacement(hwnd_,&wp_);
+    };
+
     virtual void text(std::wstring& text)
     {
       ::SetWindowTextW(*this,text.c_str());
@@ -377,9 +398,11 @@ namespace sf{
     std::wstring name_;
     float width_,height_;
     bool fit_to_display_;
-    boost::shared_ptr<sf::window_class_ex> wnd_class_;
+    std::shared_ptr<sf::window_class_ex> wnd_class_;
     WNDPROC thunk_proc_;
-  };
+    dpi dpi_;
+    WINDOWPLACEMENT wp_;
+   };
   
   struct av_mm_thread_characteristics
   {
@@ -403,7 +426,7 @@ namespace sf{
     std::wstring name_;
     float width_,height_;
     bool fit_to_display_;
-
+    WINDOWPLACEMENT wp_;//
   };
 
   struct widget
index b0d4776..175e7c9 100644 (file)
@@ -1,4 +1,11 @@
-#include "StdAfx.h"
+#include "StdAfx.h"
+
+#if _DEBUG
+#define _CRTDBG_MAP_ALLOC
+#include <crtdbg.h>
+#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
+#endif
+
 #include "sf_windows.h"
 #include "taskbar.h"
 
@@ -29,27 +36,38 @@ struct taskbar::impl
   void create() {
     throw_if_err_()(taskbar_.CreateInstance(CLSID_TaskbarList));
   }
-
+  bool is_create() const 
+  {
+    return (taskbar_ != 0);
+  }
   void discard()
   {
     safe_release(taskbar_);
   }
     
-  void overlay_icon(sf::base_window& w,HICON icon,std::wstring& description)
+  void overlay_icon(const sf::base_window& w,const sf::icon& ic,const std::wstring& description)
   {
-    throw_if_err_()(taskbar_->SetOverlayIcon(reinterpret_cast<HWND>(w.raw_handle()),icon,description.c_str()));
+    throw_if_err_()(taskbar_->SetOverlayIcon(reinterpret_cast<HWND>(w.raw_handle()),ic.get(),description.c_str()));
   }
 
-  void progress_state(sf::base_window& w,TBPFLAG state)
+  void progress_state(const sf::base_window& w,TBPFLAG state)
   {
     throw_if_err_()(taskbar_->SetProgressState(reinterpret_cast<HWND>(w.raw_handle()),state));
   }
 
-  void progress_value(sf::base_window& w,boost::uint64_t completed, boost::uint64_t total)
+  void progress_value(const sf::base_window& w,boost::uint64_t completed, boost::uint64_t total)
   {
     throw_if_err_()(taskbar_->SetProgressValue(reinterpret_cast<HWND>(w.raw_handle()),completed,total));
   }
-   
+
+  void add_thumb_buttons(const sf::base_window& w,const std::vector<THUMBBUTTON>& tbs){
+      taskbar_->ThumbBarAddButtons(reinterpret_cast<HWND>(w.raw_handle()),tbs.size(),const_cast<LPTHUMBBUTTON>(&(tbs[0])));
+  };
+
+  void update_thumb_buttons(const sf::base_window& w,const std::vector<THUMBBUTTON>& tbs){
+      taskbar_->ThumbBarUpdateButtons(reinterpret_cast<HWND>(w.raw_handle()),tbs.size(),const_cast<LPTHUMBBUTTON>(&(tbs[0])));
+  };
+
 private:
   _COM_SMARTPTR_TYPEDEF(ITaskbarList4,__uuidof(ITaskbarList4));
   ITaskbarList4Ptr taskbar_;
@@ -60,9 +78,21 @@ taskbar::taskbar() : impl_(new sf::taskbar::impl()) {}
 taskbar::~taskbar() { discard();};
 
 void taskbar::create(){impl_->create();};
+bool taskbar::is_create() const {return impl_->is_create();};
 void taskbar::discard(){impl_->discard();};
-void taskbar::overlay_icon(sf::base_window& w,HICON icon,std::wstring& description){impl_->overlay_icon(w,icon,description);};
-void taskbar::progress_state(sf::base_window& w,int state){impl_->progress_state(w,(TBPFLAG)state);};
-void taskbar::progress_value(sf::base_window& w,boost::uint64_t completed, boost::uint64_t total){impl_->progress_value(w,completed,total);};
+void taskbar::overlay_icon(const sf::base_window& w,const icon& ic,const std::wstring& description){impl_->overlay_icon(w,ic,description);};
+void taskbar::progress_state(const sf::base_window& w,int state){impl_->progress_state(w,(TBPFLAG)state);};
+void taskbar::progress_value(const sf::base_window& w,boost::uint64_t completed, boost::uint64_t total){impl_->progress_value(w,completed,total);};
+void taskbar::add_thumb_buttons(const sf::base_window& w,const thumb_button_manager& tm){
+  BOOST_ASSERT(!tm.is_added);
+  impl_->add_thumb_buttons(w,tm.thumbbuttons_);
+  tm.is_added = true;
+};
+void taskbar::update_thumb_buttons(const sf::base_window& w,const thumb_button_manager& tm){
+  BOOST_ASSERT(tm.is_added);
+  if(tm.is_added){
+    impl_->update_thumb_buttons(w,tm.thumbbuttons_);
+  }
+};
 
 }
\ No newline at end of file
index 5878ce2..e56847b 100644 (file)
@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
 
 /*
   ==============================================================================
 */
 
 #include "exception.h"
+#include "icon.h"
 
 namespace sf
 {
   
+  ///** インターフェース */
+  //struct thumb_button : boost::noncopyable
+  //{
+  //  typedef std::shared_ptr<thumb_button> ptr;
+  //  static ptr create_thumb_button();
+  //  virtual void show()  = 0;
+  //  virtual void hide()  = 0;
+  //  virtual void enable() = 0;
+  //  virtual void disable() = 0;
+  //private:
+  //  thumb_button();
+  //};
+
+  struct taskbar;
+
+  /** サムネイルボタン管理 */
+  struct thumb_button_manager
+  {
+    friend struct taskbar;
+    // Thumb Buttonは最大7個まで
+    static const int THUMB_BUTTON_MAX = 7;
+
+    // THUMBBUTTON構造体操作クラス
+    struct thumb_button {
+
+      // コンストラクタ
+      thumb_button(uint32_t id ,const icon& i,const std::wstring& tool_tip,THUMBBUTTON& t) : thumb_(t)
+      {
+        BOOST_ASSERT(tool_tip.size() < 259);
+        memset(&thumb_,0,sizeof(THUMBBUTTON));
+        thumb_.dwMask = THB_ICON | THB_TOOLTIP | THB_FLAGS;
+        thumb_.hIcon = i.get();
+        thumb_.iId = id;
+        std::copy(tool_tip.begin(),tool_tip.end(),thumb_.szTip);
+        //thumb_.szTip = const_cast<wchar_t*>(tool_tip_.c_str());
+      }
+      
+      /** アイコン */
+      thumb_button& set_icon(icon& ic) {thumb_.hIcon = ic.get(); return *this;};
+      /** IDのセット */
+      thumb_button& id(uint32_t v) {thumb_.iId = v; return *this;}
+      /** ツールチップ */
+      thumb_button& tool_tip(const std::wstring& v) {
+        BOOST_ASSERT(v.size() < 259);
+        std::copy(v.begin(),v.end(),thumb_.szTip);
+        thumb_.szTip[v.size()] = L'\0';
+        return *this;
+      }
+      /** 有効化・無効化 */
+      thumb_button& enable(bool v){v?(thumb_.dwFlags &= ~THBF_ENABLED):(thumb_.dwFlags |= THBF_DISABLED); return *this;}
+      /** クリックされたらサムネイルを閉じるか */
+      thumb_button& dismission_click(bool v){ v?(thumb_.dwFlags |= THBF_DISMISSONCLICK):(thumb_.dwFlags &= ~THBF_DISMISSONCLICK); return *this;}
+      /** ボタンの外枠を描画するかどうか */
+      thumb_button& no_background(bool v){v?(thumb_.dwFlags |= THBF_NOBACKGROUND):(thumb_.dwFlags &= ~THBF_NOBACKGROUND);return *this;}
+      /** 隠すか・表示するか */
+      thumb_button& hidden(bool v){v?(thumb_.dwFlags |= THBF_HIDDEN):(thumb_.dwFlags &= ~ THBF_HIDDEN);return *this;}
+      /** ボタンアクションを起こすかどうか。ボタンを通知目的で使用する際に用いる。*/
+      thumb_button& no_interacive(bool v){v?(thumb_.dwFlags |= THBF_NONINTERACTIVE):(thumb_.dwFlags &= ~THBF_NONINTERACTIVE);return *this;}
+
+    private:
+      THUMBBUTTON& thumb_;
+    };
+    
+    thumb_button_manager() : is_added(false) {}
+
+    // Thumb Buttonは7個までに制限されている
+    thumb_button&  add_thumb_button(uint32_t id,const icon& i,const std::wstring& str)
+    {
+      // 事前条件
+      BOOST_ASSERT(thumb_buttons_.size() < 7 && is_added == false);
+      if(!is_added){
+        thumbbuttons_.push_back(THUMBBUTTON());
+        thumb_buttons_.push_back(thumb_button(id,i,str, (thumbbuttons_.at(thumbbuttons_.size() - 1))));
+      }
+      return thumb_buttons_.at(thumb_buttons_.size() - 1);
+    }
+
+    thumb_button& at(uint32_t i){
+      BOOST_ASSERT(i < thumb_buttons_.size());
+      return thumb_buttons_.at(i);
+    }
+
+    size_t size() const {return thumb_buttons_.size();}
+  private:
+    mutable bool is_added;
+    // メモリ配列を合わせるためにこうした。
+    std::vector<THUMBBUTTON> thumbbuttons_;
+    std::vector<thumb_button> thumb_buttons_;
+    //typedef boost::ptr_vector<thumb_button> thumb_buttons;
+  };
+
+  /** タスクバーAPIのラップクラス。本来であればインターフェースにする方が良いかもしれないけれど */
   struct taskbar : boost::noncopyable
   {
     struct exception
@@ -41,9 +134,14 @@ namespace sf
     ~taskbar();
     void create();
     void discard();
-    void overlay_icon(sf::base_window& w,HICON icon,std::wstring& description);
-    void progress_state(sf::base_window& w,int state);
-    void progress_value(sf::base_window& w,boost::uint64_t completed, boost::uint64_t total);
+    void overlay_icon(const sf::base_window& w,const icon& ic,const std::wstring& description);
+    void progress_state(const sf::base_window& w,int state);
+    void progress_value(const sf::base_window& w,boost::uint64_t completed, boost::uint64_t total);
+
+    void add_thumb_buttons(const sf::base_window& w,const thumb_button_manager& tm);
+    void update_thumb_buttons(const sf::base_window& w,const thumb_button_manager& tm);
+    bool is_create() const;
+
     static long register_message();
 
     static const int none;
@@ -55,6 +153,7 @@ namespace sf
   private:
     struct impl;
     std::shared_ptr<impl> impl_;
+    friend struct impl;
   };
 
 }
index cd86e9e..f468e20 100644 (file)
@@ -1,4 +1,4 @@
-/*
+/*
   ==============================================================================
 
    This file is part of the mini timer
 */
 
 #include "StdAfx.h"
+
+#if _DEBUG
+#define _CRTDBG_MAP_ALLOC
+#include <crtdbg.h>
+#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
+#endif
+
 #include "sf_windows.h"
 #include "timer.h"
 
index f1154fd..81298c0 100644 (file)
@@ -1,4 +1,4 @@
-/*
+/*
   ==============================================================================
 
    This file is part of the mini timer
index 96072e0..92bce0e 100644 (file)
@@ -1,11 +1,19 @@
 #include "stdafx.h"
+#include "resource.h"
 #define BOOST_ASSIGN_MAX_PARAMS 7
 #include <boost/assign.hpp>
 #include <boost/assign/ptr_list_of.hpp>
 #include <boost/assign/ptr_list_inserter.hpp>
 #include <boost/foreach.hpp>
-#include "toplevel_window.h"
+
+#if _DEBUG
+#define _CRTDBG_MAP_ALLOC
+#include <crtdbg.h>
+#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
+#endif
+
 #include "sf_windows.h"
+#include "toplevel_window.h"
 #include "icon.h"
 #include "timer.h"
 #include "exception.h"
@@ -55,109 +63,6 @@ struct toplevel_window::impl : public base_win32_window
     safe_release(write_factory_);
   };
 
-  // 互換ビットマップにDirect2Dで描画し、
-  // アイコンにして返すメソッド
-  icon create_icon()
-  {
-    // アイコンサイズの取得
-    icon_size_ = D2D1::SizeU(::GetSystemMetrics(SM_CXICON),::GetSystemMetrics(SM_CYICON));
-    // ビットマップヘッダのセットアップ
-    BITMAPV5HEADER bi = {0};
-    bi.bV5Size           = sizeof(BITMAPV5HEADER);
-    bi.bV5Width           = icon_size_.width;
-    bi.bV5Height          = icon_size_.height;
-    bi.bV5Planes = 1;
-    bi.bV5BitCount = 32;
-    bi.bV5Compression = BI_BITFIELDS;
-    bi.bV5RedMask   =  0x00FF0000;
-    bi.bV5GreenMask =  0x0000FF00;
-    bi.bV5BlueMask  =  0x000000FF;
-    bi.bV5AlphaMask =  0xFF000000; 
-
-    // デスクトップHDCの取得
-    {
-      get_dc dc(NULL);
-
-      // DIBセクションの作成
-      bmp_.reset(
-        ::CreateDIBSection(
-          dc.get(),reinterpret_cast<BITMAPINFO *>(&bi),DIB_RGB_COLORS,0,NULL,0));
-      { 
-
-        // DC互換レンダーターゲットのセットアップ
-        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
-        );
-
-        throw_if_err<>()(factory_->CreateDCRenderTarget(&props,&dcr_));
-      }
-    }
-
-    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();
-    }
-
-
-  }
 
 
   // -------------------------------------------------------------------
@@ -170,14 +75,12 @@ struct toplevel_window::impl : public base_win32_window
       {
         // TODO:
         create_device();
-        
-
         wm_task_bar_create_ = taskbar::register_message();
         text(std::wstring(L"ミニタイマー(活動中)"));
         //MARGINS mgn = {-1,0,0,0};//let,right,top,bottom
         //HRESULT hr = DwmExtendFrameIntoClientArea(hwnd_, &mgn);
-        break;
       }
+      break;
     case WM_SIZE:
       {
         //if (render_target_)
@@ -192,14 +95,13 @@ struct toplevel_window::impl : public base_win32_window
         //     render_target_->Resize(size);
         //}
       }
+      break;
     case WM_PAINT:
       {
         //create_device();
 
         { 
-
           paint_struct begin_paint(hwnd);
-        
           //CloseHandle(cb);
           // 描画コードの呼び出し
           render();
@@ -207,11 +109,11 @@ struct toplevel_window::impl : public base_win32_window
         }
 
 //        ::ShowWindow(hwnd_,SW_MINIMIZE);
-        return FALSE;
       }
+      return FALSE;
     case WM_DISPLAYCHANGE:
       {
-        ::InvalidateRect(hwnd, NULL, FALSE);
+        invalidate_rect();
       }
       break;
     case WM_ERASEBKGND:
@@ -239,18 +141,11 @@ struct toplevel_window::impl : public base_win32_window
 
             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"ミニタイマー(休憩中)"));
+              update_status(sleep);
+            } else {
+              update_icon();
+              invalidate_rect();
             }
-
-            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;
         case sleep:
@@ -260,37 +155,43 @@ struct toplevel_window::impl : public base_win32_window
             taskbar_.progress_value(*this,result_time_,INTERVAL_SEC2);
             if(result_time_ == 0)
             {
-              ::MessageBeep(MB_OK);
-              status_ = active;
-              result_time_ = INTERVAL_SEC1;
-              taskbar_.progress_state(*this,taskbar::indeterminate);
-              taskbar_.progress_value(*this,result_time_,INTERVAL_SEC1);
-              text(std::wstring(L"ミニタイマー(活動中)"));
+              update_status(active);
+            } else {
+              update_icon();
+              invalidate_rect();
             }
-
-            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;
         }
+      }
     case WM_DWMCOMPOSITIONCHANGED:
       {
         //MARGINS mgn = {-1,0,0,0};//let,right,top,bottom
         //HRESULT hr = DwmExtendFrameIntoClientArea(hwnd_, &mgn);
       }
       break;
-        //::SetTimer(hwnd_,(UINT_PTR)&timer_id_,1000,NULL);
+    case WM_COMMAND:
+      if(HIWORD(wParam) == THBN_CLICKED ){
+        switch(LOWORD(wParam)){
+        case THUMB_START:
+          {
+            if(status_ != stop)
+            {
+              update_status(stop);
+            } else {
+              update_status(active);
+            }
+          }
+          break;
+        }
       }
+      break;
+        //::SetTimer(hwnd_,(UINT_PTR)&timer_id_,1000,NULL);
     }
 
     if(message == wm_task_bar_create_)
     {
-      taskbar_.create();
-      taskbar_.overlay_icon(*this,NULL,std::wstring(L"ミニタイマー"));
-      taskbar_.progress_state(*this,taskbar::indeterminate);
-      taskbar_.progress_value(*this,100,100);
+      create_task_bar();
       // タイマーの設定
       //timer_.reset(new sf::timer(*this,1000));
       timer_.start();
@@ -306,6 +207,7 @@ struct toplevel_window::impl : public base_win32_window
       // 後始末
       discard_device();
       // レンダーターゲットのリリース
+      safe_release(dcr_);
       safe_release(render_target_);
       // Windowの破棄
       BOOL ret(::DestroyWindow(hwnd));
@@ -320,7 +222,7 @@ struct toplevel_window::impl : public base_win32_window
 
     return ::DefWindowProcW(hwnd,message,wParam,lParam);
   }
-
+  
   virtual void create(){
     create_device_independent_resources();
     icon_ = create_icon();
@@ -496,8 +398,8 @@ struct toplevel_window::impl : public base_win32_window
       0 ,
       CW_USEDEFAULT,
       CW_USEDEFAULT,
-      static_cast<uint32_t>(ceil(width_ /** dpiX / 96.f*/)),
-      static_cast<uint32_t>(ceil(height_ /** dpiY / 96.f*/)),
+      static_cast<uint32_t>(dpi_.scale_x(width_)),
+      static_cast<uint32_t>(dpi_.scale_x(height_)),
       NULL,
       NULL,
       HINST_THISCOMPONENT,
@@ -506,6 +408,225 @@ struct toplevel_window::impl : public base_win32_window
   };
 
 private:
+  // 互換ビットマップにDirect2Dで描画し、
+  // アイコンにして返すメソッド
+  icon create_icon()
+  {
+    // アイコンサイズの取得
+    icon_size_ = D2D1::SizeU(::GetSystemMetrics(SM_CXICON),::GetSystemMetrics(SM_CYICON));
+    // ビットマップヘッダのセットアップ
+    BITMAPV5HEADER bi = {0};
+    bi.bV5Size           = sizeof(BITMAPV5HEADER);
+    bi.bV5Width           = icon_size_.width;
+    bi.bV5Height          = icon_size_.height;
+    bi.bV5Planes = 1;
+    bi.bV5BitCount = 32;
+    bi.bV5Compression = BI_BITFIELDS;
+    bi.bV5RedMask   =  0x00FF0000;
+    bi.bV5GreenMask =  0x0000FF00;
+    bi.bV5BlueMask  =  0x000000FF;
+    bi.bV5AlphaMask =  0xFF000000; 
+
+    // デスクトップHDCの取得
+    {
+      get_dc dc(NULL);
+
+      // DIBセクションの作成
+      bmp_.reset(
+        ::CreateDIBSection(
+          dc.get(),reinterpret_cast<BITMAPINFO *>(&bi),DIB_RGB_COLORS,0,NULL,0));
+      { 
+
+        // DC互換レンダーターゲットのセットアップ
+        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
+        );
+
+        throw_if_err<>()(factory_->CreateDCRenderTarget(&props,&dcr_));
+      }
+    }
+
+    draw_icon();
+    return std::move(icon(bmp_,icon_size_.width,icon_size_.height));
+  };
+  void update_icon()
+  {
+    draw_icon();
+    icon_ = icon(bmp_,icon_size_.width,icon_size_.height);
+    icon_holder ic_backup((HICON)::SetClassLongPtrW(hwnd_,GCLP_HICON,(LONG_PTR)icon_.get()));
+  }
+
+  void update_status(uint32_t s)
+  {
+    switch(s)
+    {
+    case stop:
+      status_ = stop;
+      result_time_ = INTERVAL_SEC1;
+      timer_.stop();
+      break;
+    case active:
+      result_time_ = INTERVAL_SEC1;
+      if(status_ == stop)
+      {
+        timer_.start();
+      }
+      status_ = active;
+      break;
+    case sleep:
+      status_ = sleep;
+      result_time_ = INTERVAL_SEC2;
+      break;
+    }
+    update_ui_status();
+  }
+
+  void update_ui_status()
+  {
+    switch(status_)
+    {
+    case stop:
+      {
+        // タイトルバー
+        text(std::wstring(L"ミニタイマー(停止)"));
+
+        if(taskbar_.is_create()){
+          // サムネイル・ツールバー・ボタン
+          thumb_button_manager_
+            .at(0)
+            .tool_tip(L"開始")
+            .set_icon(thumb_icons_[0]);
+          taskbar_.update_thumb_buttons(*this,thumb_button_manager_);
+
+          // プログレス
+          taskbar_.progress_state(*this,taskbar::error);
+          taskbar_.progress_value(*this,0,0);
+        }
+
+      }
+      break;
+    case active:
+      {
+        ::MessageBeep(MB_OK);
+
+        // タイトルバー
+        text(std::wstring(L"ミニタイマー(活動中)"));
+
+        if(taskbar_.is_create()){
+          // サムネイル・ツールバー・ボタン
+          thumb_button_manager_
+            .at(0)
+            .tool_tip(L"停止")
+            .set_icon(thumb_icons_[1]);
+          taskbar_.update_thumb_buttons(*this,thumb_button_manager_);
+
+          // プログレス
+          taskbar_.progress_state(*this,taskbar::indeterminate);
+          taskbar_.progress_value(*this,result_time_,INTERVAL_SEC1);
+        }
+      }
+      break;
+    case sleep:
+      {
+        ::MessageBeep(MB_ICONEXCLAMATION);
+        // タイトルバー
+        text(std::wstring(L"ミニタイマー(休憩中)"));
+
+        if(taskbar_.is_create()){
+          // プログレス
+          taskbar_.progress_state(*this,taskbar::paused);
+          taskbar_.progress_value(*this,result_time_,INTERVAL_SEC2);
+        }
+
+      }
+      break;
+    }
+    update_icon();
+    invalidate_rect();
+  }
+
+  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"活動中":(status_ == sleep?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();
+    }
+
+
+  }
+
+  void create_task_bar()
+  {
+      taskbar_.create();
+      taskbar_.overlay_icon(*this,icon(),std::wstring(L"ミニタイマー"));
+      taskbar_.progress_state(*this,taskbar::indeterminate);
+      taskbar_.progress_value(*this,100,100);
+
+      thumb_icons_.push_back(icon(THUMB_START));
+      thumb_icons_.push_back(icon(THUMB_STOP));
+
+      thumb_button_manager_
+        .add_thumb_button(THUMB_START,thumb_icons_[1],std::wstring(L"停止"))
+        .enable(true);
+
+      //thumb_button_manager_
+      //  .add_thumb_button(THUMB_STOP,thumb_icons_[1],std::wstring(L"停止"))
+      //  .enable(true);
+
+      taskbar_.add_thumb_buttons(*this,thumb_button_manager_);
+  }
 
   long wm_task_bar_create_;
   sf::taskbar taskbar_;
@@ -514,7 +635,9 @@ private:
   static const int INTERVAL_SEC2 = 30;// 30秒
 
   int result_time_;
-  enum timer_status {
+  enum timer_status 
+  {
+    stop,
     active,
     sleep
   };
@@ -532,7 +655,8 @@ private:
   D2D1_SIZE_U icon_size_;
   bitmap_holder bmp_;
   ID2D1DCRenderTargetPtr dcr_;
-
+  std::vector<icon> thumb_icons_;
+  thumb_button_manager thumb_button_manager_;
 };
 
   //
@@ -632,9 +756,11 @@ private:
 
   };
 
-  void * toplevel_window::raw_handle(){return impl_->raw_handle();};
+  void * toplevel_window::raw_handle() const {return impl_->raw_handle();};
   void toplevel_window::create(){impl_->create();};
-  void toplevel_window::show(uint32_t show_flag){impl_->show(show_flag);};
+  void toplevel_window::show(){impl_->show();};
+  void toplevel_window::hide(){impl_->hide();};
+  bool toplevel_window::is_show(){return impl_->is_show();};
   void toplevel_window::text(std::wstring& text){impl_->text(text);};
   void toplevel_window::update(){impl_->update();};
 
@@ -650,7 +776,7 @@ private:
   {
     toplevel_window* p = new toplevel_window(menu_name,name,fit_to_display,width,height);
     p->create();
-    p->show(show_flag);
+    p->show();
     p->update();
     return toplevel_window_ptr(p);
   }
index 4d843c6..939b084 100644 (file)
@@ -8,7 +8,7 @@ namespace sf
 {
 
   struct toplevel_window;
-  typedef boost::shared_ptr<toplevel_window> toplevel_window_ptr;
+  typedef std::shared_ptr<toplevel_window> toplevel_window_ptr;
 
   /** toplevel_window を生成する関数 */
   toplevel_window_ptr create_toplevel_window (
@@ -37,9 +37,12 @@ namespace sf
 
     ~toplevel_window(){};
  
-    void * raw_handle();
+    void * raw_handle() const;
     void create();
-    void show(uint32_t show_flag);
+    void toplevel_window::show();
+    bool toplevel_window::is_show();
+    void toplevel_window::hide();
+
     void text(std::wstring& text);
     void update();
 
index 1c51c65..850aa59 100644 (file)
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
     </Link>
+    <Manifest>
+      <AdditionalManifestFiles>DeclareDPIAware.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>
+    </Manifest>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <FunctionLevelLinking>false</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
     </ClCompile>
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
     <ClInclude Include="base_window.h" />
     <ClInclude Include="code_converter.h" />
     <ClInclude Include="dout.h" />
+    <ClInclude Include="dpi.h" />
     <ClInclude Include="exception.h" />
     <ClInclude Include="icon.h" />
     <ClInclude Include="jumplist.h" />
     <ClInclude Include="logger.h" />
     <ClInclude Include="message_loop.h" />
+    <ClInclude Include="resource.h" />
     <ClInclude Include="sf_com.h" />
     <ClInclude Include="sf_memory.h" />
     <ClInclude Include="sf_windows.h" />
@@ -88,6 +94,7 @@
     <ClCompile Include="application.cpp" />
     <ClCompile Include="base_window.cpp" />
     <ClCompile Include="code_converter.cpp" />
+    <ClCompile Include="dpi.cpp" />
     <ClCompile Include="exception.cpp" />
     <ClCompile Include="icon.cpp" />
     <ClCompile Include="jumplist.cpp" />
     <ClCompile Include="toplevel_window.cpp" />
     <ClCompile Include="winmain.cpp" />
   </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="minitimer.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="icon1.ico" />
+  </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
index eb50fc1..43ec4ee 100644 (file)
@@ -30,6 +30,8 @@
     <ClInclude Include="jumplist.h" />
     <ClInclude Include="icon.h" />
     <ClInclude Include="timer.h" />
+    <ClInclude Include="resource.h" />
+    <ClInclude Include="dpi.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="code_converter.cpp" />
     <ClCompile Include="jumplist.cpp" />
     <ClCompile Include="icon.cpp" />
     <ClCompile Include="timer.cpp" />
+    <ClCompile Include="dpi.cpp" />
   </ItemGroup>
   <ItemGroup>
     <Filter Include="windows">
       <UniqueIdentifier>{ac651b31-e7cb-4909-a4cd-059605cc42dd}</UniqueIdentifier>
     </Filter>
   </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="minitimer.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="icon1.ico">
+      <Filter>windows</Filter>
+    </None>
+  </ItemGroup>
 </Project>
\ No newline at end of file