OSDN Git Service

とりあえず実行できるようになった。
[winaudioj/stedx.git] / sf_windows.h
1 #pragma once
2 /*
3 */
4 // Windows Header Files:
5 #define XBYAK64
6 #include "exception.h"
7 #include "base_window.h"
8 #include "dpi.h"
9 #include "xbyak.h"
10 #include "windows.h"
11 #include "windowsx.h"
12 #include "CommCtrl.h"
13 #include <type_traits>
14 #include "timer.h"
15 //#include <boost/type_traits/is_same.hpp>
16 // DLLのリンク
17 #pragma comment(lib,"d2d1.lib")
18 #pragma comment(lib,"winmm.lib")
19 #pragma comment(lib,"dwrite.lib")
20 #pragma comment(lib,"dwmapi.lib")
21
22 //#include "input.h"
23
24
25 // Direct Write
26
27 _WRL_PTR_TYPEDEF(IDWriteFactory);
28 _WRL_PTR_TYPEDEF(IDWriteGdiInterop);
29 _WRL_PTR_TYPEDEF(IDWriteFontFace);
30 _WRL_PTR_TYPEDEF(IDWriteFont);
31 _WRL_PTR_TYPEDEF(IDWriteFontFamily);
32 _WRL_PTR_TYPEDEF(IDWriteFontCollection);
33 _WRL_PTR_TYPEDEF(IDWriteLocalizedStrings);
34 _WRL_PTR_TYPEDEF(IDWriteTextFormat);
35 _WRL_PTR_TYPEDEF(IDWriteTextLayout);
36 _WRL_PTR_TYPEDEF(IDWriteFontFile);
37 //_WRL_PTR_TYPEDEF(IDWriteFontFile);
38
39 // Direct2D
40
41 _WRL_PTR_TYPEDEF(ID2D1Factory);
42 _WRL_PTR_TYPEDEF(ID2D1HwndRenderTarget);
43 _WRL_PTR_TYPEDEF(ID2D1BitmapRenderTarget);
44 _WRL_PTR_TYPEDEF(ID2D1GdiInteropRenderTarget);
45 _WRL_PTR_TYPEDEF(ID2D1DCRenderTarget);
46 _WRL_PTR_TYPEDEF(ID2D1PathGeometry);
47 _WRL_PTR_TYPEDEF(ID2D1LinearGradientBrush);
48 _WRL_PTR_TYPEDEF(ID2D1GradientStopCollection);
49 _WRL_PTR_TYPEDEF(ID2D1SolidColorBrush);
50 _WRL_PTR_TYPEDEF(ID2D1BitmapBrush);
51 _WRL_PTR_TYPEDEF(ID2D1Bitmap);
52
53 // WIC
54
55 _WRL_PTR_TYPEDEF(IWICImagingFactory);
56 _WRL_PTR_TYPEDEF(IWICBitmapDecoder);
57 _WRL_PTR_TYPEDEF(IWICBitmapFrameDecode);
58 _WRL_PTR_TYPEDEF(IWICStream);
59 _WRL_PTR_TYPEDEF(IWICFormatConverter);
60 _WRL_PTR_TYPEDEF(IWICBitmapScaler);
61 _WRL_PTR_TYPEDEF(ITaskbarList3);
62
63 // DXGI 
64
65 _WRL_PTR_TYPEDEF(IDXGISwapChain);
66 _WRL_PTR_TYPEDEF(IDXGIFactory1);
67 _WRL_PTR_TYPEDEF(IDXGIAdapter1);
68 _WRL_PTR_TYPEDEF(IDXGIDevice1);
69 _WRL_PTR_TYPEDEF(IDXGIKeyedMutex);
70 _WRL_PTR_TYPEDEF(IDXGIObject);
71 _WRL_PTR_TYPEDEF(IDXGIDeviceSubObject);
72 _WRL_PTR_TYPEDEF(IDXGISurface1);
73 _WRL_PTR_TYPEDEF(IDXGIOutput);
74 //_WRL_PTR_TYPEDEF(IDXGI);
75 //_WRL_PTR_TYPEDEF(IDXGI);
76
77 // Direct3D
78
79 _WRL_PTR_TYPEDEF(ID3D11Device);
80 _WRL_PTR_TYPEDEF(ID3D11DeviceContext);
81 _WRL_PTR_TYPEDEF(ID3D11RenderTargetView);
82 _WRL_PTR_TYPEDEF(ID3D11DepthStencilView);
83 _WRL_PTR_TYPEDEF(ID3D11VertexShader);
84 _WRL_PTR_TYPEDEF(ID3D11PixelShader);
85 _WRL_PTR_TYPEDEF(ID3D11InputLayout);
86 _WRL_PTR_TYPEDEF(ID3D11Buffer);
87 _WRL_PTR_TYPEDEF(ID3D11Texture2D);
88 _WRL_PTR_TYPEDEF(ID3DBlob);
89 _WRL_PTR_TYPEDEF(ID3D11ShaderResourceView);
90 _WRL_PTR_TYPEDEF(ID3D11SamplerState);
91 _WRL_PTR_TYPEDEF(ID3D11Resource);
92
93 namespace sf{
94
95   /* inline template <class Exc = win32_error_exception> void throw_if_err<>()(HRESULT hr)
96   {
97   if(hr != S_OK){throw Exc(hr);}
98   };*/
99
100
101   ID2D1BitmapPtr load_bitmap_from_file(
102     ID2D1HwndRenderTargetPtr render_target,
103     IWICImagingFactoryPtr wic_factory,
104     std::wstring uri,
105     uint32_t destination_width = 0,
106     uint32_t destination_height = 0
107     );
108
109   /** WNDCLASSEXラッパクラス */
110   struct window_class_ex
111   {
112     window_class_ex(
113       const wchar_t*  menu_name ,
114       const std::wstring&  class_name ,
115       HINSTANCE   hInstance = NULL,
116       WNDPROC     lpfnWndProc = ::DefWindowProcW,
117       uint32_t        style = CS_HREDRAW | CS_VREDRAW,
118       int32_t     cbClsExtra  = 0,
119       int32_t     cbWndExtra = sizeof(LONG_PTR), 
120       HICON       hIcon = ::LoadIcon(NULL,IDI_APPLICATION),
121       HCURSOR     hCursor = ::LoadCursor(NULL, IDC_ARROW),
122       HBRUSH      hbrBackground = ::CreateSolidBrush(0xff000000),
123       HICON       hIconSm = NULL
124       ) : is_register_(false)
125     {
126
127       if(::GetClassInfoExW(hInstance,class_name.c_str(),&wndclass_) == 0)
128       {
129         if(::GetLastError() == ERROR_CLASS_DOES_NOT_EXIST)
130         { 
131           ::ZeroMemory(&wndclass_,sizeof(wndclass_));
132           wndclass_.lpszMenuName = (LPCWSTR)menu_name;
133           wndclass_.lpszClassName = class_name.c_str();
134           wndclass_.cbSize = sizeof(::WNDCLASSEXW);
135           wndclass_.cbWndExtra = cbWndExtra;
136           wndclass_.hInstance = hInstance;
137           wndclass_.lpfnWndProc = lpfnWndProc;
138           wndclass_.style = style;
139           wndclass_.cbClsExtra = cbClsExtra;
140           wndclass_.hIcon = hIcon;
141           wndclass_.hCursor = hCursor;
142           wndclass_.hbrBackground = hbrBackground;
143           wndclass_.hIconSm = hIconSm;
144           atom_ = ::RegisterClassExW(&wndclass_) ;
145           BOOST_ASSERT(atom_ != 0);
146           is_register_ = true;
147         } else {
148           throw win32_error_exception();
149         }
150       } else {
151         is_register_ = false;
152       }
153     };
154
155     ~window_class_ex()
156     {
157       if(is_register_){
158         ::UnregisterClassW(wndclass_.lpszClassName,wndclass_.hInstance);
159       }
160     }
161
162   private:
163     bool is_register_;
164     ATOM atom_;
165     ::WNDCLASSEXW wndclass_;
166   };
167
168   struct get_dc {
169     get_dc(HWND hwnd) : hwnd_(hwnd),hdc_(GetDC(hwnd)) {}
170     HDC get(){return hdc_;}
171     ~get_dc(){::ReleaseDC(hwnd_,hdc_);}
172   private:
173     HDC hdc_;
174     HWND hwnd_;
175   };
176
177   struct get_window_dc {
178     get_window_dc(HWND hwnd) : hwnd_(hwnd),hdc_(GetWindowDC(hwnd)) {}
179     HDC get(){return hdc_;}
180     ~get_window_dc(){::ReleaseDC(hwnd_,hdc_);}
181   private:
182     HDC hdc_;
183     HWND hwnd_;
184   };
185
186   struct compatible_dc {
187     compatible_dc(HDC hdc) : hdc_(::CreateCompatibleDC(hdc)){}; 
188     ~compatible_dc(){::DeleteDC(hdc_);};
189     HDC get() { return hdc_;};
190   private:
191     HDC hdc_;
192   };
193
194   struct ref_dc {
195     ref_dc(HDC& hdc) : hdc_(hdc) {};
196     ~ref_dc(){};
197     HDC get() { return hdc_;};
198   private:
199     HDC& hdc_;
200   };
201
202   struct d2_dc {
203     d2_dc(ID2D1GdiInteropRenderTargetPtr& ptr,D2D1_DC_INITIALIZE_MODE mode) :hdc_(0),ptr_(ptr)
204     {
205       hr_ = ptr->GetDC(mode,&hdc_);
206     };
207     ~d2_dc(){ptr_->ReleaseDC(NULL);};
208     HDC get() { return hdc_;};
209   private:
210     HRESULT hr_;
211     HDC hdc_;
212     ID2D1GdiInteropRenderTargetPtr& ptr_;
213   };
214
215   template <typename Holder>
216   struct device_context
217   {
218     explicit device_context(Holder* holder) : holder_(holder){};
219     ~device_context() {}
220     operator HDC(){return holder_->get();}
221   private:
222     std::unique_ptr<Holder> holder_;
223   };
224
225   //struct handle_holder : boost::noncopyable
226   //{
227   //  explicit handle_holder(HANDLE handle) : handle_(handle) {};
228   //  ~handle_holder(){if(handle_) ::CloseHandle(handle_);}
229   //  operator HANDLE(){return handle_;}
230   //private:
231   //  HANDLE handle_;
232   //};
233
234
235   struct HBITMAP_deleter {
236     typedef HBITMAP pointer;
237     void operator ()(HBITMAP handle) {
238       if (handle) {
239         ::DeleteObject(handle);
240       }
241     }
242   };
243
244   //template <typename Handle,typename Handle_Deleter>
245   //struct handle_holder {
246   //  typedef boost::unique_ptr<Handle,Handle_Deleter> holder_type;
247   //  handle_holder(Handle handle) : holder_(handle) {}
248   //  operator Handle(){return holder_->get();}
249   //private:
250   //  holder_type holder_;
251   //};
252
253   typedef std::unique_ptr<HBITMAP,HBITMAP_deleter> bitmap_holder;
254
255   typedef device_context<d2_dc> d2_dc_type;
256
257   struct paint_struct 
258   {
259     paint_struct(HWND hwnd) : hwnd_(hwnd)
260     {
261       ::BeginPaint(hwnd,&paintstruct_);
262     }
263     ~paint_struct() {::EndPaint(hwnd_,&paintstruct_);}
264     PAINTSTRUCT* operator->(){return &paintstruct_;}
265   private:
266     HWND hwnd_;
267     PAINTSTRUCT paintstruct_;
268   };
269
270   // GDI オブジェクト管理テンプレート
271   template <class GdiObject> 
272   struct gdi_object: boost::noncopyable
273   {
274     explicit gdi_object(GdiObject obj) : gdiobj_(obj) {}
275     ~gdi_object(){::DeleteObject(gdiobj_);}
276     operator GdiObject(){return gdiobj_;}
277   private:
278     GdiObject gdiobj_;
279   };
280
281   //
282   struct select_object 
283   {
284     select_object(HDC dc,HGDIOBJ o) : dc_(dc),o_(::SelectObject(dc,o)) {}
285     ~select_object(){::SelectObject(dc_,o_);}
286   private:
287     HDC dc_;
288     HGDIOBJ o_;
289   };
290
291   // Direct2D BeginDrawヘルパ関数
292   template <typename T >
293   struct begin_draw
294   {
295     typedef std::function<void(HRESULT hr)> err_handler_type;
296
297     begin_draw(T& render_target,err_handler_type& handler = err_handler_type([](HRESULT hr)->void{throw sf::win32_error_exception(hr);}))
298       : render_target_(render_target) ,
299       handler_(handler)
300     {render_target->BeginDraw();}
301
302     ~begin_draw(){ 
303       HRESULT hr = S_OK;
304       hr = render_target_->EndDraw();
305       if( hr != S_OK)
306       {
307         handler_(hr);
308       }
309     }
310   private:
311     T& render_target_;
312     err_handler_type handler_;
313   };
314
315   struct mouse
316   {
317     mouse() : x_(0.0f),y_(0.0f),left_button_(false),middle_button_(false),right_button_(false){}
318   private:
319     float x_,y_;
320     bool left_button_,middle_button_,right_button_;
321   };
322
323
324   // ウィンドウプロシージャの識別用クラス
325   struct wndproc 
326   {
327     typedef WNDPROC proc_type;
328     typedef LRESULT return_type;
329     static inline return_type def_wnd_proc(HWND hwnd,uint32_t message, WPARAM wParam, LPARAM lParam) 
330     {
331       return ::DefWindowProcW(hwnd,message,wParam,lParam);
332     }
333   };
334
335   // ダイアログプロシージャの識別用クラス
336   struct dlgproc
337   {
338     typedef DLGPROC proc_type;
339     typedef INT_PTR return_type;
340     static inline return_type def_wnd_proc(HWND hwnd,uint32_t message, WPARAM wParam, LPARAM lParam)
341     {
342       return FALSE;
343     }
344   };
345
346   /** window ベースクラス */
347   template <typename ProcType = wndproc>
348   struct base_win32_window : public base_window 
349   {
350     typedef ProcType proc_t;
351     typedef typename proc_t::return_type result_t;
352 //    typedef proc_t::return_type result_t;
353
354     operator HWND() const {return hwnd_;};
355
356     virtual void * raw_handle() const {return hwnd_;};
357     //    virtual void show(uint32_t show_flag);
358
359     virtual void show() {
360       ::ShowWindow(hwnd_,SW_SHOW);
361       ::GetWindowPlacement(hwnd_,&wp_);
362     }
363
364     // Window を画面から隠す
365     virtual bool is_show() {
366       return ( wp_.showCmd == SW_SHOWMAXIMIZED 
367         || wp_.showCmd == SW_SHOWMINIMIZED
368         || wp_.showCmd == SW_SHOWNORMAL );
369     };
370
371     //
372     virtual void hide()
373     {
374       ::ShowWindow(hwnd_,SW_HIDE);
375       ::GetWindowPlacement(hwnd_,&wp_);
376     };
377
378     virtual void text(std::wstring& text)
379     {
380       ::SetWindowTextW(*this,text.c_str());
381     };
382
383     virtual void send_message(uint32_t message,uint32_t wparam,uint32_t lparam )
384     {
385       ::SendNotifyMessage(hwnd_,message,wparam,lparam);
386     }
387
388     virtual void post_message(uint32_t message,uint32_t wparam,uint32_t lparam )
389     {
390       ::PostMessage(hwnd_,message,wparam,lparam);
391     }
392
393     virtual void message_box(const std::wstring& text,const std::wstring& caption,uint32_t type = MB_OK)
394     {
395       ::MessageBox(hwnd_,text.c_str(),caption.c_str(),type);
396     }
397
398     virtual void update();
399
400     virtual void create_device_independent_resources();
401     virtual void create_device();
402     virtual void create_swapchain_dependent_resources();
403
404     virtual void discard_swapchain_dependent_resources();
405     virtual void discard_device();
406     virtual void discard_device_independant_resources();
407
408   protected:
409
410     base_win32_window(
411       const std::wstring& title,
412       const std::wstring& name,bool fit_to_display,
413       float width,float height);
414
415
416     ~base_win32_window();
417
418     void register_class (
419       const wchar_t* menu_name,
420       uint32_t style, 
421       int32_t     cbClsExtra  = 0,
422       int32_t     cbWndExtra  = sizeof(LONG_PTR),
423       HICON       hIcon = ::LoadIcon(NULL,IDI_APPLICATION),
424       HCURSOR     hCursor = ::LoadCursor(NULL, IDC_ARROW),
425       HBRUSH      hbrBackground = ::CreateSolidBrush(0xff000000),
426       HICON       hIconSm = NULL
427       );                
428
429     /** デフォルト設定 */
430     void register_class();
431     void create_window(HWND parent = NULL);
432
433     void calc_client_size()
434     {
435       //クライアント領域の現在の幅、高さを求める
436       RECT rc;
437       GetClientRect( hwnd_, &rc );
438       client_width_ = rc.right - rc.left;
439       client_height_ = rc.bottom - rc.top;
440     }
441   public:
442     // SetWindowLong API
443     void set_long(int index,long data)
444     {
445       SetLastError(0);
446       if(::SetWindowLongW(hwnd_,index,data) == 0)
447       {
448         long err = 0;
449         if( (err = GetLastError()) != 0){
450           SetLastError(err);
451           throw sf::win32_error_exception();
452         }
453       };
454     }
455
456     void set_pos(
457       HWND hwnd_insert_after,  // 配置順序のハンドル
458       int x,                 // 横方向の位置
459       int y,                 // 縦方向の位置
460       int cx,                // 幅
461       int cy,                // 高さ
462       UINT flags            // ウィンドウ位置のオプション
463       )
464     {
465       BOOL res = SetWindowPos(hwnd_,hwnd_insert_after,x,y,cx,cy,flags);
466       if(!res)
467       {
468         throw win32_error_exception();
469       }
470     }
471
472     bool invalidate_rect(bool erase = false,const RECT * rect_ptr = 0)
473     {
474       return ::InvalidateRect(*this,rect_ptr,erase) == TRUE;
475     }
476
477     void enable_control(uint32_t id,bool enable)
478     {
479       ::EnableWindow(GetDlgItem(hwnd_,id),enable?TRUE:FALSE);
480     }
481
482     void enable_control(HWND hwnd,uint32_t id,bool enable)
483     {
484       ::EnableWindow(GetDlgItem(hwnd,id),enable?TRUE:FALSE);
485     };
486
487     virtual result_t window_proc(HWND hwnd,uint32_t message, WPARAM wParam, LPARAM lParam);
488     virtual result_t other_window_proc(HWND hwnd,uint32_t message, WPARAM wParam, LPARAM lParam)
489     {
490       return proc_t::def_wnd_proc(hwnd,message,wParam,lParam);
491     };
492
493     // デフォルトウィンドウメッセージハンドラ
494     virtual result_t on_nccreate(CREATESTRUCT *p) ;//{ return std::is_same<proc_t,wndproc>::value?1:FALSE;}
495     virtual result_t on_create(CREATESTRUCT *p); //{ return std::is_same<proc_t,wndproc>::value?0:FALSE;}
496     virtual result_t on_init_dialog(HWND default_focus_ctrl,LPARAM data) {return TRUE;}
497     virtual result_t on_size(uint32_t flag,uint32_t width,uint32_t height);//{return std::is_same<proc_t,wndproc>::value?0:FALSE;    }
498     //virtual LRESULT 
499     virtual result_t on_paint();
500     virtual result_t on_display_change(uint32_t bpp,uint32_t h_resolution,uint32_t v_resolution) {         invalidate_rect();return std::is_same<proc_t,wndproc>::value?0:FALSE;}
501     virtual result_t on_erase_backgroud(HDC dc) {return std::is_same<proc_t,wndproc>::value?1:TRUE;}
502     virtual result_t on_hscroll(uint32_t state,uint32_t position,HWND ctrl_hwnd) {return std::is_same<proc_t,wndproc>::value?0:FALSE;}
503     virtual result_t on_vscroll(uint32_t state,uint32_t position,HWND ctrl_hwnd) {return std::is_same<proc_t,wndproc>::value?0:FALSE;}
504     virtual result_t on_left_mouse_button_down(uint32_t mouse_key,int x,int y ) { return std::is_same<proc_t,wndproc>::value?0:FALSE; }
505     virtual result_t on_left_mouse_button_up(uint32_t mouse_key,int x,int y) { return std::is_same<proc_t,wndproc>::value?0:FALSE; }
506     virtual result_t on_left_mouse_button_double_click(uint32_t mouse_key,int x,int y) { return std::is_same<proc_t,wndproc>::value?0:FALSE; }
507     virtual result_t on_mouse_move(uint32_t mouse_key,int x,int y) {return std::is_same<proc_t,wndproc>::value?0:FALSE; }
508     virtual result_t on_mouse_wheel(uint32_t mouse_key,int delta,int x,int y) {  return std::is_same<proc_t,wndproc>::value?0:FALSE; }
509     //virtual bool on_mouse_enter(uint32_t mouse_key,int x,int y) {  return false; }
510     virtual result_t on_mouse_leave() {  return std::is_same<proc_t,wndproc>::value?0:FALSE; }
511     virtual result_t on_destroy(){   
512       //::PostQuitMessage(0);
513       return std::is_same<proc_t,wndproc>::value?0:FALSE;
514     }
515
516     virtual result_t on_close()
517     {
518       discard_device();
519       // Windowの破棄
520       BOOL ret(::DestroyWindow(hwnd_));
521       BOOST_ASSERT(ret != 0);
522 //      return TRUE;
523       return std::is_same<proc_t,wndproc>::value?1:TRUE;
524     }
525
526     virtual result_t on_set_cursor() { return std::is_same<proc_t,wndproc>::value?0:FALSE; }
527     virtual result_t on_key_down(uint32_t vkey,uint32_t ext_key,uint32_t repeat) { return std::is_same<proc_t,wndproc>::value?0:FALSE; }
528     virtual result_t on_key_up(uint32_t vkey,uint32_t ext_key,uint32_t repeat) { return std::is_same<proc_t,wndproc>::value?0:FALSE; }
529     virtual result_t on_app_command(uint32_t command,uint32_t device,uint32_t keystate) {return std::is_same<proc_t,wndproc>::value?0:FALSE;}
530     virtual result_t on_command(uint32_t wparam, uint32_t lparam)  { return std::is_same<proc_t,wndproc>::value?0:FALSE; } 
531     virtual result_t on_timer(uint32_t timer_id)  {
532       //::InvalidateRect(hwnd_,NULL,FALSE);
533       render();
534       return std::is_same<proc_t,wndproc>::value?0:FALSE; 
535     } 
536     virtual result_t on_notify(NMHDR* nmhdr)  { return std::is_same<proc_t,wndproc>::value?0:FALSE; }
537     virtual result_t on_dwm_composition_changed();
538     virtual void render();
539   protected:
540     void get_dxgi_information();
541
542     // Window生成後呼ばれる関数
543     // WM_NCCREATEメッセージの時にthunkに切り替える
544     static result_t CALLBACK start_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
545     {
546       if(message == WM_NCCREATE)
547       {
548         LPCREATESTRUCT param = reinterpret_cast<LPCREATESTRUCT>(lParam);
549         base_win32_window* ptr = reinterpret_cast<base_win32_window*>(param->lpCreateParams);
550         ptr->hwnd_ = hwnd;
551         // ウィンドウプロシージャをインスタンスと結び付けるthunkプロシージャに入れ替える
552         LONG_PTR r = SetWindowLongPtr(hwnd,GWLP_WNDPROC,reinterpret_cast<LONG_PTR>(ptr->thunk_proc_));
553         assert(r == reinterpret_cast<LONG_PTR>(&start_wnd_proc));
554         return ptr->window_proc(hwnd,message,wParam,lParam);
555       }
556       return ::DefWindowProcW(hwnd,message,wParam,lParam);
557     };
558
559     static result_t CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
560     {
561       base_win32_window* ptr = reinterpret_cast<base_win32_window*>(hwnd);
562       return ptr->window_proc(ptr->hwnd_,message,wParam,lParam);
563     };
564
565     // thisとhwndをつなぐthunkクラス
566     struct hwnd_this_thunk : public Xbyak::CodeGenerator {
567       hwnd_this_thunk(base_win32_window* impl,typename proc_t::proc_type proc)
568       {
569         // rcxにhwndが格納されているので、それをimpl->hwndに保存
570 //        mov(ptr[&(impl->hwnd_)],rcx); // <-- エラー発生部分
571                 mov(rax,(size_t)&impl->hwnd_);  // <-- 訂正
572         mov(ptr[rax],rcx);                              // <-- 訂正
573         // 代わりにthisのアドレスをrcxに格納
574         mov(rcx,(LONG_PTR)impl);
575         // r10にproc(Window プロシージャ)へのアドレスを格納
576         mov(r10,(LONG_PTR)proc);
577         // Window プロシージャへへジャンプ
578         jmp(r10);
579       }
580     };
581
582     void update_window_size()
583     {
584       RECT r;
585       GetWindowRect(hwnd_,&r);
586       width_ = r.right - r.left;
587       height_ = r.bottom - r.top;
588     }
589
590     void init_view_matrix();
591
592     HWND hwnd_;
593     hwnd_this_thunk thunk_;
594     std::wstring title_;
595     std::wstring name_;
596     float width_,height_;
597     bool fit_to_display_;
598     std::shared_ptr<sf::window_class_ex> wnd_class_;
599     typename proc_t::proc_type thunk_proc_;
600     dpi dpi_;
601     WINDOWPLACEMENT wp_;
602     bool init_;
603
604     ID2D1FactoryPtr factory_;
605     ID2D1HwndRenderTargetPtr render_target_;
606     IDWriteFactoryPtr write_factory_;
607     IWICImagingFactoryPtr wic_imaging_factory_;
608     IDWriteTextFormatPtr write_text_format_;
609
610     IDXGIFactory1Ptr dxgi_factory_;
611     IDXGIAdapter1Ptr adapter_;
612     IDXGIOutputPtr output_;
613     ID3D11DevicePtr d3d_device_;
614     ID3D11DeviceContextPtr d3d_context_;
615     ID3D11Texture2DPtr texture_;
616     ID3D11RenderTargetViewPtr view_;
617     ID3D11Texture2DPtr depth_texture_;
618     ID3D11DepthStencilViewPtr depth_view_;
619     ID3D11VertexShaderPtr v_shader_;
620     ID3D11InputLayoutPtr input_layout_;
621     ID3D11PixelShaderPtr p_shader_;
622     ID3D11BufferPtr v_buffer_;
623     ID3D11BufferPtr i_buffer_;
624     ID3D11BufferPtr cb_never_changes_;
625     ID3D11BufferPtr cb_change_on_resize_;
626     ID3D11BufferPtr cb_changes_every_frame_;
627     ID3D11ShaderResourceViewPtr shader_res_view_;
628     ID3D11SamplerStatePtr sampler_state_;
629     ID3D11Texture2DPtr back_buffer_;
630     
631     ID3D11SamplerStatePtr cube_sampler_state_;
632     ID3D11Texture2DPtr cube_texture_;
633     ID3D11Texture2DPtr cube_depth_texture_;
634     ID3D11ShaderResourceViewPtr cube_shader_res_view_;
635     ID3D11RenderTargetViewPtr cube_view_;
636     ID3D11DepthStencilViewPtr cube_depth_view_;
637
638     DXGI_MODE_DESC actual_desc_;
639     IDXGISwapChainPtr swap_chain_;
640     std::wstring dxgi_info_;
641
642         
643         
644     DirectX::XMMATRIX                            mat_world_;
645     DirectX::XMMATRIX                            mat_view_;
646     DirectX::XMMATRIX                            mat_projection_;
647     DirectX::XMMATRIX                            cube_mat_projection_;
648         
649     DirectX::XMFLOAT4                            mesh_color_;
650     float client_width_,client_height_;
651
652     timer timer_;
653
654     // __declspec ( thread ) static std::queue<proc_t::proc_type> ptrs_ ;// thread local storage
655
656   };
657
658   typedef base_win32_window<> base_win32_window_t;
659   typedef base_win32_window<dlgproc> base_win32_dialog_t;
660
661   /// サブクラスウィンドウ
662   struct subclass_window : public base_win32_window_t
663   {
664     subclass_window(HWND hwnd);
665     subclass_window();
666     void attach(HWND hwnd);
667     void detatch();
668     ~subclass_window();
669     virtual result_t window_proc(HWND hwnd,uint32_t message, WPARAM wParam, LPARAM lParam) 
670     {
671       return CallWindowProc(proc_backup_,hwnd,message,wParam,lParam);
672     };
673   protected:
674     bool is_subclassed_;
675     WNDPROC proc_backup_;
676   };
677
678   struct av_mm_thread_characteristics
679   {
680     av_mm_thread_characteristics(std::wstring& str) : task_name_(str)
681     {
682       handle_ = ::AvSetMmThreadCharacteristicsW(str.c_str(),(LPDWORD)&task_index_);
683     }
684
685     bool set_priority(AVRT_PRIORITY p){return (::AvSetMmThreadPriority(handle_,p) == TRUE);}
686
687     ~av_mm_thread_characteristics()
688     {
689       ::AvRevertMmThreadCharacteristics(handle_);
690     }
691
692   private:
693     std::wstring task_name_;
694     uint32_t task_index_;
695     HANDLE handle_;
696   };
697
698   struct widget
699   {
700     void draw();
701     float x_,y_;
702   };
703
704   typedef sf::begin_draw<ID2D1BitmapRenderTargetPtr> begin_draw_bitmap;
705   typedef sf::begin_draw<ID2D1HwndRenderTargetPtr> begin_draw_hwnd;
706
707 }