Merge branch 'msw-art-big-icons'

Add support for big icons to the MSW art provider.

See https://github.com/wxWidgets/wxWidgets/pull/1025

Closes #18248.
This commit is contained in:
Vadim Zeitlin
2018-11-20 17:58:19 +01:00
4 changed files with 111 additions and 41 deletions

View File

@@ -31,6 +31,7 @@ Lauri Nurmi <lanurmi@iki.fi> <lauri@ksenos.fi>
Lynn C. Rees <lcrees@gmail.com>
Maarten Bent <MaartenBent@users.noreply.github.com>
Manuel Martin <mmartin@ceyd.es>
Markus Juergens <mj@be-enabled.de> <markusj@trac.wxwidgets.org>
Martin Ettl <ettl.martin78@googlemail.com>
Martin Ettl <ettl.martin78@googlemail.com> <ettl.martin78@gmail.com>
Martin Ettl <ettl.martin78@googlemail.com> <orbitcowboy@web.de>

View File

@@ -126,8 +126,14 @@ static void FillBitmaps(wxImageList *images, wxListCtrl *list,
#include "null.xpm"
const int SIZE_CHOICE_ID = ::wxNewId();
// Bitmap sizes that can be chosen in the size selection wxChoice.
static const int bitmapSizes[] = { -1, 16, 32, 64, 128, 256, 0 };
wxBEGIN_EVENT_TABLE(wxArtBrowserDialog, wxDialog)
EVT_LIST_ITEM_SELECTED(wxID_ANY, wxArtBrowserDialog::OnSelectItem)
EVT_CHOICE(SIZE_CHOICE_ID, wxArtBrowserDialog::OnChangeSize)
EVT_CHOICE(wxID_ANY, wxArtBrowserDialog::OnChooseClient)
wxEND_EVENT_TABLE()
@@ -136,6 +142,8 @@ wxArtBrowserDialog::wxArtBrowserDialog(wxWindow *parent)
wxDefaultPosition, wxDefaultSize,
wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
{
m_currentArtId = wxART_ERROR;
wxSizer *sizer = new wxBoxSizer(wxVERTICAL);
wxSizer *subsizer;
@@ -152,16 +160,28 @@ wxArtBrowserDialog::wxArtBrowserDialog(wxWindow *parent)
m_list = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxSize(250, 300),
wxLC_REPORT | wxSUNKEN_BORDER);
m_list->AppendColumn("wxArtID");
subsizer->Add(m_list, 1, wxEXPAND | wxRIGHT, 10);
subsizer->Add(m_list, 0, wxEXPAND | wxRIGHT, 10);
wxSizer *subsub = new wxBoxSizer(wxVERTICAL);
m_sizes = new wxChoice( this, SIZE_CHOICE_ID );
for ( const int* p = bitmapSizes; *p; ++p )
{
if ( *p == -1 )
m_sizes->Append( "Default" );
else
m_sizes->Append( wxString::Format("%d x %d", *p, *p ) );
}
m_sizes->SetSelection(0);
subsub->Add(m_sizes, 0, wxALL, 4);
m_text = new wxStaticText(this, wxID_ANY, "Size: 333x333");
subsub->Add(m_text);
subsub->Add(m_text, 0, wxALL, 4);
m_canvas = new wxStaticBitmap(this, wxID_ANY, wxBitmap(null_xpm));
subsub->Add(m_canvas);
subsub->Add(100, 100);
subsizer->Add(subsub);
subsub->Add(256, 256);
subsizer->Add(subsub, 1, wxLEFT, 4 );
sizer->Add(subsizer, 1, wxEXPAND | wxLEFT|wxRIGHT, 10);
@@ -176,6 +196,13 @@ wxArtBrowserDialog::wxArtBrowserDialog(wxWindow *parent)
}
wxSize wxArtBrowserDialog::GetSelectedBitmapSize() const
{
const int size = bitmapSizes[m_sizes->GetSelection()];
return wxSize(size, size);
}
void wxArtBrowserDialog::SetArtClient(const wxArtClient& client)
{
wxBusyCursor bcur;
@@ -201,7 +228,13 @@ void wxArtBrowserDialog::SetArtClient(const wxArtClient& client)
void wxArtBrowserDialog::OnSelectItem(wxListEvent &event)
{
const char *data = (const char*)event.GetData();
SetArtBitmap(data, m_client, wxDefaultSize);
m_currentArtId = wxString( data );
SetArtBitmap(data, m_client, GetSelectedBitmapSize());
}
void wxArtBrowserDialog::OnChangeSize(wxCommandEvent& WXUNUSED(event))
{
SetArtBitmap(m_currentArtId, m_client, GetSelectedBitmapSize() );
}
void wxArtBrowserDialog::OnChooseClient(wxCommandEvent &event)

View File

@@ -28,12 +28,17 @@ public:
private:
void OnSelectItem(wxListEvent &event);
void OnChangeSize(wxCommandEvent &event);
void OnChooseClient(wxCommandEvent &event);
wxSize GetSelectedBitmapSize() const;
wxListCtrl *m_list;
wxStaticBitmap *m_canvas;
wxStaticText *m_text;
wxString m_client;
wxChoice *m_sizes;
wxString m_currentArtId;
wxDECLARE_EVENT_TABLE();
};

View File

@@ -25,6 +25,7 @@
#include "wx/volume.h"
#include "wx/msw/private.h"
#include "wx/msw/wrapwin.h"
#include "wx/msw/wrapshl.h"
#ifdef SHGSI_ICON
#define wxHAS_SHGetStockIconInfo
@@ -33,6 +34,39 @@
namespace
{
#ifdef SHDefExtractIcon
#define MSW_SHDefExtractIcon SHDefExtractIcon
#else // !defined(SHDefExtractIcon)
// MinGW doesn't provide SHDefExtractIcon() up to at least the 5.3 version, so
// define it ourselves.
HRESULT
MSW_SHDefExtractIcon(LPCTSTR pszIconFile, int iIndex, UINT uFlags,
HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize)
{
typedef HRESULT
(WINAPI *SHDefExtractIcon_t)(LPCTSTR, int, UINT, HICON*, HICON*, UINT);
static SHDefExtractIcon_t s_SHDefExtractIcon = NULL;
if ( !s_SHDefExtractIcon )
{
wxDynamicLibrary shell32(wxT("shell32.dll"));
wxDL_INIT_FUNC_AW(s_, SHDefExtractIcon, shell32);
if ( !s_SHDefExtractIcon )
return E_FAIL;
// Prevent the DLL from being unloaded while we use its function.
// Normally it's not a problem as shell32.dll is always loaded anyhow.
shell32.Detach();
}
return (*s_SHDefExtractIcon)(pszIconFile, iIndex, uFlags,
phiconLarge, phiconSmall, nIconSize);
}
#endif // !defined(SHDefExtractIcon)
#ifdef wxHAS_SHGetStockIconInfo
SHSTOCKICONID MSWGetStockIconIdForArtProviderId(const wxArtID& art_id)
@@ -51,6 +85,9 @@ SHSTOCKICONID MSWGetStockIconIdForArtProviderId(const wxArtID& art_id)
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;
else if ( art_id == wxART_PRINT ) return SIID_PRINTER;
else if ( art_id == wxART_EXECUTABLE_FILE ) return SIID_APPLICATION;
else if ( art_id == wxART_NORMAL_FILE ) return SIID_DOCNOASSOC;
return SIID_INVALID;
};
@@ -81,32 +118,38 @@ MSW_SHGetStockIconInfo(SHSTOCKICONID siid,
#endif // #ifdef wxHAS_SHGetStockIconInfo
// Wrapper for SHDefExtractIcon().
wxBitmap
MSWGetBitmapFromIconLocation(const TCHAR* path, int index, const wxSize& size)
{
HICON hIcon = NULL;
if ( MSW_SHDefExtractIcon(path, index, 0, &hIcon, NULL, size.x) != S_OK )
return wxNullBitmap;
// Note that using "size.x" twice here is not a typo: normally size.y is
// the same anyhow, of course, but if it isn't, the actual icon size would
// be size.x in both directions as we only pass "x" to SHDefExtractIcon()
// above.
wxIcon icon;
if ( !icon.InitFromHICON((WXHICON)hIcon, size.x, size.x) )
return wxNullBitmap;
return wxBitmap(icon);
}
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;
}
uFlags |= SHGFI_USEFILEATTRIBUTES | SHGFI_ICONLOCATION;
if ( !SHGetFileInfo(path.t_str(), FILE_ATTRIBUTE_DIRECTORY,
&fi, sizeof(SHFILEINFO), uFlags) )
return wxNullBitmap;
return wxNullBitmap;
wxIcon icon;
icon.CreateFromHICON((WXHICON)fi.hIcon);
wxBitmap bitmap(icon);
::DestroyIcon(fi.hIcon);
return bitmap;
return MSWGetBitmapFromIconLocation(fi.szDisplayName, fi.iIcon, size);
}
#if wxUSE_FSVOLUME
@@ -178,33 +221,21 @@ wxBitmap wxWindowsArtProvider::CreateBitmap(const wxArtID& id,
{
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;
}
UINT uFlags = SHGSI_ICONLOCATION | SHGSI_SYSICONINDEX;
HRESULT res = MSW_SHGetStockIconInfo(stockIconId, uFlags, &sii);
if ( res == S_OK )
{
wxIcon icon;
icon.CreateFromHICON( (WXHICON)sii.hIcon );
bitmap = wxBitmap(icon);
::DestroyIcon(sii.hIcon);
const wxSize
sizeNeeded = size.IsFullySpecified()
? size
: wxArtProvider::GetNativeSizeHint(client);
bitmap = MSWGetBitmapFromIconLocation(sii.szPath, sii.iIcon,
sizeNeeded);
if ( bitmap.IsOk() )
{
const wxSize
sizeNeeded = size.IsFullySpecified()
? size
: wxArtProvider::GetNativeSizeHint(client);
if ( sizeNeeded.IsFullySpecified() &&
bitmap.GetSize() != sizeNeeded )
if ( bitmap.GetSize() != sizeNeeded )
{
wxArtProvider::RescaleBitmap(bitmap, sizeNeeded);
}