Use more native icons in wxMSW wxArtProvider.
Use SHGetStockIconInfo() and SHGetFileInfo() to look up some icons. Closes #15068. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@73593 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -652,6 +652,7 @@ wxMSW:
|
|||||||
- Add wxIcon::CreateFromHICON() (troelsk).
|
- Add wxIcon::CreateFromHICON() (troelsk).
|
||||||
- Improve wxCURSOR_RIGHT_ARROW appearance (DoltAlya).
|
- Improve wxCURSOR_RIGHT_ARROW appearance (DoltAlya).
|
||||||
- Generate menu highlight events for popup menus in wxDialog (Sam Partington).
|
- Generate menu highlight events for popup menus in wxDialog (Sam Partington).
|
||||||
|
- Return more native shell icons from wxArtProvider (Markus Juergens).
|
||||||
|
|
||||||
wxOSX/Cocoa:
|
wxOSX/Cocoa:
|
||||||
|
|
||||||
|
@@ -22,8 +22,116 @@
|
|||||||
|
|
||||||
#include "wx/artprov.h"
|
#include "wx/artprov.h"
|
||||||
#include "wx/image.h"
|
#include "wx/image.h"
|
||||||
|
#include "wx/dynlib.h"
|
||||||
|
#include "wx/volume.h"
|
||||||
|
#include "wx/msw/private.h"
|
||||||
#include "wx/msw/wrapwin.h"
|
#include "wx/msw/wrapwin.h"
|
||||||
|
|
||||||
|
#ifdef SHGSI_ICON
|
||||||
|
#define wxHAS_SHGetStockIconInfo
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef wxHAS_SHGetStockIconInfo
|
||||||
|
|
||||||
|
SHSTOCKICONID MSWGetStockIconIdForArtProviderId(const wxArtID& art_id)
|
||||||
|
{
|
||||||
|
// try to find an equivalent MSW stock icon id for wxArtID
|
||||||
|
if ( art_id == wxART_ERROR) return SIID_ERROR;
|
||||||
|
else if ( art_id == wxART_QUESTION ) return SIID_HELP;
|
||||||
|
else if ( art_id == wxART_WARNING ) return SIID_WARNING;
|
||||||
|
else if ( art_id == wxART_INFORMATION ) return SIID_INFO;
|
||||||
|
else if ( art_id == wxART_HELP ) return SIID_HELP;
|
||||||
|
else if ( art_id == wxART_FOLDER ) return SIID_FOLDER;
|
||||||
|
else if ( art_id == wxART_FOLDER_OPEN ) return SIID_FOLDEROPEN;
|
||||||
|
else if ( art_id == wxART_DELETE ) return SIID_DELETE;
|
||||||
|
else if ( art_id == wxART_FIND ) return SIID_FIND;
|
||||||
|
else if ( art_id == wxART_HARDDISK ) return SIID_DRIVEFIXED;
|
||||||
|
else if ( art_id == wxART_FLOPPY ) return SIID_DRIVE35;
|
||||||
|
else if ( art_id == wxART_CDROM ) return SIID_DRIVECD;
|
||||||
|
else if ( art_id == wxART_REMOVABLE ) return SIID_DRIVEREMOVE;
|
||||||
|
|
||||||
|
return SIID_INVALID;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// try to load SHGetStockIconInfo dynamically, so this code runs
|
||||||
|
// even on pre-Vista Windows versions
|
||||||
|
HRESULT
|
||||||
|
MSW_SHGetStockIconInfo(SHSTOCKICONID siid,
|
||||||
|
UINT uFlags,
|
||||||
|
SHSTOCKICONINFO *psii)
|
||||||
|
{
|
||||||
|
typedef HRESULT (WINAPI *PSHGETSTOCKICONINFO)(SHSTOCKICONID, UINT, SHSTOCKICONINFO *);
|
||||||
|
static PSHGETSTOCKICONINFO pSHGetStockIconInfo = (PSHGETSTOCKICONINFO)-1;
|
||||||
|
|
||||||
|
if ( pSHGetStockIconInfo == (PSHGETSTOCKICONINFO)-1 )
|
||||||
|
{
|
||||||
|
wxDynamicLibrary shell32(wxT("shell32.dll"));
|
||||||
|
|
||||||
|
pSHGetStockIconInfo = (PSHGETSTOCKICONINFO)shell32.RawGetSymbol( wxT("SHGetStockIconInfo") );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !pSHGetStockIconInfo )
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
return pSHGetStockIconInfo(siid, uFlags, psii);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // #ifdef wxHAS_SHGetStockIconInfo
|
||||||
|
|
||||||
|
wxBitmap
|
||||||
|
MSWGetBitmapForPath(const wxString& path, const wxSize& size, DWORD uFlags = 0)
|
||||||
|
{
|
||||||
|
SHFILEINFO fi;
|
||||||
|
wxZeroMemory(fi);
|
||||||
|
|
||||||
|
uFlags |= SHGFI_USEFILEATTRIBUTES | SHGFI_ICON;
|
||||||
|
if ( size != wxDefaultSize )
|
||||||
|
{
|
||||||
|
if ( size.x <= 16 )
|
||||||
|
uFlags |= SHGFI_SMALLICON;
|
||||||
|
else if ( size.x >= 64 )
|
||||||
|
uFlags |= SHGFI_LARGEICON;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !SHGetFileInfo(path.t_str(), FILE_ATTRIBUTE_DIRECTORY,
|
||||||
|
&fi, sizeof(SHFILEINFO), uFlags) )
|
||||||
|
return wxNullBitmap;
|
||||||
|
|
||||||
|
wxIcon icon;
|
||||||
|
icon.CreateFromHICON((WXHICON)fi.hIcon);
|
||||||
|
|
||||||
|
wxBitmap bitmap(icon);
|
||||||
|
::DestroyIcon(fi.hIcon);
|
||||||
|
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if wxUSE_FSVOLUME
|
||||||
|
|
||||||
|
wxBitmap
|
||||||
|
GetDriveBitmapForVolumeType(const wxFSVolumeKind& volKind, const wxSize& size)
|
||||||
|
{
|
||||||
|
// get all volumes and try to find one with a matching type
|
||||||
|
wxArrayString volumes = wxFSVolume::GetVolumes();
|
||||||
|
for ( size_t i = 0; i < volumes.Count(); i++ )
|
||||||
|
{
|
||||||
|
wxFSVolume vol( volumes[i] );
|
||||||
|
if ( vol.GetKind() == volKind )
|
||||||
|
{
|
||||||
|
return MSWGetBitmapForPath(volumes[i], size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxNullBitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // wxUSE_FSVOLUME
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxWindowsArtProvider
|
// wxWindowsArtProvider
|
||||||
@@ -64,25 +172,86 @@ static wxBitmap CreateFromStdIcon(const char *iconName,
|
|||||||
|
|
||||||
wxBitmap wxWindowsArtProvider::CreateBitmap(const wxArtID& id,
|
wxBitmap wxWindowsArtProvider::CreateBitmap(const wxArtID& id,
|
||||||
const wxArtClient& client,
|
const wxArtClient& client,
|
||||||
const wxSize& WXUNUSED(size))
|
const wxSize& size)
|
||||||
{
|
{
|
||||||
// handle message box icons specially (wxIcon ctor treat these names
|
wxBitmap bitmap;
|
||||||
// as special cases via wxICOResourceHandler::LoadIcon):
|
|
||||||
const char *name = NULL;
|
|
||||||
if ( id == wxART_ERROR )
|
|
||||||
name = "wxICON_ERROR";
|
|
||||||
else if ( id == wxART_INFORMATION )
|
|
||||||
name = "wxICON_INFORMATION";
|
|
||||||
else if ( id == wxART_WARNING )
|
|
||||||
name = "wxICON_WARNING";
|
|
||||||
else if ( id == wxART_QUESTION )
|
|
||||||
name = "wxICON_QUESTION";
|
|
||||||
|
|
||||||
if ( name )
|
#ifdef wxHAS_SHGetStockIconInfo
|
||||||
return CreateFromStdIcon(name, client);
|
// first try to use SHGetStockIconInfo, available only on Vista and higher
|
||||||
|
SHSTOCKICONID stockIconId = MSWGetStockIconIdForArtProviderId( id );
|
||||||
|
if ( stockIconId != SIID_INVALID )
|
||||||
|
{
|
||||||
|
WinStruct<SHSTOCKICONINFO> sii;
|
||||||
|
|
||||||
|
UINT uFlags = SHGSI_ICON;
|
||||||
|
if ( size != wxDefaultSize )
|
||||||
|
{
|
||||||
|
if ( size.x <= 16 )
|
||||||
|
uFlags |= SHGSI_SMALLICON;
|
||||||
|
else if ( size.x >= 64 )
|
||||||
|
uFlags |= SHGSI_LARGEICON;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT res = MSW_SHGetStockIconInfo(stockIconId, uFlags, &sii);
|
||||||
|
if ( res == S_OK )
|
||||||
|
{
|
||||||
|
wxIcon icon;
|
||||||
|
icon.CreateFromHICON( (WXHICON)sii.hIcon );
|
||||||
|
|
||||||
|
wxBitmap bitmap( icon );
|
||||||
|
::DestroyIcon(sii.hIcon);
|
||||||
|
|
||||||
|
if ( bitmap.IsOk() )
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // wxHAS_SHGetStockIconInfo
|
||||||
|
|
||||||
|
|
||||||
|
#if wxUSE_FSVOLUME
|
||||||
|
// now try SHGetFileInfo
|
||||||
|
wxFSVolumeKind volKind = wxFS_VOL_OTHER;
|
||||||
|
if ( id == wxART_HARDDISK )
|
||||||
|
volKind = wxFS_VOL_DISK;
|
||||||
|
else if ( id == wxART_FLOPPY )
|
||||||
|
volKind = wxFS_VOL_FLOPPY;
|
||||||
|
else if ( id == wxART_CDROM )
|
||||||
|
volKind = wxFS_VOL_CDROM;
|
||||||
|
|
||||||
|
if ( volKind != wxFS_VOL_OTHER )
|
||||||
|
{
|
||||||
|
bitmap = GetDriveBitmapForVolumeType(volKind, size);
|
||||||
|
if ( bitmap.IsOk() )
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
#endif // wxUSE_FSVOLUME
|
||||||
|
|
||||||
|
// notice that the directory used here doesn't need to exist
|
||||||
|
if ( id == wxART_FOLDER )
|
||||||
|
bitmap = MSWGetBitmapForPath("C:\\wxdummydir\\", size );
|
||||||
|
else if ( id == wxART_FOLDER_OPEN )
|
||||||
|
bitmap = MSWGetBitmapForPath("C:\\wxdummydir\\", size, SHGFI_OPENICON );
|
||||||
|
|
||||||
|
if ( !bitmap.IsOk() )
|
||||||
|
{
|
||||||
|
// handle message box icons specially (wxIcon ctor treat these names
|
||||||
|
// as special cases via wxICOResourceHandler::LoadIcon):
|
||||||
|
const char *name = NULL;
|
||||||
|
if ( id == wxART_ERROR )
|
||||||
|
name = "wxICON_ERROR";
|
||||||
|
else if ( id == wxART_INFORMATION )
|
||||||
|
name = "wxICON_INFORMATION";
|
||||||
|
else if ( id == wxART_WARNING )
|
||||||
|
name = "wxICON_WARNING";
|
||||||
|
else if ( id == wxART_QUESTION )
|
||||||
|
name = "wxICON_QUESTION";
|
||||||
|
|
||||||
|
if ( name )
|
||||||
|
return CreateFromStdIcon(name, client);
|
||||||
|
}
|
||||||
|
|
||||||
// for anything else, fall back to generic provider:
|
// for anything else, fall back to generic provider:
|
||||||
return wxNullBitmap;
|
return bitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
Reference in New Issue
Block a user