int wxRadioBox::GetItemFromPoint(const wxPoint& pt) const
{
    const unsigned int count = GetCount();
#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
    for ( unsigned int i = 0; i < count; i++ )
    {
        RECT rect = wxGetWindowRect((*m_radioButtons)[i]);

        if ( rect.left <= pt.x && pt.x < rect.right &&
                rect.top  <= pt.y && pt.y < rect.bottom )
        {
            return i;
        }
    }

    return wxNOT_FOUND;
}
Beispiel #2
0
UINT_PTR APIENTRY
wxFileDialogHookFunction(HWND      hDlg,
                         UINT      iMsg,
                         WPARAM    WXUNUSED(wParam),
                         LPARAM    lParam)
{
    switch ( iMsg )
    {
#ifndef __WXWINCE__
    case WM_INITDIALOG:
    {
        OPENFILENAME* ofn = reinterpret_cast<OPENFILENAME *>(lParam);
        reinterpret_cast<wxFileDialog *>(ofn->lCustData)
        ->MSWOnInitDialogHook((WXHWND)hDlg);
    }
    break;
#endif // __WXWINCE__

    case WM_NOTIFY:
    {
        NMHDR* const pNM = reinterpret_cast<NMHDR*>(lParam);
        if ( pNM->code > CDN_LAST && pNM->code <= CDN_FIRST )
        {
            OFNOTIFY* const
            pNotifyCode = reinterpret_cast<OFNOTIFY *>(lParam);
            wxFileDialog* const
            dialog = reinterpret_cast<wxFileDialog *>(
                         pNotifyCode->lpOFN->lCustData
                     );

            switch ( pNotifyCode->hdr.code )
            {
            case CDN_INITDONE:
                dialog->MSWOnInitDone((WXHWND)hDlg);
                break;

            case CDN_SELCHANGE:
                dialog->MSWOnSelChange((WXHWND)hDlg);
                break;
            }
        }
    }
    break;

    case WM_DESTROY:
        // reuse the position used for the dialog the next time by default
        //
        // NB: at least under Windows 2003 this is useless as after the
        //     first time it's shown the dialog always remembers its size
        //     and position itself and ignores any later SetWindowPos calls
        wxCopyRECTToRect(wxGetWindowRect(::GetParent(hDlg)), gs_rectDialog);
        break;
    }

    // do the default processing
    return 0;
}
Beispiel #3
0
// generate an artificial resize event
void wxFrame::SendSizeEvent()
{
    if ( !m_iconized )
    {
        RECT r = wxGetWindowRect(GetHwnd());

        (void)::PostMessage(GetHwnd(), WM_SIZE,
                            IsMaximized() ? SIZE_MAXIMIZED : SIZE_RESTORED,
                            MAKELPARAM(r.right - r.left, r.bottom - r.top));
    }
}
Beispiel #4
0
void wxDialog::ResizeGripper()
{
    wxASSERT_MSG( m_hGripper, wxT("shouldn't be called if we have no gripper") );

    HWND hwndGripper = (HWND)m_hGripper;

    const wxRect rectGripper = wxRectFromRECT(wxGetWindowRect(hwndGripper));
    const wxSize size = GetClientSize() - rectGripper.GetSize();

    ::SetWindowPos(hwndGripper, HWND_BOTTOM,
                   size.x, size.y,
                   rectGripper.width, rectGripper.height,
                   SWP_NOACTIVATE);
}
Beispiel #5
0
int wxRadioBox::GetItemFromPoint(const wxPoint& pt) const
{
    const unsigned int count = GetCount();
    for ( unsigned int i = 0; i < count; i++ )
    {
        RECT rect = wxGetWindowRect((*m_radioButtons)[i]);

        if ( rect.left <= pt.x && pt.x < rect.right &&
                rect.top  <= pt.y && pt.y < rect.bottom )
        {
            return i;
        }
    }

    return wxNOT_FOUND;
}
bool
wxNativeWindow::Create(wxWindow* parent,
                       wxWindowID winid,
                       wxNativeWindowHandle hwnd)
{
    wxCHECK_MSG( hwnd, false, wxS("Invalid null HWND") );
    wxCHECK_MSG( parent, false, wxS("Must have a valid parent") );
    wxASSERT_MSG( ::GetParent(hwnd) == GetHwndOf(parent),
                  wxS("The native window has incorrect parent") );

    const wxRect r = wxRectFromRECT(wxGetWindowRect(hwnd));

    // Skip wxWindow::Create() which would try to create a new HWND, we don't
    // want this as we already have one.
    if ( !CreateBase(parent, winid,
                     r.GetPosition(), r.GetSize(),
                     0, wxDefaultValidator, wxS("nativewindow")) )
        return false;

    parent->AddChild(this);

    SubclassWin(hwnd);

    if ( winid == wxID_ANY )
    {
        // We allocated a new ID to the control, use it at Windows level as
        // well because we assume that our and MSW IDs are the same in many
        // places and it seems prudent to avoid breaking this assumption.
        SetId(GetId());
    }
    else // We used a fixed ID.
    {
        // For the same reason as above, check that it's the same as the one
        // used by the native HWND.
        wxASSERT_MSG( ::GetWindowLong(hwnd, GWL_ID) == winid,
                      wxS("Mismatch between wx and native IDs") );
    }

    InheritAttributes();

    return true;
}
Beispiel #7
0
// generate an artificial resize event
void wxFrame::SendSizeEvent(int flags)
{
    if ( !m_iconized )
    {
        RECT r = wxGetWindowRect(GetHwnd());

        if ( flags & wxSEND_EVENT_POST )
        {
            ::PostMessage(GetHwnd(), WM_SIZE,
                          IsMaximized() ? SIZE_MAXIMIZED : SIZE_RESTORED,
                          MAKELPARAM(r.right - r.left, r.bottom - r.top));
        }
        else // send it
        {
            ::SendMessage(GetHwnd(), WM_SIZE,
                          IsMaximized() ? SIZE_MAXIMIZED : SIZE_RESTORED,
                          MAKELPARAM(r.right - r.left, r.bottom - r.top));
        }
    }
}
Beispiel #8
0
bool wxSpinCtrl::Reparent(wxWindowBase *newParent)
{
    // Reparenting both the updown control and its buddy does not seem to work:
    // they continue to be connected somehow, but visually there is no feedback
    // on the buddy edit control. To avoid this problem, we reparent the buddy
    // window normally, but we recreate the updown control and reassign its
    // buddy.

    if ( !wxWindowBase::Reparent(newParent) )
        return false;

    newParent->GetChildren().DeleteObject(this);

    // preserve the old values
    const wxSize size = GetSize();
    int value = GetValue();
    const wxRect btnRect = wxRectFromRECT(wxGetWindowRect(GetHwnd()));

    // destroy the old spin button
    UnsubclassWin();
    if ( !::DestroyWindow(GetHwnd()) )
    {
        wxLogLastError(wxT("DestroyWindow"));
    }

    // create and initialize the new one
    if ( !wxSpinButton::Create(GetParent(), GetId(),
                               btnRect.GetPosition(), btnRect.GetSize(),
                               GetWindowStyle(), GetName()) )
        return false;

    SetValue(value);
    SetRange(m_min, m_max);
    SetInitialSize(size);

    // associate it with the buddy control again
    ::SetParent(GetBuddyHwnd(), GetHwndOf(GetParent()));
    (void)::SendMessage(GetHwnd(), UDM_SETBUDDY, (WPARAM)GetBuddyHwnd(), 0);

    return true;
}
Beispiel #9
0
UINT_PTR APIENTRY
wxFileDialogHookFunction(HWND      hDlg,
                         UINT      iMsg,
                         WPARAM    WXUNUSED(wParam),
                         LPARAM    lParam)
{
    switch ( iMsg )
    {
        case WM_NOTIFY:
            {
                OFNOTIFY *pNotifyCode = wx_reinterpret_cast(OFNOTIFY *, lParam);
                if ( pNotifyCode->hdr.code == CDN_INITDONE )
                {
                    // note that we need to move the parent window: hDlg is a
                    // child of it when OFN_EXPLORER is used
                    ::SetWindowPos
                      (
                        ::GetParent(hDlg),
                        HWND_TOP,
                        gs_rectDialog.x, gs_rectDialog.y,
                        0, 0,
                        SWP_NOZORDER | SWP_NOSIZE
                      );
                 }
            }
            break;

        case WM_DESTROY:
            // reuse the position used for the dialog the next time by default
            //
            // NB: at least under Windows 2003 this is useless as after the
            //     first time it's shown the dialog always remembers its size
            //     and position itself and ignores any later SetWindowPos calls
            wxCopyRECTToRect(wxGetWindowRect(::GetParent(hDlg)), gs_rectDialog);
            break;
    }

    // do the default processing
    return 0;
}
Beispiel #10
0
bool wxTopLevelWindowMSW::ShowFullScreen(bool show, long style)
{
    if ( show == IsFullScreen() )
    {
        // nothing to do
        return true;
    }

    m_fsIsShowing = show;

    if ( show )
    {
        m_fsStyle = style;

        // zap the frame borders

        // save the 'normal' window style
        m_fsOldWindowStyle = GetWindowLong(GetHwnd(), GWL_STYLE);

        // save the old position, width & height, maximize state
        m_fsOldSize = GetRect();
        m_fsIsMaximized = IsMaximized();

        // decide which window style flags to turn off
        LONG newStyle = m_fsOldWindowStyle;
        LONG offFlags = 0;

        if (style & wxFULLSCREEN_NOBORDER)
        {
            offFlags |= WS_BORDER;
#ifndef __WXWINCE__
            offFlags |= WS_THICKFRAME;
#endif
        }
        if (style & wxFULLSCREEN_NOCAPTION)
            offFlags |= WS_CAPTION | WS_SYSMENU;

        newStyle &= ~offFlags;

        // Full screen windows should logically be popups as they don't have
        // decorations (and are definitely not children) and while not using
        // this style doesn't seem to make any difference for most windows, it
        // breaks wxGLCanvas in some cases, see #15434, so just always use it.
        newStyle |= WS_POPUP;

        // change our window style to be compatible with full-screen mode
        ::SetWindowLong(GetHwnd(), GWL_STYLE, newStyle);

        wxRect rect;
#if wxUSE_DISPLAY
        // resize to the size of the display containing us
        int dpy = wxDisplay::GetFromWindow(this);
        if ( dpy != wxNOT_FOUND )
        {
            rect = wxDisplay(dpy).GetGeometry();
        }
        else // fall back to the main desktop
#endif // wxUSE_DISPLAY
        {
            // resize to the size of the desktop
            wxCopyRECTToRect(wxGetWindowRect(::GetDesktopWindow()), rect);
#ifdef __WXWINCE__
            // FIXME: size of the bottom menu (toolbar)
            // should be taken in account
            rect.height += rect.y;
            rect.y       = 0;
#endif
        }

        SetSize(rect);

        // now flush the window style cache and actually go full-screen
        long flags = SWP_FRAMECHANGED;

        // showing the frame full screen should also show it if it's still
        // hidden
        if ( !IsShown() )
        {
            // don't call wxWindow version to avoid flicker from calling
            // ::ShowWindow() -- we're going to show the window at the correct
            // location directly below -- but do call the wxWindowBase version
            // to sync the internal m_isShown flag
            wxWindowBase::Show();

            flags |= SWP_SHOWWINDOW;
        }

        SetWindowPos(GetHwnd(), HWND_TOP,
                     rect.x, rect.y, rect.width, rect.height,
                     flags);

#if !defined(__HANDHELDPC__) && (defined(__WXWINCE__) && (_WIN32_WCE < 400))
        ::SHFullScreen(GetHwnd(), SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON);
#endif

        // finally send an event allowing the window to relayout itself &c
        wxSizeEvent event(rect.GetSize(), GetId());
        event.SetEventObject(this);
        HandleWindowEvent(event);
    }
    else // stop showing full screen
    {
#if !defined(__HANDHELDPC__) && (defined(__WXWINCE__) && (_WIN32_WCE < 400))
        ::SHFullScreen(GetHwnd(), SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON);
#endif
        Maximize(m_fsIsMaximized);
        SetWindowLong(GetHwnd(),GWL_STYLE, m_fsOldWindowStyle);
        SetWindowPos(GetHwnd(),HWND_TOP,m_fsOldSize.x, m_fsOldSize.y,
            m_fsOldSize.width, m_fsOldSize.height, SWP_FRAMECHANGED);
    }

    return true;
}
Beispiel #11
0
void wxMessageDialog::AdjustButtonLabels()
{
    // changing the button labels is the easy part but we also need to ensure
    // that the buttons are big enough for the label strings and increase their
    // size (and maybe the size of the message box itself) if they are not

    // TODO-RTL: check whether this works correctly in RTL

    // we want to use this font in GetTextExtent() calls below but we don't
    // want to send WM_SETFONT to the message box, who knows how is it going to
    // react to it (right now it doesn't seem to do anything but what if this
    // changes)
    wxWindowBase::SetFont(GetMessageFont());

    // first iteration: find the widest button and update the buttons labels
    int wBtnOld = 0,            // current buttons width
        wBtnNew = 0;            // required new buttons width
    RECT rcBtn;                 // stores the button height and y positions
    unsigned numButtons = 0;    // total number of buttons in the message box
    unsigned n;
    for ( n = 0; n < WXSIZEOF(ms_buttons); n++ )
    {
        const HWND hwndBtn = ::GetDlgItem(GetHwnd(), ms_buttons[n].id);
        if ( !hwndBtn )
            continue;   // it's ok, not all buttons are always present

        numButtons++;

        const wxString label = (this->*ms_buttons[n].getter)();
        const wxSize sizeLabel = wxWindowBase::GetTextExtent(label);

        // check if the button is big enough for this label
        const RECT rc = wxGetWindowRect(hwndBtn);
        if ( !wBtnOld )
        {
            // initialize wBtnOld using the first button width, all the other
            // ones should have the same one
            wBtnOld = rc.right - rc.left;

            rcBtn = rc; // remember for use below when we reposition the buttons
        }
        else
        {
            wxASSERT_MSG( wBtnOld == rc.right - rc.left,
                          "all buttons are supposed to be of same width" );
        }

        const int widthNeeded = wxMSWButton::GetFittingSize(this, sizeLabel).x;
        if ( widthNeeded > wBtnNew )
            wBtnNew = widthNeeded;

        ::SetWindowText(hwndBtn, label.wx_str());
    }

    if ( wBtnNew <= wBtnOld )
    {
        // all buttons fit, nothing else to do
        return;
    }

    // resize the message box to be wider if needed
    const int wBoxOld = wxGetClientRect(GetHwnd()).right;

    const int CHAR_WIDTH = GetCharWidth();
    const int MARGIN_OUTER = 2*CHAR_WIDTH;  // margin between box and buttons
    const int MARGIN_INNER = CHAR_WIDTH;    // margin between buttons

    RECT rcBox = wxGetWindowRect(GetHwnd());

    const int wAllButtons = numButtons*(wBtnNew + MARGIN_INNER) - MARGIN_INNER;
    int wBoxNew = 2*MARGIN_OUTER + wAllButtons;
    if ( wBoxNew > wBoxOld )
    {
        const int dw = wBoxNew - wBoxOld;
        rcBox.left -= dw/2;
        rcBox.right += dw - dw/2;

        SetWindowRect(GetHwnd(), rcBox);

        // surprisingly, we don't need to resize the static text control, it
        // seems to adjust itself to the new size, at least under Windows 2003
        // (TODO: test if this happens on older Windows versions)
    }
    else // the current width is big enough
    {
        wBoxNew = wBoxOld;
    }


    // finally position all buttons

    // notice that we have to take into account the difference between window
    // and client width
    rcBtn.left = (rcBox.left + rcBox.right - wxGetClientRect(GetHwnd()).right +
                  wBoxNew - wAllButtons) / 2;
    rcBtn.right = rcBtn.left + wBtnNew;

    for ( n = 0; n < WXSIZEOF(ms_buttons); n++ )
    {
        const HWND hwndBtn = ::GetDlgItem(GetHwnd(), ms_buttons[n].id);
        if ( !hwndBtn )
            continue;

        MoveWindowToScreenRect(hwndBtn, rcBtn);

        rcBtn.left += wBtnNew + MARGIN_INNER;
        rcBtn.right += wBtnNew + MARGIN_INNER;
    }
}
Beispiel #12
0
void wxMessageDialog::ReplaceStaticWithEdit()
{
    // check if the message box fits the display
    int nDisplay = wxDisplay::GetFromWindow(this);
    if ( nDisplay == wxNOT_FOUND )
        nDisplay = 0;
    const wxRect rectDisplay = wxDisplay(nDisplay).GetClientArea();

    if ( rectDisplay.Contains(GetRect()) )
    {
        // nothing to do
        return;
    }


    // find the static control to replace: normally there are two of them, the
    // icon and the text itself so search for all of them and ignore the icon
    // ones
    HWND hwndStatic = ::FindWindowEx(GetHwnd(), NULL, wxT("STATIC"), NULL);
    if ( ::GetWindowLong(hwndStatic, GWL_STYLE) & SS_ICON )
        hwndStatic = ::FindWindowEx(GetHwnd(), hwndStatic, wxT("STATIC"), NULL);

    if ( !hwndStatic )
    {
        wxLogDebug("Failed to find the static text control in message box.");
        return;
    }

    // set the right font for GetCharHeight() call below
    wxWindowBase::SetFont(GetMessageFont());

    // put the new edit control at the same place
    RECT rc = wxGetWindowRect(hwndStatic);
    ScreenRectToClient(GetHwnd(), rc);

    // but make it less tall so that the message box fits on the screen: we try
    // to make the message box take no more than 7/8 of the screen to leave
    // some space above and below it
    const int hText = (7*rectDisplay.height)/8 -
                      (
                         2*::GetSystemMetrics(SM_CYFIXEDFRAME) +
                         ::GetSystemMetrics(SM_CYCAPTION) +
                         5*GetCharHeight() // buttons + margins
                      );
    const int dh = (rc.bottom - rc.top) - hText; // vertical space we save
    rc.bottom -= dh;

    // and it also must be wider as it needs a vertical scrollbar (in order
    // to preserve the word wrap, otherwise the number of lines would change
    // and we want the control to look as similar as possible to the original)
    //
    // NB: you would have thought that 2*SM_CXEDGE would be enough but it
    //     isn't, somehow, and the text control breaks lines differently from
    //     the static one so fudge by adding some extra space
    const int dw = ::GetSystemMetrics(SM_CXVSCROLL) +
                        4*::GetSystemMetrics(SM_CXEDGE);
    rc.right += dw;


    // chop of the trailing new line(s) from the message box text, they are
    // ignored by the static control but result in extra lines and hence extra
    // scrollbar position in the edit one
    wxString text(wxGetWindowText(hwndStatic));
    for ( wxString::reverse_iterator i = text.rbegin(); i != text.rend(); ++i )
    {
        if ( *i != '\n' )
        {
            // found last non-newline char, remove everything after it and stop
            text.erase(i.base() + 1, text.end());
            break;
        }
    }

    // do create the new control
    HWND hwndEdit = ::CreateWindow
                      (
                        wxT("EDIT"),
                        wxTextBuffer::Translate(text).wx_str(),
                        WS_CHILD | WS_VSCROLL | WS_VISIBLE |
                        ES_MULTILINE | ES_READONLY | ES_AUTOVSCROLL,
                        rc.left, rc.top,
                        rc.right - rc.left, rc.bottom - rc.top,
                        GetHwnd(),
                        NULL,
                        wxGetInstance(),
                        NULL
                      );

    if ( !hwndEdit )
    {
        wxLogDebug("Creation of replacement edit control failed in message box");
        return;
    }

    // copy the font from the original control
    LRESULT hfont = ::SendMessage(hwndStatic, WM_GETFONT, 0, 0);
    ::SendMessage(hwndEdit, WM_SETFONT, hfont, 0);

    // and get rid of it
    ::DestroyWindow(hwndStatic);


    // shrink and centre the message box vertically and widen it box to account
    // for the extra scrollbar
    RECT rcBox = wxGetWindowRect(GetHwnd());
    const int hMsgBox = rcBox.bottom - rcBox.top - dh;
    rcBox.top = (rectDisplay.height - hMsgBox)/2;
    rcBox.bottom = rcBox.top + hMsgBox + (rectDisplay.height - hMsgBox)%2;
    rcBox.left -= dw/2;
    rcBox.right += dw - dw/2;
    SetWindowRect(GetHwnd(), rcBox);

    // and adjust all the buttons positions
    for ( unsigned n = 0; n < WXSIZEOF(ms_buttons); n++ )
    {
        const HWND hwndBtn = ::GetDlgItem(GetHwnd(), ms_buttons[n].id);
        if ( !hwndBtn )
            continue;   // it's ok, not all buttons are always present

        RECT rc = wxGetWindowRect(hwndBtn);
        rc.top -= dh;
        rc.bottom -= dh;
        rc.left += dw/2;
        rc.right += dw/2;
        MoveWindowToScreenRect(hwndBtn, rc);
    }
}