Merge branch 'prewinxp_cleanup' of https://github.com/TcT2k/wxWidgets
Remove the code checking for Windows versions < XP and update the documention to not mention them any more neither. Closes https://github.com/wxWidgets/wxWidgets/pull/82
This commit is contained in:
@@ -102,10 +102,6 @@ public:
|
||||
// wasn't found at all
|
||||
static int GetComCtl32Version();
|
||||
|
||||
// the same for shell32.dll: returns 400, 471, 500, 600, ... (4.70 not
|
||||
// currently detected)
|
||||
static int GetShell32Version();
|
||||
|
||||
// the SW_XXX value to be used for the frames opened by the application
|
||||
// (currently seems unused which is a bug -- TODO)
|
||||
static int m_nCmdShow;
|
||||
|
@@ -164,9 +164,8 @@ struct wxFontMetrics
|
||||
|
||||
@section Support for Transformation Matrix
|
||||
|
||||
On some platforms (currently only under MSW and only on Windows NT, i.e.
|
||||
not Windows 9x/ME, systems) wxDC has support for applying an arbitrary
|
||||
affine transformation matrix to its coordinate system. Call
|
||||
On some platforms (currently only under MSW) wxDC has support for applying
|
||||
an arbitrary affine transformation matrix to its coordinate system. Call
|
||||
CanUseTransformMatrix() to check if this support is available and then call
|
||||
SetTransformMatrix() if it is. If the transformation matrix is not
|
||||
supported, SetTransformMatrix() always simply returns false and doesn't do
|
||||
@@ -1516,10 +1515,7 @@ public:
|
||||
Check if the use of transformation matrix is supported by the current
|
||||
system.
|
||||
|
||||
Currently this function always returns @false for non-MSW platforms and
|
||||
may return @false for old (Windows 9x/ME) Windows systems. Normally
|
||||
support for the transformation matrix is always available in any
|
||||
relatively recent Windows versions.
|
||||
Currently this function always returns @false for non-MSW platforms.
|
||||
|
||||
@since 2.9.2
|
||||
*/
|
||||
|
@@ -485,7 +485,7 @@ public:
|
||||
|
||||
/**
|
||||
Check whether the operating system and/or C run time environment supports
|
||||
this locale. For example in Windows 2000 and Windows XP, support for many
|
||||
this locale. For example in Windows, support for many
|
||||
locales is not installed by default. Returns @true if the locale is
|
||||
supported.
|
||||
|
||||
|
@@ -110,9 +110,9 @@ public:
|
||||
HKCU, ///< HKEY_CURRENT_USER
|
||||
HKLM, ///< HKEY_LOCAL_MACHINE
|
||||
HKUSR, ///< HKEY_USERS
|
||||
HKPD, ///< HKEY_PERFORMANCE_DATA (Windows NT and 2K only)
|
||||
HKPD, ///< HKEY_PERFORMANCE_DATA
|
||||
HKCC, ///< HKEY_CURRENT_CONFIG
|
||||
HKDD, ///< HKEY_DYN_DATA (Windows 95 and 98 only)
|
||||
HKDD, ///< HKEY_DYN_DATA (Obsolete: Windows 9x only)
|
||||
HKMAX
|
||||
};
|
||||
|
||||
|
@@ -63,7 +63,7 @@ wxEventType wxEVT_NOTEBOOK_PAGE_CHANGING;
|
||||
@endStyleTable
|
||||
|
||||
The styles wxNB_LEFT, RIGHT and BOTTOM are not supported under
|
||||
Microsoft Windows XP when using visual themes.
|
||||
Microsoft Windows when using visual themes.
|
||||
|
||||
@beginEventEmissionTable{wxBookCtrlEvent}
|
||||
@event{EVT_NOTEBOOK_PAGE_CHANGED(id, func)}
|
||||
@@ -78,7 +78,7 @@ wxEventType wxEVT_NOTEBOOK_PAGE_CHANGING;
|
||||
|
||||
@section notebook_bg Page backgrounds
|
||||
|
||||
On Windows XP, the default theme paints a gradient on the notebook's pages.
|
||||
On Windows, the default theme paints a background on the notebook's pages.
|
||||
If you wish to suppress this theme, for aesthetic or performance reasons,
|
||||
there are three ways of doing it.
|
||||
You can use @c wxNB_NOPAGETHEME to disable themed drawing for a particular
|
||||
|
@@ -29,7 +29,7 @@ enum wxOperatingSystemId
|
||||
wxOS_MAC = wxOS_MAC_OS|wxOS_MAC_OSX_DARWIN,
|
||||
|
||||
wxOS_WINDOWS_9X = 1 << 2, //!< Windows 9x family (95/98/ME)
|
||||
wxOS_WINDOWS_NT = 1 << 3, //!< Windows NT family (NT/2000/XP/Vista/7)
|
||||
wxOS_WINDOWS_NT = 1 << 3, //!< Windows NT family (XP/Vista/7/8/10)
|
||||
wxOS_WINDOWS_MICRO = 1 << 4, //!< MicroWindows
|
||||
wxOS_WINDOWS_CE = 1 << 5, //!< Windows CE (Windows Mobile)
|
||||
|
||||
|
@@ -526,8 +526,8 @@ public:
|
||||
/**
|
||||
Invokes the print setup dialog.
|
||||
|
||||
@remarks
|
||||
The setup dialog is obsolete from Windows 95, though retained
|
||||
@deprecated
|
||||
The setup dialog is obsolete, though retained
|
||||
for backward compatibility.
|
||||
*/
|
||||
virtual bool Setup(wxWindow* parent);
|
||||
|
@@ -28,7 +28,7 @@ enum wxSystemFont
|
||||
/// dialog box controls, and text.
|
||||
wxSYS_SYSTEM_FONT,
|
||||
|
||||
/// Device-dependent font (Windows NT and later only).
|
||||
/// Device-dependent font.
|
||||
wxSYS_DEVICE_DEFAULT_FONT,
|
||||
|
||||
/**
|
||||
|
@@ -52,8 +52,8 @@ enum
|
||||
@style{wxSP_NOBORDER}
|
||||
No border (default).
|
||||
@style{wxSP_NO_XP_THEME}
|
||||
Under Windows XP, switches off the attempt to draw the splitter
|
||||
using Windows XP theming, so the borders and sash will take on the
|
||||
Under Windows, switches off the attempt to draw the splitter
|
||||
using Windows theming, so the borders and sash will take on the
|
||||
pre-XP look.
|
||||
@style{wxSP_PERMIT_UNSPLIT}
|
||||
Always allow to unsplit, even with the minimum pane size other than zero.
|
||||
|
@@ -10,8 +10,7 @@
|
||||
|
||||
A static bitmap control displays a bitmap. Native implementations on some
|
||||
platforms are only meant for display of the small icons in the dialog
|
||||
boxes. In particular, under Windows 9x the size of bitmap is limited
|
||||
to 64*64 pixels.
|
||||
boxes.
|
||||
|
||||
If you want to display larger images portably, you may use generic
|
||||
implementation wxGenericStaticBitmap declared in \<wx/generic/statbmpg.h\>.
|
||||
|
@@ -1005,8 +1005,7 @@ enum
|
||||
Under Unix, if the process is the group leader then passing
|
||||
wxKILL_CHILDREN to wxKill() kills all children as well as pid.
|
||||
|
||||
Under MSW, applies only to console applications and is only supported
|
||||
under NT family (i.e. not under Windows 9x). It corresponds to the
|
||||
Under MSW, applies only to console applications. It corresponds to the
|
||||
native @c CREATE_NEW_PROCESS_GROUP and, in particular, ensures that
|
||||
Ctrl-Break signals will be sent to all children of this process as well
|
||||
to the process itself. Support for this flag under MSW was added in
|
||||
@@ -1341,7 +1340,7 @@ bool wxShell(const wxString& command = wxEmptyString);
|
||||
the @a flags.
|
||||
|
||||
@note Note that performing the shutdown requires the corresponding access
|
||||
rights (superuser under Unix, SE_SHUTDOWN privilege under Windows NT)
|
||||
rights (superuser under Unix, SE_SHUTDOWN privilege under Windows)
|
||||
and that this function is only implemented under Unix and MSW.
|
||||
|
||||
@param flags
|
||||
|
@@ -137,7 +137,7 @@ enum wxWindowVariant
|
||||
is the old name for this style. Windows only.
|
||||
@style{wxBORDER_THEME}
|
||||
Displays a native border suitable for a control, on the current
|
||||
platform. On Windows XP or Vista, this will be a themed border; on
|
||||
platform. On Windows, this will be a themed border; on
|
||||
most other platforms a sunken border will be used. For more
|
||||
information for themed borders on Windows, please see Themed
|
||||
borders on Windows.
|
||||
|
@@ -377,10 +377,7 @@ bool wxConsoleStderr::DoInit()
|
||||
if ( !m_dllKernel32.Load(wxT("kernel32.dll")) )
|
||||
return false;
|
||||
|
||||
typedef BOOL (WINAPI *AttachConsole_t)(DWORD dwProcessId);
|
||||
AttachConsole_t wxDL_INIT_FUNC(pfn, AttachConsole, m_dllKernel32);
|
||||
|
||||
if ( !pfnAttachConsole || !pfnAttachConsole(ATTACH_PARENT_PROCESS) )
|
||||
if ( !::AttachConsole(ATTACH_PARENT_PROCESS) )
|
||||
return false;
|
||||
|
||||
// console attached, set m_hStderr now to ensure that we free it in the
|
||||
@@ -892,37 +889,6 @@ int wxApp::GetComCtl32Version()
|
||||
return s_verComCtl32;
|
||||
}
|
||||
|
||||
/* static */
|
||||
int wxApp::GetShell32Version()
|
||||
{
|
||||
static int s_verShell32 = -1;
|
||||
if ( s_verShell32 == -1 )
|
||||
{
|
||||
// we're prepared to handle the errors
|
||||
wxLogNull noLog;
|
||||
|
||||
wxDynamicLibrary dllShell32(wxT("shell32.dll"), wxDL_VERBATIM);
|
||||
if ( dllShell32.IsLoaded() )
|
||||
{
|
||||
s_verShell32 = CallDllGetVersion(dllShell32);
|
||||
|
||||
if ( !s_verShell32 )
|
||||
{
|
||||
// there doesn't seem to be any way to distinguish between 4.00
|
||||
// and 4.70 (starting from 4.71 we have DllGetVersion()) so
|
||||
// just assume it is 4.0
|
||||
s_verShell32 = 400;
|
||||
}
|
||||
}
|
||||
else // failed load the DLL?
|
||||
{
|
||||
s_verShell32 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return s_verShell32;
|
||||
}
|
||||
|
||||
#else // !wxUSE_DYNLIB_CLASS
|
||||
|
||||
/* static */
|
||||
@@ -931,12 +897,6 @@ int wxApp::GetComCtl32Version()
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* static */
|
||||
int wxApp::GetShell32Version()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // wxUSE_DYNLIB_CLASS/!wxUSE_DYNLIB_CLASS
|
||||
|
||||
#if wxUSE_EXCEPTIONS
|
||||
|
@@ -54,13 +54,6 @@ bool wxMSWDateControls::CheckInitialization()
|
||||
// it's enough to give the error only once
|
||||
s_initResult = false;
|
||||
|
||||
if ( wxApp::GetComCtl32Version() < 470 )
|
||||
{
|
||||
wxLogError(_("This system doesn't support date controls, please upgrade your version of comctl32.dll"));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#if wxUSE_DYNLIB_CLASS
|
||||
INITCOMMONCONTROLSEX icex;
|
||||
icex.dwSize = sizeof(icex);
|
||||
|
@@ -70,9 +70,7 @@ WXDWORD wxDatePickerCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const
|
||||
{
|
||||
WXDWORD styleMSW = wxDatePickerCtrlBase::MSWGetStyle(style, exstyle);
|
||||
|
||||
// although MSDN doesn't mention it, DTS_UPDOWN doesn't work with
|
||||
// comctl32.dll 4.72
|
||||
if ( wxApp::GetComCtl32Version() > 472 && (style & wxDP_SPIN) )
|
||||
if ( style & wxDP_SPIN )
|
||||
styleMSW |= DTS_UPDOWN;
|
||||
//else: drop down by default
|
||||
|
||||
|
@@ -267,19 +267,14 @@ int wxDirDialog::ShowSHBrowseForFolder(WXHWND owner)
|
||||
|
||||
static const int verComCtl32 = wxApp::GetComCtl32Version();
|
||||
|
||||
// we always add the edit box (it doesn't hurt anybody, does it?) if it is
|
||||
// supported by the system
|
||||
if ( verComCtl32 >= 471 )
|
||||
{
|
||||
bi.ulFlags |= BIF_EDITBOX;
|
||||
}
|
||||
// we always add the edit box (it doesn't hurt anybody, does it?)
|
||||
bi.ulFlags |= BIF_EDITBOX;
|
||||
|
||||
// to have the "New Folder" button we must use the "new" dialog style which
|
||||
// is also the only way to have a resizable dialog
|
||||
//
|
||||
// "new" style is only available in the version 5.0+ of comctl32.dll
|
||||
const bool needNewDir = !HasFlag(wxDD_DIR_MUST_EXIST);
|
||||
if ( (needNewDir || HasFlag(wxRESIZE_BORDER)) && (verComCtl32 >= 500) )
|
||||
if ( needNewDir || HasFlag(wxRESIZE_BORDER) )
|
||||
{
|
||||
if (needNewDir)
|
||||
{
|
||||
|
@@ -70,32 +70,6 @@
|
||||
|
||||
static const wxChar displayDllName[] = wxT("user32.dll");
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// typedefs for dynamically loaded Windows functions
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
typedef LONG (WINAPI *ChangeDisplaySettingsEx_t)(LPCTSTR lpszDeviceName,
|
||||
LPDEVMODE lpDevMode,
|
||||
HWND hwnd,
|
||||
DWORD dwFlags,
|
||||
LPVOID lParam);
|
||||
|
||||
typedef BOOL (WINAPI *EnumDisplayMonitors_t)(HDC,LPCRECT,MONITORENUMPROC,LPARAM);
|
||||
typedef HMONITOR (WINAPI *MonitorFromPoint_t)(POINT,DWORD);
|
||||
typedef HMONITOR (WINAPI *MonitorFromWindow_t)(HWND,DWORD);
|
||||
typedef BOOL (WINAPI *GetMonitorInfo_t)(HMONITOR,LPMONITORINFO);
|
||||
|
||||
// emulation of ChangeDisplaySettingsEx() for Win95
|
||||
LONG WINAPI ChangeDisplaySettingsExForWin95(LPCTSTR WXUNUSED(lpszDeviceName),
|
||||
LPDEVMODE lpDevMode,
|
||||
HWND WXUNUSED(hwnd),
|
||||
DWORD dwFlags,
|
||||
LPVOID WXUNUSED(lParam))
|
||||
{
|
||||
return ::ChangeDisplaySettings(lpDevMode, dwFlags);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxDisplayMSW declaration
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -148,12 +122,6 @@ private:
|
||||
|
||||
WX_DEFINE_ARRAY(HMONITOR, wxMonitorHandleArray);
|
||||
|
||||
// functions dynamically bound by wxDisplayFactoryMSW ctor.
|
||||
static MonitorFromPoint_t gs_MonitorFromPoint = NULL;
|
||||
static MonitorFromWindow_t gs_MonitorFromWindow = NULL;
|
||||
static GetMonitorInfo_t gs_GetMonitorInfo = NULL;
|
||||
static EnumDisplayMonitors_t gs_EnumDisplayMonitors = NULL;
|
||||
|
||||
class wxDisplayFactoryMSW : public wxDisplayFactory
|
||||
{
|
||||
public:
|
||||
@@ -236,7 +204,7 @@ wxDisplayFactoryMSW* wxDisplayFactoryMSW::ms_factory = NULL;
|
||||
|
||||
bool wxDisplayMSW::GetMonInfo(MONITORINFOEX& monInfo) const
|
||||
{
|
||||
if ( !gs_GetMonitorInfo(m_hmon, &monInfo) )
|
||||
if ( !::GetMonitorInfo(m_hmon, &monInfo) )
|
||||
{
|
||||
wxLogLastError(wxT("GetMonitorInfo"));
|
||||
return false;
|
||||
@@ -390,30 +358,8 @@ bool wxDisplayMSW::ChangeMode(const wxVideoMode& mode)
|
||||
}
|
||||
|
||||
|
||||
// get pointer to the function dynamically
|
||||
//
|
||||
// we're only called from the main thread, so it's ok to use static
|
||||
// variable
|
||||
static ChangeDisplaySettingsEx_t pfnChangeDisplaySettingsEx = NULL;
|
||||
if ( !pfnChangeDisplaySettingsEx )
|
||||
{
|
||||
wxDynamicLibrary dllDisplay(displayDllName, wxDL_VERBATIM | wxDL_QUIET);
|
||||
if ( dllDisplay.IsLoaded() )
|
||||
{
|
||||
wxDL_INIT_FUNC_AW(pfn, ChangeDisplaySettingsEx, dllDisplay);
|
||||
}
|
||||
//else: huh, no this DLL must always be present, what's going on??
|
||||
|
||||
if ( !pfnChangeDisplaySettingsEx )
|
||||
{
|
||||
// we must be under Win95 and so there is no multiple monitors
|
||||
// support anyhow
|
||||
pfnChangeDisplaySettingsEx = ChangeDisplaySettingsExForWin95;
|
||||
}
|
||||
}
|
||||
|
||||
// do change the mode
|
||||
switch ( pfnChangeDisplaySettingsEx
|
||||
switch ( ::ChangeDisplaySettingsEx
|
||||
(
|
||||
GetName().t_str(), // display name
|
||||
pDevMode, // dev mode or NULL to reset
|
||||
@@ -478,25 +424,6 @@ wxDisplayFactoryMSW::wxDisplayFactoryMSW()
|
||||
m_hiddenHwnd = NULL;
|
||||
m_hiddenClass = NULL;
|
||||
|
||||
if ( gs_MonitorFromPoint==NULL || gs_MonitorFromWindow==NULL
|
||||
|| gs_GetMonitorInfo==NULL || gs_EnumDisplayMonitors==NULL )
|
||||
{
|
||||
// First initialization, or last initialization failed.
|
||||
wxDynamicLibrary dllDisplay(displayDllName, wxDL_VERBATIM | wxDL_QUIET);
|
||||
|
||||
wxDL_INIT_FUNC(gs_, MonitorFromPoint, dllDisplay);
|
||||
wxDL_INIT_FUNC(gs_, MonitorFromWindow, dllDisplay);
|
||||
wxDL_INIT_FUNC_AW(gs_, GetMonitorInfo, dllDisplay);
|
||||
wxDL_INIT_FUNC(gs_, EnumDisplayMonitors, dllDisplay);
|
||||
|
||||
// we can safely let dllDisplay go out of scope, the DLL itself will
|
||||
// still remain loaded as all programs link to it statically anyhow
|
||||
}
|
||||
|
||||
if ( gs_MonitorFromPoint==NULL || gs_MonitorFromWindow==NULL
|
||||
|| gs_GetMonitorInfo==NULL || gs_EnumDisplayMonitors==NULL )
|
||||
return;
|
||||
|
||||
DoRefreshMonitors();
|
||||
|
||||
// Also create a hidden window to listen for WM_SETTINGCHANGE that we
|
||||
@@ -535,7 +462,7 @@ void wxDisplayFactoryMSW::DoRefreshMonitors()
|
||||
{
|
||||
m_displays.Clear();
|
||||
|
||||
if ( !gs_EnumDisplayMonitors(NULL, NULL, MultimonEnumProc, (LPARAM)this) )
|
||||
if ( !::EnumDisplayMonitors(NULL, NULL, MultimonEnumProc, (LPARAM)this) )
|
||||
{
|
||||
wxLogLastError(wxT("EnumDisplayMonitors"));
|
||||
}
|
||||
@@ -586,14 +513,14 @@ int wxDisplayFactoryMSW::GetFromPoint(const wxPoint& pt)
|
||||
pt2.x = pt.x;
|
||||
pt2.y = pt.y;
|
||||
|
||||
return FindDisplayFromHMONITOR(gs_MonitorFromPoint(pt2,
|
||||
return FindDisplayFromHMONITOR(::MonitorFromPoint(pt2,
|
||||
MONITOR_DEFAULTTONULL));
|
||||
}
|
||||
|
||||
int wxDisplayFactoryMSW::GetFromWindow(const wxWindow *window)
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
return FindDisplayFromHMONITOR(gs_MonitorFromWindow(GetHwndOf(window),
|
||||
return FindDisplayFromHMONITOR(::MonitorFromWindow(GetHwndOf(window),
|
||||
MONITOR_DEFAULTTONULL));
|
||||
#else
|
||||
const wxSize halfsize = window->GetSize() / 2;
|
||||
|
@@ -32,40 +32,6 @@
|
||||
// private classes
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// wrap some functions from version.dll: load them dynamically and provide a
|
||||
// clean interface
|
||||
class wxVersionDLL
|
||||
{
|
||||
public:
|
||||
// load version.dll and bind to its functions
|
||||
wxVersionDLL();
|
||||
|
||||
// return the file version as string, e.g. "x.y.z.w"
|
||||
wxString GetFileVersion(const wxString& filename) const;
|
||||
|
||||
private:
|
||||
typedef DWORD (APIENTRY *GetFileVersionInfoSize_t)(PTSTR, PDWORD);
|
||||
typedef BOOL (APIENTRY *GetFileVersionInfo_t)(PTSTR, DWORD, DWORD, PVOID);
|
||||
typedef BOOL (APIENTRY *VerQueryValue_t)(const PVOID, PTSTR, PVOID *, PUINT);
|
||||
|
||||
#define DO_FOR_ALL_VER_FUNCS(what) \
|
||||
what(GetFileVersionInfoSize); \
|
||||
what(GetFileVersionInfo); \
|
||||
what(VerQueryValue)
|
||||
|
||||
#define DECLARE_VER_FUNCTION(func) func ## _t m_pfn ## func
|
||||
|
||||
DO_FOR_ALL_VER_FUNCS(DECLARE_VER_FUNCTION);
|
||||
|
||||
#undef DECLARE_VER_FUNCTION
|
||||
|
||||
|
||||
wxDynamicLibrary m_dll;
|
||||
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(wxVersionDLL);
|
||||
};
|
||||
|
||||
// class used to create wxDynamicLibraryDetails objects
|
||||
class WXDLLIMPEXP_BASE wxDynamicLibraryDetailsCreator
|
||||
{
|
||||
@@ -74,87 +40,44 @@ public:
|
||||
struct EnumModulesProcParams
|
||||
{
|
||||
wxDynamicLibraryDetailsArray *dlls;
|
||||
wxVersionDLL *verDLL;
|
||||
};
|
||||
|
||||
static BOOL CALLBACK
|
||||
EnumModulesProc(const wxChar* name, DWORD64 base, ULONG size, PVOID data);
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// wxVersionDLL implementation
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// loading
|
||||
// DLL version operations
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxVersionDLL::wxVersionDLL()
|
||||
{
|
||||
// don't give errors if DLL can't be loaded or used, we're prepared to
|
||||
// handle it
|
||||
wxLogNull noLog;
|
||||
|
||||
if ( m_dll.Load(wxT("version.dll"), wxDL_VERBATIM) )
|
||||
{
|
||||
// the functions we load have either 'A' or 'W' suffix depending on
|
||||
// whether we're in ANSI or Unicode build
|
||||
#ifdef UNICODE
|
||||
#define SUFFIX L"W"
|
||||
#else // ANSI
|
||||
#define SUFFIX "A"
|
||||
#endif // UNICODE/ANSI
|
||||
|
||||
#define LOAD_VER_FUNCTION(name) \
|
||||
m_pfn ## name = (name ## _t)m_dll.GetSymbol(wxT(#name SUFFIX)); \
|
||||
if ( !m_pfn ## name ) \
|
||||
{ \
|
||||
m_dll.Unload(); \
|
||||
return; \
|
||||
}
|
||||
|
||||
DO_FOR_ALL_VER_FUNCS(LOAD_VER_FUNCTION);
|
||||
|
||||
#undef LOAD_VER_FUNCTION
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxVersionDLL operations
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxString wxVersionDLL::GetFileVersion(const wxString& filename) const
|
||||
static wxString GetFileVersion(const wxString& filename)
|
||||
{
|
||||
wxString ver;
|
||||
if ( m_dll.IsLoaded() )
|
||||
{
|
||||
wxChar *pc = const_cast<wxChar *>((const wxChar*) filename.t_str());
|
||||
wxChar *pc = const_cast<wxChar *>((const wxChar*) filename.t_str());
|
||||
|
||||
DWORD dummy;
|
||||
DWORD sizeVerInfo = m_pfnGetFileVersionInfoSize(pc, &dummy);
|
||||
if ( sizeVerInfo )
|
||||
DWORD dummy;
|
||||
DWORD sizeVerInfo = ::GetFileVersionInfoSize(pc, &dummy);
|
||||
if ( sizeVerInfo )
|
||||
{
|
||||
wxCharBuffer buf(sizeVerInfo);
|
||||
if ( ::GetFileVersionInfo(pc, 0, sizeVerInfo, buf.data()) )
|
||||
{
|
||||
wxCharBuffer buf(sizeVerInfo);
|
||||
if ( m_pfnGetFileVersionInfo(pc, 0, sizeVerInfo, buf.data()) )
|
||||
void *pVer;
|
||||
UINT sizeInfo;
|
||||
if ( ::VerQueryValue(buf.data(),
|
||||
const_cast<wxChar *>(wxT("\\")),
|
||||
&pVer,
|
||||
&sizeInfo) )
|
||||
{
|
||||
void *pVer;
|
||||
UINT sizeInfo;
|
||||
if ( m_pfnVerQueryValue(buf.data(),
|
||||
const_cast<wxChar *>(wxT("\\")),
|
||||
&pVer,
|
||||
&sizeInfo) )
|
||||
{
|
||||
VS_FIXEDFILEINFO *info = (VS_FIXEDFILEINFO *)pVer;
|
||||
ver.Printf(wxT("%d.%d.%d.%d"),
|
||||
HIWORD(info->dwFileVersionMS),
|
||||
LOWORD(info->dwFileVersionMS),
|
||||
HIWORD(info->dwFileVersionLS),
|
||||
LOWORD(info->dwFileVersionLS));
|
||||
}
|
||||
VS_FIXEDFILEINFO *info = (VS_FIXEDFILEINFO *)pVer;
|
||||
ver.Printf(wxT("%d.%d.%d.%d"),
|
||||
HIWORD(info->dwFileVersionMS),
|
||||
LOWORD(info->dwFileVersionMS),
|
||||
HIWORD(info->dwFileVersionLS),
|
||||
LOWORD(info->dwFileVersionLS));
|
||||
}
|
||||
}
|
||||
}
|
||||
//else: we failed to load DLL, can't retrieve version info
|
||||
|
||||
return ver;
|
||||
}
|
||||
@@ -191,7 +114,7 @@ wxDynamicLibraryDetailsCreator::EnumModulesProc(const wxChar* name,
|
||||
if ( !fullname.empty() )
|
||||
{
|
||||
details->m_path = fullname;
|
||||
details->m_version = params->verDLL->GetFileVersion(fullname);
|
||||
details->m_version = GetFileVersion(fullname);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,12 +181,8 @@ wxDynamicLibraryDetailsArray wxDynamicLibrary::ListLoaded()
|
||||
#if wxUSE_DBGHELP
|
||||
if ( wxDbgHelpDLL::Init() )
|
||||
{
|
||||
// prepare to use functions for version info extraction
|
||||
wxVersionDLL verDLL;
|
||||
|
||||
wxDynamicLibraryDetailsCreator::EnumModulesProcParams params;
|
||||
params.dlls = &dlls;
|
||||
params.verDLL = &verDLL;
|
||||
|
||||
if ( !wxDbgHelpDLL::CallEnumerateLoadedModules
|
||||
(
|
||||
|
@@ -289,26 +289,23 @@ bool wxListCtrl::Create(wxWindow *parent,
|
||||
|
||||
void wxListCtrl::MSWSetExListStyles()
|
||||
{
|
||||
// for comctl32.dll v 4.70+ we want to have some non default extended
|
||||
// we want to have some non default extended
|
||||
// styles because it's prettier (and also because wxGTK does it like this)
|
||||
if ( wxApp::GetComCtl32Version() >= 470 )
|
||||
{
|
||||
::SendMessage
|
||||
(
|
||||
GetHwnd(), LVM_SETEXTENDEDLISTVIEWSTYLE, 0,
|
||||
// LVS_EX_LABELTIP shouldn't be used under Windows CE where it's
|
||||
// not defined in the SDK headers
|
||||
::SendMessage
|
||||
(
|
||||
GetHwnd(), LVM_SETEXTENDEDLISTVIEWSTYLE, 0,
|
||||
// LVS_EX_LABELTIP shouldn't be used under Windows CE where it's
|
||||
// not defined in the SDK headers
|
||||
#ifdef LVS_EX_LABELTIP
|
||||
LVS_EX_LABELTIP |
|
||||
LVS_EX_LABELTIP |
|
||||
#endif
|
||||
LVS_EX_FULLROWSELECT |
|
||||
LVS_EX_SUBITEMIMAGES |
|
||||
// normally this should be governed by a style as it's probably not
|
||||
// always appropriate, but we don't have any free styles left and
|
||||
// it seems better to enable it by default than disable
|
||||
LVS_EX_HEADERDRAGDROP
|
||||
);
|
||||
}
|
||||
LVS_EX_FULLROWSELECT |
|
||||
LVS_EX_SUBITEMIMAGES |
|
||||
// normally this should be governed by a style as it's probably not
|
||||
// always appropriate, but we don't have any free styles left and
|
||||
// it seems better to enable it by default than disable
|
||||
LVS_EX_HEADERDRAGDROP
|
||||
);
|
||||
}
|
||||
|
||||
WXDWORD wxListCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const
|
||||
@@ -371,13 +368,6 @@ WXDWORD wxListCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const
|
||||
#if !( defined(__GNUWIN32__) && !wxCHECK_W32API_VERSION( 1, 0 ) )
|
||||
if ( style & wxLC_VIRTUAL )
|
||||
{
|
||||
int ver = wxApp::GetComCtl32Version();
|
||||
if ( ver < 470 )
|
||||
{
|
||||
wxLogWarning(_("Please install a newer version of comctl32.dll\n(at least version 4.70 is required but you have %d.%02d)\nor this program won't operate correctly."),
|
||||
ver / 100, ver % 100);
|
||||
}
|
||||
|
||||
wstyle |= LVS_OWNERDATA;
|
||||
}
|
||||
#endif // ancient cygwin
|
||||
@@ -1631,7 +1621,7 @@ wxListCtrl::HitTest(const wxPoint& point, int& flags, long *ptrSubItem) const
|
||||
|
||||
long item;
|
||||
#ifdef LVM_SUBITEMHITTEST
|
||||
if ( ptrSubItem && wxApp::GetComCtl32Version() >= 470 )
|
||||
if ( ptrSubItem )
|
||||
{
|
||||
item = ListView_SubItemHitTest(GetHwnd(), &hitTestInfo);
|
||||
*ptrSubItem = hitTestInfo.iSubItem;
|
||||
@@ -3285,40 +3275,36 @@ static void wxConvertToMSWListCol(HWND hwndList,
|
||||
#ifdef NM_CUSTOMDRAW // _WIN32_IE >= 0x0300
|
||||
if ( item.m_mask & wxLIST_MASK_IMAGE )
|
||||
{
|
||||
if ( wxApp::GetComCtl32Version() >= 470 )
|
||||
lvCol.mask |= LVCF_IMAGE;
|
||||
|
||||
// we use LVCFMT_BITMAP_ON_RIGHT because the images on the right
|
||||
// seem to be generally nicer than on the left and the generic
|
||||
// version only draws them on the right (we don't have a flag to
|
||||
// specify the image location anyhow)
|
||||
//
|
||||
// we don't use LVCFMT_COL_HAS_IMAGES because it doesn't seem to
|
||||
// make any difference in my tests -- but maybe we should?
|
||||
if ( item.m_image != -1 )
|
||||
{
|
||||
lvCol.mask |= LVCF_IMAGE;
|
||||
|
||||
// we use LVCFMT_BITMAP_ON_RIGHT because the images on the right
|
||||
// seem to be generally nicer than on the left and the generic
|
||||
// version only draws them on the right (we don't have a flag to
|
||||
// specify the image location anyhow)
|
||||
//
|
||||
// we don't use LVCFMT_COL_HAS_IMAGES because it doesn't seem to
|
||||
// make any difference in my tests -- but maybe we should?
|
||||
if ( item.m_image != -1 )
|
||||
// as we're going to overwrite the format field, get its
|
||||
// current value first -- unless we want to overwrite it anyhow
|
||||
if ( !(lvCol.mask & LVCF_FMT) )
|
||||
{
|
||||
// as we're going to overwrite the format field, get its
|
||||
// current value first -- unless we want to overwrite it anyhow
|
||||
if ( !(lvCol.mask & LVCF_FMT) )
|
||||
LV_COLUMN lvColOld;
|
||||
wxZeroMemory(lvColOld);
|
||||
lvColOld.mask = LVCF_FMT;
|
||||
if ( ListView_GetColumn(hwndList, col, &lvColOld) )
|
||||
{
|
||||
LV_COLUMN lvColOld;
|
||||
wxZeroMemory(lvColOld);
|
||||
lvColOld.mask = LVCF_FMT;
|
||||
if ( ListView_GetColumn(hwndList, col, &lvColOld) )
|
||||
{
|
||||
lvCol.fmt = lvColOld.fmt;
|
||||
}
|
||||
|
||||
lvCol.mask |= LVCF_FMT;
|
||||
lvCol.fmt = lvColOld.fmt;
|
||||
}
|
||||
|
||||
lvCol.fmt |= LVCFMT_BITMAP_ON_RIGHT | LVCFMT_IMAGE;
|
||||
lvCol.mask |= LVCF_FMT;
|
||||
}
|
||||
|
||||
lvCol.iImage = item.m_image;
|
||||
lvCol.fmt |= LVCFMT_BITMAP_ON_RIGHT | LVCFMT_IMAGE;
|
||||
}
|
||||
//else: it doesn't support item images anyhow
|
||||
|
||||
lvCol.iImage = item.m_image;
|
||||
}
|
||||
#endif // _WIN32_IE >= 0x0300
|
||||
}
|
||||
|
@@ -580,21 +580,11 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
|
||||
// boxes are used together with bitmaps and this is not the
|
||||
// case in wx API
|
||||
WinStruct<MENUINFO> mi;
|
||||
|
||||
// don't call SetMenuInfo() directly, this would prevent
|
||||
// the app from starting up under Windows 95/NT 4
|
||||
typedef BOOL (WINAPI *SetMenuInfo_t)(HMENU, MENUINFO *);
|
||||
|
||||
wxDynamicLibrary dllUser(wxT("user32"));
|
||||
wxDYNLIB_FUNCTION(SetMenuInfo_t, SetMenuInfo, dllUser);
|
||||
if ( pfnSetMenuInfo )
|
||||
mi.fMask = MIM_STYLE;
|
||||
mi.dwStyle = MNS_CHECKORBMP;
|
||||
if ( !::SetMenuInfo(GetHmenu(), &mi) )
|
||||
{
|
||||
mi.fMask = MIM_STYLE;
|
||||
mi.dwStyle = MNS_CHECKORBMP;
|
||||
if ( !(*pfnSetMenuInfo)(GetHmenu(), &mi) )
|
||||
{
|
||||
wxLogLastError(wxT("SetMenuInfo(MNS_NOCHECK)"));
|
||||
}
|
||||
wxLogLastError(wxT("SetMenuInfo(MNS_NOCHECK)"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -227,31 +227,13 @@ wxString wxAssocQueryString(ASSOCSTR assoc,
|
||||
wxString ext,
|
||||
const wxString& verb = wxString())
|
||||
{
|
||||
typedef HRESULT (WINAPI *AssocQueryString_t)(ASSOCF, ASSOCSTR,
|
||||
LPCTSTR, LPCTSTR, LPTSTR,
|
||||
DWORD *);
|
||||
static AssocQueryString_t s_pfnAssocQueryString = (AssocQueryString_t)-1;
|
||||
static wxDynamicLibrary s_dllShlwapi;
|
||||
|
||||
if ( s_pfnAssocQueryString == (AssocQueryString_t)-1 )
|
||||
{
|
||||
if ( !s_dllShlwapi.Load(wxT("shlwapi.dll"), wxDL_VERBATIM | wxDL_QUIET) )
|
||||
s_pfnAssocQueryString = NULL;
|
||||
else
|
||||
wxDL_INIT_FUNC_AW(s_pfn, AssocQueryString, s_dllShlwapi);
|
||||
}
|
||||
|
||||
if ( !s_pfnAssocQueryString )
|
||||
return wxString();
|
||||
|
||||
|
||||
DWORD dwSize = MAX_PATH;
|
||||
TCHAR bufOut[MAX_PATH] = { 0 };
|
||||
|
||||
if ( ext.empty() || ext[0] != '.' )
|
||||
ext.Prepend('.');
|
||||
|
||||
HRESULT hr = s_pfnAssocQueryString
|
||||
HRESULT hr = ::AssocQueryString
|
||||
(
|
||||
wxASSOCF_NOTRUNCATE,// Fail if buffer is too small.
|
||||
assoc, // The association to retrieve.
|
||||
|
@@ -452,7 +452,7 @@ bool wxNotificationMessage::Show(int timeout)
|
||||
{
|
||||
if ( !m_impl )
|
||||
{
|
||||
if ( !ms_alwaysUseGeneric && wxTheApp->GetShell32Version() >= 500 )
|
||||
if ( !ms_alwaysUseGeneric )
|
||||
{
|
||||
if ( timeout == Timeout_Never )
|
||||
m_impl = new wxManualNotifMsgImpl(GetParent());
|
||||
|
@@ -168,17 +168,12 @@ int wxSpinButton::GetValue() const
|
||||
{
|
||||
int n;
|
||||
#ifdef UDM_GETPOS32
|
||||
if ( wxApp::GetComCtl32Version() >= 580 )
|
||||
{
|
||||
// use the full 32 bit range if available
|
||||
n = ::SendMessage(GetHwnd(), UDM_GETPOS32, 0, 0);
|
||||
}
|
||||
else
|
||||
// use the full 32 bit range if available
|
||||
n = ::SendMessage(GetHwnd(), UDM_GETPOS32, 0, 0);
|
||||
#else
|
||||
// we're limited to 16 bit
|
||||
n = (short)LOWORD(::SendMessage(GetHwnd(), UDM_GETPOS, 0, 0));
|
||||
#endif // UDM_GETPOS32
|
||||
{
|
||||
// we're limited to 16 bit
|
||||
n = (short)LOWORD(::SendMessage(GetHwnd(), UDM_GETPOS, 0, 0));
|
||||
}
|
||||
|
||||
if (n < m_min) n = m_min;
|
||||
if (n > m_max) n = m_max;
|
||||
@@ -191,16 +186,11 @@ void wxSpinButton::SetValue(int val)
|
||||
// wxSpinButtonBase::SetValue(val); -- no, it is pure virtual
|
||||
|
||||
#ifdef UDM_SETPOS32
|
||||
if ( wxApp::GetComCtl32Version() >= 580 )
|
||||
{
|
||||
// use the full 32 bit range if available
|
||||
::SendMessage(GetHwnd(), UDM_SETPOS32, 0, val);
|
||||
}
|
||||
else // we're limited to 16 bit
|
||||
// use the full 32 bit range if available
|
||||
::SendMessage(GetHwnd(), UDM_SETPOS32, 0, val);
|
||||
#else
|
||||
::SendMessage(GetHwnd(), UDM_SETPOS, 0, MAKELONG((short) val, 0));
|
||||
#endif // UDM_SETPOS32
|
||||
{
|
||||
::SendMessage(GetHwnd(), UDM_SETPOS, 0, MAKELONG((short) val, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void wxSpinButton::NormalizeValue()
|
||||
@@ -215,17 +205,13 @@ void wxSpinButton::SetRange(int minVal, int maxVal)
|
||||
wxSpinButtonBase::SetRange(minVal, maxVal);
|
||||
|
||||
#ifdef UDM_SETRANGE32
|
||||
if ( wxApp::GetComCtl32Version() >= 471 )
|
||||
{
|
||||
// use the full 32 bit range if available
|
||||
::SendMessage(GetHwnd(), UDM_SETRANGE32, minVal, maxVal);
|
||||
}
|
||||
else // we're limited to 16 bit
|
||||
// use the full 32 bit range if available
|
||||
::SendMessage(GetHwnd(), UDM_SETRANGE32, minVal, maxVal);
|
||||
#else
|
||||
// we're limited to 16 bit
|
||||
::SendMessage(GetHwnd(), UDM_SETRANGE, 0,
|
||||
(LPARAM) MAKELONG((short)maxVal, (short)minVal));
|
||||
#endif // UDM_SETRANGE32
|
||||
{
|
||||
::SendMessage(GetHwnd(), UDM_SETRANGE, 0,
|
||||
(LPARAM) MAKELONG((short)maxVal, (short)minVal));
|
||||
}
|
||||
|
||||
// the current value might be out of the new range, force it to be in it
|
||||
NormalizeValue();
|
||||
|
@@ -45,14 +45,6 @@
|
||||
#define NIF_INFO 0x00000010
|
||||
#endif
|
||||
|
||||
#ifndef NOTIFYICONDATA_V1_SIZE
|
||||
#ifdef UNICODE
|
||||
#define NOTIFYICONDATA_V1_SIZE 0x0098
|
||||
#else
|
||||
#define NOTIFYICONDATA_V1_SIZE 0x0058
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NOTIFYICONDATA_V2_SIZE
|
||||
#ifdef UNICODE
|
||||
#define NOTIFYICONDATA_V2_SIZE 0x03A8
|
||||
@@ -122,12 +114,8 @@ struct NotifyIconData : public NOTIFYICONDATA
|
||||
// we could do complicated tests for the exact system version it's
|
||||
// easier to just use an old size which should be supported everywhere
|
||||
// from Windows 2000 up and which is all we need as we don't use any
|
||||
// newer features so far. But if we're running under a really ancient
|
||||
// system (Win9x), fall back to even smaller size -- then the balloon
|
||||
// related features won't be available but the rest will still work.
|
||||
cbSize = wxTheApp->GetShell32Version() >= 500
|
||||
? NOTIFYICONDATA_V2_SIZE
|
||||
: NOTIFYICONDATA_V1_SIZE;
|
||||
// newer features so far.
|
||||
cbSize = NOTIFYICONDATA_V2_SIZE;
|
||||
|
||||
hWnd = (HWND) hwnd;
|
||||
uCallbackMessage = gs_msgTaskbar;
|
||||
|
@@ -39,6 +39,9 @@
|
||||
#include "wx/msw/uxtheme.h"
|
||||
#endif
|
||||
|
||||
#include "wx/msw/wrapwin.h"
|
||||
#include <Shlwapi.h>
|
||||
|
||||
#define GetEditHwnd() ((HWND)(GetEditHWND()))
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -775,24 +778,6 @@ void wxTextEntry::GetSelection(long *from, long *to) const
|
||||
|
||||
bool wxTextEntry::DoAutoCompleteFileNames(int flags)
|
||||
{
|
||||
typedef HRESULT (WINAPI *SHAutoComplete_t)(HWND, DWORD);
|
||||
static SHAutoComplete_t s_pfnSHAutoComplete = (SHAutoComplete_t)-1;
|
||||
static wxDynamicLibrary s_dllShlwapi;
|
||||
if ( s_pfnSHAutoComplete == (SHAutoComplete_t)-1 )
|
||||
{
|
||||
if ( !s_dllShlwapi.Load(wxT("shlwapi.dll"), wxDL_VERBATIM | wxDL_QUIET) )
|
||||
{
|
||||
s_pfnSHAutoComplete = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxDL_INIT_FUNC(s_pfn, SHAutoComplete, s_dllShlwapi);
|
||||
}
|
||||
}
|
||||
|
||||
if ( !s_pfnSHAutoComplete )
|
||||
return false;
|
||||
|
||||
DWORD dwFlags = 0;
|
||||
if ( flags & wxFILE )
|
||||
dwFlags |= SHACF_FILESYS_ONLY;
|
||||
@@ -804,7 +789,7 @@ bool wxTextEntry::DoAutoCompleteFileNames(int flags)
|
||||
return false;
|
||||
}
|
||||
|
||||
HRESULT hr = (*s_pfnSHAutoComplete)(GetEditHwnd(), dwFlags);
|
||||
HRESULT hr = ::SHAutoComplete(GetEditHwnd(), dwFlags);
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
wxLogApiError(wxT("SHAutoComplete()"), hr);
|
||||
|
@@ -386,8 +386,7 @@ bool wxToolBar::MSWCreateToolbar(const wxPoint& pos, const wxSize& size)
|
||||
::SendMessage(GetHwnd(), TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
|
||||
|
||||
#ifdef TB_SETEXTENDEDSTYLE
|
||||
if ( wxApp::GetComCtl32Version() >= 471 )
|
||||
::SendMessage(GetHwnd(), TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_DRAWDDARROWS);
|
||||
::SendMessage(GetHwnd(), TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_DRAWDDARROWS);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
@@ -523,10 +522,10 @@ WXDWORD wxToolBar::MSWGetStyle(long style, WXDWORD *exstyle) const
|
||||
if ( !(style & wxTB_NO_TOOLTIPS) )
|
||||
msStyle |= TBSTYLE_TOOLTIPS;
|
||||
|
||||
if ( style & wxTB_FLAT && wxApp::GetComCtl32Version() > 400 )
|
||||
if ( style & wxTB_FLAT )
|
||||
msStyle |= TBSTYLE_FLAT;
|
||||
|
||||
if ( style & wxTB_HORZ_LAYOUT && wxApp::GetComCtl32Version() >= 470 )
|
||||
if ( style & wxTB_HORZ_LAYOUT )
|
||||
msStyle |= TBSTYLE_LIST;
|
||||
|
||||
if ( style & wxTB_NODIVIDER )
|
||||
@@ -607,34 +606,27 @@ void wxToolBar::CreateDisabledImageList()
|
||||
{
|
||||
wxDELETE(m_disabledImgList);
|
||||
|
||||
// as we can't use disabled image list with older versions of comctl32.dll,
|
||||
// don't even bother creating it
|
||||
if ( wxApp::GetComCtl32Version() >= 470 )
|
||||
// search for the first disabled button img in the toolbar, if any
|
||||
for ( wxToolBarToolsList::compatibility_iterator
|
||||
node = m_tools.GetFirst(); node; node = node->GetNext() )
|
||||
{
|
||||
// search for the first disabled button img in the toolbar, if any
|
||||
for ( wxToolBarToolsList::compatibility_iterator
|
||||
node = m_tools.GetFirst(); node; node = node->GetNext() )
|
||||
wxToolBarToolBase *tool = node->GetData();
|
||||
wxBitmap bmpDisabled = tool->GetDisabledBitmap();
|
||||
if ( bmpDisabled.IsOk() )
|
||||
{
|
||||
wxToolBarToolBase *tool = node->GetData();
|
||||
wxBitmap bmpDisabled = tool->GetDisabledBitmap();
|
||||
if ( bmpDisabled.IsOk() )
|
||||
{
|
||||
const wxSize sizeBitmap = bmpDisabled.GetSize();
|
||||
m_disabledImgList = new wxImageList
|
||||
(
|
||||
sizeBitmap.x,
|
||||
sizeBitmap.y,
|
||||
// Don't use mask if we have alpha
|
||||
// (wxImageList will fall back to
|
||||
// mask if alpha not supported)
|
||||
!bmpDisabled.HasAlpha(),
|
||||
GetToolsCount()
|
||||
);
|
||||
break;
|
||||
}
|
||||
const wxSize sizeBitmap = bmpDisabled.GetSize();
|
||||
m_disabledImgList = new wxImageList
|
||||
(
|
||||
sizeBitmap.x,
|
||||
sizeBitmap.y,
|
||||
// Don't use mask if we have alpha
|
||||
// (wxImageList will fall back to
|
||||
// mask if alpha not supported)
|
||||
!bmpDisabled.HasAlpha(),
|
||||
GetToolsCount()
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
// we don't have any disabled bitmaps
|
||||
}
|
||||
}
|
||||
|
||||
@@ -824,35 +816,30 @@ bool wxToolBar::Realize()
|
||||
if ( oldToolBarBitmap )
|
||||
{
|
||||
#ifdef TB_REPLACEBITMAP
|
||||
if ( wxApp::GetComCtl32Version() >= 400 )
|
||||
TBREPLACEBITMAP replaceBitmap;
|
||||
replaceBitmap.hInstOld = NULL;
|
||||
replaceBitmap.hInstNew = NULL;
|
||||
replaceBitmap.nIDOld = (UINT_PTR)oldToolBarBitmap;
|
||||
replaceBitmap.nIDNew = (UINT_PTR)hBitmap;
|
||||
replaceBitmap.nButtons = nButtons;
|
||||
if ( !::SendMessage(GetHwnd(), TB_REPLACEBITMAP,
|
||||
0, (LPARAM) &replaceBitmap) )
|
||||
{
|
||||
TBREPLACEBITMAP replaceBitmap;
|
||||
replaceBitmap.hInstOld = NULL;
|
||||
replaceBitmap.hInstNew = NULL;
|
||||
replaceBitmap.nIDOld = (UINT_PTR)oldToolBarBitmap;
|
||||
replaceBitmap.nIDNew = (UINT_PTR)hBitmap;
|
||||
replaceBitmap.nButtons = nButtons;
|
||||
if ( !::SendMessage(GetHwnd(), TB_REPLACEBITMAP,
|
||||
0, (LPARAM) &replaceBitmap) )
|
||||
{
|
||||
wxFAIL_MSG(wxT("Could not replace the old bitmap"));
|
||||
}
|
||||
|
||||
::DeleteObject(oldToolBarBitmap);
|
||||
|
||||
// already done
|
||||
addBitmap = false;
|
||||
wxFAIL_MSG(wxT("Could not replace the old bitmap"));
|
||||
}
|
||||
else
|
||||
|
||||
::DeleteObject(oldToolBarBitmap);
|
||||
|
||||
// already done
|
||||
addBitmap = false;
|
||||
#else
|
||||
// we can't replace the old bitmap, so we will add another one
|
||||
// (awfully inefficient, but what else to do?) and shift the bitmap
|
||||
// indices accordingly
|
||||
addBitmap = true;
|
||||
|
||||
bitmapId = m_nButtons;
|
||||
#endif // TB_REPLACEBITMAP
|
||||
{
|
||||
// we can't replace the old bitmap, so we will add another one
|
||||
// (awfully inefficient, but what else to do?) and shift the bitmap
|
||||
// indices accordingly
|
||||
addBitmap = true;
|
||||
|
||||
bitmapId = m_nButtons;
|
||||
}
|
||||
}
|
||||
|
||||
if ( addBitmap ) // no old bitmap or we can't replace it
|
||||
@@ -867,22 +854,18 @@ bool wxToolBar::Realize()
|
||||
}
|
||||
}
|
||||
|
||||
// disable image lists are only supported in comctl32.dll 4.70+
|
||||
if ( wxApp::GetComCtl32Version() >= 470 )
|
||||
{
|
||||
HIMAGELIST hil = m_disabledImgList
|
||||
? GetHimagelistOf(m_disabledImgList)
|
||||
: 0;
|
||||
HIMAGELIST hil = m_disabledImgList
|
||||
? GetHimagelistOf(m_disabledImgList)
|
||||
: 0;
|
||||
|
||||
// notice that we set the image list even if don't have one right
|
||||
// now as we could have it before and need to reset it in this case
|
||||
HIMAGELIST oldImageList = (HIMAGELIST)
|
||||
::SendMessage(GetHwnd(), TB_SETDISABLEDIMAGELIST, 0, (LPARAM)hil);
|
||||
// notice that we set the image list even if don't have one right
|
||||
// now as we could have it before and need to reset it in this case
|
||||
HIMAGELIST oldImageList = (HIMAGELIST)
|
||||
::SendMessage(GetHwnd(), TB_SETDISABLEDIMAGELIST, 0, (LPARAM)hil);
|
||||
|
||||
// delete previous image list if any
|
||||
if ( oldImageList )
|
||||
::DeleteObject(oldImageList);
|
||||
}
|
||||
// delete previous image list if any
|
||||
if ( oldImageList )
|
||||
::DeleteObject(oldImageList);
|
||||
}
|
||||
|
||||
|
||||
@@ -900,14 +883,6 @@ bool wxToolBar::Realize()
|
||||
{
|
||||
wxToolBarTool *tool = static_cast<wxToolBarTool *>(node->GetData());
|
||||
|
||||
// don't add separators to the vertical toolbar with old comctl32.dll
|
||||
// versions as they didn't handle this properly
|
||||
if ( IsVertical() && tool->IsSeparator() &&
|
||||
wxApp::GetComCtl32Version() <= 472 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
TBBUTTON& button = buttons[i];
|
||||
|
||||
wxZeroMemory(button);
|
||||
@@ -1492,21 +1467,9 @@ void wxToolBar::SetRows(int nRows)
|
||||
// The button size is bigger than the bitmap size
|
||||
wxSize wxToolBar::GetToolSize() const
|
||||
{
|
||||
// TB_GETBUTTONSIZE is supported from version 4.70
|
||||
#if defined(_WIN32_IE) && (_WIN32_IE >= 0x300 ) \
|
||||
&& !( defined(__GNUWIN32__) && !wxCHECK_W32API_VERSION( 1, 0 ) )
|
||||
if ( wxApp::GetComCtl32Version() >= 470 )
|
||||
{
|
||||
DWORD dw = ::SendMessage(GetHwnd(), TB_GETBUTTONSIZE, 0, 0);
|
||||
DWORD dw = ::SendMessage(GetHwnd(), TB_GETBUTTONSIZE, 0, 0);
|
||||
|
||||
return wxSize(LOWORD(dw), HIWORD(dw));
|
||||
}
|
||||
else
|
||||
#endif // comctl32.dll 4.70+
|
||||
{
|
||||
// defaults
|
||||
return wxSize(m_defaultWidth + 8, m_defaultHeight + 7);
|
||||
}
|
||||
return wxSize(LOWORD(dw), HIWORD(dw));
|
||||
}
|
||||
|
||||
wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const
|
||||
|
@@ -130,10 +130,7 @@ public:
|
||||
// then as the control gets "focus lost" events and dismisses the
|
||||
// tooltip which then reappears because mouse remains hovering over the
|
||||
// control, see SF patch 1821229
|
||||
if ( wxApp::GetComCtl32Version() >= 470 )
|
||||
{
|
||||
uFlags |= TTF_TRANSPARENT;
|
||||
}
|
||||
uFlags |= TTF_TRANSPARENT;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -539,81 +536,76 @@ void wxToolTip::DoSetTip(WXHWND hWnd)
|
||||
|
||||
bool wxToolTip::AdjustMaxWidth()
|
||||
{
|
||||
if ( wxApp::GetComCtl32Version() >= 470 )
|
||||
{
|
||||
// use TTM_SETMAXTIPWIDTH to make tooltip multiline using the
|
||||
// extent of its first line as max value
|
||||
HFONT hfont = (HFONT)
|
||||
SendTooltipMessage(GetToolTipCtrl(), WM_GETFONT, 0);
|
||||
// use TTM_SETMAXTIPWIDTH to make tooltip multiline using the
|
||||
// extent of its first line as max value
|
||||
HFONT hfont = (HFONT)
|
||||
SendTooltipMessage(GetToolTipCtrl(), WM_GETFONT, 0);
|
||||
|
||||
if ( !hfont )
|
||||
{
|
||||
hfont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
|
||||
if ( !hfont )
|
||||
{
|
||||
hfont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
|
||||
if ( !hfont )
|
||||
{
|
||||
wxLogLastError(wxT("GetStockObject(DEFAULT_GUI_FONT)"));
|
||||
}
|
||||
wxLogLastError(wxT("GetStockObject(DEFAULT_GUI_FONT)"));
|
||||
}
|
||||
|
||||
MemoryHDC hdc;
|
||||
if ( !hdc )
|
||||
{
|
||||
wxLogLastError(wxT("CreateCompatibleDC(NULL)"));
|
||||
}
|
||||
|
||||
if ( !SelectObject(hdc, hfont) )
|
||||
{
|
||||
wxLogLastError(wxT("SelectObject(hfont)"));
|
||||
}
|
||||
|
||||
// find the width of the widest line
|
||||
int maxWidth = 0;
|
||||
wxStringTokenizer tokenizer(m_text, wxT("\n"));
|
||||
while ( tokenizer.HasMoreTokens() )
|
||||
{
|
||||
const wxString token = tokenizer.GetNextToken();
|
||||
|
||||
SIZE sz;
|
||||
if ( !::GetTextExtentPoint32(hdc, token.t_str(),
|
||||
token.length(), &sz) )
|
||||
{
|
||||
wxLogLastError(wxT("GetTextExtentPoint32"));
|
||||
}
|
||||
|
||||
if ( sz.cx > maxWidth )
|
||||
maxWidth = sz.cx;
|
||||
}
|
||||
|
||||
// limit size to ms_maxWidth, if set
|
||||
if ( ms_maxWidth == 0 )
|
||||
{
|
||||
// this is more or less arbitrary but seems to work well
|
||||
static const int DEFAULT_MAX_WIDTH = 400;
|
||||
|
||||
ms_maxWidth = wxGetClientDisplayRect().width / 2;
|
||||
|
||||
if ( ms_maxWidth > DEFAULT_MAX_WIDTH )
|
||||
ms_maxWidth = DEFAULT_MAX_WIDTH;
|
||||
}
|
||||
|
||||
if ( ms_maxWidth != -1 && maxWidth > ms_maxWidth )
|
||||
maxWidth = ms_maxWidth;
|
||||
|
||||
// only set a new width if it is bigger than the current setting:
|
||||
// otherwise adding a tooltip with shorter line(s) than a previous
|
||||
// one would result in breaking the longer lines unnecessarily as
|
||||
// all our tooltips share the same maximal width
|
||||
if ( maxWidth > SendTooltipMessage(GetToolTipCtrl(),
|
||||
TTM_GETMAXTIPWIDTH, 0) )
|
||||
{
|
||||
SendTooltipMessage(GetToolTipCtrl(), TTM_SETMAXTIPWIDTH,
|
||||
wxUIntToPtr(maxWidth));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
MemoryHDC hdc;
|
||||
if ( !hdc )
|
||||
{
|
||||
wxLogLastError(wxT("CreateCompatibleDC(NULL)"));
|
||||
}
|
||||
|
||||
if ( !SelectObject(hdc, hfont) )
|
||||
{
|
||||
wxLogLastError(wxT("SelectObject(hfont)"));
|
||||
}
|
||||
|
||||
// find the width of the widest line
|
||||
int maxWidth = 0;
|
||||
wxStringTokenizer tokenizer(m_text, wxT("\n"));
|
||||
while ( tokenizer.HasMoreTokens() )
|
||||
{
|
||||
const wxString token = tokenizer.GetNextToken();
|
||||
|
||||
SIZE sz;
|
||||
if ( !::GetTextExtentPoint32(hdc, token.t_str(),
|
||||
token.length(), &sz) )
|
||||
{
|
||||
wxLogLastError(wxT("GetTextExtentPoint32"));
|
||||
}
|
||||
|
||||
if ( sz.cx > maxWidth )
|
||||
maxWidth = sz.cx;
|
||||
}
|
||||
|
||||
// limit size to ms_maxWidth, if set
|
||||
if ( ms_maxWidth == 0 )
|
||||
{
|
||||
// this is more or less arbitrary but seems to work well
|
||||
static const int DEFAULT_MAX_WIDTH = 400;
|
||||
|
||||
ms_maxWidth = wxGetClientDisplayRect().width / 2;
|
||||
|
||||
if ( ms_maxWidth > DEFAULT_MAX_WIDTH )
|
||||
ms_maxWidth = DEFAULT_MAX_WIDTH;
|
||||
}
|
||||
|
||||
if ( ms_maxWidth != -1 && maxWidth > ms_maxWidth )
|
||||
maxWidth = ms_maxWidth;
|
||||
|
||||
// only set a new width if it is bigger than the current setting:
|
||||
// otherwise adding a tooltip with shorter line(s) than a previous
|
||||
// one would result in breaking the longer lines unnecessarily as
|
||||
// all our tooltips share the same maximal width
|
||||
if ( maxWidth > SendTooltipMessage(GetToolTipCtrl(),
|
||||
TTM_GETMAXTIPWIDTH, 0) )
|
||||
{
|
||||
SendTooltipMessage(GetToolTipCtrl(), TTM_SETMAXTIPWIDTH,
|
||||
wxUIntToPtr(maxWidth));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void wxToolTip::DoForAllWindows(void (wxToolTip::*func)(WXHWND))
|
||||
|
@@ -1078,44 +1078,28 @@ bool wxTopLevelWindowMSW::EnableMinimizeButton(bool enable)
|
||||
|
||||
void wxTopLevelWindowMSW::RequestUserAttention(int flags)
|
||||
{
|
||||
#if defined(FLASHW_STOP) && wxUSE_DYNLIB_CLASS
|
||||
// available in the headers, check if it is supported by the system
|
||||
typedef BOOL (WINAPI *FlashWindowEx_t)(FLASHWINFO *pfwi);
|
||||
static FlashWindowEx_t s_pfnFlashWindowEx = NULL;
|
||||
if ( !s_pfnFlashWindowEx )
|
||||
#if defined(FLASHW_STOP)
|
||||
WinStruct<FLASHWINFO> fwi;
|
||||
fwi.hwnd = GetHwnd();
|
||||
fwi.dwFlags = FLASHW_ALL;
|
||||
if ( flags & wxUSER_ATTENTION_INFO )
|
||||
{
|
||||
wxDynamicLibrary dllUser32(wxT("user32.dll"));
|
||||
s_pfnFlashWindowEx = (FlashWindowEx_t)
|
||||
dllUser32.GetSymbol(wxT("FlashWindowEx"));
|
||||
|
||||
// we can safely unload user32.dll here, it's going to remain loaded as
|
||||
// long as the program is running anyhow
|
||||
// just flash a few times
|
||||
fwi.uCount = 3;
|
||||
}
|
||||
else // wxUSER_ATTENTION_ERROR
|
||||
{
|
||||
// flash until the user notices it
|
||||
fwi.dwFlags |= FLASHW_TIMERNOFG;
|
||||
}
|
||||
|
||||
if ( s_pfnFlashWindowEx )
|
||||
{
|
||||
WinStruct<FLASHWINFO> fwi;
|
||||
fwi.hwnd = GetHwnd();
|
||||
fwi.dwFlags = FLASHW_ALL;
|
||||
if ( flags & wxUSER_ATTENTION_INFO )
|
||||
{
|
||||
// just flash a few times
|
||||
fwi.uCount = 3;
|
||||
}
|
||||
else // wxUSER_ATTENTION_ERROR
|
||||
{
|
||||
// flash until the user notices it
|
||||
fwi.dwFlags |= FLASHW_TIMERNOFG;
|
||||
}
|
||||
|
||||
s_pfnFlashWindowEx(&fwi);
|
||||
}
|
||||
else // FlashWindowEx() not available
|
||||
#endif // FlashWindowEx() defined
|
||||
::FlashWindowEx(&fwi);
|
||||
#else
|
||||
{
|
||||
wxUnusedVar(flags);
|
||||
::FlashWindow(GetHwnd(), TRUE);
|
||||
}
|
||||
#endif // defined(FLASHW_STOP)
|
||||
}
|
||||
|
||||
wxMenu *wxTopLevelWindowMSW::MSWGetSystemMenu() const
|
||||
@@ -1157,28 +1141,6 @@ wxMenu *wxTopLevelWindowMSW::MSWGetSystemMenu() const
|
||||
|
||||
bool wxTopLevelWindowMSW::SetTransparent(wxByte alpha)
|
||||
{
|
||||
#if wxUSE_DYNLIB_CLASS
|
||||
typedef DWORD (WINAPI *PSETLAYEREDWINDOWATTR)(HWND, DWORD, BYTE, DWORD);
|
||||
static PSETLAYEREDWINDOWATTR
|
||||
pSetLayeredWindowAttributes = (PSETLAYEREDWINDOWATTR)-1;
|
||||
|
||||
if ( pSetLayeredWindowAttributes == (PSETLAYEREDWINDOWATTR)-1 )
|
||||
{
|
||||
wxDynamicLibrary dllUser32(wxT("user32.dll"));
|
||||
|
||||
// use RawGetSymbol() and not GetSymbol() to avoid error messages under
|
||||
// Windows 95: there is nothing the user can do about this anyhow
|
||||
pSetLayeredWindowAttributes = (PSETLAYEREDWINDOWATTR)
|
||||
dllUser32.RawGetSymbol(wxT("SetLayeredWindowAttributes"));
|
||||
|
||||
// it's ok to destroy dllUser32 here, we link statically to user32.dll
|
||||
// anyhow so it won't be unloaded
|
||||
}
|
||||
|
||||
if ( !pSetLayeredWindowAttributes )
|
||||
return false;
|
||||
#endif // wxUSE_DYNLIB_CLASS
|
||||
|
||||
LONG exstyle = GetWindowLong(GetHwnd(), GWL_EXSTYLE);
|
||||
|
||||
// if setting alpha to fully opaque then turn off the layered style
|
||||
@@ -1189,14 +1151,12 @@ bool wxTopLevelWindowMSW::SetTransparent(wxByte alpha)
|
||||
return true;
|
||||
}
|
||||
|
||||
#if wxUSE_DYNLIB_CLASS
|
||||
// Otherwise, set the layered style if needed and set the alpha value
|
||||
if ((exstyle & WS_EX_LAYERED) == 0 )
|
||||
SetWindowLong(GetHwnd(), GWL_EXSTYLE, exstyle | WS_EX_LAYERED);
|
||||
|
||||
if ( pSetLayeredWindowAttributes(GetHwnd(), 0, (BYTE)alpha, LWA_ALPHA) )
|
||||
if ( ::SetLayeredWindowAttributes(GetHwnd(), 0, (BYTE)alpha, LWA_ALPHA) )
|
||||
return true;
|
||||
#endif // wxUSE_DYNLIB_CLASS
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@@ -763,8 +763,7 @@ bool wxTreeCtrl::Create(wxWindow *parent,
|
||||
|
||||
if ( m_windowStyle & wxTR_FULL_ROW_HIGHLIGHT )
|
||||
{
|
||||
if ( wxApp::GetComCtl32Version() >= 471 )
|
||||
wstyle |= TVS_FULLROWSELECT;
|
||||
wstyle |= TVS_FULLROWSELECT;
|
||||
}
|
||||
|
||||
#if defined(TVS_INFOTIP)
|
||||
|
@@ -29,10 +29,11 @@
|
||||
#include "wx/utils.h"
|
||||
#endif //WX_PRECOMP
|
||||
|
||||
#include "wx/dynlib.h"
|
||||
|
||||
#include "wx/msw/private.h" // includes <windows.h>
|
||||
|
||||
#include "wx/msw/wrapwin.h"
|
||||
#include <Shlwapi.h>
|
||||
|
||||
// ============================================================================
|
||||
// implementation
|
||||
// ============================================================================
|
||||
@@ -264,34 +265,7 @@ void wxDrawLine(HDC hdc, int x1, int y1, int x2, int y2)
|
||||
|
||||
extern bool wxEnableFileNameAutoComplete(HWND hwnd)
|
||||
{
|
||||
#if wxUSE_DYNLIB_CLASS
|
||||
typedef HRESULT (WINAPI *SHAutoComplete_t)(HWND, DWORD);
|
||||
|
||||
static SHAutoComplete_t s_pfnSHAutoComplete = NULL;
|
||||
static bool s_initialized = false;
|
||||
|
||||
if ( !s_initialized )
|
||||
{
|
||||
s_initialized = true;
|
||||
|
||||
wxLogNull nolog;
|
||||
wxDynamicLibrary dll(wxT("shlwapi.dll"));
|
||||
if ( dll.IsLoaded() )
|
||||
{
|
||||
s_pfnSHAutoComplete =
|
||||
(SHAutoComplete_t)dll.GetSymbol(wxT("SHAutoComplete"));
|
||||
if ( s_pfnSHAutoComplete )
|
||||
{
|
||||
// won't be unloaded until the process termination, no big deal
|
||||
dll.Detach();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !s_pfnSHAutoComplete )
|
||||
return false;
|
||||
|
||||
HRESULT hr = s_pfnSHAutoComplete(hwnd, 0x10 /* SHACF_FILESYS_ONLY */);
|
||||
HRESULT hr = ::SHAutoComplete(hwnd, 0x10 /* SHACF_FILESYS_ONLY */);
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
wxLogApiError(wxT("SHAutoComplete"), hr);
|
||||
@@ -299,8 +273,4 @@ extern bool wxEnableFileNameAutoComplete(HWND hwnd)
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
wxUnusedVar(hwnd);
|
||||
return false;
|
||||
#endif // wxUSE_DYNLIB_CLASS/!wxUSE_DYNLIB_CLASS
|
||||
}
|
||||
|
@@ -637,24 +637,6 @@ wxWindowMSW::MSWShowWithEffect(bool show,
|
||||
if ( !wxWindowBase::Show(show) )
|
||||
return false;
|
||||
|
||||
typedef BOOL (WINAPI *AnimateWindow_t)(HWND, DWORD, DWORD);
|
||||
|
||||
static AnimateWindow_t s_pfnAnimateWindow = NULL;
|
||||
static bool s_initDone = false;
|
||||
if ( !s_initDone )
|
||||
{
|
||||
wxDynamicLibrary dllUser32(wxT("user32.dll"), wxDL_VERBATIM | wxDL_QUIET);
|
||||
wxDL_INIT_FUNC(s_pfn, AnimateWindow, dllUser32);
|
||||
|
||||
s_initDone = true;
|
||||
|
||||
// notice that it's ok to unload user32.dll here as it won't be really
|
||||
// unloaded, being still in use because we link to it statically too
|
||||
}
|
||||
|
||||
if ( !s_pfnAnimateWindow )
|
||||
return Show(show);
|
||||
|
||||
// Show() has a side effect of sending a WM_SIZE to the window, which helps
|
||||
// ensuring that it's laid out correctly, but AnimateWindow() doesn't do
|
||||
// this so send the event ourselves
|
||||
@@ -719,7 +701,7 @@ wxWindowMSW::MSWShowWithEffect(bool show,
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !(*s_pfnAnimateWindow)(GetHwnd(), timeout, dwFlags) )
|
||||
if ( !::AnimateWindow(GetHwnd(), timeout, dwFlags) )
|
||||
{
|
||||
wxLogLastError(wxT("AnimateWindow"));
|
||||
|
||||
|
Reference in New Issue
Block a user