Working on scrollable window

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/SOC2011_GTK3@68618 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
John Chain
2011-08-10 06:46:03 +00:00
16 changed files with 286 additions and 166 deletions
+1
View File
@@ -467,6 +467,7 @@ GTK:
MSW:
- Added wxGCDC(wxEnhMetaFileDC) ctor (Marcin Wojdyr).
- Added wxTopLevelWindow::MSWGetSystemMenu().
2.9.2: (released 2011-07-05)
-8
View File
@@ -190,14 +190,6 @@ public:
virtual void StartEditor( const wxDataViewItem & item, unsigned int column );
protected:
virtual int GetSelections( wxArrayInt & sel ) const;
virtual void SetSelections( const wxArrayInt & sel );
virtual void Select( int row );
virtual void Unselect( int row );
virtual bool IsSelected( int row ) const;
virtual void SelectRange( int from, int to );
virtual void UnselectRange( int from, int to );
virtual void EnsureVisible( int row, int column );
virtual wxDataViewItem GetItemByRow( unsigned int row ) const;
+6
View File
@@ -351,6 +351,12 @@ static inline GdkWindow* wx_gtk_entry_get_text_window(GtkEntry* entry)
}
#define gtk_entry_get_text_window wx_gtk_entry_get_text_window
static void wx_gtk_widget_set_has_window(GtkWidget* widget, gboolean has_window)
{
gtk_fixed_set_has_window(GTK_FIXED(widget), has_window);
}
#define gtk_widget_set_has_window wx_gtk_widget_set_has_window
// ----------------------------------------------------------------------------
// the following were introduced in GTK+ 2.22
+2
View File
@@ -22,7 +22,9 @@ struct WXDLLIMPEXP_CORE wxPizza
wxBORDER_SIMPLE | wxBORDER_RAISED | wxBORDER_SUNKEN | wxBORDER_THEME };
static GtkWidget* New(long windowStyle = 0);
#if defined(__WXGTK20__) && !defined(__WXGTK30__)
static GType type();
#endif
void move(GtkWidget* widget, int x, int y);
void put(GtkWidget* widget, int x, int y);
void scroll(int dx, int dy);
+16 -1
View File
@@ -61,6 +61,14 @@ public:
virtual void SetTitle(const wxString& title);
// MSW-only methods
// ----------------
// Create a new menu from the given native HMENU. Takes ownership of the
// menu handle and will delete it when this object is destroyed.
static wxMenu *MSWNewFromHMENU(WXHMENU hMenu) { return new wxMenu(hMenu); }
// implementation only from now on
// -------------------------------
@@ -120,7 +128,14 @@ protected:
virtual wxMenuItem* DoRemove(wxMenuItem *item);
private:
// common part of all ctors
// This constructor is private, use MSWNewFromHMENU() to use it.
wxMenu(WXHMENU hMenu);
// Common part of all ctors, it doesn't create a new HMENU.
void InitNoCreate();
// Common part of all ctors except of the one above taking a native menu
// handler: calls InitNoCreate() and also creates a new menu.
void Init();
// common part of Append/Insert (behaves as Append is pos == (size_t)-1)
+17
View File
@@ -77,6 +77,19 @@ public:
virtual bool CanSetTransparent();
// MSW-specific methods
// --------------------
// Return the menu representing the "system" menu of the window. You can
// call wxMenu::AppendWhatever() methods on it but removing items from it
// is in general not a good idea.
//
// The pointer returned by this method belongs to the window and will be
// deleted when the window itself is, do not delete it yourself. May return
// NULL if getting the system menu failed.
wxMenu *MSWGetSystemMenu() const;
// implementation from now on
// --------------------------
@@ -214,6 +227,10 @@ private:
void* m_activateInfo;
#endif
// The system menu: initially NULL but can be set (once) by
// MSWGetSystemMenu(). Owned by this window.
wxMenu *m_menuSystem;
DECLARE_EVENT_TABLE()
wxDECLARE_NO_COPY_CLASS(wxTopLevelWindowMSW);
};
+1 -1
View File
@@ -467,7 +467,7 @@ WX_STRCMP_FUNC(wxStricmp, wxCRT_StricmpA, wxCRT_StricmpW, wxStricmp_String)
// forward-declare the template and implement it below WX_STRCMP_FUNC. OTOH,
// this fails to compile with VC6, so don't do it for VC. It also causes
// problems with GCC visibility in newer GCC versions.
#if !(defined(__VISUALC__) || wxCHECK_GCC_VERSION(3,5)) || defined(__clang__)
#if !(defined(__VISUALC__) || (wxCHECK_GCC_VERSION(3,5) && !wxCHECK_GCC_VERSION(4,7))) || defined(__clang__)
#define wxNEEDS_DECL_BEFORE_TEMPLATE
#endif
+27
View File
@@ -262,6 +262,33 @@ public:
*/
virtual void Maximize(bool maximize = true);
/**
MSW-specific function for accessing the system menu.
Returns a wxMenu pointer representing the system menu of the window
under MSW. The returned wxMenu may be used, if non-@c NULL, to add
extra items to the system menu. The usual @c wxEVT_COMMAND_MENU_SELECTED
events (that can be processed using @c EVT_MENU event table macro) will
then be generated for them. All the other wxMenu methods may be used as
well but notice that they won't allow you to access any standard system
menu items (e.g. they can't be deleted or modified in any way
currently).
Notice that because of the native system limitations the identifiers of
the items added to the system menu must be multiples of 16, otherwise
no events will be generated for them.
The returned pointer must @em not be deleted, it is owned by the window
and will be only deleted when the window itself is destroyed.
This function is not available in the other ports by design, any
occurrences of it in the portable code must be guarded by @code #ifdef
__WXMSW__ @endcode preprocessor guards.
@since 2.9.3
*/
wxMenu *MSWGetSystemMenu() const;
/**
Use a system-dependent way to attract users attention to the window when
it is in background.
+18
View File
@@ -648,6 +648,24 @@ MyFrame::MyFrame(const wxString& title)
// covers our entire client area to avoid jarring colour jumps
SetOwnBackgroundColour(m_canvas->GetBackgroundColour());
#endif // wxUSE_INFOBAR
#ifdef __WXMSW__
// Test MSW-specific function allowing to access the "system" menu.
wxMenu * const menu = MSWGetSystemMenu();
if ( menu )
{
menu->AppendSeparator();
// The ids of the menu commands in MSW system menu must be multiple of
// 16 so we can't use DIALOGS_ABOUTDLG_SIMPLE here because it might not
// satisfy this condition and need to define and connect a separate id.
static const int DIALOGS_SYSTEM_ABOUT = 0x4010;
menu->Append(DIALOGS_SYSTEM_ABOUT, "&About...");
Connect(DIALOGS_SYSTEM_ABOUT, wxEVT_COMMAND_MENU_SELECTED,
wxCommandEventHandler(MyFrame::ShowSimpleAboutDialog));
}
#endif // __WXMSW__
}
MyFrame::~MyFrame()
+1 -1
View File
@@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////////
// Name: printing.cpp
// Name: helpview.cpp
// Purpose: wxHtml sample: help browser
// Author: ?
// Modified by:
+57 -123
View File
@@ -414,10 +414,7 @@ int LINKAGEMODE wxGenericTreeModelItemCmp( void ** id1, void ** id2)
// wxDataViewMainWindow
//-----------------------------------------------------------------------------
WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_SIZE_T(unsigned int, wxDataViewSelection,
WXDLLIMPEXP_ADV);
WX_DECLARE_LIST(wxDataViewItem, ItemList);
WX_DEFINE_LIST(ItemList)
WX_DEFINE_SORTED_ARRAY_SIZE_T(unsigned int, wxDataViewSelection);
class wxDataViewMainWindow: public wxWindow
{
@@ -2009,70 +2006,65 @@ bool wxDataViewMainWindow::ItemDeleted(const wxDataViewItem& parent,
(wxDataViewVirtualListModel*) GetOwner()->GetModel();
m_count = list_model->GetCount();
if( m_currentRow > GetRowCount() )
m_currentRow = m_count - 1;
// TODO: why empty the entire selection?
m_selection.Empty();
UpdateDisplay();
return true;
}
wxDataViewTreeNode * node = FindNode(parent);
// Notice that it is possible that the item being deleted is not in the
// tree at all, for example we could be deleting a never shown (because
// collapsed) item in a tree model. So it's not an error if we don't know
// about this item, just return without doing anything then.
if ( !node || node->GetChildren().Index(item.GetID()) == wxNOT_FOUND )
return false;
int sub = -1;
node->GetChildren().Remove( item.GetID() );
// Manipolate selection
if( m_selection.GetCount() > 1 )
else // general case
{
m_selection.Empty();
}
bool isContainer = false;
wxDataViewTreeNodes nds = node->GetNodes();
for (size_t i = 0; i < nds.GetCount(); i ++)
{
if (nds[i]->GetItem() == item)
wxDataViewTreeNode * node = FindNode(parent);
// Notice that it is possible that the item being deleted is not in the
// tree at all, for example we could be deleting a never shown (because
// collapsed) item in a tree model. So it's not an error if we don't know
// about this item, just return without doing anything then.
if ( !node || node->GetChildren().Index(item.GetID()) == wxNOT_FOUND )
return false;
int sub = -1;
node->GetChildren().Remove( item.GetID() );
// Manipolate selection
if( m_selection.GetCount() > 1 )
{
isContainer = true;
break;
m_selection.Empty();
}
}
if( isContainer )
{
wxDataViewTreeNode * n = NULL;
wxDataViewTreeNodes nodes = node->GetNodes();
int len = nodes.GetCount();
for( int i = 0; i < len; i ++)
bool isContainer = false;
wxDataViewTreeNodes nds = node->GetNodes();
for (size_t i = 0; i < nds.GetCount(); i ++)
{
if( nodes[i]->GetItem() == item )
if (nds[i]->GetItem() == item)
{
n = nodes[i];
isContainer = true;
break;
}
}
if( isContainer )
{
wxDataViewTreeNode * n = NULL;
wxDataViewTreeNodes nodes = node->GetNodes();
int len = nodes.GetCount();
for( int i = 0; i < len; i ++)
{
if( nodes[i]->GetItem() == item )
{
n = nodes[i];
break;
}
}
wxCHECK_MSG( n != NULL, false, "item not found" );
wxCHECK_MSG( n != NULL, false, "item not found" );
node->GetNodes().Remove( n );
sub -= n->GetSubTreeCount();
::DestroyTreeHelper(n);
node->GetNodes().Remove( n );
sub -= n->GetSubTreeCount();
::DestroyTreeHelper(n);
}
// Make the row number invalid and get a new valid one when user call GetRowCount
m_count = -1;
node->ChangeSubTreeCount(sub);
}
// Make the row number invalid and get a new valid one when user call GetRowCount
m_count = -1;
node->ChangeSubTreeCount(sub);
// Change the current row to the last row if the current exceed the max row number
if( m_currentRow > GetRowCount() )
m_currentRow = m_count - 1;
ChangeCurrentRow(m_count - 1);
UpdateDisplay();
@@ -4436,13 +4428,22 @@ int wxDataViewCtrl::GetSelections( wxDataViewItemArray & sel ) const
{
sel.Empty();
wxDataViewSelection selection = m_clientArea->GetSelections();
int len = selection.GetCount();
for( int i = 0; i < len; i ++)
const size_t len = selection.size();
for ( size_t i = 0; i < len; i++ )
{
unsigned int row = selection[i];
sel.Add( m_clientArea->GetItemByRow( row ) );
wxDataViewItem item = m_clientArea->GetItemByRow(selection[i]);
if ( item.IsOk() )
{
sel.Add(item);
}
else
{
wxFAIL_MSG( "invalid item in selection - bad internal state" );
}
}
return len;
return sel.size();
}
void wxDataViewCtrl::SetSelections( const wxDataViewItemArray & sel )
@@ -4506,73 +4507,6 @@ bool wxDataViewCtrl::IsSelected( const wxDataViewItem & item ) const
return false;
}
// Selection code with row number as parameter
int wxDataViewCtrl::GetSelections( wxArrayInt & sel ) const
{
sel.Empty();
wxDataViewSelection selection = m_clientArea->GetSelections();
int len = selection.GetCount();
for( int i = 0; i < len; i ++)
{
unsigned int row = selection[i];
sel.Add( row );
}
return len;
}
void wxDataViewCtrl::SetSelections( const wxArrayInt & sel )
{
wxDataViewSelection selection(wxDataViewSelectionCmp);
int len = sel.GetCount();
for( int i = 0; i < len; i ++ )
{
int row = sel[i];
if( row >= 0 )
selection.Add( static_cast<unsigned int>(row) );
}
m_clientArea->SetSelections( selection );
}
void wxDataViewCtrl::Select( int row )
{
if( row >= 0 )
{
if (m_clientArea->IsSingleSel())
m_clientArea->SelectAllRows(false);
m_clientArea->SelectRow( row, true );
}
}
void wxDataViewCtrl::Unselect( int row )
{
if( row >= 0 )
m_clientArea->SelectRow(row, false);
}
bool wxDataViewCtrl::IsSelected( int row ) const
{
if( row >= 0 )
return m_clientArea->IsRowSelected(row);
return false;
}
void wxDataViewCtrl::SelectRange( int from, int to )
{
wxArrayInt sel;
for( int i = from; i < to; i ++ )
sel.Add( i );
m_clientArea->Select(sel);
}
void wxDataViewCtrl::UnselectRange( int from, int to )
{
wxDataViewSelection sel = m_clientArea->GetSelections();
for( int i = from; i < to; i ++ )
if( sel.Index( i ) != wxNOT_FOUND )
sel.Remove( i );
m_clientArea->SetSelections(sel);
}
void wxDataViewCtrl::SelectAll()
{
m_clientArea->SelectAllRows(true);
+9 -7
View File
@@ -224,10 +224,17 @@ wxSize wxCollapsiblePane::DoGetBestSize() const
req.width = 2;
req.height = 2;
#ifdef __WXGTK30__
// NB: I have to declear this dummy variable 'nat' otherwise get_preferred_height/width
// will crash. But per gtk+ documentation, it seems OK that the third argument be
// NULL (JC)
GtkRequisition nat;
nat.width = 0;
nat.height = 0;
(* GTK_WIDGET_CLASS( GTK_WIDGET_GET_CLASS(m_widget) )->get_preferred_width )
(m_widget, &(req.width), NULL );
(m_widget, &(req.width), &(nat.width) );
(* GTK_WIDGET_CLASS( GTK_WIDGET_GET_CLASS(m_widget) )->get_preferred_height )
(m_widget, &(req.height), NULL );
(m_widget, &(req.height), &(nat.height) );
#else
(* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(m_widget) )->size_request )
(m_widget, &req );
@@ -288,13 +295,8 @@ void wxCollapsiblePane::OnSize(wxSizeEvent &ev)
GdkWindow *wxCollapsiblePane::GTKGetWindow(wxArrayGdkWindows& windows) const
{
GtkWidget *label = gtk_expander_get_label_widget( GTK_EXPANDER(m_widget) );
#ifdef __WXGTK30__
windows.Add( gtk_widget_get_window(label) );
windows.Add( gtk_widget_get_window(m_widget) );
#else
windows.Add( label->window );
windows.Add( m_widget->window );
#endif
return NULL;
}
+25 -10
View File
@@ -31,12 +31,23 @@ static GtkWidgetClass* parent_class;
extern "C" {
struct wxPizzaClass
{
GtkFixedClass parent;
void (*set_scroll_adjustments)(GtkWidget*, GtkAdjustment*, GtkAdjustment*);
};
#ifdef __WXGTK30__
enum {
P_HADJUSTMENT,
P_VADJUSTMENT
};
G_DEFINE_TYPE_WITH_CODE(wxPizza, wxpizza, GTK_TYPE_FIXED,
G_IMPLEMENT_INTERFACE(GTK_TYPE_SCROLLABLE, NULL));
#endif
static void size_allocate(GtkWidget* widget, GtkAllocation* alloc)
{
GtkAllocation allocation;
@@ -212,7 +223,11 @@ g_cclosure_user_marshal_VOID__OBJECT_OBJECT (GClosure *closure,
data2);
}
static void class_init(void* g_class, void*)
#ifdef __WXGTK30__
static void wxpizza_class_init(wxPizzaClass* g_class)
#else
static void wxpizza_class_init(void* g_class, void*)
#endif
{
GtkWidgetClass* widget_class = (GtkWidgetClass*)g_class;
widget_class->size_allocate = size_allocate;
@@ -225,6 +240,11 @@ static void class_init(void* g_class, void*)
klass->set_scroll_adjustments = set_scroll_adjustments;
#ifdef __WXGTK30__
// TODO Make widget appear scrollable to GTK3
GObjectClass *gobject_class = G_OBJECT_CLASS(g_class);
// Override properties
g_object_class_override_property(gobject_class, P_HADJUSTMENT, "hadjustment");
g_object_class_override_property(gobject_class, P_VADJUSTMENT, "vadjustment");
#else
widget_class->set_scroll_adjustments_signal =
g_signal_new(
@@ -242,20 +262,17 @@ static void class_init(void* g_class, void*)
} // extern "C"
#if defined(__WXGTK20__) && !defined(__WXGTK30__)
GType wxPizza::type()
{
#ifdef __WXGTK30__
static GType type;
#else
static GtkType type;
#endif
if (type == 0)
{
const GTypeInfo info = {
sizeof(wxPizzaClass),
NULL, NULL,
class_init,
wxpizza_class_init,
NULL, NULL,
sizeof(wxPizza), 0,
NULL, NULL
@@ -263,8 +280,10 @@ GType wxPizza::type()
type = g_type_register_static(
GTK_TYPE_FIXED, "wxPizza", &info, GTypeFlags(0));
}
return type;
}
#endif
GtkWidget* wxPizza::New(long windowStyle)
{
@@ -275,11 +294,7 @@ GtkWidget* wxPizza::New(long windowStyle)
pizza->m_is_scrollable = (windowStyle & (wxHSCROLL | wxVSCROLL)) != 0;
// mask off border styles not useable with wxPizza
pizza->m_border_style = int(windowStyle & BORDER_STYLES);
#ifdef __WXGTK30__
gtk_widget_set_has_window(widget, true);
#else
gtk_fixed_set_has_window(GTK_FIXED(widget), true);
#endif
gtk_widget_add_events(widget,
GDK_EXPOSURE_MASK |
GDK_SCROLL_MASK |
+1 -1
View File
@@ -1906,7 +1906,7 @@ void wxGDIPlusRenderer::Unload()
if ( m_gditoken )
{
GdiplusShutdown(m_gditoken);
m_gditoken = NULL;
m_gditoken = 0;
}
m_loaded = -1; // next Load() will try again
}
+24 -1
View File
@@ -260,7 +260,7 @@ inline bool IsGreaterThanStdSize(const wxBitmap& bmp)
// ---------------------------------------------------------------------------
// Construct a menu with optional title (then use append)
void wxMenu::Init()
void wxMenu::InitNoCreate()
{
m_radioData = NULL;
m_doBreak = false;
@@ -270,6 +270,11 @@ void wxMenu::Init()
m_maxBitmapWidth = 0;
m_maxAccelWidth = -1;
#endif // wxUSE_OWNER_DRAWN
}
void wxMenu::Init()
{
InitNoCreate();
// create the menu
m_hMenu = (WXHMENU)CreatePopupMenu();
@@ -287,6 +292,24 @@ void wxMenu::Init()
}
}
wxMenu::wxMenu(WXHMENU hMenu)
{
InitNoCreate();
m_hMenu = hMenu;
// Ensure that our internal idea of how many items we have corresponds to
// the real number of items in the menu.
//
// We could also retrieve the real labels of the items here but it doesn't
// seem to be worth the trouble.
const int numExistingItems = ::GetMenuItemCount(m_hMenu);
for ( int n = 0; n < numExistingItems; n++ )
{
wxMenuBase::DoAppend(wxMenuItem::New(this, wxID_SEPARATOR));
}
}
// The wxWindow destructor will take care of deleting the submenus.
wxMenu::~wxMenu()
{
+81 -13
View File
@@ -141,6 +141,8 @@ void wxTopLevelWindowMSW::Init()
m_activateInfo = (void*) info;
#endif
m_menuSystem = NULL;
}
WXDWORD wxTopLevelWindowMSW::MSWGetStyle(long style, WXDWORD *exflags) const
@@ -326,9 +328,9 @@ WXLRESULT wxTopLevelWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WX
WXLRESULT rc = 0;
bool processed = false;
#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
switch ( message )
{
#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
case WM_ACTIVATE:
{
SHACTIVATEINFO* info = (SHACTIVATEINFO*) m_activateInfo;
@@ -355,8 +357,32 @@ WXLRESULT wxTopLevelWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WX
}
break;
}
#endif // __SMARTPHONE__ || __POCKETPC__
case WM_SYSCOMMAND:
// We may need to generate events for the items added to the system
// menu if it had been created (and presumably modified).
if ( m_menuSystem )
{
// From MSDN:
//
// ... the four low-order bits of the wParam parameter are
// used internally by the system. To obtain the correct
// result when testing the value of wParam, an application
// must combine the value 0xFFF0 with the wParam value by
// using the bitwise AND operator.
unsigned id = wParam & 0xfff0;
// SC_SIZE is the first of the system-defined commands and we
// leave those to DefWindowProc().
if ( id < SC_SIZE )
{
if ( m_menuSystem->MSWCommand(0 /* unused anyhow */, id) )
processed = true;
}
}
break;
}
#endif
if ( !processed )
rc = wxTopLevelWindowBase::MSWWindowProc(message, wParam, lParam);
@@ -413,25 +439,26 @@ bool wxTopLevelWindowMSW::CreateDialog(const void *dlgTemplate,
}
#endif // !__WXWINCE__
#if !defined(__WXWINCE__) || defined(__WINCE_STANDARDSDK__)
// move the dialog to its initial position without forcing repainting
int x, y, w, h;
(void)MSWGetCreateWindowCoords(pos, size, x, y, w, h);
if ( x == (int)CW_USEDEFAULT )
{
// centre it on the screen - what else can we do?
wxSize sizeDpy = wxGetDisplaySize();
x = (sizeDpy.x - w) / 2;
y = (sizeDpy.y - h) / 2;
// Let the system position the window, just set its size.
::SetWindowPos(GetHwnd(), 0,
0, 0, w, h,
SWP_NOMOVE | SWP_NOZORDER);
}
#if !defined(__WXWINCE__) || defined(__WINCE_STANDARDSDK__)
if ( !::MoveWindow(GetHwnd(), x, y, w, h, FALSE) )
else // Move the window to the desired location and set its size too.
{
wxLogLastError(wxT("MoveWindow"));
if ( !::MoveWindow(GetHwnd(), x, y, w, h, FALSE) )
{
wxLogLastError(wxT("MoveWindow"));
}
}
#endif
#endif // !__WXWINCE__
if ( !title.empty() )
{
@@ -578,6 +605,8 @@ bool wxTopLevelWindowMSW::Create(wxWindow *parent,
wxTopLevelWindowMSW::~wxTopLevelWindowMSW()
{
delete m_menuSystem;
SendDestroyEvent();
#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
@@ -608,7 +637,13 @@ void wxTopLevelWindowMSW::DoShowWindow(int nShowCmd)
{
::ShowWindow(GetHwnd(), nShowCmd);
m_iconized = nShowCmd == SW_MINIMIZE;
// Hiding the window doesn't change its iconized state.
if ( nShowCmd != SW_HIDE )
{
// Otherwise restoring, maximizing or showing the window normally also
// makes it not iconized and only minimizing it does make it iconized.
m_iconized = nShowCmd == SW_MINIMIZE;
}
}
void wxTopLevelWindowMSW::ShowWithoutActivating()
@@ -1226,6 +1261,39 @@ void wxTopLevelWindowMSW::RequestUserAttention(int flags)
}
}
wxMenu *wxTopLevelWindowMSW::MSWGetSystemMenu() const
{
if ( !m_menuSystem )
{
HMENU hmenu = ::GetSystemMenu(GetHwnd(), FALSE);
if ( !hmenu )
{
wxLogLastError(wxT("GetSystemMenu()"));
return NULL;
}
wxTopLevelWindowMSW * const
self = const_cast<wxTopLevelWindowMSW *>(this);
self->m_menuSystem = wxMenu::MSWNewFromHMENU(hmenu);
// We need to somehow associate this menu with this window to ensure
// that we get events from it. A natural idea would be to pretend that
// it's attached to our menu bar but this wouldn't work if we don't
// have any menu bar which is a common case for applications using
// custom items in the system menu (they mostly do it exactly because
// they don't have any other menus).
//
// So reuse the invoking window pointer instead, this is not exactly
// correct but doesn't seem to have any serious drawbacks.
m_menuSystem->SetInvokingWindow(self);
}
return m_menuSystem;
}
// ----------------------------------------------------------------------------
// Transparency support
// ---------------------------------------------------------------------------
bool wxTopLevelWindowMSW::SetTransparent(wxByte alpha)