4 // Windows Header Files:
6 #include "base_window.h"
11 #pragma comment(lib,"d2d1.lib")
12 #pragma comment(lib,"winmm.lib")
13 #pragma comment(lib,"dwrite.lib")
14 #pragma comment(lib,"dwmapi.lib")
18 _COM_SMARTPTR_TYPEDEF(ID2D1Factory,__uuidof(ID2D1Factory));
19 _COM_SMARTPTR_TYPEDEF(IWICImagingFactory, __uuidof(IWICImagingFactory));
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(ID2D1HwndRenderTarget , __uuidof(ID2D1HwndRenderTarget));
28 _COM_SMARTPTR_TYPEDEF(ID2D1BitmapRenderTarget , __uuidof(ID2D1BitmapRenderTarget));
29 _COM_SMARTPTR_TYPEDEF(ID2D1GdiInteropRenderTarget , __uuidof(ID2D1GdiInteropRenderTarget));
30 _COM_SMARTPTR_TYPEDEF(ID2D1DCRenderTarget , __uuidof(ID2D1DCRenderTarget));
31 _COM_SMARTPTR_TYPEDEF(IDWriteTextFormat, __uuidof(IDWriteTextFormat));
32 _COM_SMARTPTR_TYPEDEF(IDWriteTextLayout, __uuidof(IDWriteTextLayout));
33 _COM_SMARTPTR_TYPEDEF(ID2D1PathGeometry , __uuidof(ID2D1PathGeometry));
34 _COM_SMARTPTR_TYPEDEF(ID2D1LinearGradientBrush , __uuidof(ID2D1LinearGradientBrush));
35 _COM_SMARTPTR_TYPEDEF(ID2D1GradientStopCollection , __uuidof(ID2D1GradientStopCollection));
36 _COM_SMARTPTR_TYPEDEF(ID2D1SolidColorBrush , __uuidof(ID2D1SolidColorBrush));
37 _COM_SMARTPTR_TYPEDEF(ID2D1BitmapBrush , __uuidof(ID2D1BitmapBrush));
38 _COM_SMARTPTR_TYPEDEF(ID2D1Bitmap , __uuidof(ID2D1Bitmap));
39 _COM_SMARTPTR_TYPEDEF(IWICBitmapDecoder,__uuidof(IWICBitmapDecoder));
40 _COM_SMARTPTR_TYPEDEF(IWICBitmapFrameDecode,__uuidof(IWICBitmapFrameDecode));
41 _COM_SMARTPTR_TYPEDEF(IWICStream,__uuidof(IWICStream));
42 _COM_SMARTPTR_TYPEDEF(IWICFormatConverter,__uuidof(IWICFormatConverter));
43 _COM_SMARTPTR_TYPEDEF(IWICBitmapScaler,__uuidof(IWICBitmapScaler));
44 _COM_SMARTPTR_TYPEDEF(ITaskbarList3,__uuidof(ITaskbarList3));
46 template <class COM_SMART_PTR > inline void safe_release(COM_SMART_PTR& ptr)
56 template <class Exc = win32_error_exception> struct throw_if_err
58 void operator()(HRESULT hr) {if(hr != S_OK){throw Exc(hr);}}
61 /* inline template <class Exc = win32_error_exception> void throw_if_err<>()(HRESULT hr)
63 if(hr != S_OK){throw Exc(hr);}
67 ID2D1BitmapPtr load_bitmap_from_file(
68 ID2D1HwndRenderTargetPtr render_target,
69 IWICImagingFactoryPtr wic_factory,
71 uint32_t destination_width = 0,
72 uint32_t destination_height = 0
75 /** WNDCLASSEXラッパクラス */
76 struct window_class_ex
79 const wchar_t* menu_name ,
80 const std::wstring& class_name ,
81 HINSTANCE hInstance = NULL,
82 WNDPROC lpfnWndProc = ::DefWindowProcW,
83 uint32_t style = CS_HREDRAW | CS_VREDRAW,
84 boost::int32_t cbClsExtra = 0,
85 HICON hIcon = ::LoadIcon(NULL,IDI_APPLICATION),
86 HCURSOR hCursor = ::LoadCursor(NULL, IDC_ARROW),
87 HBRUSH hbrBackground = ::CreateSolidBrush(0xff000000),
89 ) : is_register_(false)
92 if(::GetClassInfoExW(hInstance,class_name.c_str(),&wndclass_) == 0)
94 if(::GetLastError() == ERROR_CLASS_DOES_NOT_EXIST)
96 ::ZeroMemory(&wndclass_,sizeof(wndclass_));
97 wndclass_.lpszMenuName = (LPCWSTR)menu_name;
98 wndclass_.lpszClassName = class_name.c_str();
99 wndclass_.cbSize = sizeof(::WNDCLASSEXW);
100 wndclass_.cbWndExtra = sizeof(LONG_PTR);
101 wndclass_.hInstance = hInstance;
102 wndclass_.lpfnWndProc = lpfnWndProc;
103 wndclass_.style = style;
104 wndclass_.cbClsExtra = cbClsExtra;
105 wndclass_.hIcon = hIcon;
106 wndclass_.hCursor = hCursor;
107 wndclass_.hbrBackground = hbrBackground;
108 wndclass_.hIconSm = hIconSm;
109 atom_ = ::RegisterClassExW(&wndclass_) ;
110 BOOST_ASSERT(atom_ != 0);
113 throw win32_error_exception();
116 is_register_ = false;
123 ::UnregisterClassW(wndclass_.lpszClassName,wndclass_.hInstance);
130 ::WNDCLASSEXW wndclass_;
134 get_dc(HWND hwnd) : hwnd_(hwnd),hdc_(GetDC(hwnd)) {}
135 HDC get(){return hdc_;}
136 ~get_dc(){::ReleaseDC(hwnd_,hdc_);}
142 struct compatible_dc {
143 compatible_dc(HDC hdc) : hdc_(::CreateCompatibleDC(hdc)){};
144 ~compatible_dc(){::DeleteDC(hdc_);};
145 HDC get() { return hdc_;};
151 ref_dc(HDC& hdc) : hdc_(hdc) {};
153 HDC get() { return hdc_;};
159 d2_dc(ID2D1GdiInteropRenderTargetPtr& ptr,D2D1_DC_INITIALIZE_MODE mode) :hdc_(0),ptr_(ptr)
161 hr_ = ptr->GetDC(mode,&hdc_);
163 ~d2_dc(){ptr_->ReleaseDC(NULL);};
164 HDC get() { return hdc_;};
168 ID2D1GdiInteropRenderTargetPtr& ptr_;
171 template <typename Holder>
172 struct device_context
174 explicit device_context(Holder* holder) : holder_(holder){};
176 operator HDC(){return holder_->get();}
178 std::unique_ptr<Holder> holder_;
181 //struct handle_holder : boost::noncopyable
183 // explicit handle_holder(HANDLE handle) : handle_(handle) {};
184 // ~handle_holder(){if(handle_) ::CloseHandle(handle_);}
185 // operator HANDLE(){return handle_;}
192 struct handle_deleter {
193 typedef HANDLE pointer;
194 void operator ()(HANDLE handle) {
195 if (handle != INVALID_HANDLE_VALUE) {
201 struct HBITMAP_deleter {
202 typedef HBITMAP pointer;
203 void operator ()(HBITMAP handle) {
205 ::DeleteObject(handle);
210 //template <typename Handle,typename Handle_Deleter>
211 //struct handle_holder {
212 // typedef boost::unique_ptr<Handle,Handle_Deleter> holder_type;
213 // handle_holder(Handle handle) : holder_(handle) {}
214 // operator Handle(){return holder_->get();}
216 // holder_type holder_;
219 typedef std::unique_ptr<HANDLE,handle_deleter> handle_holder;
220 typedef std::unique_ptr<HBITMAP,HBITMAP_deleter> bitmap_holder;
222 typedef device_context<d2_dc> d2_dc_type;
226 paint_struct(HWND hwnd) : hwnd_(hwnd)
228 ::BeginPaint(hwnd,&paintstruct_);
230 ~paint_struct() {::EndPaint(hwnd_,&paintstruct_);}
231 PAINTSTRUCT* operator->(){return &paintstruct_;}
234 PAINTSTRUCT paintstruct_;
237 // GDI オブジェクト管理テンプレート
238 template <class GdiObject>
239 struct gdi_object: boost::noncopyable
241 explicit gdi_object(GdiObject obj) : gdiobj_(obj) {}
242 ~gdi_object(){::DeleteObject(gdiobj_);}
243 operator GdiObject(){return gdiobj_;}
251 select_object(HDC dc,HGDIOBJ o) : dc_(dc),o_(::SelectObject(dc,o)) {}
252 ~select_object(){::SelectObject(dc_,o_);}
258 // Direct2D BeginDrawヘルパ関数
259 template <typename T >
262 typedef std::function<void(HRESULT hr)> err_handler_type;
264 begin_draw(T& render_target,err_handler_type& handler)
265 : render_target_(render_target) ,
266 is_end_(false),handler_(handler)
267 {render_target->BeginDraw();}
271 hr = render_target_->EndDraw();
279 err_handler_type handler_;
284 mouse() : x_(0.0f),y_(0.0f),left_button_(false),middle_button_(false),right_button_(false){}
287 bool left_button_,middle_button_,right_button_;
292 struct base_win32_window : public base_window
294 typedef boost::signals2::signal<LRESULT (HWND,uint32_t,WPARAM, LPARAM) > on_message_type;
295 on_message_type on_message;
297 operator HWND() const {return hwnd_;};
299 virtual void * raw_handle() const {return hwnd_;};
300 // virtual void show(uint32_t show_flag);
302 virtual void show() {
303 ::ShowWindow(hwnd_,SW_SHOW);
304 ::GetWindowPlacement(hwnd_,&wp_);
308 virtual bool is_show() {
309 return ( wp_.showCmd == SW_SHOWMAXIMIZED
310 || wp_.showCmd == SW_SHOWMINIMIZED
311 || wp_.showCmd == SW_SHOWNORMAL );
317 ::ShowWindow(hwnd_,SW_HIDE);
318 ::GetWindowPlacement(hwnd_,&wp_);
321 virtual void text(std::wstring& text)
323 ::SetWindowTextW(*this,text.c_str());
326 virtual void update();
331 const std::wstring& title,
332 const std::wstring& name,bool fit_to_display,
333 float width,float height);
335 ~base_win32_window();
337 void register_class (
338 const wchar_t* menu_name,
340 boost::int32_t cbClsExtra = 0,
341 HICON hIcon = ::LoadIcon(NULL,IDI_APPLICATION),
342 HCURSOR hCursor = ::LoadCursor(NULL, IDC_ARROW),
343 HBRUSH hbrBackground = ::CreateSolidBrush(0xff000000),
348 void register_class();
349 void create_window();
352 void set_long(int index,long data)
355 if(::SetWindowLongW(hwnd_,index,data) == 0)
358 if( (err = GetLastError()) != 0){
360 throw sf::win32_error_exception();
365 bool invalidate_rect(bool erase = false,const RECT * rect_ptr = 0)
367 return ::InvalidateRect(*this,rect_ptr,erase) == TRUE;
371 virtual LRESULT window_proc(HWND hwnd,uint32_t message, WPARAM wParam, LPARAM lParam);
373 static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
375 base_win32_window* ptr = reinterpret_cast<base_win32_window*>(hwnd);
377 return ptr->window_proc(hwnd,message,wParam,lParam);
380 // thisとhwndをつなぐthunkクラス
381 struct hwnd_this_thunk : public Xbyak::CodeGenerator {
382 hwnd_this_thunk(base_win32_window* impl,WNDPROC proc)
384 // rcxにhwndが格納されているので、それをimpl->hwndに保存
385 mov(qword[&(impl->hwnd_)],rcx);
386 // 代わりにthisのアドレスをrcxに格納
387 mov(rcx,(LONG_PTR)impl);
388 // r10にproc(Window プロシージャ)へのアドレスを格納
389 mov(r10,(LONG_PTR)proc);
390 // Window プロシージャへへジャンプ
396 hwnd_this_thunk thunk_;
399 float width_,height_;
400 bool fit_to_display_;
401 std::shared_ptr<sf::window_class_ex> wnd_class_;
407 struct av_mm_thread_characteristics
409 av_mm_thread_characteristics(std::wstring& str) : task_name_(str)
411 handle_ = ::AvSetMmThreadCharacteristicsW(str.c_str(),(LPDWORD)&task_index_);
414 bool set_priority(AVRT_PRIORITY p){return (::AvSetMmThreadPriority(handle_,p) == TRUE);}
416 ~av_mm_thread_characteristics()
418 ::AvRevertMmThreadCharacteristics(handle_);
422 std::wstring task_name_;
423 uint32_t task_index_;
427 float width_,height_;
428 bool fit_to_display_;
429 WINDOWPLACEMENT wp_;//
438 typedef sf::begin_draw<ID2D1BitmapRenderTargetPtr> begin_draw_bitmap;
439 typedef sf::begin_draw<ID2D1HwndRenderTargetPtr> begin_draw_hwnd;