#endif
#ifndef WX_PRECOMP
-#include <stdio.h>
-#include "wx/setup.h"
-#include "wx/menu.h"
-#include "wx/dc.h"
-#include "wx/dcclient.h"
-#include "wx/utils.h"
-#include "wx/app.h"
-#include "wx/panel.h"
-#include "wx/layout.h"
-#include "wx/dialog.h"
-#include "wx/frame.h"
-#include "wx/listbox.h"
-#include "wx/button.h"
-#include "wx/settings.h"
-#include "wx/msgdlg.h"
+ #include "wx/setup.h"
+ #include "wx/menu.h"
+ #include "wx/dc.h"
+ #include "wx/dcclient.h"
+ #include "wx/utils.h"
+ #include "wx/app.h"
+ #include "wx/panel.h"
+ #include "wx/layout.h"
+ #include "wx/dialog.h"
+ #include "wx/frame.h"
+ #include "wx/listbox.h"
+ #include "wx/button.h"
+ #include "wx/settings.h"
+ #include "wx/msgdlg.h"
+
+ #include <stdio.h>
#endif
#if wxUSE_OWNER_DRAWN
#include "wx/menuitem.h"
#include "wx/log.h"
+
+#if wxUSE_TOOLTIPS
+#include "wx/tooltip.h"
+#endif
+
+#include "wx/intl.h"
+#include "wx/log.h"
+
#include "wx/msw/private.h"
#include <string.h>
#ifndef __GNUWIN32__
-#include <shellapi.h>
-#include <mmsystem.h>
+ #include <shellapi.h>
+ #include <mmsystem.h>
#endif
#ifdef __WIN32__
-#include <windowsx.h>
+ #include <windowsx.h>
#endif
-#ifndef __TWIN32__
-#ifdef __GNUWIN32__
-#include <wx/msw/gnuwin32/extra.h>
+#if (defined(__WIN95__) && !defined(__GNUWIN32__)) || defined(__TWIN32__)
+#include <commctrl.h>
#endif
+
+#ifndef __TWIN32__
+ #ifdef __GNUWIN32__
+ #include <wx/msw/gnuwin32/extra.h>
+ #endif
#endif
+// all these are defined in <windows.h>
#ifdef GetCharWidth
#undef GetCharWidth
#endif
wxWindow *wxFindWinFromHandle(WXHWND hWnd);
#if !USE_SHARED_LIBRARY
-IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxEvtHandler)
+ IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxEvtHandler)
#endif
BEGIN_EVENT_TABLE(wxWindow, wxEvtHandler)
EVT_CHAR(wxWindow::OnChar)
- EVT_KEY_DOWN(wxWindow::OnKeyDown)
- EVT_KEY_UP(wxWindow::OnKeyUp)
EVT_ERASE_BACKGROUND(wxWindow::OnEraseBackground)
EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged)
EVT_INIT_DIALOG(wxWindow::OnInitDialog)
}
bool wxWindow::MSWNotify(WXWPARAM WXUNUSED(wParam),
- WXLPARAM WXUNUSED(lParam),
+ WXLPARAM lParam,
WXLPARAM* WXUNUSED(result))
{
+#ifdef __WIN95__
+#if wxUSE_TOOLTIPS
+ NMHDR* hdr = (NMHDR *)lParam;
+ if ( hdr->code == TTN_NEEDTEXT && m_tooltip )
+ {
+ TOOLTIPTEXT *ttt = (TOOLTIPTEXT *)lParam;
+ ttt->lpszText = (char *)m_tooltip->GetTip().c_str();
+
+ // processed
+ return TRUE;
+ }
+#endif
+#endif
+
return FALSE;
}
#if wxUSE_DRAG_AND_DROP
m_pDropTarget = NULL;
#endif
+
+#if wxUSE_TOOLTIPS
+ m_tooltip = NULL;
+#endif
}
wxWindow::wxWindow()
// Destructor
wxWindow::~wxWindow()
{
+ // Remove potential dangling pointer
+ if (GetParent() && GetParent()->IsKindOf(CLASSINFO(wxPanel)))
+ {
+ wxPanel* panel = (wxPanel*) GetParent();
+ if (panel->GetLastFocus() == this)
+ panel->SetLastFocus((wxWindow*) NULL);
+ }
+
m_isBeingDeleted = TRUE;
+ // first of all, delete the things on which nothing else depends
+
+#if wxUSE_TOOLTIPS
+ wxDELETE(m_tooltip);
+#endif
+
// JACS - if behaviour is odd, restore this
// to the start of ~wxWindow. Vadim has changed
// it to nearer the end. Unsure of side-effects
// delete themselves.
#if wxUSE_CONSTRAINTS
DeleteRelatedConstraints();
+
if (m_constraints)
{
// This removes any dangling pointers to this window
delete m_constraints;
m_constraints = NULL;
}
- if (m_windowSizer)
- {
- delete m_windowSizer;
- m_windowSizer = NULL;
- }
+
+ wxDELETE(m_windowSizer);
+
// If this is a child of a sizer, remove self from parent
if (m_sizerParent)
m_sizerParent->RemoveChild((wxWindow *)this);
m_pDropTarget->Register(m_hWnd);
}
-#endif
+#endif // wxUSE_DRAG_AND_DROP
+
//old style file-manager drag&drop support
// I think we should retain the old-style
::DragAcceptFiles(hWnd, (BOOL)accept);
}
+// ----------------------------------------------------------------------------
+// tooltips
+// ----------------------------------------------------------------------------
+
+#if wxUSE_TOOLTIPS
+
+void wxWindow::SetToolTip(const wxString &tip)
+{
+ SetToolTip(new wxToolTip(tip));
+}
+
+void wxWindow::SetToolTip(wxToolTip *tooltip)
+{
+ if ( m_tooltip )
+ delete m_tooltip;
+
+ m_tooltip = tooltip;
+ m_tooltip->SetWindow(this);
+}
+
+#endif // wxUSE_TOOLTIPS
+
// Get total size
void wxWindow::GetSize(int *x, int *y) const
{
bool wxWindow::Show(bool show)
{
+ m_isShown = show;
HWND hWnd = (HWND) GetHWND();
int cshow;
if (show)
cshow = SW_SHOW;
else
cshow = SW_HIDE;
- ShowWindow(hWnd, (BOOL)cshow);
+ ShowWindow(hWnd, cshow);
if (show)
{
BringWindowToTop(hWnd);
bool wxWindow::IsShown(void) const
{
- return (::IsWindowVisible((HWND) GetHWND()) != 0);
+ // Can't rely on IsWindowVisible, since it will return FALSE
+ // if the parent is not visible.
+ return m_isShown;
+// int ret = ::IsWindowVisible((HWND) GetHWND()) ;
+// return (ret != 0);
}
int wxWindow::GetCharHeight(void) const
wnd->m_hWnd = (WXHWND) hWnd;
}
- // Stop right here if we don't have a valid handle
- // in our wxWnd object.
+ // Stop right here if we don't have a valid handle in our wxWindow object.
if (wnd && !wnd->m_hWnd) {
- // wxDebugMsg("Warning: could not find a valid handle, wx_win.cc/wxWndProc.\n");
wnd->m_hWnd = (WXHWND) hWnd;
long res = wnd->MSWDefWindowProc(message, wParam, lParam );
wnd->m_hWnd = 0;
#ifdef __WXDEBUG__
wxLogTrace(wxTraceMessages, "Processing %s(%lx, %lx)",
- wxGetMessageName(message), wParam, lParam);
+ wxGetMessageName(message), wParam, lParam);
#endif // __WXDEBUG__
HWND hWnd = (HWND)m_hWnd;
case WM_KEYDOWN:
{
- MSWOnKeyDown((WORD) wParam, lParam);
-#if 0
- // we consider these message "not interesting"
+ // If this has been processed by an event handler,
+ // return 0 now (we've handled it).
+ if (MSWOnKeyDown((WORD) wParam, lParam))
+ {
+ return 0;
+ }
+
+ // we consider these message "not interesting" to OnChar
if ( wParam == VK_SHIFT || wParam == VK_CONTROL )
+ {
return Default();
+ }
- // Avoid duplicate messages to OnChar
- if ( (wParam != VK_ESCAPE) && (wParam != VK_SPACE) &&
- (wParam != VK_RETURN) && (wParam != VK_BACK) &&
- (wParam != VK_TAB) )
+ // Avoid duplicate messages to OnChar for these special keys
+ switch ( wParam )
{
- MSWOnChar((WORD)wParam, lParam);
- if ( ::GetKeyState(VK_CONTROL) & 0x100 )
- return Default();
+ case VK_ESCAPE:
+ case VK_SPACE:
+ case VK_RETURN:
+ case VK_BACK:
+ case VK_TAB:
+ case VK_LEFT:
+ case VK_RIGHT:
+ case VK_DOWN:
+ case VK_UP:
+/*
+// if ( ::GetKeyState(VK_CONTROL) & 0x100 ) // Don't understand purpose of this test
+ if (!MSWOnChar((WORD)wParam, lParam))
+ return Default();
+ break;
+*/
+ default:
+ if (!MSWOnChar((WORD)wParam, lParam))
+ {
+ return Default();
+ }
+/*
+ if ( ::GetKeyState(VK_CONTROL) & 0x100 )
+ return Default();
+*/
+ break;
}
- else if ( ::GetKeyState(VK_CONTROL) & 0x100 )
- MSWOnChar((WORD)wParam, lParam);
- else
- return Default();
-#endif
+
break;
}
-
case WM_KEYUP:
{
- MSWOnKeyUp((WORD) wParam, lParam);
+ if (!MSWOnKeyUp((WORD) wParam, lParam))
+ return Default();
break;
}
case WM_CHAR: // Always an ASCII character
{
- MSWOnChar((WORD)wParam, lParam, TRUE);
+ if (!MSWOnChar((WORD)wParam, lParam, TRUE))
+ return Default();
break;
}
default:
return MSWDefWindowProc(message, wParam, lParam );
}
+
return 0; // Success: we processed this command.
}
::ShowCaret((HWND) GetHWND());
}
+ // panel wants to track the window which was the last to have focus in it
+ wxWindow *parent = GetParent();
+ if ( parent && parent->IsKindOf(CLASSINFO(wxPanel)) )
+ {
+ ((wxPanel *)parent)->SetLastFocus(this);
+ }
+
wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId);
event.SetEventObject(this);
if (!GetEventHandler()->ProcessEvent(event))
if ( msg->message != WM_KEYDOWN )
bProcess = FALSE;
- if ( (HIWORD(msg->lParam) & KF_ALTDOWN) == KF_ALTDOWN )
+ if ( bProcess && (HIWORD(msg->lParam) & KF_ALTDOWN) == KF_ALTDOWN )
bProcess = FALSE;
- bool bCtrlDown = (::GetKeyState(VK_CONTROL) & 0x100) != 0;
+ if ( bProcess )
+ {
+ bool bCtrlDown = (::GetKeyState(VK_CONTROL) & 0x100) != 0;
- // WM_GETDLGCODE: if the control wants it for itself, don't process it
- // (except for Ctrl-Tab combination which is always processed)
- LONG lDlgCode = 0;
- if ( bProcess && !bCtrlDown ) {
- lDlgCode = ::SendMessage(msg->hwnd, WM_GETDLGCODE, 0, 0);
- }
+ // WM_GETDLGCODE: ask the control if it wants the key for itself,
+ // don't process it if it's the case (except for Ctrl-Tab/Enter
+ // combinations which are always processed)
+ LONG lDlgCode = 0;
+ if ( !bCtrlDown )
+ {
+ lDlgCode = ::SendMessage(msg->hwnd, WM_GETDLGCODE, 0, 0);
+ }
- bool bForward = TRUE;
- if ( bProcess ) {
- switch ( msg->wParam ) {
+ bool bForward = TRUE,
+ bWindowChange = FALSE;
+
+ switch ( msg->wParam )
+ {
case VK_TAB:
- if ( lDlgCode & DLGC_WANTTAB ) // FALSE for Ctrl-Tab
+ if ( lDlgCode & DLGC_WANTTAB ) {
bProcess = FALSE;
- else
+ }
+ else {
+ // Ctrl-Tab cycles thru notebook pages
+ bWindowChange = bCtrlDown;
bForward = !(::GetKeyState(VK_SHIFT) & 0x100);
+ }
break;
case VK_UP:
bProcess = FALSE;
break;
+ case VK_RETURN:
+ {
+ if ( lDlgCode & DLGC_WANTMESSAGE )
+ {
+ // control wants to process Enter itself, don't
+ // call IsDialogMessage() which would interpret
+ // it
+ return FALSE;
+ }
+#ifndef __WIN16__
+ wxButton *btnDefault = GetDefaultItem();
+ if ( btnDefault && !bCtrlDown )
+ {
+ // if there is a default button, Enter should
+ // press it
+ (void)::SendMessage((HWND)btnDefault->GetHWND(),
+ BM_CLICK, 0, 0);
+ return TRUE;
+ }
+ // else: but if there is not it makes sense to make it
+ // work like a TAB - and that's what we do.
+ // Note that Ctrl-Enter always works this way.
+#endif
+ }
+ break;
+
default:
bProcess = FALSE;
}
- }
- if ( bProcess ) {
- wxNavigationKeyEvent event;
- event.SetDirection(bForward);
- event.SetWindowChange(bCtrlDown);
- event.SetEventObject(this);
+ if ( bProcess )
+ {
+ wxNavigationKeyEvent event;
+ event.SetDirection(bForward);
+ event.SetWindowChange(bWindowChange);
+ event.SetEventObject(this);
- if ( GetEventHandler()->ProcessEvent(event) )
- return TRUE;
+ if ( GetEventHandler()->ProcessEvent(event) )
+ return TRUE;
+ }
}
- return ::IsDialogMessage((HWND)GetHWND(), msg) != 0;
+ if ( ::IsDialogMessage((HWND)GetHWND(), msg) )
+ return TRUE;
+ }
+#if wxUSE_TOOLTIPS
+ if ( m_tooltip )
+ {
+ // relay mouse move events to the tooltip control
+ MSG *msg = (MSG *)pMsg;
+ if ( msg->message == WM_MOUSEMOVE )
+ m_tooltip->RelayEvent(pMsg);
}
+#endif // wxUSE_TOOLTIPS
return FALSE;
}
void wxWindow::MSWOnMButtonUp(int x, int y, WXUINT flags)
{
- //wxDebugMsg("MButtonUp\n") ;
wxMouseEvent event(wxEVT_MIDDLE_UP);
event.m_x = x; event.m_y = y;
GetEventHandler()->ProcessEvent(event);
}
-void wxWindow::MSWOnChar(WXWORD wParam, WXLPARAM lParam, bool isASCII)
+bool wxWindow::MSWOnChar(WXWORD wParam, WXLPARAM lParam, bool isASCII)
{
int id;
bool tempControlDown = FALSE;
event.m_x = pt.x; event.m_y = pt.y;
- if (!GetEventHandler()->ProcessEvent(event))
- Default();
+ if (GetEventHandler()->ProcessEvent(event))
+ return TRUE;
+ else
+ return FALSE;
}
+ else
+ return FALSE;
}
-void wxWindow::MSWOnKeyDown(WXWORD wParam, WXLPARAM lParam, bool isASCII)
+bool wxWindow::MSWOnKeyDown(WXWORD wParam, WXLPARAM lParam, bool isASCII)
{
int id;
event.m_x = pt.x; event.m_y = pt.y;
- if (!GetEventHandler()->ProcessEvent(event))
- Default();
+ if (GetEventHandler()->ProcessEvent(event))
+ {
+ return TRUE;
+ }
+ else return FALSE;
+ }
+ else
+ {
+ return FALSE;
}
}
-void wxWindow::MSWOnKeyUp(WXWORD wParam, WXLPARAM lParam, bool isASCII)
+bool wxWindow::MSWOnKeyUp(WXWORD wParam, WXLPARAM lParam, bool isASCII)
{
int id;
event.m_x = pt.x; event.m_y = pt.y;
- if (!GetEventHandler()->ProcessEvent(event))
- Default();
+ if (GetEventHandler()->ProcessEvent(event))
+ return TRUE;
+ else
+ return FALSE;
}
+ else
+ return FALSE;
}
void wxWindow::MSWOnJoyDown(int joystick, int x, int y, WXUINT flags)
}
-/* TODO (maybe)
-void wxWindow::OnPaint()
-{
-PaintSelectionHandles();
-}
-*/
-
void wxWindow::WarpPointer (int x_pos, int y_pos)
{
// Move the pointer to (x_pos,y_pos) coordinates. They are expressed in
// 5) If this isn't a Win95 app, and we are using CTL3D, remove border
// effects from extended style
-#if CTL3D
+#if wxUSE_CTL3D
if ( *want3D )
nativeBorder = FALSE;
#endif
// If we want 3D, but haven't specified a border here,
// apply the default border style specified.
// TODO what about non-Win95 WIN32? Does it have borders?
-#if defined(__WIN95__) && !CTL3D
+#if defined(__WIN95__) && !wxUSE_CTL3D
if (defaultBorderStyle && (*want3D) && ! ((m_windowStyle & wxDOUBLE_BORDER) || (m_windowStyle & wxRAISED_BORDER) ||
(m_windowStyle & wxSTATIC_BORDER) || (m_windowStyle & wxSIMPLE_BORDER) ))
exStyle |= defaultBorderStyle; // WS_EX_CLIENTEDGE ;
void wxWindow::OnChar(wxKeyEvent& event)
{
-/* I'm commenting this out because otherwise, we lose tabs in e.g. a text window (see MDI sample)
- * (JACS, 14/01/99)
- if ( event.KeyCode() == WXK_TAB ) {
- // propagate the TABs to the parent - it's up to it to decide what
- // to do with it
- if ( GetParent() ) {
- if ( GetParent()->GetEventHandler()->ProcessEvent(event) )
- return;
- }
- }
-*/
-
bool isVirtual;
int id = wxCharCodeWXToMSW((int)event.KeyCode(), &isVirtual);
if ( id == -1 )
id= m_lastWParam;
- if ( !event.ControlDown() )
+ if ( !event.ControlDown() ) // Why this test?
(void) MSWDefWindowProc(m_lastMsg, (WPARAM) id, m_lastLParam);
}
if ( child->GetValidator() && /* child->GetValidator()->Ok() && */
!child->GetValidator()->TransferToWindow() )
{
- wxMessageBox("Application Error", "Could not transfer data to window", wxOK|wxICON_EXCLAMATION);
+ wxLogError(_("Could not transfer data to window"));
return FALSE;
}
winName = "unnamed";
else
winName = GetName();
- wxDebugMsg("Constraint(s) not satisfied for window of type %s, name %s:\n", (const char *)windowClass, (const char *)winName);
+ wxLogDebug("Constraint(s) not satisfied for window of type %s, name %s:",
+ (const char *)windowClass, (const char *)winName);
if (!constr->left.GetDone())
- wxDebugMsg(" unsatisfied 'left' constraint.\n");
+ wxLogDebug(" unsatisfied 'left' constraint.");
if (!constr->right.GetDone())
- wxDebugMsg(" unsatisfied 'right' constraint.\n");
+ wxLogDebug(" unsatisfied 'right' constraint.");
if (!constr->width.GetDone())
- wxDebugMsg(" unsatisfied 'width' constraint.\n");
+ wxLogDebug(" unsatisfied 'width' constraint.");
if (!constr->height.GetDone())
- wxDebugMsg(" unsatisfied 'height' constraint.\n");
- wxDebugMsg("Please check constraints: try adding AsIs() constraints.\n");
+ wxLogDebug(" unsatisfied 'height' constraint.");
+ wxLogDebug("Please check constraints: try adding AsIs() constraints.\n");
}
if (recurse)
{
wxCloseEvent event(wxEVT_CLOSE_WINDOW, m_windowId);
event.SetEventObject(this);
+#if WXWIN_COMPATIBILITY
event.SetForce(force);
+#endif
event.SetCanVeto(!force);
return (GetEventHandler()->ProcessEvent(event) && !event.GetVeto());
bool wxWindow::AcceptsFocus() const
{
+ // invisible and disabled controls don't need focus
return IsShown() && IsEnabled();
}