WXHRGN wxStaticBox::MSWGetRegionWithoutChildren() { RECT rc; ::GetWindowRect(GetHwnd(), &rc); HRGN hrgn = ::CreateRectRgn(rc.left, rc.top, rc.right + 1, rc.bottom + 1); // iterate over all child windows (not just wxWindows but all windows) for ( HWND child = ::GetWindow(GetHwndOf(GetParent()), GW_CHILD); child; child = ::GetWindow(child, GW_HWNDNEXT) ) { if ( ! ::IsWindowVisible(child) ) { // if the window isn't visible then it doesn't need clipped continue; } LONG style = ::GetWindowLong(child, GWL_STYLE); wxString str(wxGetWindowClass(child)); str.UpperCase(); if ( str == wxT("BUTTON") && (style & BS_GROUPBOX) == BS_GROUPBOX ) { // Don't clip any static boxes, not just this one. This will // result in flicker in overlapping static boxes, but at least // they will all be drawn correctly and we shouldn't have // overlapping windows anyway. continue; } ::GetWindowRect(child, &rc); if ( ::RectInRegion(hrgn, &rc) ) { // need to remove WS_CLIPSIBLINGS from all sibling windows // that are within this staticbox if set if ( style & WS_CLIPSIBLINGS ) { style &= ~WS_CLIPSIBLINGS; ::SetWindowLong(child, GWL_STYLE, style); // MSDN: "If you have changed certain window data using // SetWindowLong, you must call SetWindowPos to have the // changes take effect." ::SetWindowPos(child, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); } AutoHRGN hrgnChild(::CreateRectRgnIndirect(&rc)); ::CombineRgn(hrgn, hrgn, hrgnChild, RGN_DIFF); } } return (WXHRGN)hrgn; }
wxWindow* wxWindow::CreateWindowFromHWND ( wxWindow* pParent , WXHWND hWnd ) { wxString sStr(wxGetWindowClass(hWnd)); long lId = wxGetWindowId(hWnd); long lStyle = ::WinQueryWindowULong((HWND)hWnd ,QWL_STYLE ); wxWindow* pWin = NULL; sStr.UpperCase(); if (sStr == wxT("BUTTON")) { if (lStyle == BS_AUTOCHECKBOX) { pWin = new wxCheckBox; } else if (lStyle == BS_AUTORADIOBUTTON) { pWin = new wxRadioButton; } else if (lStyle & BS_BITMAP || lStyle == BS_USERBUTTON) { pWin = new wxBitmapButton; } else if (lStyle == BS_PUSHBUTTON) { pWin = new wxButton; } else if (lStyle == SS_GROUPBOX) { pWin = new wxStaticBox; } else { wxLogError(wxT("Don't know what kind of button this is: id = %ld"), lId); } } else if (sStr == wxT("COMBOBOX")) { pWin = new wxComboBox; } else if (sStr == wxT("EDIT")) { pWin = new wxTextCtrl; } else if (sStr == wxT("LISTBOX")) { pWin = new wxListBox; } else if (sStr == wxT("SCROLLBAR")) { pWin = new wxScrollBar; } else if (sStr == wxT("MSCTLS_UPDOWN32")) { pWin = new wxSpinButton; } else if (sStr == wxT("MSCTLS_TRACKBAR32")) { pWin = new wxSlider; } else if (sStr == wxT("STATIC")) { if (lStyle == SS_TEXT) pWin = new wxStaticText; else if (lStyle == SS_ICON) { pWin = new wxStaticBitmap; } } else { wxString sMsg(wxT("Don't know how to convert from Windows class ")); sMsg += sStr; wxLogError(sMsg); } if (pWin) { pParent->AddChild(pWin); pWin->SetEventHandler(pWin); pWin->SetHWND(hWnd); pWin->SetId(lId); pWin->SubclassWin(hWnd); pWin->AdoptAttributesFromHWND(); pWin->SetupColours(); return pWin; } else return NULL; } // end of wxWindow::CreateWindowFromHWND
WXHRGN wxStaticBox::MSWGetRegionWithoutChildren() { RECT rc; ::GetWindowRect(GetHwnd(), &rc); HRGN hrgn = ::CreateRectRgn(rc.left, rc.top, rc.right + 1, rc.bottom + 1); bool foundThis = false; // iterate over all child windows (not just wxWindows but all windows) for ( HWND child = ::GetWindow(GetHwndOf(GetParent()), GW_CHILD); child; child = ::GetWindow(child, GW_HWNDNEXT) ) { if ( ! ::IsWindowVisible(child) ) { // if the window isn't visible then it doesn't need clipped continue; } LONG style = ::GetWindowLong(child, GWL_STYLE); wxString str(wxGetWindowClass(child)); str.UpperCase(); if ( str == wxT("BUTTON") && (style & BS_GROUPBOX) == BS_GROUPBOX ) { if ( child == GetHwnd() ) foundThis = true; // Any static boxes below this one in the Z-order can't be clipped // since if we have the case where a static box with a low Z-order // is nested inside another static box with a high Z-order then the // nested static box would be painted over. Doing it this way // unfortunately results in flicker if the Z-order of nested static // boxes is not inside (lowest) to outside (highest) but at least // they are still shown. if ( foundThis ) continue; } ::GetWindowRect(child, &rc); if ( ::RectInRegion(hrgn, &rc) ) { // need to remove WS_CLIPSIBLINGS from all sibling windows // that are within this staticbox if set if ( style & WS_CLIPSIBLINGS ) { style &= ~WS_CLIPSIBLINGS; ::SetWindowLong(child, GWL_STYLE, style); // MSDN: "If you have changed certain window data using // SetWindowLong, you must call SetWindowPos to have the // changes take effect." ::SetWindowPos(child, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); } AutoHRGN hrgnChild(::CreateRectRgnIndirect(&rc)); ::CombineRgn(hrgn, hrgn, hrgnChild, RGN_DIFF); } } return (WXHRGN)hrgn; }
wxWindow* wxWindow::CreateWindowFromHWND(wxWindow* parent, WXHWND hWnd) { wxCHECK_MSG( parent, NULL, _T("must have valid parent for a control") ); wxString str(wxGetWindowClass(hWnd)); str.UpperCase(); long id = wxGetWindowId(hWnd); long style = GetWindowLong((HWND) hWnd, GWL_STYLE); wxWindow* win = NULL; if (str == wxT("BUTTON")) { int style1 = (style & 0xFF); #if wxUSE_CHECKBOX if ((style1 == BS_3STATE) || (style1 == BS_AUTO3STATE) || (style1 == BS_AUTOCHECKBOX) || (style1 == BS_CHECKBOX)) { win = new wxCheckBox; } else #endif #if wxUSE_RADIOBTN if ((style1 == BS_AUTORADIOBUTTON) || (style1 == BS_RADIOBUTTON)) { win = new wxRadioButton; } else #endif #if wxUSE_BMPBUTTON #if defined(__WIN32__) && defined(BS_BITMAP) if (style & BS_BITMAP) { // TODO: how to find the bitmap? win = new wxBitmapButton; wxLogError(wxT("Have not yet implemented bitmap button as BS_BITMAP button.")); } else #endif if (style1 == BS_OWNERDRAW) { // TODO: how to find the bitmap? // TODO: can't distinguish between bitmap button and bitmap static. // Change implementation of wxStaticBitmap to SS_BITMAP. // PROBLEM: this assumes that we're using resource-based bitmaps. // So maybe need 2 implementations of bitmap buttons/static controls, // with a switch in the drawing code. Call default proc if BS_BITMAP. win = new wxBitmapButton; } else #endif #if wxUSE_BUTTON if ((style1 == BS_PUSHBUTTON) || (style1 == BS_DEFPUSHBUTTON)) { win = new wxButton; } else #endif #if wxUSE_STATBOX if (style1 == BS_GROUPBOX) { win = new wxStaticBox; } else #endif { wxLogError(wxT("Don't know what kind of button this is: id = %ld"), id); } } #if wxUSE_COMBOBOX else if (str == wxT("COMBOBOX")) { win = new wxComboBox; } #endif #if wxUSE_TEXTCTRL // TODO: Problem if the user creates a multiline - but not rich text - text control, // since wxWin assumes RichEdit control for this. Should have m_isRichText in // wxTextCtrl. Also, convert as much of the window style as is necessary // for correct functioning. // Could have wxWindow::AdoptAttributesFromHWND(WXHWND) // to be overridden by each control class. else if (str == wxT("EDIT")) { win = new wxTextCtrl; } #endif #if wxUSE_LISTBOX else if (str == wxT("LISTBOX")) { win = new wxListBox; } #endif #if wxUSE_SCROLLBAR else if (str == wxT("SCROLLBAR")) { win = new wxScrollBar; } #endif #if wxUSE_SPINBTN else if (str == wxT("MSCTLS_UPDOWN32")) { win = new wxSpinButton; } #endif #if wxUSE_SLIDER else if (str == wxT("MSCTLS_TRACKBAR32")) { // Need to ascertain if it's horiz or vert win = new wxSlider; } #endif // wxUSE_SLIDER #if wxUSE_STATTEXT else if (str == wxT("STATIC")) { int style1 = (style & 0xFF); if ((style1 == SS_LEFT) || (style1 == SS_RIGHT) #ifndef __WXWINCE__ || (style1 == SS_SIMPLE) #endif ) win = new wxStaticText; #if wxUSE_STATBMP #if defined(__WIN32__) && defined(BS_BITMAP) else if (style1 == SS_BITMAP) { win = new wxStaticBitmap; // Help! this doesn't correspond with the wxWin implementation. wxLogError(wxT("Please make SS_BITMAP statics into owner-draw buttons.")); } #endif #endif /* wxUSE_STATBMP */ } #endif else { wxString msg(wxT("Don't know how to convert from Windows class ")); msg += str; wxLogError(msg); } if (win) { parent->AddChild(win); win->SubclassWin(hWnd); win->AdoptAttributesFromHWND(); win->SetupColours(); } return win; }