+// ----------------------------------------------------------------------------
+// Transparency support
+// ---------------------------------------------------------------------------
+
+bool wxTopLevelWindowMSW::SetTransparent(wxByte alpha)
+{
+#if wxUSE_DYNLIB_CLASS
+ typedef DWORD (WINAPI *PSETLAYEREDWINDOWATTR)(HWND, DWORD, BYTE, DWORD);
+ static PSETLAYEREDWINDOWATTR
+ pSetLayeredWindowAttributes = (PSETLAYEREDWINDOWATTR)-1;
+
+ if ( pSetLayeredWindowAttributes == (PSETLAYEREDWINDOWATTR)-1 )
+ {
+ wxDynamicLibrary dllUser32(wxT("user32.dll"));
+
+ // use RawGetSymbol() and not GetSymbol() to avoid error messages under
+ // Windows 95: there is nothing the user can do about this anyhow
+ pSetLayeredWindowAttributes = (PSETLAYEREDWINDOWATTR)
+ dllUser32.RawGetSymbol(wxT("SetLayeredWindowAttributes"));
+
+ // it's ok to destroy dllUser32 here, we link statically to user32.dll
+ // anyhow so it won't be unloaded
+ }
+
+ if ( !pSetLayeredWindowAttributes )
+ return false;
+#endif // wxUSE_DYNLIB_CLASS
+
+ 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;
+ }
+
+#if wxUSE_DYNLIB_CLASS
+ // 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);
+
+ if ( pSetLayeredWindowAttributes(GetHwnd(), 0, (BYTE)alpha, LWA_ALPHA) )
+ return true;
+#endif // wxUSE_DYNLIB_CLASS
+
+ return false;
+}
+
+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 == wxOS_WINDOWS_NT && ver_major >= 5);
+}
+
+void wxTopLevelWindowMSW::DoEnable(bool enable)
+{
+ wxTopLevelWindowBase::DoEnable(enable);
+
+ // Enabling or disabling a window may change its appearance. Unfortunately,
+ // in at least some situation, toplevel windows don't repaint themselves,
+ // so we have to issue explicit refresh to avoid rendering artifacts.
+ //
+ // TODO: find out just what exactly is wrong here
+ Refresh();
+}
+
+void wxTopLevelWindowMSW::DoFreeze()
+{
+ // do nothing: freezing toplevel window causes paint and mouse events
+ // to go through it any TLWs under it, so the best we can do is to freeze
+ // all children -- and wxWindowBase::Freeze() does that
+}
+
+void wxTopLevelWindowMSW::DoThaw()
+{
+ // intentionally empty -- see DoFreeze()
+}
+
+
+// ----------------------------------------------------------------------------
+// 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(wxT("focus"), wxT("wxTLW %p activated."), m_hWnd);
+
+ wxWindow *winFocus = FindFocus();
+ if ( !winFocus || wxGetTopLevelParent(winFocus) != this )
+ {
+ wxWindow *parent = m_winLastFocused ? m_winLastFocused->GetParent()
+ : NULL;
+ if ( !parent )
+ {
+ parent = this;
+ }
+
+ wxSetFocusToChild(parent, &m_winLastFocused);
+ }
+ }
+ else // deactivating
+ {
+ // remember the last focused child if it is our child
+ m_winLastFocused = FindFocus();
+
+ if ( m_winLastFocused )
+ {
+ // let it know that it doesn't have focus any more
+ // But this will already be done via WM_KILLFOCUS, so we'll get two kill
+ // focus events if we call it explicitly.
+ // m_winLastFocused->HandleKillFocus((WXHWND)NULL);
+
+ // and don't remember it if it's a child from some other frame
+ if ( wxGetTopLevelParent(m_winLastFocused) != this )
+ {
+ m_winLastFocused = NULL;
+ }
+ }
+
+ wxLogTrace(wxT("focus"),
+ wxT("wxTLW %p deactivated, last focused: %p."),
+ m_hWnd,
+ m_winLastFocused ? GetHwndOf(m_winLastFocused) : NULL);
+
+ event.Skip();
+ }
+}
+
+// the DialogProc for all wxWidgets dialogs
+LONG APIENTRY _EXPORT
+wxDlgProc(HWND hDlg,
+ UINT message,
+ WPARAM WXUNUSED(wParam),
+ LPARAM WXUNUSED(lParam))
+{
+ switch ( message )
+ {
+ case WM_INITDIALOG:
+ {
+ // under CE, add a "Ok" button in the dialog title bar and make it full
+ // screen
+ //
+ // TODO: find the window for this HWND, and take into account
+ // wxMAXIMIZE and wxCLOSE_BOX. For now, assume both are present.
+ //
+ // Standard SDK doesn't have aygshell.dll: see
+ // include/wx/msw/wince/libraries.h
+#if defined(__WXWINCE__) && !defined(__WINCE_STANDARDSDK__) && !defined(__HANDHELDPC__)
+ SHINITDLGINFO shidi;
+ shidi.dwMask = SHIDIM_FLAGS;
+ shidi.dwFlags = SHIDIF_SIZEDLG // take account of the SIP or menubar
+#ifndef __SMARTPHONE__
+ | SHIDIF_DONEBUTTON
+#endif
+ ;
+ shidi.hDlg = hDlg;
+ SHInitDialog( &shidi );
+#else // no SHInitDialog()
+ wxUnusedVar(hDlg);
+#endif
+ // for WM_INITDIALOG, returning TRUE tells system to set focus to
+ // the first control in the dialog box, but as we set the focus
+ // ourselves, we return FALSE for it as well
+ return FALSE;
+ }
+ }
+
+ // for almost all messages, returning FALSE means that we didn't process
+ // the message
+ return FALSE;
+}
+
+// ============================================================================
+// wxTLWHiddenParentModule implementation
+// ============================================================================
+
+HWND wxTLWHiddenParentModule::ms_hwnd = NULL;
+
+const wxChar *wxTLWHiddenParentModule::ms_className = NULL;
+
+bool wxTLWHiddenParentModule::OnInit()
+{
+ ms_hwnd = NULL;
+ ms_className = NULL;
+
+ return true;
+}
+
+void wxTLWHiddenParentModule::OnExit()
+{
+ if ( ms_hwnd )
+ {
+ if ( !::DestroyWindow(ms_hwnd) )
+ {
+ wxLogLastError(wxT("DestroyWindow(hidden TLW parent)"));
+ }
+
+ ms_hwnd = NULL;
+ }
+
+ if ( ms_className )
+ {
+ if ( !::UnregisterClass(ms_className, wxGetInstance()) )
+ {
+ wxLogLastError(wxT("UnregisterClass(\"wxTLWHiddenParent\")"));
+ }
+
+ ms_className = NULL;
+ }
+}
+
+/* static */
+HWND wxTLWHiddenParentModule::GetHWND()
+{
+ if ( !ms_hwnd )
+ {
+ if ( !ms_className )
+ {
+ static const wxChar *HIDDEN_PARENT_CLASS = wxT("wxTLWHiddenParent");
+
+ WNDCLASS wndclass;
+ wxZeroMemory(wndclass);
+
+ wndclass.lpfnWndProc = DefWindowProc;
+ wndclass.hInstance = wxGetInstance();
+ wndclass.lpszClassName = HIDDEN_PARENT_CLASS;
+
+ if ( !::RegisterClass(&wndclass) )
+ {
+ wxLogLastError(wxT("RegisterClass(\"wxTLWHiddenParent\")"));
+ }
+ else
+ {
+ ms_className = HIDDEN_PARENT_CLASS;
+ }
+ }
+
+ ms_hwnd = ::CreateWindow(ms_className, wxEmptyString, 0, 0, 0, 0, 0, NULL,
+ (HMENU)NULL, wxGetInstance(), NULL);
+ if ( !ms_hwnd )
+ {
+ wxLogLastError(wxT("CreateWindow(hidden TLW parent)"));
+ }
+ }
+
+ return ms_hwnd;
+}