- wxTreeCtrl::IsVisible() bug fixed (thanks to Gary Chessun)
- loading/saving big (> 32K) files in wxTextCtrl works
- tooltips work with wxRadioBox
+- wxBitmap/wxIcon may be constructed from XPM included into a program, as in
+ Unix ports
- returning FALSE from OnPrintPage() aborts printing
wxGTK:
/////////////////////////////////////////////////////////////////////////////
-// Name: scrolwin.h
+// Name: wx/generic/scrolwin.h
// Purpose: wxScrolledWindow class
// Author: Julian Smart
// Modified by:
// Created: 01/02/97
// RCS-ID: $Id$
// Copyright: (c) Julian Smart and Markus Holzem
-// Licence: wxWindows license
+// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
-#ifndef __SCROLWINH_G__
-#define __SCROLWINH_G__
+#ifndef _WX_GENERIC_SCROLLWIN_H_
+#define _WX_GENERIC_SCROLLWIN_H_
#ifdef __GNUG__
-#pragma interface "scrolwin.h"
+ #pragma interface "scrolwin.h"
#endif
+// ----------------------------------------------------------------------------
+// headers and constants
+// ----------------------------------------------------------------------------
+
#include "wx/window.h"
#include "wx/panel.h"
WXDLLEXPORT_DATA(extern const wxChar*) wxPanelNameStr;
+// default scrolled window style
+#define wxScrolledWindowStyle (wxHSCROLL | wxVSCROLL | wxTAB_TRAVERSAL)
+
+// ----------------------------------------------------------------------------
+// wxScrolledWindow
+// ----------------------------------------------------------------------------
+
class WXDLLEXPORT wxScrolledWindow : public wxPanel
{
public:
wxScrolledWindow();
- inline wxScrolledWindow(wxWindow *parent, wxWindowID id = -1,
- const wxPoint& pos = wxDefaultPosition,
- const wxSize& size = wxDefaultSize,
- long style = wxHSCROLL|wxVSCROLL,
- const wxString& name = wxPanelNameStr)
+ wxScrolledWindow(wxWindow *parent,
+ wxWindowID id = -1,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = wxScrolledWindowStyle,
+ const wxString& name = wxPanelNameStr)
{
- Create(parent, id, pos, size, style, name);
+ Create(parent, id, pos, size, style, name);
}
~wxScrolledWindow();
- bool Create(wxWindow *parent, wxWindowID id,
- const wxPoint& pos = wxDefaultPosition,
- const wxSize& size = wxDefaultSize,
- long style = wxHSCROLL|wxVSCROLL,
- const wxString& name = wxPanelNameStr);
+ bool Create(wxWindow *parent,
+ wxWindowID id,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = wxScrolledWindowStyle,
+ const wxString& name = wxPanelNameStr);
- // Normally the wxScrolledWindow will scroll itself, but in
- // some rare occasions you might want it to scroll another
- // window (e.g. a child of it in order to scroll only a portion
+ // Normally the wxScrolledWindow will scroll itself, but in
+ // some rare occasions you might want it to scroll another
+ // window (e.g. a child of it in order to scroll only a portion
// the area between the scrollbars (spreadsheet: only cell area
- // will move).
+ // will move).
virtual void SetTargetWindow( wxWindow *target );
virtual wxWindow *GetTargetWindow();
virtual void SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY,
int noUnitsX, int noUnitsY,
int xPos = 0, int yPos = 0,
- bool noRefresh = FALSE );
+ bool noRefresh = FALSE );
// Physically scroll the window
virtual void Scroll(int x_pos, int y_pos);
#if WXWIN_COMPATIBILITY
virtual void GetScrollUnitsPerPage(int *x_page, int *y_page) const;
- virtual void CalcUnscrolledPosition(int x, int y, float *xx, float *yy) const ;
+ virtual void CalcUnscrolledPosition(int x, int y, float *xx, float *yy) const;
#endif
- int GetScrollPageSize(int orient) const ;
+ int GetScrollPageSize(int orient) const;
void SetScrollPageSize(int orient, int pageSize);
virtual void GetScrollPixelsPerUnit(int *x_unit, int *y_unit) const;
-
+
// Enable/disable Windows scrolling in either direction.
// If TRUE, wxWindows scrolls the canvas and only a bit of
// the canvas is invalidated; no Clear() is necessary.
double GetScaleX() const { return m_scaleX; }
double GetScaleY() const { return m_scaleY; }
- virtual void CalcScrolledPosition(int x, int y, int *xx, int *yy) const ;
- virtual void CalcUnscrolledPosition(int x, int y, int *xx, int *yy) const ;
+ virtual void CalcScrolledPosition(int x, int y, int *xx, int *yy) const;
+ virtual void CalcUnscrolledPosition(int x, int y, int *xx, int *yy) const;
// Adjust the scrollbars
virtual void AdjustScrollbars(void);
};
#endif
- // __SCROLWINH_G__
+ // _WX_GENERIC_SCROLLWIN_H_
// to invert the mask each time we pass one/get one to/from Windows
extern HBITMAP wxInvertMask(HBITMAP hbmpMask, int w = 0, int h = 0);
+// get (x, y) from DWORD - notice that HI/LOWORD can *not* be used because they
+// will fail on system with multiple monitors where the coords may be negative
+//
+// these macros are standard now (Win98) but some older headers don't have them
+#ifndef GET_X_LPARAM
+ #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
+ #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
+#endif // GET_X_LPARAM
+
// ---------------------------------------------------------------------------
// small helper classes
// ---------------------------------------------------------------------------
wxSUNKEN_BORDER | wxDOUBLE_BORDER)) != 0;
}
+// find the window for HWND which is part of some wxWindow, returns just the
+// corresponding wxWindow for HWND which just is one
+//
+// may return NULL
+extern wxWindow *wxGetWindowFromHWND(WXHWND hwnd);
+
#endif // wxUSE_GUI
#endif
int GetNumVer() const;
int GetNumHor() const;
+ // compatibility ctor
#if WXWIN_COMPATIBILITY
wxRadioBox(wxWindow *parent, wxFunction func, const char *title,
int x = -1, int y = -1, int width = -1, int height = -1,
virtual bool MSWOnScroll(int orientation, WXWORD wParam,
WXWORD pos, WXHWND control);
+ // a wxSpinButton can't do anything useful with focus, only wxSpinCtrl can
+ virtual bool AcceptsFocus() const { return FALSE; }
+
protected:
virtual wxSize DoGetBestSize() const;
virtual bool Enable(bool enable = TRUE);
virtual bool Show(bool show = TRUE);
+ virtual bool AcceptsFocus() const { return TRUE; }
+
protected:
virtual void DoMoveWindow(int x, int y, int width, int height);
virtual wxSize DoGetBestSize() const;
// set the delay after which the tooltip appears
static void SetDelay(long milliseconds);
- // implementation
+ // implementation only from now on
+ // -------------------------------
+
+ // should be called in responde to WM_MOUSEMOVE
void RelayEvent(WXMSG *msg);
private:
+ // the one and only one tooltip control we use - never access it directly
+ // but use GetToolTipCtrl() which will create it when needed
static WXHWND ms_hwndTT;
// create the tooltip ctrl if it doesn't exist yet and return its HWND
- WXHWND GetToolTipCtrl();
+ static WXHWND GetToolTipCtrl();
// remove this tooltip from the tooltip control
void Remove();
void wxPanel::OnNavigationKey( wxNavigationKeyEvent& event )
{
- // the event is propagated downwards if the event emitter was our parent
- bool goingDown = event.GetEventObject() == GetParent();
+ const wxWindowList& children = GetChildren();
- // we're not interested in "notebook page change" events here
- if ( event.IsWindowChange() )
+ // there is not much to do if we don't have children and we're not
+ // interested in "notebook page change" events here
+ if ( !children.GetCount() || event.IsWindowChange() )
{
wxWindow *parent = GetParent();
if ( !parent || !parent->GetEventHandler()->ProcessEvent(event) )
// next acceptable child
wxWindowList::Node *node, *start_node;
- const wxWindowList& children = GetChildren();
+ // the event is propagated downwards if the event emitter was our parent
+ bool goingDown = event.GetEventObject() == GetParent();
// we should start from the first/last control and not from the one which
// had focus the last time if we're propagating the event downwards because
#include "wx/resource.h"
#endif
+#if wxUSE_TOOLTIPS
+ #include "wx/tooltip.h"
+#endif // wxUSE_TOOLTIPS
+
// OLE is used for drag-and-drop, clipboard, OLE Automation...
#ifndef wxUSE_NORLANDER_HEADERS
#if defined(__GNUWIN32__) || defined(__SC__) || defined(__SALFORDC__)
{
MSG *msg = (MSG *)wxmsg;
HWND hWnd = msg->hwnd;
- wxWindow *wndThis = wxFindWinFromHandle((WXHWND)hWnd), *wnd;
+ wxWindow *wndThis = wxGetWindowFromHWND((WXHWND)hWnd);
- // for some composite controls (like a combobox), wndThis might be NULL
- // because the subcontrol is not a wxWindow, but only the control itself
- // is - try to catch this case
- while ( hWnd && !wndThis )
+#if wxUSE_TOOLTIPS
+ // we must relay WM_MOUSEMOVE events to the tooltip ctrl if we want it to
+ // popup the tooltip bubbles
+ if ( wndThis && (msg->message == WM_MOUSEMOVE) )
{
- hWnd = ::GetParent(hWnd);
- wndThis = wxFindWinFromHandle((WXHWND)hWnd);
+ wxToolTip *tt = wndThis->GetToolTip();
+ if ( tt )
+ {
+ tt->RelayEvent(wxmsg);
+ }
}
+#endif // wxUSE_TOOLTIPS
// Try translations first; find the youngest window with
// a translation table.
+ wxWindow *wnd;
for ( wnd = wndThis; wnd; wnd = wnd->GetParent() )
{
if ( wnd->MSWTranslateMessage(wxmsg) )
#include "wx/msw/private.h"
#if wxUSE_TOOLTIPS
-
-#ifndef __GNUWIN32__
- #include <commctrl.h>
-#endif
+ #ifndef __GNUWIN32__
+ #include <commctrl.h>
+ #endif
#include "wx/tooltip.h"
#endif // wxUSE_TOOLTIPS
IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
-// VZ: the new behaviour is to create the radio buttons as children of the
-// radiobox instead of creating them as children of the radiobox' parent.
+// there are two possible ways to create the radio buttons: either as children
+// of the radiobox or as siblings of it - allow playing with both variants for
+// now, eventually we will choose the best one for our purposes
//
-// This seems more logical, more consistent with what other frameworks do
-// and allows tooltips to work with radioboxes, so there should be no
-// reason to revert to the backward compatible behaviour - but I still
-// leave this possibility just in case.
-
+// two main problems are the keyboard navigation inside the radiobox (arrows
+// should switch between buttons, not pass focus to the next control) and the
+// tooltips - a tooltip is associated with the radiobox itself, not the
+// children...
+//
+// the problems with setting this to 1:
+// a) Alt-<mnemonic of radiobox> isn't handled properly by IsDialogMessage()
+// because it sets focus to the next control accepting it which is not a
+// radio button but a radiobox sibling in this case - the only solution to
+// this would be to handle Alt-<mnemonic> ourselves
+// b) the problems with setting radiobox colours under Win98/2K were reported
+// but I couldn't reproduce it so I have no idea about what causes it
+//
+// the problems with setting this to 0:
+// a) the tooltips are not shown for the radiobox - possible solution: make
+// TTM_WINDOWFROMPOS handling code in msw/tooltip.cpp work (easier said than
+// done because I don't know why it doesn't work)
#define RADIOBTN_PARENT_IS_RADIOBOX 0
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// the pointer to standard radio button wnd proc
-static WXFARPROC s_wndprocRadioBtn = (WXFARPROC)NULL;
+static WNDPROC s_wndprocRadioBtn = (WNDPROC)NULL;
#endif // __WIN32__
ProcessCommand (event);
}
+// NB: if this code is changed, wxGetWindowForHWND() which relies on having the
+// radiobox pointer in GWL_USERDATA for radio buttons must be updated too!
void wxRadioBox::SubclassRadioButton(WXHWND hWndBtn)
{
+ // No GWL_USERDATA in Win16, so omit this subclassing.
#ifdef __WIN32__
HWND hwndBtn = (HWND)hWndBtn;
if ( !s_wndprocRadioBtn )
- s_wndprocRadioBtn = (WXFARPROC)::GetWindowLong(hwndBtn, GWL_WNDPROC);
+ s_wndprocRadioBtn = (WNDPROC)::GetWindowLong(hwndBtn, GWL_WNDPROC);
- // No GWL_USERDATA in Win16, so omit this subclassing.
::SetWindowLong(hwndBtn, GWL_WNDPROC, (long)wxRadioBtnWndProc);
::SetWindowLong(hwndBtn, GWL_USERDATA, (long)this);
#endif // __WIN32__
::SendMessage((HWND)m_radioButtons[n], WM_SETFONT, (WPARAM)hfont, 0L);
}
+ // this is needed because otherwise the buttons are not redrawn correctly
+ Refresh();
+
return TRUE;
}
+// ----------------------------------------------------------------------------
+// our window proc
+// ----------------------------------------------------------------------------
+
long wxRadioBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
{
switch ( nMsg )
{
-#ifndef __WIN16__
+#ifdef __WIN32__
case WM_CTLCOLORSTATIC:
// set the colour of the radio buttons to be the same as ours
{
return (WXHBRUSH)brush->GetResourceHandle();
}
-#endif
+#endif // Win32
// This is required for the radiobox to be sensitive to mouse input,
// e.g. for Dialog Editor.
if (yPos < 10)
return (long)HTCLIENT;
}
- // fall through
-
- default:
- return wxControl::MSWWindowProc(nMsg, wParam, lParam);
+ break;
}
+
+ return wxControl::MSWWindowProc(nMsg, wParam, lParam);
}
// ---------------------------------------------------------------------------
#ifdef __WIN32__
LRESULT APIENTRY _EXPORT wxRadioBtnWndProc(HWND hwnd,
- UINT msg,
+ UINT message,
WPARAM wParam,
LPARAM lParam)
{
- bool processed = FALSE;
- if ( msg == WM_KEYDOWN
-#if wxUSE_TOOLTIPS
- || msg == WM_NOTIFY
-#endif // wxUSE_TOOLTIPS
- )
+ switch ( message )
{
- wxRadioBox *radiobox = (wxRadioBox *)::GetWindowLong(hwnd, GWL_USERDATA);
-
- wxCHECK_MSG( radiobox, 0, wxT("radio button without radio box?") );
+ case WM_GETDLGCODE:
+ // we must tell IsDialogMessage()/our kbd processing code that we
+ // want to process arrows ourselves because neither of them is
+ // smart enough to handle arrows properly for us
+ {
+ long lDlgCode = ::CallWindowProc(s_wndprocRadioBtn, hwnd,
+ message, wParam, lParam);
+ return lDlgCode | DLGC_WANTARROWS;
+ }
-#if wxUSE_TOOLTIPS && !defined(__GNUWIN32__)
- if ( msg == WM_NOTIFY )
- {
- NMHDR* hdr = (NMHDR *)lParam;
- if ( (int)hdr->code == TTN_NEEDTEXT )
+#if wxUSE_TOOLTIPS
+ case WM_NOTIFY:
{
- wxToolTip *tt = radiobox->GetToolTip();
- if ( tt )
+ NMHDR* hdr = (NMHDR *)lParam;
+ if ( (int)hdr->code == TTN_NEEDTEXT )
{
- TOOLTIPTEXT *ttt = (TOOLTIPTEXT *)lParam;
- ttt->lpszText = (wxChar *)tt->GetTip().c_str();
+ wxRadioBox *radiobox = (wxRadioBox *)
+ ::GetWindowLong(hwnd, GWL_USERDATA);
- processed = TRUE;
+ wxCHECK_MSG( radiobox, 0,
+ wxT("radio button without radio box?") );
+
+ wxToolTip *tooltip = radiobox->GetToolTip();
+ if ( tooltip )
+ {
+ TOOLTIPTEXT *ttt = (TOOLTIPTEXT *)lParam;
+ ttt->lpszText = (wxChar *)tooltip->GetTip().c_str();
+ }
+
+ // processed
+ return 0;
}
}
- }
- else // msg == WM_KEYDOWN
+ break;
#endif // wxUSE_TOOLTIPS
- {
- processed = TRUE;
- int sel = radiobox->GetSelection();
-
- switch ( wParam )
+ case WM_KEYDOWN:
{
- case VK_UP:
- sel--;
- break;
+ wxRadioBox *radiobox = (wxRadioBox *)
+ ::GetWindowLong(hwnd, GWL_USERDATA);
- case VK_LEFT:
- sel -= radiobox->GetNumVer();
- break;
+ wxCHECK_MSG( radiobox, 0, wxT("radio button without radio box?") );
- case VK_DOWN:
- sel++;
- break;
+ bool processed = TRUE;
- case VK_RIGHT:
- sel += radiobox->GetNumVer();
- break;
+ int selOld = radiobox->GetSelection();
+ int selNew = selOld;
- case VK_TAB:
- {
- wxNavigationKeyEvent event;
- event.SetDirection(!(::GetKeyState(VK_SHIFT) & 0x100));
- event.SetWindowChange(FALSE);
- event.SetEventObject(radiobox);
+ switch ( wParam )
+ {
+ case VK_UP:
+ selNew--;
+ break;
- if ( radiobox->GetEventHandler()->ProcessEvent(event) )
- return 0;
- }
- // fall through
+ case VK_LEFT:
+ selNew -= radiobox->GetNumVer();
+ break;
- default:
- processed = FALSE;
- }
+ case VK_DOWN:
+ selNew++;
+ break;
- if ( processed )
- {
- if ( sel >= 0 && sel < radiobox->Number() )
+ case VK_RIGHT:
+ selNew += radiobox->GetNumVer();
+ break;
+
+ default:
+ processed = FALSE;
+ }
+
+ if ( processed )
{
- radiobox->SetSelection(sel);
+ // ensure that selNew is in range [0..num)
+ int num = radiobox->Number();
+ selNew += num;
+ selNew %= num;
+
+ if ( selNew != selOld )
+ {
+ radiobox->SetSelection(selNew);
+
+ // emulate the button click
+ radiobox->SendNotificationEvent();
- // emulate the button click
- radiobox->SendNotificationEvent();
+ return 0;
+ }
}
}
- }
}
- if ( processed )
- return 0;
-
- return ::CallWindowProc(CASTWNDPROC s_wndprocRadioBtn, hwnd, msg, wParam, lParam);
+ return ::CallWindowProc(s_wndprocRadioBtn, hwnd, message, wParam, lParam);
}
#endif // __WIN32__
// ourselves the fact that we got here means that the user code
// decided to skip processing of this TAB - probably to let it
// do its default job.
- //
- // NB: Notice that Ctrl-Tab is handled elsewhere and Alt-Tab is
- // handled by Windows
{
wxNavigationKeyEvent eventNav;
eventNav.SetDirection(!event.ShiftDown());
- eventNav.SetWindowChange(FALSE);
+ eventNav.SetWindowChange(event.ControlDown());
eventNav.SetEventObject(this);
if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav) )
return;
}
break;
-
- default:
- event.Skip();
- return;
}
- // don't just call event.Skip() because this will cause TABs and ENTERs
- // be passed upwards and we don't always want this - instead process it
- // right here
-
- // FIXME
+ // no, we didn't process it
event.Skip();
}
#include <commctrl.h>
#endif
+#ifndef _WIN32_IE
+ // minimal set of features by default
+ #define _WIN32_IE 0x0200
+#endif
+
// VZ: normally, the trick with subclassing the tooltip control and processing
// TTM_WINDOWFROMPOINT should work but, somehow, it doesn't. I leave the
// code here for now (but it's not compiled) in case we need it later.
//
-// For now, instead of this, we just add all radiobox buttons to the
-// tooltip control as well (see SetWindow) - this is probably less
-// efficient, but it works.
-#define wxUSE_TTM_WINDOWFROMPOINT 1
+// For now I use an ugly workaround and process TTN_NEEDTEXT directly in
+// radio button wnd proc - fixing TTM_WINDOWFROMPOINT code would be nice
+// because it would then work for all controls, not only radioboxes but for
+// now I don't understand what's wrong with it...
+#define wxUSE_TTM_WINDOWFROMPOINT 0
// ----------------------------------------------------------------------------
// global variables
// version of it. So we always use the old size - if we ever start
// using our lParam member, we'd have to check for comctl32 version
// during run-time
-#if defined(_WIN32_IE) && (_WIN32_IE >= 0x0300)
+#if _WIN32_IE >= 0x0300
cbSize = sizeof(TOOLINFO) - sizeof(LPARAM);
#else // old headers
cbSize = sizeof(TOOLINFO);
if ( msg == TTM_WINDOWFROMPOINT )
{
LPPOINT ppt = (LPPOINT)lParam;
- // is the window under control a wxWindow?
+
+ // the window on which event occured
HWND hwnd = ::WindowFromPoint(*ppt);
- // return a HWND correspondign to wxWindow because only wxWindows are
+ OutputDebugString("TTM_WINDOWFROMPOINT: ");
+ OutputDebugString(wxString::Format("0x%08x => ", hwnd));
+
+ // return a HWND corresponding to a wxWindow because only wxWindows are
// associated with tooltips using TTM_ADDTOOL
- while ( hwnd && !wxFindWinFromHandle((WXHWND)hwnd) )
- {
- hwnd = ::GetParent(hwnd);
- }
+ wxWindow *win = wxGetWindowFromHWND((WXHWND)hwnd);
- if ( hwnd )
+ if ( win )
{
+ hwnd = GetHwndOf(win);
+ OutputDebugString(wxString::Format("0x%08x\r\n", hwnd));
+
+#if 0
// modify the point too!
RECT rect;
GetWindowRect(hwnd, &rect);
- ppt->x = rect.left;
- ppt->y = rect.top;
-
+ ppt->x = (rect.right - rect.left) / 2;
+ ppt->y = (rect.bottom - rect.top) / 2;
+#endif // 0
return (LRESULT)hwnd;
}
+ else
+ {
+ OutputDebugString("no window\r\n");
+ }
}
return ::CallWindowProc(CASTWNDPROC gs_wndprocToolTip, hwndTT, msg, wParam, lParam);
{
wxLogDebug(_T("Failed to create the tooltip '%s'"), m_text.c_str());
}
+ else
+ {
+ // check for multiline toopltip
+ int index = m_text.Find(_T('\n'));
+
+ if ( index != wxNOT_FOUND )
+ {
+#if _WIN32_IE >= 0x0300
+ if ( wxTheApp->GetComCtl32Version() >= 470 )
+ {
+ // use TTM_SETMAXWIDTH to make tooltip multiline using the
+ // extent of its first line as max value
+ HFONT hfont = (HFONT)SendTooltipMessage(GetToolTipCtrl(),
+ WM_GETFONT,
+ 0, 0);
+ if ( !hfont )
+ {
+ hfont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+ if ( !hfont )
+ {
+ wxLogLastError("GetStockObject(DEFAULT_GUI_FONT)");
+ }
+ }
+
+ HDC hdc = CreateCompatibleDC(NULL);
+ if ( !hdc )
+ {
+ wxLogLastError("CreateCompatibleDC(NULL)");
+ }
+
+ if ( !SelectObject(hdc, hfont) )
+ {
+ wxLogLastError("SelectObject(hfont)");
+ }
+
+ SIZE sz;
+ if ( !GetTextExtentPoint(hdc, m_text, index, &sz) )
+ {
+ wxLogLastError("GetTextExtentPoint");
+ }
+
+ DeleteDC(hdc);
+
+ SendTooltipMessage(GetToolTipCtrl(), TTM_SETMAXTIPWIDTH,
+ 0, (void *)sz.cx);
+ }
+#endif // comctl32.dll >= 4.70
+
+ // replace the '\n's with spaces because otherwise they appear as
+ // unprintable characters in the tooltip string
+ m_text.Replace(_T("\n"), _T(" "));
+ }
+ }
}
void wxToolTip::SetWindow(wxWindow *win)
Add(m_window->GetHWND());
}
-#if 1 //!wxUSE_TTM_WINDOWFROMPOINT
// and all of its subcontrols (e.g. radiobuttons in a radiobox) as well
wxControl *control = wxDynamicCast(m_window, wxControl);
if ( control )
{
- size_t count = control->GetSubcontrols().GetCount();
+ const wxArrayLong& subcontrols = control->GetSubcontrols();
+ size_t count = subcontrols.GetCount();
for ( size_t n = 0; n < count; n++ )
{
- wxWindowID id = control->GetSubcontrols()[n];
+ int id = subcontrols[n];
HWND hwnd = GetDlgItem(GetHwndOf(m_window), id);
-
- if ( hwnd )
+ if ( !hwnd )
{
- Add((WXHWND)hwnd);
+ // may be it's a child of parent of the control, in fact?
+ // (radiobuttons are subcontrols, i.e. children of the radiobox
+ // for wxWindows but are its siblings at Windows level)
+ hwnd = GetDlgItem(GetHwndOf(m_window->GetParent()), id);
}
+
+ // must have it by now!
+ wxASSERT_MSG( hwnd, _T("no hwnd for subcontrol?") );
+
+ Add((WXHWND)hwnd);
}
}
-#endif // !wxUSE_TTM_WINDOWFROMPOINT
}
void wxToolTip::SetTip(const wxString& tip)
#endif
#endif
-// ---------------------------------------------------------------------------
-// macros
-// ---------------------------------------------------------------------------
-
-// standard macros missing from some compilers headers
-#ifndef GET_X_LPARAM
- #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
- #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
-#endif // GET_X_LPARAM
-
// ---------------------------------------------------------------------------
// global variables
// ---------------------------------------------------------------------------
if ( width > -1 ) width1 = width;
if ( height > -1 ) height1 = height;
+ // if we have wxTAB_TRAVERSAL style, we want WS_EX_CONTROLPARENT or
+ // IsDialogMessage() won't work for us
+ if ( GetWindowStyleFlag() & wxTAB_TRAVERSAL )
+ {
+ extendedStyle |= WS_EX_CONTROLPARENT;
+ }
+
HWND hParent = (HWND)NULL;
if ( parent )
hParent = (HWND) parent->GetHWND();
return NULL;
}
+extern wxWindow *wxGetWindowFromHWND(WXHWND hWnd)
+{
+ HWND hwnd = (HWND)hWnd;
+
+ // For a radiobutton, we get the radiobox from GWL_USERDATA (which is set
+ // by code in msw/radiobox.cpp), for all the others we just search up the
+ // window hierarchy
+ wxWindow *win = (wxWindow *)NULL;
+ if ( hwnd )
+ {
+ win = wxFindWinFromHandle((WXHWND)hwnd);
+ if ( !win )
+ {
+ // native radiobuttons return DLGC_RADIOBUTTON here and for any
+ // wxWindow class which overrides WM_GETDLGCODE processing to
+ // do it as well, win would be already non NULL
+ if ( ::SendMessage((HWND)hwnd, WM_GETDLGCODE,
+ 0, 0) & DLGC_RADIOBUTTON )
+ {
+ win = (wxWindow *)::GetWindowLong(hwnd, GWL_USERDATA);
+ }
+ else
+ {
+ // hwnd is not a wxWindow, try its parent next below
+ hwnd = ::GetParent(hwnd);
+ }
+ }
+ //else: it's a wxRadioButton, not a radiobutton from wxRadioBox
+ }
+
+ while ( hwnd && !win )
+ {
+ win = wxFindWinFromHandle((WXHWND)hwnd);
+ hwnd = ::GetParent(hwnd);
+ }
+
+ return win;
+}
+
// Windows keyboard hook. Allows interception of e.g. F1, ESCAPE
// in active frames and dialogs, regardless of where the focus is.
static HHOOK wxTheKeyboardHook = 0;
wxTheKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC) wxTheKeyboardHookProc, wxGetInstance(),
#if defined(__WIN32__) && !defined(__TWIN32__)
- GetCurrentThreadId());
+ GetCurrentThreadId()
// (DWORD)GetCurrentProcess()); // This is another possibility. Which is right?
#else
- GetCurrentTask());
+ GetCurrentTask()
#endif
+ );
}
else
{