Thanks,
Noel
PS: Your 'flat' controls look great!
By using the above code you *will* get shadow to your window, *BUT* you
will also get shadow for every other window which is a subclass of the
same Windows class (not wx class).
So, if you are using this code, let say on a class which is derived from
wxPanel, you will get shadow for every class that is derived from
wxPanel! not only for your class.
To get the proper behavior, the drop shadow style flag (CS_DROPSHADOW),
should be done when registering the class to Windows
So basically, to achieve what you want, you need to derive new class
from wxWindow, and override its CreateMSW. then make your classed derive
this new class:
Your CreateMSW should be something like this:
void wxShadowPopupWindow::CreateMSW()
{
static bool classRegistered = false;
static wxString className( wxT("wxMenuNR") );
if( !classRegistered )
{
// Register class
WNDCLASS wndclass;
wxZeroMemory(wndclass);
// for each class we register one with CS_(V|H)REDRAW style and one
// without for windows created with wxNO_FULL_REDRAW_ON_REPAINT flag
static long styleNoRedraw = CS_DBLCLKS;
#if(_WIN32_WINNT >= 0x0501)
// This style is available from WIN2K and above
styleNoRedraw |= CS_DROPSHADOW;
#endif /* _WIN32_WINNT >= 0x0501 */
// the fields which are common to all classes
wndclass.lpfnWndProc = (WNDPROC)wxWndProc;
wndclass.hInstance = wxhInstance;
wndclass.hCursor = ::LoadCursor((HINSTANCE)NULL, IDC_ARROW);
// register the class for all normal windows
wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wndclass.lpszClassName = className.GetData();
wndclass.style = styleNoRedraw;
if ( !RegisterClass(&wndclass) )
{
wxLogLastError(wxT("RegisterClass"));
}
classRegistered = true;
}
// choose the position/size for the new window
int x, y, w, h;
(void)MSWGetCreateWindowCoords(GetPosition(), GetSize(), x, y, w, h);
// controlId is menu handle for the top level windows, so set it to 0
// unless we're creating a child window
unsigned long controlId = (unsigned long)GetWindowStyleFlag() &
WS_CHILD ? GetId() : 0;
WXDWORD exstyle;
DWORD msflags = MSWGetCreateWindowFlags(&exstyle);
#ifdef __WXUNIVERSAL__
// no borders, we draw them ourselves
exstyle &= ~(WS_EX_DLGMODALFRAME |
WS_EX_STATICEDGE |
WS_EX_CLIENTEDGE |
WS_EX_WINDOWEDGE);
msflags &= ~WS_BORDER;
#endif // wxUniversal
// do create the window
wxWindowCreationHook hook(this);
::DestroyWindow((HWND)m_hWnd);
m_hWnd = (WXHWND)::CreateWindowEx
(
exstyle,
className.GetData(),
wxT("ShadowWindow"),
msflags,
x, y, w, h,
(HWND)MSWGetParent(),
(HMENU)controlId,
wxGetInstance(),
NULL // no extra data
);
if ( !m_hWnd )
{
wxLogSysError(wxT("Can't create window of class wxMenu"));
return;
}
SetHWND( m_hWnd );
}
For GTK:
I tried to find implementation for it for weeks, but could not. I found
a patch to gnome that can do that, but this is not a reasonable solution.
Eran
On X11 systems (as is currently only supported by wxGTK) it is not an
application business to try to add drop shadows to a toplevel.
It is the business of a compositing manager, in coordination with the
window manager (which are in any serious solution the same process)
based on the window type that is set on it, or other means the
compositing manager deems appropriate, including the users desktop-wide
preferences.
Regards,
Mart Raudsepp
For wxFlatMenu, I achieved the same thing by creating a new class
wxShadowPopupWindow which derives from wxPopupWindow and implements its
own CreateMSW function, you can simply use it or convert it to python
Under GTK, this class is a define for wxPopupWindow.
have a look at flat_menu.h and flat_menu.cpp
>> PS: Your 'flat' controls look great!
Thanks
Eran