4 // Windows Header Files:
6 #include "base_window.h"
10 #pragma comment(lib,"d2d1.lib")
11 #pragma comment(lib,"winmm.lib")
12 #pragma comment(lib,"dwrite.lib")
13 #pragma comment(lib,"dwmapi.lib")
17 _COM_SMARTPTR_TYPEDEF(ID2D1Factory,__uuidof(ID2D1Factory));
18 _COM_SMARTPTR_TYPEDEF(IWICImagingFactory, __uuidof(IWICImagingFactory));
19 _COM_SMARTPTR_TYPEDEF(IDWriteFactory , __uuidof(IDWriteFactory));
20 _COM_SMARTPTR_TYPEDEF(IDWriteGdiInterop , __uuidof(IDWriteGdiInterop));
21 _COM_SMARTPTR_TYPEDEF(IDWriteFontFace , __uuidof(IDWriteFontFace));
22 _COM_SMARTPTR_TYPEDEF(IDWriteFont , __uuidof(IDWriteFont));
23 _COM_SMARTPTR_TYPEDEF(IDWriteFontFamily , __uuidof(IDWriteFontFamily));
24 _COM_SMARTPTR_TYPEDEF(IDWriteFontCollection , __uuidof(IDWriteFontCollection));
25 _COM_SMARTPTR_TYPEDEF(IDWriteLocalizedStrings , __uuidof(IDWriteLocalizedStrings));
26 _COM_SMARTPTR_TYPEDEF(ID2D1HwndRenderTarget , __uuidof(ID2D1HwndRenderTarget));
27 _COM_SMARTPTR_TYPEDEF(ID2D1BitmapRenderTarget , __uuidof(ID2D1BitmapRenderTarget));
28 _COM_SMARTPTR_TYPEDEF(ID2D1GdiInteropRenderTarget , __uuidof(ID2D1GdiInteropRenderTarget));
29 _COM_SMARTPTR_TYPEDEF(IDWriteTextFormat, __uuidof(IDWriteTextFormat));
30 _COM_SMARTPTR_TYPEDEF(IDWriteTextLayout, __uuidof(IDWriteTextLayout));
31 _COM_SMARTPTR_TYPEDEF(ID2D1PathGeometry , __uuidof(ID2D1PathGeometry));
32 _COM_SMARTPTR_TYPEDEF(ID2D1LinearGradientBrush , __uuidof(ID2D1LinearGradientBrush));
33 _COM_SMARTPTR_TYPEDEF(ID2D1GradientStopCollection , __uuidof(ID2D1GradientStopCollection));
34 _COM_SMARTPTR_TYPEDEF(ID2D1SolidColorBrush , __uuidof(ID2D1SolidColorBrush));
35 _COM_SMARTPTR_TYPEDEF(ID2D1BitmapBrush , __uuidof(ID2D1BitmapBrush));
36 _COM_SMARTPTR_TYPEDEF(ID2D1Bitmap , __uuidof(ID2D1Bitmap));
37 _COM_SMARTPTR_TYPEDEF(IWICBitmapDecoder,__uuidof(IWICBitmapDecoder));
38 _COM_SMARTPTR_TYPEDEF(IWICBitmapFrameDecode,__uuidof(IWICBitmapFrameDecode));
39 _COM_SMARTPTR_TYPEDEF(IWICStream,__uuidof(IWICStream));
40 _COM_SMARTPTR_TYPEDEF(IWICFormatConverter,__uuidof(IWICFormatConverter));
41 _COM_SMARTPTR_TYPEDEF(IWICBitmapScaler,__uuidof(IWICBitmapScaler));
42 _COM_SMARTPTR_TYPEDEF(ITaskbarList3,__uuidof(ITaskbarList3));
44 template <class COM_SMART_PTR > inline void safe_release(COM_SMART_PTR& ptr)
54 template <class Exc> struct throw_if_err
56 void operator()(HRESULT hr) {if(hr != S_OK){throw Exc(hr);}}
60 ID2D1BitmapPtr load_bitmap_from_file(
61 ID2D1HwndRenderTargetPtr render_target,
62 IWICImagingFactoryPtr wic_factory,
64 boost::uint32_t destination_width = 0,
65 boost::uint32_t destination_height = 0
68 /** WNDCLASSEXラッパクラス */
69 struct window_class_ex
72 const wchar_t* menu_name ,
73 const std::wstring& class_name ,
74 HINSTANCE hInstance = NULL,
75 WNDPROC lpfnWndProc = ::DefWindowProcW,
76 boost::uint32_t style = CS_HREDRAW | CS_VREDRAW,
77 boost::int32_t cbClsExtra = 0,
78 HICON hIcon = ::LoadIcon(NULL,IDI_APPLICATION),
79 HCURSOR hCursor = ::LoadCursor(NULL, IDC_ARROW),
80 HBRUSH hbrBackground = ::CreateSolidBrush(0xff000000),
82 ) : is_register_(false)
85 if(::GetClassInfoExW(hInstance,class_name.c_str(),&wndclass_) == 0)
87 if(::GetLastError() == ERROR_CLASS_DOES_NOT_EXIST)
89 ::ZeroMemory(&wndclass_,sizeof(wndclass_));
90 wndclass_.lpszMenuName = (LPCWSTR)menu_name;
91 wndclass_.lpszClassName = class_name.c_str();
92 wndclass_.cbSize = sizeof(::WNDCLASSEXW);
93 wndclass_.cbWndExtra = sizeof(LONG_PTR);
94 wndclass_.hInstance = hInstance;
95 wndclass_.lpfnWndProc = lpfnWndProc;
96 wndclass_.style = style;
97 wndclass_.cbClsExtra = cbClsExtra;
98 wndclass_.hIcon = hIcon;
99 wndclass_.hCursor = hCursor;
100 wndclass_.hbrBackground = hbrBackground;
101 wndclass_.hIconSm = hIconSm;
102 atom_ = ::RegisterClassExW(&wndclass_) ;
103 BOOST_ASSERT(atom_ != 0);
106 throw win32_error_exception();
109 is_register_ = false;
116 ::UnregisterClassW(wndclass_.lpszClassName,wndclass_.hInstance);
123 ::WNDCLASSEXW wndclass_;
129 get_dc(HWND hwnd) : hwnd_(hwnd),hdc_(GetDC(hwnd)) {}
130 HDC get(){return hdc_;}
131 ~get_dc(){::ReleaseDC(hwnd_,hdc_);}
137 struct compatible_dc {
138 compatible_dc(HDC hdc) : hdc_(::CreateCompatibleDC(hdc)){};
139 ~compatible_dc(){::DeleteDC(hdc_);};
140 HDC get() { return hdc_;};
146 ref_dc(HDC& hdc) : hdc_(hdc) {};
148 HDC get() { return hdc_;};
154 d2_dc(ID2D1GdiInteropRenderTargetPtr& ptr,D2D1_DC_INITIALIZE_MODE mode) :hdc_(0),ptr_(ptr)
156 hr_ = ptr->GetDC(mode,&hdc_);
158 ~d2_dc(){ptr_->ReleaseDC(NULL);};
159 HDC get() { return hdc_;};
163 ID2D1GdiInteropRenderTargetPtr& ptr_;
166 template <typename Holder>
167 struct device_context
169 explicit device_context(Holder* holder) : holder_(holder){};
171 operator HDC(){return holder_->get();}
173 boost::scoped_ptr<Holder> holder_;
176 struct handle_holder : boost::noncopyable
178 explicit handle_holder(HANDLE handle) : handle_(handle) {};
179 ~handle_holder(){if(handle_) ::CloseHandle(handle_);}
180 operator HANDLE(){return handle_;}
185 typedef device_context<d2_dc> d2_dc_type;
189 paint_struct(HWND hwnd) : hwnd_(hwnd)
191 ::BeginPaint(hwnd,&paintstruct_);
193 ~paint_struct() {::EndPaint(hwnd_,&paintstruct_);}
194 PAINTSTRUCT* operator->(){return &paintstruct_;}
197 PAINTSTRUCT paintstruct_;
200 // GDI オブジェクト管理テンプレート
201 template <class GdiObject>
202 struct gdi_object: boost::noncopyable
204 explicit gdi_object(GdiObject obj) : gdiobj_(obj) {}
205 ~gdi_object(){::DeleteObject(gdiobj_);}
206 operator GdiObject(){return gdiobj_;}
212 // Direct2D BeginDrawヘルパ関数
213 template <typename T >
216 typedef std::function<void(HRESULT hr)> err_handler_type;
218 begin_draw(T& render_target,err_handler_type& handler)
219 : render_target_(render_target) ,
220 is_end_(false),handler_(handler)
221 {render_target->BeginDraw();}
225 hr = render_target_->EndDraw();
233 err_handler_type handler_;
238 mouse() : x_(0.0f),y_(0.0f),left_button_(false),middle_button_(false),right_button_(false){}
241 bool left_button_,middle_button_,right_button_;
246 struct base_win32_window : public base_window
248 typedef boost::signals2::signal<LRESULT (HWND,boost::uint32_t,WPARAM, LPARAM) > on_message_type;
249 on_message_type on_message;
251 operator HWND() {return hwnd_;};
253 virtual void * raw_handle(){return hwnd_;};
254 virtual void show(boost::uint32_t show_flag);
255 virtual void text(std::wstring& text)
257 ::SetWindowTextW(*this,text.c_str());
260 virtual void update();
265 const std::wstring& title,
266 const std::wstring& name,bool fit_to_display,
267 float width,float height);
269 ~base_win32_window();
271 void register_class (
273 boost::uint32_t style,
274 boost::int32_t cbClsExtra = 0,
275 HICON hIcon = ::LoadIcon(NULL,IDI_APPLICATION),
276 HCURSOR hCursor = ::LoadCursor(NULL, IDC_ARROW),
277 HBRUSH hbrBackground = ::CreateSolidBrush(0xff000000),
282 void register_class();
283 void create_window();
286 void set_long(int index,long data)
289 if(::SetWindowLongW(hwnd_,index,data) == 0)
292 if( (err = GetLastError()) != 0){
294 throw sf::win32_error_exception();
299 bool invalidate_rect(bool erase = false,const RECT * rect_ptr = 0)
301 return ::InvalidateRect(*this,rect_ptr,erase) == TRUE;
305 virtual LRESULT window_proc(HWND hwnd,boost::uint32_t message, WPARAM wParam, LPARAM lParam);
307 static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
309 base_win32_window* ptr = reinterpret_cast<base_win32_window*>(hwnd);
311 return ptr->window_proc(hwnd,message,wParam,lParam);
314 // thisとhwndをつなぐthunkクラス
315 struct hwnd_this_thunk : public Xbyak::CodeGenerator {
316 hwnd_this_thunk(base_win32_window* impl,WNDPROC proc)
318 // rcxにhwndが格納されているので、それをimpl->hwndに保存
319 mov(qword[&(impl->hwnd_)],rcx);
320 // 代わりにthisのアドレスをrcxに格納
321 mov(rcx,(LONG_PTR)impl);
322 // r10にproc(Window プロシージャ)へのアドレスを格納
323 mov(r10,(LONG_PTR)proc);
324 // Window プロシージャへへジャンプ
330 hwnd_this_thunk thunk_;
333 float width_,height_;
334 bool fit_to_display_;
335 boost::shared_ptr<sf::window_class_ex> wnd_class_;
339 struct av_mm_thread_characteristics
341 av_mm_thread_characteristics(std::wstring& str) : task_name_(str)
343 handle_ = ::AvSetMmThreadCharacteristicsW(str.c_str(),(LPDWORD)&task_index_);
346 bool set_priority(AVRT_PRIORITY p){return (::AvSetMmThreadPriority(handle_,p) == TRUE);}
348 ~av_mm_thread_characteristics()
350 ::AvRevertMmThreadCharacteristics(handle_);
354 std::wstring task_name_;
355 boost::uint32_t task_index_;
359 float width_,height_;
360 bool fit_to_display_;
370 typedef sf::begin_draw<ID2D1BitmapRenderTargetPtr> begin_draw_bitmap;
371 typedef sf::begin_draw<ID2D1HwndRenderTargetPtr> begin_draw_hwnd;