OSDN Git Service

276d966e215f863f8267c220983e585ac6365c76
[shooting3/dxgi_test.git] / dxgi_test / sf_windows.h
1 #pragma once
2 /*
3 */
4 // Windows Header Files:
5 #include "exception.h"
6 #include "base_window.h"
7 #include "dpi.h"
8 #define XBYAK64
9 #include "xbyak.h"
10 // DLLのリンク
11 #pragma comment(lib,"d2d1.lib")
12 #pragma comment(lib,"winmm.lib")
13 #pragma comment(lib,"dwrite.lib")
14 #pragma comment(lib,"dwmapi.lib")
15
16 //#include "input.h"
17
18 // Direct Write
19
20 _COM_SMARTPTR_TYPEDEF(IDWriteFactory , __uuidof(IDWriteFactory));
21 _COM_SMARTPTR_TYPEDEF(IDWriteGdiInterop , __uuidof(IDWriteGdiInterop));
22 _COM_SMARTPTR_TYPEDEF(IDWriteFontFace , __uuidof(IDWriteFontFace));
23 _COM_SMARTPTR_TYPEDEF(IDWriteFont , __uuidof(IDWriteFont));
24 _COM_SMARTPTR_TYPEDEF(IDWriteFontFamily , __uuidof(IDWriteFontFamily));
25 _COM_SMARTPTR_TYPEDEF(IDWriteFontCollection , __uuidof(IDWriteFontCollection));
26 _COM_SMARTPTR_TYPEDEF(IDWriteLocalizedStrings , __uuidof(IDWriteLocalizedStrings));
27 _COM_SMARTPTR_TYPEDEF(IDWriteTextFormat, __uuidof(IDWriteTextFormat));
28 _COM_SMARTPTR_TYPEDEF(IDWriteTextLayout, __uuidof(IDWriteTextLayout));
29
30 // Direct2D
31
32 _COM_SMARTPTR_TYPEDEF(ID2D1Factory,__uuidof(ID2D1Factory));
33 _COM_SMARTPTR_TYPEDEF(ID2D1HwndRenderTarget , __uuidof(ID2D1HwndRenderTarget));
34 _COM_SMARTPTR_TYPEDEF(ID2D1BitmapRenderTarget , __uuidof(ID2D1BitmapRenderTarget));
35 _COM_SMARTPTR_TYPEDEF(ID2D1GdiInteropRenderTarget , __uuidof(ID2D1GdiInteropRenderTarget));
36 _COM_SMARTPTR_TYPEDEF(ID2D1DCRenderTarget , __uuidof(ID2D1DCRenderTarget));
37 _COM_SMARTPTR_TYPEDEF(ID2D1PathGeometry , __uuidof(ID2D1PathGeometry));
38 _COM_SMARTPTR_TYPEDEF(ID2D1LinearGradientBrush , __uuidof(ID2D1LinearGradientBrush));
39 _COM_SMARTPTR_TYPEDEF(ID2D1GradientStopCollection , __uuidof(ID2D1GradientStopCollection));
40 _COM_SMARTPTR_TYPEDEF(ID2D1SolidColorBrush , __uuidof(ID2D1SolidColorBrush));
41 _COM_SMARTPTR_TYPEDEF(ID2D1BitmapBrush , __uuidof(ID2D1BitmapBrush));
42 _COM_SMARTPTR_TYPEDEF(ID2D1Bitmap , __uuidof(ID2D1Bitmap));
43
44 // WIC
45
46 _COM_SMARTPTR_TYPEDEF(IWICImagingFactory, __uuidof(IWICImagingFactory));
47 _COM_SMARTPTR_TYPEDEF(IWICBitmapDecoder,__uuidof(IWICBitmapDecoder));
48 _COM_SMARTPTR_TYPEDEF(IWICBitmapFrameDecode,__uuidof(IWICBitmapFrameDecode));
49 _COM_SMARTPTR_TYPEDEF(IWICStream,__uuidof(IWICStream));
50 _COM_SMARTPTR_TYPEDEF(IWICFormatConverter,__uuidof(IWICFormatConverter));
51 _COM_SMARTPTR_TYPEDEF(IWICBitmapScaler,__uuidof(IWICBitmapScaler));
52 _COM_SMARTPTR_TYPEDEF(ITaskbarList3,__uuidof(ITaskbarList3));
53
54 // DXGI 
55
56 _COM_SMARTPTR_TYPEDEF(IDXGISwapChain,__uuidof(IDXGISwapChain));
57 _COM_SMARTPTR_TYPEDEF(IDXGIFactory1,__uuidof(IDXGIFactory1));
58 _COM_SMARTPTR_TYPEDEF(IDXGIAdapter1,__uuidof(IDXGIAdapter1));
59 _COM_SMARTPTR_TYPEDEF(IDXGIDevice1,__uuidof(IDXGIDevice1));
60 _COM_SMARTPTR_TYPEDEF(IDXGIKeyedMutex,__uuidof(IDXGIKeyedMutex));
61 _COM_SMARTPTR_TYPEDEF(IDXGIObject,__uuidof(IDXGIObject));
62 _COM_SMARTPTR_TYPEDEF(IDXGIDeviceSubObject,__uuidof(IDXGIDeviceSubObject));
63 _COM_SMARTPTR_TYPEDEF(IDXGISurface1,__uuidof(IDXGISurface1));
64 _COM_SMARTPTR_TYPEDEF(IDXGIOutput,__uuidof(IDXGIOutput));
65 //_COM_SMARTPTR_TYPEDEF(IDXGI,__uuidof(IDXGI));
66 //_COM_SMARTPTR_TYPEDEF(IDXGI,__uuidof(IDXGI));
67
68 // Direct3D
69
70 _COM_SMARTPTR_TYPEDEF(ID3D11Device,__uuidof(ID3D11Device));
71 _COM_SMARTPTR_TYPEDEF(ID3D11DeviceContext,__uuidof(ID3D11DeviceContext));
72 _COM_SMARTPTR_TYPEDEF(ID3D11RenderTargetView,__uuidof(ID3D11RenderTargetView));
73 _COM_SMARTPTR_TYPEDEF(ID3D11VertexShader,__uuidof(ID3D11VertexShader));
74 _COM_SMARTPTR_TYPEDEF(ID3D11PixelShader,__uuidof(ID3D11PixelShader));
75 _COM_SMARTPTR_TYPEDEF(ID3D11InputLayout,__uuidof(ID3D11InputLayout));
76 _COM_SMARTPTR_TYPEDEF(ID3D11Buffer,__uuidof(ID3D11Buffer));
77 _COM_SMARTPTR_TYPEDEF(ID3D11Texture2D,__uuidof(ID3D11Texture2D));
78 _COM_SMARTPTR_TYPEDEF(ID3DBlob,__uuidof(ID3DBlob));
79
80 template <class COM_SMART_PTR > inline void safe_release(COM_SMART_PTR& ptr)
81 {
82   if(ptr)
83   {
84     ptr.Release();
85   }
86 };
87
88 namespace sf{
89
90  /* inline template <class Exc = win32_error_exception> void throw_if_err<>()(HRESULT hr)
91   {
92     if(hr != S_OK){throw Exc(hr);}
93   };*/
94
95
96   ID2D1BitmapPtr load_bitmap_from_file(
97     ID2D1HwndRenderTargetPtr render_target,
98     IWICImagingFactoryPtr wic_factory,
99     std::wstring uri,
100     uint32_t destination_width = 0,
101     uint32_t destination_height = 0
102     );
103
104   /** WNDCLASSEXラッパクラス */
105   struct window_class_ex
106   {
107     window_class_ex(
108       const wchar_t*  menu_name ,
109       const std::wstring&  class_name ,
110       HINSTANCE   hInstance = NULL,
111       WNDPROC     lpfnWndProc = ::DefWindowProcW,
112       uint32_t        style = CS_HREDRAW | CS_VREDRAW,
113       boost::int32_t     cbClsExtra  = 0,
114       HICON       hIcon = ::LoadIcon(NULL,IDI_APPLICATION),
115       HCURSOR     hCursor = ::LoadCursor(NULL, IDC_ARROW),
116       HBRUSH      hbrBackground = ::CreateSolidBrush(0xff000000),
117       HICON       hIconSm = NULL
118       ) : is_register_(false)
119     {
120
121       if(::GetClassInfoExW(hInstance,class_name.c_str(),&wndclass_) == 0)
122       {
123         if(::GetLastError() == ERROR_CLASS_DOES_NOT_EXIST)
124         { 
125           ::ZeroMemory(&wndclass_,sizeof(wndclass_));
126           wndclass_.lpszMenuName = (LPCWSTR)menu_name;
127           wndclass_.lpszClassName = class_name.c_str();
128           wndclass_.cbSize = sizeof(::WNDCLASSEXW);
129           wndclass_.cbWndExtra = sizeof(LONG_PTR);
130           wndclass_.hInstance = hInstance;
131           wndclass_.lpfnWndProc = lpfnWndProc;
132           wndclass_.style = style;
133           wndclass_.cbClsExtra = cbClsExtra;
134           wndclass_.hIcon = hIcon;
135           wndclass_.hCursor = hCursor;
136           wndclass_.hbrBackground = hbrBackground;
137           wndclass_.hIconSm = hIconSm;
138           atom_ = ::RegisterClassExW(&wndclass_) ;
139           BOOST_ASSERT(atom_ != 0);
140           is_register_ = true;
141         } else {
142           throw win32_error_exception();
143         }
144       } else {
145         is_register_ = false;
146       }
147     };
148
149     ~window_class_ex()
150     {
151       if(is_register_){
152         ::UnregisterClassW(wndclass_.lpszClassName,wndclass_.hInstance);
153       }
154     }
155
156   private:
157     bool is_register_;
158     ATOM atom_;
159     ::WNDCLASSEXW wndclass_;
160   };
161
162   struct get_dc {
163     get_dc(HWND hwnd) : hwnd_(hwnd),hdc_(GetDC(hwnd)) {}
164     HDC get(){return hdc_;}
165     ~get_dc(){::ReleaseDC(hwnd_,hdc_);}
166   private:
167     HDC hdc_;
168     HWND hwnd_;
169   };
170
171   struct compatible_dc {
172     compatible_dc(HDC hdc) : hdc_(::CreateCompatibleDC(hdc)){}; 
173     ~compatible_dc(){::DeleteDC(hdc_);};
174     HDC get() { return hdc_;};
175   private:
176     HDC hdc_;
177   };
178
179   struct ref_dc {
180     ref_dc(HDC& hdc) : hdc_(hdc) {};
181     ~ref_dc(){};
182     HDC get() { return hdc_;};
183   private:
184     HDC& hdc_;
185   };
186
187   struct d2_dc {
188     d2_dc(ID2D1GdiInteropRenderTargetPtr& ptr,D2D1_DC_INITIALIZE_MODE mode) :hdc_(0),ptr_(ptr)
189     {
190       hr_ = ptr->GetDC(mode,&hdc_);
191     };
192     ~d2_dc(){ptr_->ReleaseDC(NULL);};
193     HDC get() { return hdc_;};
194   private:
195     HRESULT hr_;
196     HDC hdc_;
197     ID2D1GdiInteropRenderTargetPtr& ptr_;
198   };
199
200   template <typename Holder>
201   struct device_context
202   {
203     explicit device_context(Holder* holder) : holder_(holder){};
204     ~device_context() {}
205     operator HDC(){return holder_->get();}
206   private:
207     std::unique_ptr<Holder> holder_;
208   };
209
210   //struct handle_holder : boost::noncopyable
211   //{
212   //  explicit handle_holder(HANDLE handle) : handle_(handle) {};
213   //  ~handle_holder(){if(handle_) ::CloseHandle(handle_);}
214   //  operator HANDLE(){return handle_;}
215   //private:
216   //  HANDLE handle_;
217   //};
218
219
220   struct HBITMAP_deleter {
221     typedef HBITMAP pointer;
222     void operator ()(HBITMAP handle) {
223         if (handle) {
224            ::DeleteObject(handle);
225         }
226     }
227   };
228
229   //template <typename Handle,typename Handle_Deleter>
230   //struct handle_holder {
231   //  typedef boost::unique_ptr<Handle,Handle_Deleter> holder_type;
232   //  handle_holder(Handle handle) : holder_(handle) {}
233   //  operator Handle(){return holder_->get();}
234   //private:
235   //  holder_type holder_;
236   //};
237
238   typedef std::unique_ptr<HBITMAP,HBITMAP_deleter> bitmap_holder;
239
240   typedef device_context<d2_dc> d2_dc_type;
241
242   struct paint_struct 
243   {
244     paint_struct(HWND hwnd) : hwnd_(hwnd)
245     {
246       ::BeginPaint(hwnd,&paintstruct_);
247     }
248     ~paint_struct() {::EndPaint(hwnd_,&paintstruct_);}
249     PAINTSTRUCT* operator->(){return &paintstruct_;}
250   private:
251     HWND hwnd_;
252     PAINTSTRUCT paintstruct_;
253   };
254
255   // GDI オブジェクト管理テンプレート
256   template <class GdiObject> 
257     struct gdi_object: boost::noncopyable
258   {
259     explicit gdi_object(GdiObject obj) : gdiobj_(obj) {}
260     ~gdi_object(){::DeleteObject(gdiobj_);}
261     operator GdiObject(){return gdiobj_;}
262   private:
263     GdiObject gdiobj_;
264   };
265
266   //
267   struct select_object 
268   {
269     select_object(HDC dc,HGDIOBJ o) : dc_(dc),o_(::SelectObject(dc,o)) {}
270     ~select_object(){::SelectObject(dc_,o_);}
271   private:
272     HDC dc_;
273     HGDIOBJ o_;
274   };
275   
276   // Direct2D BeginDrawヘルパ関数
277   template <typename T >
278   struct begin_draw
279   {
280     typedef std::function<void(HRESULT hr)> err_handler_type;
281
282     begin_draw(T& render_target,err_handler_type& handler)
283       : render_target_(render_target) ,
284         is_end_(false),handler_(handler)
285     {render_target->BeginDraw();}
286
287     ~begin_draw(){ 
288       HRESULT hr = S_OK;
289       hr = render_target_->EndDraw();
290       if( hr != S_OK)
291       {
292         handler_(hr);
293       }
294     }
295   private:
296     T& render_target_;
297     err_handler_type handler_;
298   };
299
300   struct mouse
301   {
302     mouse() : x_(0.0f),y_(0.0f),left_button_(false),middle_button_(false),right_button_(false){}
303   private:
304     float x_,y_;
305     bool left_button_,middle_button_,right_button_;
306   };
307
308
309   /** window ベースクラス */
310   struct base_win32_window : public base_window 
311   {
312     typedef boost::signals2::signal<LRESULT (HWND,uint32_t,WPARAM, LPARAM) > on_message_type;
313     on_message_type on_message;
314     
315     operator HWND() const {return hwnd_;};
316     
317     virtual void * raw_handle() const {return hwnd_;};
318 //    virtual void show(uint32_t show_flag);
319
320     virtual void show() {
321       ::ShowWindow(hwnd_,SW_SHOW);
322       ::GetWindowPlacement(hwnd_,&wp_);
323     }
324
325     // Window を画面から隠す
326     virtual bool is_show() {
327       return ( wp_.showCmd == SW_SHOWMAXIMIZED 
328         || wp_.showCmd == SW_SHOWMINIMIZED
329         || wp_.showCmd == SW_SHOWNORMAL );
330     };
331
332     //
333     virtual void hide()
334     {
335       ::ShowWindow(hwnd_,SW_HIDE);
336       ::GetWindowPlacement(hwnd_,&wp_);
337     };
338
339     virtual void text(std::wstring& text)
340     {
341       ::SetWindowTextW(*this,text.c_str());
342     };
343
344     virtual void update();
345
346   protected:
347     
348     base_win32_window(
349       const std::wstring& title,
350       const std::wstring& name,bool fit_to_display,
351       float width,float height);
352     
353     ~base_win32_window();
354
355     void register_class (
356       const wchar_t* menu_name,
357       uint32_t style, 
358       boost::int32_t     cbClsExtra  = 0,
359       HICON       hIcon = ::LoadIcon(NULL,IDI_APPLICATION),
360       HCURSOR     hCursor = ::LoadCursor(NULL, IDC_ARROW),
361       HBRUSH      hbrBackground = ::CreateSolidBrush(0xff000000),
362       HICON       hIconSm = NULL
363       );                
364
365     /** デフォルト設定 */
366     void register_class();
367     void create_window();
368
369     // SetWindowLong API
370     void set_long(int index,long data)
371     {
372       SetLastError(0);
373       if(::SetWindowLongW(hwnd_,index,data) == 0)
374       {
375         long err = 0;
376         if( (err = GetLastError()) != 0){
377           SetLastError(err);
378           throw sf::win32_error_exception();
379         }
380       };
381     }
382
383     bool invalidate_rect(bool erase = false,const RECT * rect_ptr = 0)
384     {
385       return ::InvalidateRect(*this,rect_ptr,erase) == TRUE;
386     }
387
388   public:
389     virtual LRESULT window_proc(HWND hwnd,uint32_t message, WPARAM wParam, LPARAM lParam);
390   protected:
391     static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
392     {
393       base_win32_window* ptr = reinterpret_cast<base_win32_window*>(hwnd);
394       hwnd = ptr->hwnd_;
395       return ptr->window_proc(hwnd,message,wParam,lParam);
396     };
397
398     // thisとhwndをつなぐthunkクラス
399     struct hwnd_this_thunk : public Xbyak::CodeGenerator {
400       hwnd_this_thunk(base_win32_window* impl,WNDPROC proc)
401       {
402         // rcxにhwndが格納されているので、それをimpl->hwndに保存
403         mov(qword[&(impl->hwnd_)],rcx);
404         // 代わりにthisのアドレスをrcxに格納
405         mov(rcx,(LONG_PTR)impl);
406         // r10にproc(Window プロシージャ)へのアドレスを格納
407         mov(r10,(LONG_PTR)proc);
408         // Window プロシージャへへジャンプ
409         jmp(r10);
410       }
411     };
412
413     HWND hwnd_;
414     hwnd_this_thunk thunk_;
415     std::wstring title_;
416     std::wstring name_;
417     float width_,height_;
418     bool fit_to_display_;
419     std::shared_ptr<sf::window_class_ex> wnd_class_;
420     WNDPROC thunk_proc_;
421     dpi dpi_;
422     WINDOWPLACEMENT wp_;
423    };
424   
425   struct av_mm_thread_characteristics
426   {
427     av_mm_thread_characteristics(std::wstring& str) : task_name_(str)
428     {
429       handle_ = ::AvSetMmThreadCharacteristicsW(str.c_str(),(LPDWORD)&task_index_);
430     }
431
432     bool set_priority(AVRT_PRIORITY p){return (::AvSetMmThreadPriority(handle_,p) == TRUE);}
433
434     ~av_mm_thread_characteristics()
435     {
436       ::AvRevertMmThreadCharacteristics(handle_);
437     }
438
439   private:
440     std::wstring task_name_;
441     uint32_t task_index_;
442     HANDLE handle_;
443     std::wstring title_;
444     std::wstring name_;
445     float width_,height_;
446     bool fit_to_display_;
447     WINDOWPLACEMENT wp_;//
448   };
449
450   struct widget
451   {
452     void draw();
453     float x_,y_;
454   };
455
456   typedef sf::begin_draw<ID2D1BitmapRenderTargetPtr> begin_draw_bitmap;
457   typedef sf::begin_draw<ID2D1HwndRenderTargetPtr> begin_draw_hwnd;
458   
459 }