+ SetIcons( wxIconBundle( icon ) );
+}
+
+void wxTopLevelWindowMSW::SetIcons(const wxIconBundle& icons)
+{
+ wxTopLevelWindowBase::SetIcons(icons);
+
+#if !defined(__WXMICROWIN__)
+ const wxIcon& sml = icons.GetIcon( wxSize( 16, 16 ) );
+ if( sml.Ok() && sml.GetWidth() == 16 && sml.GetHeight() == 16 )
+ {
+ ::SendMessage( GetHwndOf( this ), WM_SETICON, ICON_SMALL,
+ (LPARAM)GetHiconOf(sml) );
+ }
+
+ const wxIcon& big = icons.GetIcon( wxSize( 32, 32 ) );
+ if( big.Ok() && big.GetWidth() == 32 && big.GetHeight() == 32 )
+ {
+ ::SendMessage( GetHwndOf( this ), WM_SETICON, ICON_BIG,
+ (LPARAM)GetHiconOf(big) );
+ }
+#endif // !__WXMICROWIN__
+}
+
+bool wxTopLevelWindowMSW::EnableCloseButton(bool enable)
+{
+#if !defined(__WXMICROWIN__)
+ // get system (a.k.a. window) menu
+ HMENU hmenu = GetSystemMenu(GetHwnd(), FALSE /* get it */);
+ if ( !hmenu )
+ {
+ // no system menu at all -- ok if we want to remove the close button
+ // anyhow, but bad if we want to show it
+ return !enable;
+ }
+
+ // enabling/disabling the close item from it also automatically
+ // disables/enables the close title bar button
+ if ( ::EnableMenuItem(hmenu, SC_CLOSE,
+ MF_BYCOMMAND |
+ (enable ? MF_ENABLED : MF_GRAYED)) == -1 )
+ {
+ wxLogLastError(_T("EnableMenuItem(SC_CLOSE)"));
+
+ return false;
+ }
+#ifndef __WXWINCE__
+ // update appearance immediately
+ if ( !::DrawMenuBar(GetHwnd()) )
+ {
+ wxLogLastError(_T("DrawMenuBar"));
+ }
+#endif
+#endif // !__WXMICROWIN__
+
+ return true;
+}
+
+#ifndef __WXWINCE__
+
+bool wxTopLevelWindowMSW::SetShape(const wxRegion& region)
+{
+ wxCHECK_MSG( HasFlag(wxFRAME_SHAPED), false,
+ _T("Shaped windows must be created with the wxFRAME_SHAPED style."));
+
+ // The empty region signifies that the shape should be removed from the
+ // window.
+ if ( region.IsEmpty() )
+ {
+ if (::SetWindowRgn(GetHwnd(), NULL, TRUE) == 0)
+ {
+ wxLogLastError(_T("SetWindowRgn"));
+ return false;
+ }
+ return true;
+ }
+
+ // Windows takes ownership of the region, so
+ // we'll have to make a copy of the region to give to it.
+ DWORD noBytes = ::GetRegionData(GetHrgnOf(region), 0, NULL);
+ RGNDATA *rgnData = (RGNDATA*) new char[noBytes];
+ ::GetRegionData(GetHrgnOf(region), noBytes, rgnData);
+ HRGN hrgn = ::ExtCreateRegion(NULL, noBytes, rgnData);
+ delete[] (char*) rgnData;
+
+ // SetWindowRgn expects the region to be in coordinants
+ // relative to the window, not the client area. Figure
+ // out the offset, if any.
+ RECT rect;
+ DWORD dwStyle = ::GetWindowLong(GetHwnd(), GWL_STYLE);
+ DWORD dwExStyle = ::GetWindowLong(GetHwnd(), GWL_EXSTYLE);
+ ::GetClientRect(GetHwnd(), &rect);
+ ::AdjustWindowRectEx(&rect, dwStyle, FALSE, dwExStyle);
+ ::OffsetRgn(hrgn, -rect.left, -rect.top);
+
+ // Now call the shape API with the new region.
+ if (::SetWindowRgn(GetHwnd(), hrgn, TRUE) == 0)
+ {
+ wxLogLastError(_T("SetWindowRgn"));
+ return false;
+ }
+ return true;
+}
+
+#endif // !__WXWINCE__
+
+void wxTopLevelWindowMSW::RequestUserAttention(int flags)
+{
+ // check if we can use FlashWindowEx(): unfortunately a simple test for
+ // FLASHW_STOP doesn't work because MSVC6 headers do #define it but don't
+ // provide FlashWindowEx() declaration, so try to detect whether we have
+ // real headers for WINVER 0x0500 by checking for existence of a symbol not
+ // declated in MSVC6 header
+#if defined(FLASHW_STOP) && defined(VK_XBUTTON1)
+ // available in the headers, check if it is supported by the system
+ typedef BOOL (WINAPI *FlashWindowEx_t)(FLASHWINFO *pfwi);
+ FlashWindowEx_t s_pfnFlashWindowEx = NULL;
+ if ( !s_pfnFlashWindowEx )
+ {
+ wxDynamicLibrary dllUser32(_T("user32.dll"));
+ s_pfnFlashWindowEx = (FlashWindowEx_t)
+ dllUser32.GetSymbol(_T("FlashWindowEx"));
+
+ // we can safely unload user32.dll here, it's going to remain loaded as
+ // long as the program is running anyhow
+ }
+
+ 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
+ {
+ wxUnusedVar(flags);
+#ifndef __WXWINCE__
+ ::FlashWindow(GetHwnd(), TRUE);
+#endif // __WXWINCE__
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+bool wxTopLevelWindowMSW::SetTransparent(wxByte alpha)
+{
+ typedef DWORD (WINAPI *PSETLAYEREDWINDOWATTR)(HWND, DWORD, BYTE, DWORD);
+ static PSETLAYEREDWINDOWATTR pSetLayeredWindowAttributes = NULL;
+
+ if ( pSetLayeredWindowAttributes == NULL )
+ {
+ wxDynamicLibrary dllUser32(_T("user32.dll"));
+ pSetLayeredWindowAttributes = (PSETLAYEREDWINDOWATTR)
+ dllUser32.GetSymbol(wxT("SetLayeredWindowAttributes"));
+ }
+ if ( pSetLayeredWindowAttributes == NULL )
+ return false;
+
+ LONG exstyle = GetWindowLong(GetHwnd(), GWL_EXSTYLE);
+
+ // if setting alpha to fully opaque then turn off the layered style
+ if (alpha == 255)
+ {
+ SetWindowLong(GetHwnd(), GWL_EXSTYLE, exstyle & ~WS_EX_LAYERED);
+ Refresh();
+ return true;
+ }
+
+ // 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);
+
+ return pSetLayeredWindowAttributes(GetHwnd(), 0, (BYTE)alpha, LWA_ALPHA) != 0;
+}
+
+bool wxTopLevelWindowMSW::CanSetTransparent()
+{
+ // The API is available on win2k and above
+
+ static int os_type = -1;
+ static int ver_major = -1;
+
+ if (os_type == -1)
+ os_type = ::wxGetOsVersion(&ver_major);
+
+ return (os_type == wxWINDOWS_NT && ver_major >= 5);
+}
+
+// ----------------------------------------------------------------------------
+// wxTopLevelWindow event handling
+// ----------------------------------------------------------------------------
+
+// Default activation behaviour - set the focus for the first child
+// subwindow found.
+void wxTopLevelWindowMSW::OnActivate(wxActivateEvent& event)
+{
+ if ( event.GetActive() )
+ {
+ // restore focus to the child which was last focused unless we already
+ // have it
+ wxLogTrace(_T("focus"), _T("wxTLW %08x activated."), (int) m_hWnd);
+
+ wxWindow *winFocus = FindFocus();
+ if ( !winFocus || wxGetTopLevelParent(winFocus) != this )
+ {
+ wxWindow *parent = m_winLastFocused ? m_winLastFocused->GetParent()
+ : NULL;
+ if ( !parent )
+ {
+ parent = this;
+ }