X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ef359b4350a0b232dfda34b03040eab41eee2e97..e93523680ba3c83cdae75b511214c82f28a2d853:/include/wx/msw/private.h diff --git a/include/wx/msw/private.h b/include/wx/msw/private.h index bd6eec5dc8..262fc9ff80 100644 --- a/include/wx/msw/private.h +++ b/include/wx/msw/private.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: private.h +// Name: wx/msw/private.h // Purpose: Private declarations: as this header is only included by // wxWidgets itself, it may contain identifiers which don't start // with "wx". @@ -21,13 +21,11 @@ #include "wx/msw/microwin.h" #endif -// Include fixes for MSLU: -#include "wx/msw/mslu.h" - #include "wx/log.h" -class WXDLLEXPORT wxFont; -class WXDLLEXPORT wxWindow; +class WXDLLIMPEXP_FWD_CORE wxFont; +class WXDLLIMPEXP_FWD_CORE wxWindow; +class WXDLLIMPEXP_FWD_CORE wxWindowBase; // --------------------------------------------------------------------------- // private constants @@ -54,6 +52,12 @@ extern WXDLLEXPORT_DATA(HFONT) wxSTATUS_LINE_FONT; #endif // wxUSE_GUI +// --------------------------------------------------------------------------- +// global data +// --------------------------------------------------------------------------- + +extern WXDLLIMPEXP_DATA_BASE(HINSTANCE) wxhInstance; + // --------------------------------------------------------------------------- // define things missing from some compilers' headers // --------------------------------------------------------------------------- @@ -101,22 +105,6 @@ extern WXDLLEXPORT_DATA(HFONT) wxSTATUS_LINE_FONT; #endif #endif -#if wxUSE_PENWIN - WXDLLEXPORT void wxRegisterPenWin(); - WXDLLEXPORT void wxCleanUpPenWin(); - WXDLLEXPORT void wxEnablePenAppHooks (bool hook); -#endif // wxUSE_PENWIN - -#if wxUSE_ITSY_BITSY - #define IBS_HORZCAPTION 0x4000L - #define IBS_VERTCAPTION 0x8000L - - UINT WINAPI ibGetCaptionSize( HWND hWnd ) ; - UINT WINAPI ibSetCaptionSize( HWND hWnd, UINT nSize ) ; - LRESULT WINAPI ibDefWindowProc( HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam ) ; - VOID WINAPI ibAdjustWindowRect( HWND hWnd, LPRECT lprc ) ; -#endif // wxUSE_ITSY_BITSY - /* * Decide what window classes we're going to use * for this combination of CTl3D/FAFA settings @@ -168,10 +156,62 @@ extern LONG APIENTRY _EXPORT #define wxZeroMemory(obj) memset((void*) & obj, 0, sizeof(obj)) #endif +// This one is a macro so that it can be tested with #ifdef, it will be +// undefined if it cannot be implemented for a given compiler. +// Vc++, bcc, dmc, ow, mingw, codewarrior (and rsxnt) have _get_osfhandle. +// Cygwin has get_osfhandle. Others are currently unknown, e.g. Salford, +// Intel, Visual Age. +#if defined(__WXWINCE__) + #define wxGetOSFHandle(fd) ((HANDLE)fd) + #define wxOpenOSFHandle(h, flags) ((int)wxPtrToUInt(h)) +#elif defined(__CYGWIN__) + #define wxGetOSFHandle(fd) ((HANDLE)get_osfhandle(fd)) +#elif defined(__VISUALC__) \ + || defined(__BORLANDC__) \ + || defined(__DMC__) \ + || defined(__WATCOMC__) \ + || defined(__MINGW32__) \ + || (defined(__MWERKS__) && defined(__MSL__)) + #define wxGetOSFHandle(fd) ((HANDLE)_get_osfhandle(fd)) + #define wxOpenOSFHandle(h, flags) (_open_osfhandle(wxPtrToUInt(h), flags)) + #define wx_fdopen _fdopen +#endif + +// close the handle in the class dtor +class AutoHANDLE +{ +public: + wxEXPLICIT AutoHANDLE(HANDLE handle) : m_handle(handle) { } + + bool IsOk() const { return m_handle != INVALID_HANDLE_VALUE; } + operator HANDLE() const { return m_handle; } + + ~AutoHANDLE() { if ( IsOk() ) ::CloseHandle(m_handle); } + +protected: + HANDLE m_handle; +}; + +// a template to make initializing Windows styructs less painful: it zeroes all +// the struct fields and also sets cbSize member to the correct value (and so +// can be only used with structures which have this member...) +template +struct WinStruct : public T +{ + WinStruct() + { + ::ZeroMemory(this, sizeof(T)); + + // explicit qualification is required here for this to be valid C++ + this->cbSize = sizeof(T); + } +}; + + #if wxUSE_GUI -#include -#include +#include "wx/gdicmn.h" +#include "wx/colour.h" // make conversion from wxColour and COLORREF a bit less painful inline COLORREF wxColourToRGB(const wxColour& c) @@ -220,15 +260,26 @@ struct WXDLLEXPORT wxCOLORMAP extern wxCOLORMAP *wxGetStdColourMap(); // create a wxRect from Windows RECT -inline wxRect wxRectFromRECT(const RECT& r) +inline wxRect wxRectFromRECT(const RECT& rc) { - return wxRect(r.left, r.top, r.right - r.left, r.bottom - r.top); + return wxRect(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); } // copy Windows RECT to our wxRect -inline void wxCopyRECTToRect(const RECT& r, wxRect& rect) +inline void wxCopyRECTToRect(const RECT& rc, wxRect& rect) +{ + rect = wxRectFromRECT(rc); +} + +// and vice versa +inline void wxCopyRectToRECT(const wxRect& rect, RECT& rc) { - rect = wxRectFromRECT(r); + // note that we don't use wxRect::GetRight() as it is one of compared to + // wxRectFromRECT() above + rc.top = rect.y; + rc.left = rect.x; + rc.right = rect.x + rect.width; + rc.bottom = rect.y + rect.height; } // translations between HIMETRIC units (which OLE likes) and pixels (which are @@ -284,9 +335,7 @@ inline RECT wxGetWindowRect(HWND hwnd) RECT rect; if ( !::GetWindowRect(hwnd, &rect) ) - { wxLogLastError(_T("GetWindowRect")); - } return rect; } @@ -296,9 +345,7 @@ inline RECT wxGetClientRect(HWND hwnd) RECT rect; if ( !::GetClientRect(hwnd, &rect) ) - { wxLogLastError(_T("GetClientRect")); - } return rect; } @@ -307,22 +354,6 @@ inline RECT wxGetClientRect(HWND hwnd) // small helper classes // --------------------------------------------------------------------------- -// a template to make initializing Windows styructs less painful: it zeroes all -// the struct fields and also sets cbSize member to the correct value (and so -// can be only used with structures which have this member...) -template -struct WinStruct : public T -{ - WinStruct() - { - ::ZeroMemory(this, sizeof(T)); - - // explicit qualification is required here for this to be valid C++ - this->cbSize = sizeof(T); - } -}; - - // create an instance of this class and use it as the HDC for screen, will // automatically release the DC going out of scope class ScreenHDC @@ -375,59 +406,227 @@ private: // dtor class SelectInHDC { +private: + void DoInit(HGDIOBJ hgdiobj) { m_hgdiobj = ::SelectObject(m_hdc, hgdiobj); } + public: - SelectInHDC(HDC hdc, HGDIOBJ hgdiobj) : m_hdc(hdc) - { m_hgdiobj = ::SelectObject(hdc, hgdiobj); } + SelectInHDC() : m_hdc(NULL) { } + SelectInHDC(HDC hdc, HGDIOBJ hgdiobj) : m_hdc(hdc) { DoInit(hgdiobj); } - ~SelectInHDC() { ::SelectObject(m_hdc, m_hgdiobj); } + void Init(HDC hdc, HGDIOBJ hgdiobj) + { + wxASSERT_MSG( !m_hdc, _T("initializing twice?") ); + + m_hdc = hdc; - // return true if the object was successfully selected - operator bool() const { return m_hgdiobj != 0; } + DoInit(hgdiobj); + } + + ~SelectInHDC() { if ( m_hdc ) ::SelectObject(m_hdc, m_hgdiobj); } + + // return true if the object was successfully selected + operator bool() const { return m_hgdiobj != 0; } private: - HDC m_hdc; - HGDIOBJ m_hgdiobj; + HDC m_hdc; + HGDIOBJ m_hgdiobj; + + DECLARE_NO_COPY_CLASS(SelectInHDC) +}; + +// a class which cleans up any GDI object +class AutoGDIObject +{ +protected: + AutoGDIObject() { m_gdiobj = NULL; } + AutoGDIObject(HGDIOBJ gdiobj) : m_gdiobj(gdiobj) { } + ~AutoGDIObject() { if ( m_gdiobj ) ::DeleteObject(m_gdiobj); } + + void InitGdiobj(HGDIOBJ gdiobj) + { + wxASSERT_MSG( !m_gdiobj, _T("initializing twice?") ); + + m_gdiobj = gdiobj; + } + + HGDIOBJ GetObject() const { return m_gdiobj; } + +private: + HGDIOBJ m_gdiobj; +}; + +// TODO: all this asks for using a AutoHandler template... + +// a class for temporary brushes +class AutoHBRUSH : private AutoGDIObject +{ +public: + AutoHBRUSH(COLORREF col) + : AutoGDIObject(::CreateSolidBrush(col)) { } + + operator HBRUSH() const { return (HBRUSH)GetObject(); } +}; + +// a class for temporary fonts +class AutoHFONT : private AutoGDIObject +{ +private: +public: + AutoHFONT() + : AutoGDIObject() { } + + AutoHFONT(const LOGFONT& lf) + : AutoGDIObject(::CreateFontIndirect(&lf)) { } + + void Init(const LOGFONT& lf) { InitGdiobj(::CreateFontIndirect(&lf)); } + + operator HFONT() const { return (HFONT)GetObject(); } +}; + +// a class for temporary pens +class AutoHPEN : private AutoGDIObject +{ +public: + AutoHPEN(COLORREF col) + : AutoGDIObject(::CreatePen(PS_SOLID, 0, col)) { } + + operator HPEN() const { return (HPEN)GetObject(); } +}; + +// classes for temporary bitmaps +class AutoHBITMAP : private AutoGDIObject +{ +public: + AutoHBITMAP(HBITMAP hbmp) : AutoGDIObject(hbmp) { } - DECLARE_NO_COPY_CLASS(SelectInHDC) + operator HBITMAP() const { return (HBITMAP)GetObject(); } }; -// a class for temporary bitmaps -class CompatibleBitmap +class CompatibleBitmap : public AutoHBITMAP { public: CompatibleBitmap(HDC hdc, int w, int h) + : AutoHBITMAP(::CreateCompatibleBitmap(hdc, w, h)) + { + } +}; + +class MonoBitmap : public AutoHBITMAP +{ +public: + MonoBitmap(int w, int h) + : AutoHBITMAP(::CreateBitmap(w, h, 1, 1, 0)) + { + } +}; + +// class automatically destroys the region object +class AutoHRGN : private AutoGDIObject +{ +public: + AutoHRGN(HRGN hrgn) : AutoGDIObject(hrgn) { } + + operator HRGN() const { return (HRGN)GetObject(); } +}; + +// class sets the specified clipping region during its life time +class HDCClipper +{ +public: + HDCClipper(HDC hdc, HRGN hrgn) + : m_hdc(hdc) + { + if ( !::SelectClipRgn(hdc, hrgn) ) + wxLogLastError(_T("SelectClipRgn")); + } + + ~HDCClipper() + { + ::SelectClipRgn(m_hdc, NULL); + } + +private: + HDC m_hdc; + + DECLARE_NO_COPY_CLASS(HDCClipper) +}; + +// set the given map mode for the life time of this object +// +// NB: SetMapMode() is not supported by CE so we also define a helper macro +// to avoid using it there +#ifdef __WXWINCE__ + #define wxCHANGE_HDC_MAP_MODE(hdc, mm) +#else // !__WXWINCE__ + class HDCMapModeChanger { - m_hbmp = ::CreateCompatibleBitmap(hdc, w, h); + public: + HDCMapModeChanger(HDC hdc, int mm) + : m_hdc(hdc) + { + m_modeOld = ::SetMapMode(hdc, mm); + if ( !m_modeOld ) + wxLogLastError(_T("SelectClipRgn")); + } + + ~HDCMapModeChanger() + { + if ( m_modeOld ) + ::SetMapMode(m_hdc, m_modeOld); + } + + private: + HDC m_hdc; + int m_modeOld; + + DECLARE_NO_COPY_CLASS(HDCMapModeChanger) + }; + + #define wxCHANGE_HDC_MAP_MODE(hdc, mm) \ + HDCMapModeChanger wxMAKE_UNIQUE_NAME(wxHDCMapModeChanger)(hdc, mm) +#endif // __WXWINCE__/!__WXWINCE__ + +// smart buffeer using GlobalAlloc/GlobalFree() +class GlobalPtr +{ +public: + // allocates a block of given size + GlobalPtr(size_t size, unsigned flags = GMEM_MOVEABLE) + { + m_hGlobal = ::GlobalAlloc(flags, size); + if ( !m_hGlobal ) + wxLogLastError(_T("GlobalAlloc")); } - ~CompatibleBitmap() + ~GlobalPtr() { - if ( m_hbmp ) - ::DeleteObject(m_hbmp); + if ( m_hGlobal && ::GlobalFree(m_hGlobal) ) + wxLogLastError(_T("GlobalFree")); } - operator HBITMAP() const { return m_hbmp; } + // implicit conversion + operator HGLOBAL() const { return m_hGlobal; } private: - HBITMAP m_hbmp; + HGLOBAL m_hGlobal; + + DECLARE_NO_COPY_CLASS(GlobalPtr) }; // when working with global pointers (which is unfortunately still necessary // sometimes, e.g. for clipboard) it is important to unlock them exactly as // many times as we lock them which just asks for using a "smart lock" class -class GlobalPtr +class GlobalPtrLock { public: - GlobalPtr(HGLOBAL hGlobal) : m_hGlobal(hGlobal) + GlobalPtrLock(HGLOBAL hGlobal) : m_hGlobal(hGlobal) { m_ptr = GlobalLock(hGlobal); if ( !m_ptr ) - { wxLogLastError(_T("GlobalLock")); - } } - ~GlobalPtr() + ~GlobalPtrLock() { if ( !GlobalUnlock(m_hGlobal) ) { @@ -448,7 +647,65 @@ private: HGLOBAL m_hGlobal; void *m_ptr; - DECLARE_NO_COPY_CLASS(GlobalPtr) + DECLARE_NO_COPY_CLASS(GlobalPtrLock) +}; + +// register the class when it is first needed and unregister it in dtor +class ClassRegistrar +{ +public: + // ctor doesn't register the class, call Initialize() for this + ClassRegistrar() { m_registered = -1; } + + // return true if the class is already registered + bool IsInitialized() const { return m_registered != -1; } + + // return true if the class had been already registered + bool IsRegistered() const { return m_registered == 1; } + + // try to register the class if not done yet, return true on success + bool Register(const WNDCLASS& wc) + { + // we should only be called if we hadn't been initialized yet + wxASSERT_MSG( m_registered == -1, + _T("calling ClassRegistrar::Register() twice?") ); + + m_registered = ::RegisterClass(&wc) ? 1 : 0; + if ( !IsRegistered() ) + { + wxLogLastError(_T("RegisterClassEx()")); + } + else + { + m_clsname = wc.lpszClassName; + } + + return m_registered == 1; + } + + // get the name of the registered class (returns empty string if not + // registered) + const wxString& GetName() const { return m_clsname; } + + // unregister the class if it had been registered + ~ClassRegistrar() + { + if ( IsRegistered() ) + { + if ( !::UnregisterClass(m_clsname.wx_str(), wxhInstance) ) + { + wxLogLastError(_T("UnregisterClass")); + } + } + } + +private: + // initial value is -1 which means that we hadn't tried registering the + // class yet, it becomes true or false (1 or 0) when Initialize() is called + int m_registered; + + // the name of the class, only non empty if it had been registered + wxString m_clsname; }; // --------------------------------------------------------------------------- @@ -475,8 +732,8 @@ private: #define GetHaccel() ((HACCEL)GetHACCEL()) #define GetHaccelOf(table) ((HACCEL)((table).GetHACCEL())) -#define GetHbrush() ((HPEN)GetResourceHandle()) -#define GetHbrushOf(brush) ((HPEN)(brush).GetResourceHandle()) +#define GetHbrush() ((HBRUSH)GetResourceHandle()) +#define GetHbrushOf(brush) ((HBRUSH)(brush).GetResourceHandle()) #define GetHmenu() ((HMENU)GetHMenu()) #define GetHmenuOf(menu) ((HMENU)menu->GetHMenu()) @@ -487,6 +744,9 @@ private: #define GetHfont() ((HFONT)GetHFONT()) #define GetHfontOf(font) ((HFONT)(font).GetHFONT()) +#define GetHimagelist() ((HIMAGELIST)GetHIMAGELIST()) +#define GetHimagelistOf(imgl) ((HIMAGELIST)imgl->GetHIMAGELIST()) + #define GetHpalette() ((HPALETTE)GetHPALETTE()) #define GetHpaletteOf(pal) ((HPALETTE)(pal).GetHPALETTE()) @@ -498,12 +758,6 @@ private: #endif // wxUSE_GUI -// --------------------------------------------------------------------------- -// global data -// --------------------------------------------------------------------------- - -extern WXDLLIMPEXP_DATA_BASE(HINSTANCE) wxhInstance; - // --------------------------------------------------------------------------- // global functions // --------------------------------------------------------------------------- @@ -538,6 +792,44 @@ inline wxString wxGetFullModuleName() return wxGetFullModuleName((HMODULE)wxGetInstance()); } +// return the run-time version of the OS in a format similar to +// WINVER/_WIN32_WINNT compile-time macros: +// +// 0x0300 Windows NT 3.51 +// 0x0400 Windows 95, NT4 +// 0x0410 Windows 98 +// 0x0500 Windows ME, 2000 +// 0x0501 Windows XP +// 0x0502 Windows 2003 +// 0x0600 Longhorn +// +// for the other Windows versions 0 is currently returned +enum wxWinVersion +{ + wxWinVersion_Unknown = 0, + + wxWinVersion_3 = 0x0300, + wxWinVersion_NT3 = wxWinVersion_3, + + wxWinVersion_4 = 0x0400, + wxWinVersion_95 = wxWinVersion_4, + wxWinVersion_NT4 = wxWinVersion_4, + wxWinVersion_98 = 0x0410, + + wxWinVersion_5 = 0x0500, + wxWinVersion_ME = wxWinVersion_5, + wxWinVersion_NT5 = wxWinVersion_5, + wxWinVersion_2000 = wxWinVersion_5, + wxWinVersion_XP = 0x0501, + wxWinVersion_2003 = 0x0502, + + wxWinVersion_6 = 0x0600, + wxWinVersion_Vista = wxWinVersion_6, + wxWinVersion_NT6 = wxWinVersion_6 +}; + +WXDLLIMPEXP_BASE wxWinVersion wxGetWinVersion(); + #if wxUSE_GUI // cursor stuff @@ -597,6 +889,14 @@ extern WXDLLEXPORT wxSize wxGetHiconSize(HICON hicon); // Lines are drawn differently for WinCE and regular WIN32 WXDLLEXPORT void wxDrawLine(HDC hdc, int x1, int y1, int x2, int y2); +// fill the client rect of the given window on the provided dc using this brush +inline void wxFillRect(HWND hwnd, HDC hdc, HBRUSH hbr) +{ + RECT rc; + ::GetClientRect(hwnd, &rc); + ::FillRect(hdc, &rc, hbr); +} + // ---------------------------------------------------------------------------- // 32/64 bit helpers // ---------------------------------------------------------------------------- @@ -625,41 +925,30 @@ inline void *wxSetWindowUserData(HWND hwnd, void *data) #else // __WIN32__ -#ifdef __VISUALC__ - // strangely enough, VC++ 7.1 gives warnings about 32 -> 64 bit conversions - // in the functions below, even in spite of the explicit casts - #pragma warning(disable:4311) - #pragma warning(disable:4312) -#endif - -inline void *wxGetWindowProc(HWND hwnd) +// note that the casts to LONG_PTR here are required even on 32-bit machines +// for the 64-bit warning mode of later versions of MSVC (C4311/4312) +inline WNDPROC wxGetWindowProc(HWND hwnd) { - return (void *)::GetWindowLong(hwnd, GWL_WNDPROC); + return (WNDPROC)(LONG_PTR)::GetWindowLong(hwnd, GWL_WNDPROC); } inline void *wxGetWindowUserData(HWND hwnd) { - return (void *)::GetWindowLong(hwnd, GWL_USERDATA); + return (void *)(LONG_PTR)::GetWindowLong(hwnd, GWL_USERDATA); } inline WNDPROC wxSetWindowProc(HWND hwnd, WNDPROC func) { - return (WNDPROC)::SetWindowLong(hwnd, GWL_WNDPROC, (LONG)func); + return (WNDPROC)(LONG_PTR)::SetWindowLong(hwnd, GWL_WNDPROC, (LONG_PTR)func); } inline void *wxSetWindowUserData(HWND hwnd, void *data) { - return (void *)::SetWindowLong(hwnd, GWL_USERDATA, (LONG)data); + return (void *)(LONG_PTR)::SetWindowLong(hwnd, GWL_USERDATA, (LONG_PTR)data); } -#ifdef __VISUALC__ - #pragma warning(default:4311) - #pragma warning(default:4312) -#endif - #endif // __WIN64__/__WIN32__ #endif // wxUSE_GUI -#endif - // _WX_PRIVATE_H_ +#endif // _WX_PRIVATE_H_