#endif
#ifndef WX_PRECOMP
- #include <stdio.h>
#include "wx/setup.h"
#include "wx/menu.h"
#include "wx/dc.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 "wx/textctrl.h"
+
#include <string.h>
#ifndef __GNUWIN32__
WXLPARAM* WXUNUSED(result))
{
#ifdef __WIN95__
+#if wxUSE_TOOLTIPS
NMHDR* hdr = (NMHDR *)lParam;
if ( hdr->code == TTN_NEEDTEXT && m_tooltip )
{
// processed
return TRUE;
}
+#endif
#endif
return FALSE;
void wxWindow::Init()
{
+ m_isWindow = TRUE;
+
// Generic
+// m_windowCursor = * wxSTANDARD_CURSOR;
m_windowId = 0;
m_isShown = TRUE;
m_windowStyle = 0;
m_windowParent = NULL;
m_windowEventHandler = this;
- m_windowCursor = *wxSTANDARD_CURSOR;
m_children = new wxList;
m_doubleClickAllowed = 0 ;
m_winCaptured = FALSE;
m_pDropTarget = NULL;
#endif
+#if wxUSE_TOOLTIPS
m_tooltip = NULL;
+#endif
}
wxWindow::wxWindow()
// 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
// tooltips
// ----------------------------------------------------------------------------
+#if wxUSE_TOOLTIPS
+
void wxWindow::SetToolTip(const wxString &tip)
{
SetToolTip(new wxToolTip(tip));
m_tooltip->SetWindow(this);
}
+#endif // wxUSE_TOOLTIPS
+
// Get total size
void wxWindow::GetSize(int *x, int *y) const
{
{
HWND hWnd = (HWND) GetHWND();
RECT rect;
- GetClientRect(hWnd, &rect);
+ ::GetClientRect(hWnd, &rect);
*x = rect.right;
*y = rect.bottom;
}
-void wxWindow::SetSize(int x, int y, int width, int height, int sizeFlags)
+void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags)
{
int currentX, currentY;
GetPosition(¤tX, ¤tY);
MoveWindow(hWnd, actualX, actualY, actualWidth, actualHeight, (BOOL)TRUE);
}
-void wxWindow::SetClientSize(int width, int height)
+void wxWindow::DoSetClientSize(int width, int height)
{
wxWindow *parent = GetParent();
HWND hWnd = (HWND) GetHWND();
- HWND hParentWnd = (HWND) (HWND) parent->GetHWND();
+ HWND hParentWnd = (HWND) 0;
+ if (parent)
+ hParentWnd = (HWND) parent->GetHWND();
RECT rect;
- GetClientRect(hWnd, &rect);
+ ::GetClientRect(hWnd, &rect);
RECT rect2;
GetWindowRect(hWnd, &rect2);
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;
#define DIMENSION_TYPE int
#endif
-// Main Windows 3 window proc
+// Main Windows window proc
long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
{
wxASSERT( m_lastMsg == message &&
return MSWOnSysCommand(wParam, lParam);
break;
}
+
case WM_COMMAND:
{
#ifdef __WIN32__
return MSWOnMeasureItem((int)wParam, (WXMEASUREITEMSTRUCT *)lParam);
break;
}
-
case WM_KEYDOWN:
- {
- MSWOnKeyDown((WORD) wParam, lParam);
- // 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) )
+ break;
+
+ // 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) )
+ switch ( wParam )
{
- MSWOnChar((WORD)wParam, lParam);
- if ( ::GetKeyState(VK_CONTROL) & 0x100 )
+ // avoid duplicate messages to OnChar for these ASCII keys: they
+ // will be translated by TranslateMessage() and received in WM_CHAR
+ case VK_ESCAPE:
+ case VK_SPACE:
+ case VK_RETURN:
+ case VK_BACK:
+ case VK_TAB:
return Default();
+
+#ifdef VK_APPS
+
+ // normally these macros would be defined in windows.h
+#ifndef GET_X_LPARAM
+ #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
+ #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
+#endif
+
+ // special case of VK_APPS: treat it the same as right mouse click
+ // because both usually pop up a context menu
+ case VK_APPS:
+ {
+ // construct the key mask
+ WPARAM fwKeys = MK_RBUTTON;
+ if ( (::GetKeyState(VK_CONTROL) & 0x100) != 0 )
+ fwKeys |= MK_CONTROL;
+ if ( (::GetKeyState(VK_SHIFT) & 0x100) != 0 )
+ fwKeys |= MK_SHIFT;
+
+ // simulate right mouse button click
+ DWORD dwPos = ::GetMessagePos();
+ int x = GET_X_LPARAM(dwPos),
+ y = GET_Y_LPARAM(dwPos);
+
+ ScreenToClient(&x, &y);
+ MSWOnRButtonDown(x, y, fwKeys);
+ }
+ break;
+#endif // VK_APPS
+
+ case VK_LEFT:
+ case VK_RIGHT:
+ case VK_DOWN:
+ case VK_UP:
+ default:
+ if ( !MSWOnChar((WORD)wParam, lParam) )
+ {
+ return Default();
+ }
+ break;
}
- else if ( ::GetKeyState(VK_CONTROL) & 0x100 )
- MSWOnChar((WORD)wParam, lParam);
- else
- return Default();
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);
- break;
- }
+ if ( !MSWOnChar((WORD)wParam, lParam, TRUE) )
+ return Default();
+ break;
case WM_HSCROLL:
{
return 1L;
break;
}
-
case WM_GETMINMAXINFO:
{
MINMAXINFO *info = (MINMAXINFO *)lParam;
return MSWDefWindowProc(message, wParam, lParam );
break;
}
-
case WM_GETDLGCODE:
- return MSWGetDlgCode();
+ {
+ return MSWGetDlgCode();
+ }
+ case WM_SETCURSOR:
+ {
+ // don't set cursor for other windows, only for this one: this
+ // prevents children of this window from gettign the same cursor
+ // as the parent has (don't forget that this message is propagated
+ // by default up the window parent-child hierarchy)
+ if ( (HWND)wParam == hWnd )
+ {
+ // don't set cursor when the mouse is not in the client part
+ short nHitTest = LOWORD(lParam);
+ if ( nHitTest == HTCLIENT || nHitTest == HTERROR )
+ {
+ HCURSOR hcursor = 0;
+ if ( wxIsBusy() )
+ {
+ // from msw\utils.cpp
+ extern HCURSOR gs_wxBusyCursor;
+
+ hcursor = gs_wxBusyCursor;
+ }
+ else
+ {
+ wxCursor *cursor = NULL;
+
+ if ( m_windowCursor.Ok() )
+ {
+ cursor = &m_windowCursor;
+ }
+ else
+ {
+ // from msw\data.cpp
+ extern wxCursor *g_globalCursor;
+
+ if ( g_globalCursor && g_globalCursor->Ok() )
+ cursor = g_globalCursor;
+ }
+
+ if ( cursor )
+ hcursor = (HCURSOR)cursor->GetHCURSOR();
+ }
+
+ if ( hcursor )
+ {
+ ::SetCursor(hcursor);
+
+ // returning TRUE stops the DefWindowProc() from
+ // further processing this message - exactly what we
+ // need because we've just set the cursor.
+ return TRUE;
+ }
+ }
+ }
+ }
+ return MSWDefWindowProc(message, wParam, lParam );
default:
return MSWDefWindowProc(message, wParam, lParam );
}
+
return 0; // Success: we processed this command.
}
#endif // Win95
// not processed
- return FALSE;
+ return Default();
}
void wxWindow::MSWOnMenuHighlight(WXWORD WXUNUSED(item), WXWORD WXUNUSED(flags), WXHMENU WXUNUSED(sysmenu))
::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(GetId());
+ }
+
wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId);
event.SetEventObject(this);
if (!GetEventHandler()->ProcessEvent(event))
long wxWindow::Default()
{
- // Ignore 'fake' events (perhaps generated as a result of a separate real event)
- if (m_lastMsg == 0)
+ // Ignore 'fake' events (perhaps generated as a result of a separate real
+ // event)
+ if ( m_lastMsg == 0 )
return 0;
#ifdef __WXDEBUG__
wxLogTrace(wxTraceMessages, "Forwarding %s to DefWindowProc.",
- wxGetMessageName(m_lastMsg));
+ wxGetMessageName(m_lastMsg));
#endif // __WXDEBUG__
- return this->MSWDefWindowProc(m_lastMsg, m_lastWParam, m_lastLParam);
+ return MSWDefWindowProc(m_lastMsg, m_lastWParam, m_lastLParam);
}
bool wxWindow::MSWProcessMessage(WXMSG* pMsg)
{
- if ( m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL) ) {
+ if ( m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL) )
+ {
// intercept dialog navigation keys
MSG *msg = (MSG *)pMsg;
bool bProcess = TRUE;
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/Enter combinations which are 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,
+ bWindowChange = FALSE;
- bool bForward = TRUE,
- bWindowChange = FALSE;
- if ( bProcess ) {
- switch ( msg->wParam ) {
+ switch ( msg->wParam )
+ {
case VK_TAB:
if ( lDlgCode & DLGC_WANTTAB ) {
bProcess = FALSE;
break;
case VK_RETURN:
- // if there is a default button, Enter should press it
- if ( !GetDefaultItem() ) {
- // but if there is not it makes sense to make it work
- // like a TAB
- if ( bCtrlDown || (lDlgCode & DLGC_WANTMESSAGE == 0) )
- {
- // nothing to do - all variables are already set
-
- break;
- }
- else
+ {
+ 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
}
- //else: fall through and don't process the message
+ break;
default:
bProcess = FALSE;
}
- }
- if ( bProcess ) {
- wxNavigationKeyEvent event;
- event.SetDirection(bForward);
- event.SetWindowChange(bWindowChange);
- 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
- else if ( m_tooltip ) {
+ if ( m_tooltip )
+ {
// relay mouse move events to the tooltip control
MSG *msg = (MSG *)pMsg;
if ( msg->message == WM_MOUSEMOVE )
}
#endif // wxUSE_TOOLTIPS
+/* This code manages to disable character input completely. Nice one!
+ * Probably because the dialog is requesting all char input. Or,
+ * it gets called by non-dialog windows.
+
+ // In case we don't have wxTAB_TRAVERSAL style on.
+ // If we don't call this, we may never process Enter correctly.
+ if ( m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL) == 0 )
+ {
+ MSG *msg = (MSG *)pMsg;
+ if ( ::IsDialogMessage((HWND)GetHWND(), msg) )
+ return TRUE;
+ }
+*/
return FALSE;
}
long wxWindow::MSWOnSysCommand(WXWPARAM wParam, WXLPARAM lParam)
{
- switch (wParam)
+ switch (wParam & 0xFFFFFFF0)
{
case SC_MAXIMIZE:
{
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;
void wxWindow::MSWOnMouseMove(int x, int y, WXUINT flags)
{
// 'normal' move event...
- // Set cursor, but only if we're not in 'busy' mode
-
- // Trouble with this is that it sets the cursor for controls too :-(
- if (m_windowCursor.Ok() && !wxIsBusy())
- ::SetCursor((HCURSOR) m_windowCursor.GetHCURSOR());
if (!m_mouseInWindow)
{
GetEventHandler()->ProcessEvent(event);
}
-void wxWindow::MSWOnChar(WXWORD wParam, WXLPARAM lParam, bool isASCII)
+// isASCII is TRUE only when we're called from WM_CHAR handler and not from
+// WM_KEYDOWN one
+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)
{
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)
{
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)
void wxWindow::OnChar(wxKeyEvent& event)
{
-#if 0
- if ( event.KeyCode() == WXK_TAB ) {
- // propagate the TABs to the parent - it's up to it to decide what
- // to do with it
- wxWindow *parent = GetParent();
- if ( parent ) {
- if ( parent->GetEventHandler()->ProcessEvent(event) )
- return;
- }
- }
-#endif // 0
+ event.Skip();
+}
- bool isVirtual;
- int id = wxCharCodeWXToMSW((int)event.KeyCode(), &isVirtual);
+void wxWindow::OnKeyDown(wxKeyEvent& event)
+{
+ Default();
+}
- if ( id == -1 )
- id= m_lastWParam;
+void wxWindow::OnKeyUp(wxKeyEvent& event)
+{
+ Default();
+}
- if ( !event.ControlDown() )
- (void) MSWDefWindowProc(m_lastMsg, (WPARAM) id, m_lastLParam);
+void wxWindow::OnPaint(wxPaintEvent& event)
+{
+ Default();
}
bool wxWindow::IsEnabled(void) const
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());