#include <string.h>
-#if (!defined(__GNUWIN32_OLD__) && !defined(__WXMICROWIN__) && !defined(__WXWINCE__)) || defined(__CYGWIN10__)
+#if (!defined(__GNUWIN32_OLD__) && !defined(__WXMICROWIN__) /* && !defined(__WXWINCE__) */ ) || defined(__CYGWIN10__)
#include <shellapi.h>
#include <mmsystem.h>
#endif
#include <windowsx.h>
#endif
-#if (!defined(__GNUWIN32_OLD__) && !defined(__WXMICROWIN__) && !defined(__WXWINCE__)) || defined(__CYGWIN10__)
+#if (!defined(__GNUWIN32_OLD__) && !defined(__WXMICROWIN__) /* && !defined(__WXWINCE__) */ ) || defined(__CYGWIN10__)
#ifdef __WIN95__
#include <commctrl.h>
#endif
#include "wx/msw/gnuwin32/extra.h"
#endif
-#if defined(__GNUG__)
#include "wx/msw/missing.h"
-#endif
#if defined(__WXWINCE__)
#include "wx/msw/wince/missing.h"
#endif
-// ----------------------------------------------------------------------------
-// standard constants not available with all compilers/headers
-// ----------------------------------------------------------------------------
-
-// This didn't appear in mingw until 2.95.2
-#ifndef SIF_TRACKPOS
-#define SIF_TRACKPOS 16
-#endif
-
-#if wxUSE_MOUSEWHEEL
- #ifndef WM_MOUSEWHEEL
- #define WM_MOUSEWHEEL 0x020A
- #endif
- #ifndef WHEEL_DELTA
- #define WHEEL_DELTA 120
- #endif
- #ifndef SPI_GETWHEELSCROLLLINES
- #define SPI_GETWHEELSCROLLLINES 104
- #endif
-#endif // wxUSE_MOUSEWHEEL
-
-#ifndef VK_OEM_1
- #define VK_OEM_1 0xBA
- #define VK_OEM_2 0xBF
- #define VK_OEM_3 0xC0
- #define VK_OEM_4 0xDB
- #define VK_OEM_5 0xDC
- #define VK_OEM_6 0xDD
- #define VK_OEM_7 0xDE
-#endif
-
-#ifndef VK_OEM_COMMA
- #define VK_OEM_PLUS 0xBB
- #define VK_OEM_COMMA 0xBC
- #define VK_OEM_MINUS 0xBD
- #define VK_OEM_PERIOD 0xBE
-#endif
-
// ---------------------------------------------------------------------------
// global variables
// ---------------------------------------------------------------------------
// true if we had already created the std colour map, used by
// wxGetStdColourMap() and wxWindow::OnSysColourChanged() (FIXME-MT)
-static bool gs_hasStdCmap = FALSE;
+static bool gs_hasStdCmap = false;
// ---------------------------------------------------------------------------
// private functions
// Default command handler
bool wxWindowMSW::MSWCommand(WXUINT WXUNUSED(param), WXWORD WXUNUSED(id))
{
- return FALSE;
+ return false;
}
// ----------------------------------------------------------------------------
void wxWindowMSW::Init()
{
// MSW specific
- m_isBeingDeleted = FALSE;
+ m_isBeingDeleted = false;
m_oldWndProc = NULL;
- m_mouseInWindow = FALSE;
- m_lastKeydownProcessed = FALSE;
+ m_mouseInWindow = false;
+ m_lastKeydownProcessed = false;
m_childrenDisabled = NULL;
+ m_frozenness = 0;
// wxWnd
m_hMenu = 0;
m_xThumbSize = 0;
m_yThumbSize = 0;
- // as all windows are created with WS_VISIBLE style...
- m_isShown = TRUE;
-
#if wxUSE_MOUSEEVENT_HACK
m_lastMouseX =
m_lastMouseY = -1;
// Destructor
wxWindowMSW::~wxWindowMSW()
{
- m_isBeingDeleted = TRUE;
+ m_isBeingDeleted = true;
#ifndef __WXUNIVERSAL__
// VS: make sure there's no wxFrame with last focus set to us:
long style,
const wxString& name)
{
- wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") );
+ wxCHECK_MSG( parent, false, wxT("can't create wxWindow without parent") );
if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
- return FALSE;
+ return false;
parent->AddChild(this);
msflags &= ~WS_BORDER;
#endif // wxUniversal
- // all windows are created visible by default except popup ones (which are
- // like the wxTopLevelWindows in this aspect)
- if ( style & wxPOPUP_WINDOW )
- {
- msflags &= ~WS_VISIBLE;
- m_isShown = FALSE;
- }
- else
+ if ( IsShown() )
{
msflags |= WS_VISIBLE;
}
bool wxWindowMSW::Enable(bool enable)
{
if ( !wxWindowBase::Enable(enable) )
- return FALSE;
+ return false;
HWND hWnd = GetHwnd();
if ( hWnd )
// showing a modal dialog would result in total greying out (and ungreying
// out later) of everything which would be really ugly
if ( IsTopLevel() )
- return TRUE;
+ return true;
// when the parent is disabled, all of its children should be disabled as
// well but when it is enabled back, only those of the children which
m_childrenDisabled = NULL;
}
- return TRUE;
+ return true;
}
bool wxWindowMSW::Show(bool show)
{
if ( !wxWindowBase::Show(show) )
- return FALSE;
+ return false;
HWND hWnd = GetHwnd();
int cshow = show ? SW_SHOW : SW_HIDE;
wxBringWindowToTop(hWnd);
}
- return TRUE;
+ return true;
}
// Raise the window to the top of the Z order
if ( !wxWindowBase::SetFont(font) )
{
// nothing to do
- return FALSE;
+ return false;
}
HWND hWnd = GetHwnd();
::SendMessage(hWnd, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0));
}
- return TRUE;
+ return true;
}
bool wxWindowMSW::SetCursor(const wxCursor& cursor)
{
if ( !wxWindowBase::SetCursor(cursor) )
{
// no change
- return FALSE;
+ return false;
}
if ( m_cursor.Ok() )
::SetCursor(GetHcursorOf(m_cursor));
}
- return TRUE;
+ return true;
}
void wxWindowMSW::WarpPointer (int x, int y)
wxAssociateWinWithHandle(hwnd, this);
- m_oldWndProc = (WXFARPROC)::GetWindowLong((HWND)hWnd, GWL_WNDPROC);
+ m_oldWndProc = (WXFARPROC)wxGetWindowProc((HWND)hWnd);
// we don't need to subclass the window of our own class (in the Windows
// sense of the word)
if ( !wxCheckWindowWndProc(hWnd, (WXFARPROC)wxWndProc) )
{
- ::SetWindowLong(hwnd, GWL_WNDPROC, (LONG) wxWndProc);
+ wxSetWindowProc(hwnd, wxWndProc);
}
else
{
// don't bother restoring it neither: this also makes it easy to
- // implement IsOfStandardClass() method which returns TRUE for the
- // standard controls and FALSE for the wxWindows own windows as it can
+ // implement IsOfStandardClass() method which returns true for the
+ // standard controls and false for the wxWindows own windows as it can
// simply check m_oldWndProc
m_oldWndProc = NULL;
}
{
if ( !wxCheckWindowWndProc((WXHWND)hwnd, m_oldWndProc) )
{
- ::SetWindowLong(hwnd, GWL_WNDPROC, (LONG) m_oldWndProc);
+ wxSetWindowProc(hwnd, (WNDPROC)m_oldWndProc);
}
m_oldWndProc = NULL;
str == wxMDIChildFrameClassName ||
str == wxMDIChildFrameClassNameNoRedraw ||
str == _T("wxTLWHiddenParent"))
- return TRUE; // Effectively means don't subclass
+ return true; // Effectively means don't subclass
else
- return FALSE;
+ return false;
#else
WNDCLASS cls;
if ( !::GetClassInfo(wxGetInstance(), wxGetWindowClass(hWnd), &cls) )
{
wxLogLastError(_T("GetClassInfo"));
- return FALSE;
+ return false;
}
return wndProc == (WXFARPROC)cls.lpfnWndProc;
if ( !IsMouseInWindow() )
{
// Generate a LEAVE event
- m_mouseInWindow = FALSE;
+ m_mouseInWindow = false;
// Unfortunately the mouse button and keyboard state may have
// changed by the time the OnInternalIdle function is called, so 'state'
bool wxWindowMSW::Reparent(wxWindowBase *parent)
{
if ( !wxWindowBase::Reparent(parent) )
- return FALSE;
+ return false;
HWND hWndChild = GetHwnd();
HWND hWndParent = GetParent() ? GetWinHwnd(GetParent()) : (HWND)0;
}
#endif // !__WXWINCE__
- return TRUE;
+ return true;
}
static inline void SendSetRedraw(HWND hwnd, bool on)
void wxWindowMSW::Freeze()
{
- SendSetRedraw(GetHwnd(), FALSE);
+ if ( !m_frozenness++ )
+ {
+ SendSetRedraw(GetHwnd(), false);
+ }
}
void wxWindowMSW::Thaw()
{
- SendSetRedraw(GetHwnd(), TRUE);
+ wxASSERT_MSG( m_frozenness > 0, _T("Thaw() without matching Freeze()") );
+
+ if ( !--m_frozenness )
+ {
+ SendSetRedraw(GetHwnd(), true);
- // we need to refresh everything or otherwise he invalidated area is not
- // repainted
- Refresh();
+ // we need to refresh everything or otherwise he invalidated area is not
+ // repainted
+ Refresh();
+ }
}
void wxWindowMSW::Refresh(bool eraseBack, const wxRect *rect)
menu->SetInvokingWindow(NULL);
- return TRUE;
+ return true;
}
#endif // wxUSE_MENUS_NATIVE
// pre/post message processing
// ===========================================================================
-long wxWindowMSW::MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
+WXLRESULT wxWindowMSW::MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
{
if ( m_oldWndProc )
return ::CallWindowProc(CASTWNDPROC m_oldWndProc, GetHwnd(), (UINT) nMsg, (WPARAM) wParam, (LPARAM) lParam);
}
}
- bool bForward = TRUE,
- bWindowChange = FALSE;
+ bool bForward = true,
+ bWindowChange = false;
// should we process this message specially?
- bool bProcess = TRUE;
+ bool bProcess = true;
switch ( msg->wParam )
{
case VK_TAB:
- // assume that nobody wants Shift-TAB for himself - if we
- // don't do it there is no easy way for a control to grab
- // TABs but still let Shift-TAB work as navugation key
- if ( (lDlgCode & DLGC_WANTTAB) && !bShiftDown ) {
- bProcess = FALSE;
+ if ( lDlgCode & DLGC_WANTTAB ) {
+ bProcess = false;
}
else {
// Ctrl-Tab cycles thru notebook pages
case VK_UP:
case VK_LEFT:
if ( (lDlgCode & DLGC_WANTARROWS) || bCtrlDown )
- bProcess = FALSE;
+ bProcess = false;
else
- bForward = FALSE;
+ bForward = false;
break;
case VK_DOWN:
case VK_RIGHT:
if ( (lDlgCode & DLGC_WANTARROWS) || bCtrlDown )
- bProcess = FALSE;
+ bProcess = false;
+ break;
+
+ case VK_ESCAPE:
+ {
+#if wxUSE_BUTTON
+ wxButton *btn = wxDynamicCast(FindWindow(wxID_CANCEL),
+ wxButton);
+ if ( btn && btn->IsEnabled() )
+ {
+ // if we do have a cancel button, do press it
+ btn->MSWCommand(BN_CLICKED, 0 /* unused */);
+
+ // we consumed the message
+ return true;
+ }
+#endif // wxUSE_BUTTON
+
+ bProcess = false;
+ }
break;
case VK_RETURN:
// control wants to process Enter itself, don't
// call IsDialogMessage() which would interpret
// it
- return FALSE;
+ return false;
}
else if ( lDlgCode & DLGC_BUTTON )
{
btn->MSWCommand(BN_CLICKED, 0 /* unused */);
}
- bProcess = FALSE;
+ bProcess = false;
}
// FIXME: this should be handled by
// wxNavigationKeyEvent handler and not here!!
// if we do have a default button, do press it
btn->MSWCommand(BN_CLICKED, 0 /* unused */);
- return TRUE;
+ return true;
}
else // no default button
{
// need it for itself and don't let
// ::IsDialogMessage() have it as it can
// eat the Enter events sometimes
- return FALSE;
+ return false;
}
else if (!IsTopLevel())
{
// if not a top level window, let parent
// handle it
- return FALSE;
+ return false;
}
//else: treat Enter as TAB: pass to the next
// control as this is the best thing to do
break;
default:
- bProcess = FALSE;
+ bProcess = false;
}
if ( bProcess )
if ( GetEventHandler()->ProcessEvent(event) )
{
- return TRUE;
+ return true;
}
}
}
}
#endif // 1/0
- // we handle VK_ESCAPE ourselves in wxDialog::OnCharHook() and we
- // shouldn't let IsDialogMessage() get it as it _always_ eats the
+ // don't let IsDialogMessage() get VK_ESCAPE as it _always_ eats the
// message even when there is no cancel button and when the message is
// needed by the control itself: in particular, it prevents the tree in
// place edit control from being closed with Escape in a dialog
// then
// assume we can call it by default
- bool canSafelyCallIsDlgMsg = TRUE;
+ bool canSafelyCallIsDlgMsg = true;
HWND hwndFocus = ::GetFocus();
if ( ::GetWindowLong(hwndFocus, GWL_EXSTYLE) & WS_EX_CONTROLPARENT )
{
// passimistic by default
- canSafelyCallIsDlgMsg = FALSE;
+ canSafelyCallIsDlgMsg = false;
for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
node;
node = node->GetNext() )
WS_EX_CONTROLPARENT) )
{
// it shouldn't hang...
- canSafelyCallIsDlgMsg = TRUE;
+ canSafelyCallIsDlgMsg = true;
break;
}
!::IsWindowVisible(hwndFocus) )
{
// it would enter an infinite loop if we do this!
- canSafelyCallIsDlgMsg = FALSE;
+ canSafelyCallIsDlgMsg = false;
break;
}
if ( canSafelyCallIsDlgMsg && ::IsDialogMessage(GetHwnd(), msg) )
{
// IsDialogMessage() did something...
- return TRUE;
+ return true;
}
}
}
}
#endif // wxUSE_TOOLTIPS
- return FALSE;
+ return false;
}
bool wxWindowMSW::MSWTranslateMessage(WXMSG* pMsg)
return m_acceleratorTable.Translate(this, pMsg);
#else
(void) pMsg;
- return FALSE;
+ return false;
#endif // wxUSE_ACCEL
}
bool wxWindowMSW::MSWShouldPreProcessMessage(WXMSG* WXUNUSED(pMsg))
{
// preprocess all messages by default
- return TRUE;
+ return true;
}
// ---------------------------------------------------------------------------
return rc;
}
-long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
+WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
{
// did we process the message?
- bool processed = FALSE;
+ bool processed = false;
// the return value
union
{
bool allow;
- long result;
+ WXLRESULT result;
WXHICON hIcon;
WXHBRUSH hBrush;
} rc;
break;
case WM_DESTROY:
- // never set processed to TRUE and *always* pass WM_DESTROY to
+ // never set processed to true and *always* pass WM_DESTROY to
// DefWindowProc() as Windows may do some internal cleanup when
// processing it and failing to pass the message along may cause
// memory and resource leaks!
// Universal uses its own wxFrame/wxDialog, so we don't receive
// close events unless we have this.
Close();
- processed = TRUE;
+ processed = true;
rc.result = TRUE;
#else
// don't let the DefWindowProc() destroy our window - we'll do it
// ourselves in ~wxWindow
- processed = TRUE;
+ processed = true;
rc.result = TRUE;
#endif
break;
wParam);
break;
+ // Seems to be broken currently
+#if 0 // ndef __WXWINCE__
+ case WM_MOUSELEAVE:
+ {
+ wxASSERT_MSG( !m_mouseInWindow, wxT("the mouse should be in a window to generate this event!") );
+
+ // only process this message if the mouse is not in the window,
+ // This can also check for children in composite windows.
+ // however, this may mean the the wxEVT_LEAVE_WINDOW is never sent
+ // if the mouse does not enter the window from it's child before
+ // leaving the scope of the window. ( perhaps this can be picked
+ // up in the OnIdle code as before, for this special case )
+ if ( /*IsComposite() && */ !IsMouseInWindow() )
+ {
+ m_mouseInWindow = false;
+
+ // Unfortunately no mouse state is passed with a WM_MOUSE_LEAVE
+ int state = 0;
+ if ( wxIsShiftDown() )
+ state |= MK_SHIFT;
+ if ( wxIsCtrlDown() )
+ state |= MK_CONTROL;
+ if ( GetKeyState( VK_LBUTTON ) )
+ state |= MK_LBUTTON;
+ if ( GetKeyState( VK_MBUTTON ) )
+ state |= MK_MBUTTON;
+ if ( GetKeyState( VK_RBUTTON ) )
+ state |= MK_RBUTTON;
+
+ POINT pt;
+ if ( !::GetCursorPos(&pt) )
+ {
+ wxLogLastError(_T("GetCursorPos"));
+ }
+
+ // we need to have client coordinates here for symmetry with
+ // wxEVT_ENTER_WINDOW
+ RECT rect = wxGetWindowRect(GetHwnd());
+ pt.x -= rect.left;
+ pt.y -= rect.top;
+
+ wxMouseEvent event2(wxEVT_LEAVE_WINDOW);
+ InitMouseEvent(event2, pt.x, pt.y, state);
+
+ (void)GetEventHandler()->ProcessEvent(event2);
+ }
+ // always pass processed back as false, this allows the window
+ // manager to process the message too. This is needed to ensure
+ // windows XP themes work properly as the mouse moves over widgets
+ // like buttons.
+ processed = false;
+ }
+ break;
+#endif
+ // __WXWINCE__
+
#if wxUSE_MOUSEWHEEL
case WM_MOUSEWHEEL:
processed = HandleMouseWheel(wParam, lParam);
{
if (!win->IsEnabled())
{
- processed = TRUE;
+ processed = true;
break;
}
processed = HandleNotify((int)wParam, lParam, &rc.result);
break;
- // for these messages we must return TRUE if process the message
+ // we only need to reply to WM_NOTIFYFORMAT manually when using MSLU,
+ // otherwise DefWindowProc() does it perfectly fine for us, but MSLU
+ // apparently doesn't always behave properly and needs some help
+#if wxUSE_UNICODE_MSLU && defined(NF_QUERY)
+ case WM_NOTIFYFORMAT:
+ if ( lParam == NF_QUERY )
+ {
+ processed = true;
+ rc.result = NFR_UNICODE;
+ }
+ break;
+#endif // wxUSE_UNICODE_MSLU
+
+ // for these messages we must return true if process the message
#ifdef WM_DRAWITEM
case WM_DRAWITEM:
case WM_MEASUREITEM:
DLGC_WANTALLKEYS;
}
- processed = TRUE;
+ processed = true;
}
//else: get the dlg code from the DefWindowProc()
break;
m_lastKeydownProcessed = HandleKeyDown((WORD) wParam, lParam);
if ( m_lastKeydownProcessed )
{
- processed = TRUE;
+ processed = true;
}
if ( !processed )
case VK_CAPITAL:
case VK_NUMLOCK:
case VK_SCROLL:
- processed = TRUE;
+ processed = true;
break;
// avoid duplicate messages to OnChar for these ASCII keys:
case VK_OEM_COMMA:
case VK_OEM_MINUS:
case VK_OEM_PERIOD:
- // but set processed to FALSE, not TRUE to still pass them
+ // but set processed to false, not true to still pass them
// to the control's default window proc - otherwise
// built-in keyboard handling won't work
- processed = FALSE;
+ processed = false;
break;
#ifdef VK_APPS
}
}
if (message == WM_SYSKEYDOWN) // Let Windows still handle the SYSKEYs
- processed = FALSE;
+ processed = false;
break;
case WM_SYSKEYUP:
// The key was handled in the EVT_KEY_DOWN and handling
// a key in an EVT_KEY_DOWN handler is meant, by
// design, to prevent EVT_CHARs from happening
- m_lastKeydownProcessed = FALSE;
- processed = TRUE;
+ m_lastKeydownProcessed = false;
+ processed = true;
}
else
{
- processed = HandleChar((WORD)wParam, lParam, TRUE);
+ processed = HandleChar((WORD)wParam, lParam, true);
}
break;
{
#endif
wxWindowMSW* subjectOfHelp = this;
- bool eventProcessed = FALSE;
+ bool eventProcessed = false;
while (subjectOfHelp && !eventProcessed)
{
wxHelpEvent helpEvent(wxEVT_HELP,
processed = GetEventHandler()->ProcessEvent(helpEvent);
}
- //else: processed is already FALSE
+ //else: processed is already false
#endif
}
break;
wxPoint pt(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU, GetId(), pt);
- evtCtx.SetEventObject(this);
- processed = GetEventHandler()->ProcessEvent(evtCtx);
+
+ // we could have got an event from our child, reflect it back
+ // to it if this is the case
+ wxWindowMSW *win = NULL;
+ if ( (WXHWND)wParam != m_hWnd )
+ {
+ win = FindItemByHWND((WXHWND)wParam);
+ }
+
+ if ( !win )
+ win = this;
+
+ evtCtx.SetEventObject(win);
+ processed = win->GetEventHandler()->ProcessEvent(evtCtx);
}
break;
#endif
if ( i != wxNOT_FOUND )
{
rc.result = MAKELRESULT(i, MNC_EXECUTE);
- processed = TRUE;
+ processed = true;
}
}
break;
int& x, int& y,
int& w, int& h) const
{
+ // yes, those are just some arbitrary hardcoded numbers
static const int DEFAULT_Y = 200;
- static const int DEFAULT_H = 250;
- bool nonDefault = FALSE;
+ bool nonDefault = false;
if ( pos.x == -1 )
{
- // if set x to CW_USEDEFAULT, y parameter is ignored anyhow so we can
- // just as well set it to CW_USEDEFAULT as well
+ // if x is set to CW_USEDEFAULT, y parameter is ignored anyhow so we
+ // can just as well set it to CW_USEDEFAULT as well
x =
y = CW_USEDEFAULT;
}
x = pos.x;
y = pos.y == -1 ? DEFAULT_Y : pos.y;
- nonDefault = TRUE;
+ nonDefault = true;
}
/*
this and ignore any attempts to change the window size to the size it
already has - so no WM_SIZE would be sent.
*/
- if ( size.x == -1 )
- {
- // as above, h is not used at all in this case anyhow
- w =
- h = CW_USEDEFAULT;
- }
- else
- {
- // and, again as above, we can't set the height to CW_USEDEFAULT here
- w = size.x;
- h = size.y == -1 ? DEFAULT_H : size.y;
- nonDefault = TRUE;
+
+ // we don't use CW_USEDEFAULT here for several reasons:
+ //
+ // 1. it results in huge frames on modern screens (1000*800 is not
+ // uncommon on my 1280*1024 screen) which is way too big for a half
+ // empty frame of most of wxWindows samples for example)
+ //
+ // 2. it is buggy for frames with wxFRAME_TOOL_WINDOW style for which
+ // the default is for whatever reason 8*8 which breaks client <->
+ // window size calculations (it would be nice if it didn't, but it
+ // does and the simplest way to fix it seemed to change the broken
+ // default size anyhow)
+ //
+ // 3. there is just no advantage in doing it: with x and y it is
+ // possible that [future versions of] Windows position the new top
+ // level window in some smart way which we can't do, but we can
+ // guess a reasonably good size for a new window just as well
+ // ourselves
+ if ( size.x == -1 || size.y == -1)
+ {
+ nonDefault = true;
}
+ w = WidthDefault(size.x);
+ h = HeightDefault(size.y);
AdjustForParentClientOrigin(x, y);
{
wxLogSysError(_("Can't create window of class %s"), wclass);
- return FALSE;
+ return false;
}
SubclassWin(m_hWnd);
- SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
-
- return TRUE;
+ return true;
}
// ===========================================================================
wxWindow *child = node->GetData();
if ( child->MSWOnNotify(idCtrl, lParam, result) )
{
- return TRUE;
+ return true;
}
node = node->GetNext();
// by default, handle it ourselves
return MSWOnNotify(idCtrl, lParam, result);
#else // __WXMICROWIN__
- return FALSE;
+ return false;
#endif
}
// we need to handle it as well, otherwise no tooltips will be shown in
// this case
#ifndef __WXWINCE__
- if ( !(code == (WXUINT) TTN_NEEDTEXTA || code == (WXUINT) TTN_NEEDTEXTW) || ttip.empty() )
+ if ( !(code == (WXUINT) TTN_NEEDTEXTA || code == (WXUINT) TTN_NEEDTEXTW)
+ || ttip.empty() )
{
// not a tooltip message or no tooltip to show anyhow
- return FALSE;
+ return false;
}
#endif
LPTOOLTIPTEXT ttText = (LPTOOLTIPTEXT)lParam;
+ // We don't want to use the szText buffer because it has a limit of 80
+ // bytes and this is not enough, especially for Unicode build where it
+ // limits the tooltip string length to only 40 characters
+ //
+ // The best would be, of course, to not impose any length limitations at
+ // all but then the buffer would have to be dynamic and someone would have
+ // to free it and we don't have the tooltip owner object here any more, so
+ // for now use our own static buffer with a higher fixed max length.
+ //
+ // Note that using a static buffer should not be a problem as only a single
+ // tooltip can be shown at the same time anyhow.
#if !wxUSE_UNICODE
- if ( code == (WXUINT) TTN_NEEDTEXTA )
+ if ( code == (WXUINT) TTN_NEEDTEXTW )
{
- // we pass just the pointer as we store the string internally anyhow
- ttText->lpszText = (char *)ttip.c_str();
- }
- else // TTN_NEEDTEXTW
-#endif // !Unicode
- {
-#if wxUSE_UNICODE
- // in Unicode mode this is just what we need
- ttText->lpszText = (wxChar *)ttip.c_str();
-#else // !Unicode
-/*
- MultiByteToWideChar(CP_ACP, 0, ttip, ttip.length()+1,
- (wchar_t *)ttText->szText,
- sizeof(ttText->szText) / sizeof(wchar_t));
-*/
- // Fix by dimitrishortcut: see patch 771772
+ // We need to convert tooltip from multi byte to Unicode on the fly.
+ static wchar_t buf[513];
- // FIXME: szText has a max of 80 bytes, so limit the tooltip string
- // length accordingly. Ideally lpszText should be used, but who
- // would be responsible for freeing the buffer?
-
- // Maximum length of a tip is 39 characters. 39 is 80/2 minus 1 byte
- // needed for NULL character.
- size_t tipLength = wxMin(ttip.Len(), 39);
+ // Truncate tooltip length if needed as otherwise we might not have
+ // enough space for it in the buffer and MultiByteToWideChar() would
+ // return an error
+ size_t tipLength = wxMin(ttip.Len(), WXSIZEOF(buf) - 1);
// Convert to WideChar without adding the NULL character. The NULL
- // character is added afterwards (Could have used ttip.Left(tipLength)
- // and a cchMultiByte parameter of tipLength+1, but this is more
- //efficient.
- ::MultiByteToWideChar(CP_ACP, 0, ttip, tipLength,
- (wchar_t *)ttText->szText,
- sizeof(ttText->szText) / sizeof(wchar_t));
-
- // Add the NULL character.
- ttText->szText[tipLength*2+0] = '\0';
- ttText->szText[tipLength*2+1] = '\0';
+ // character is added afterwards (this is more efficient).
+ int len = ::MultiByteToWideChar
+ (
+ CP_ACP,
+ 0, // no flags
+ ttip,
+ tipLength,
+ buf,
+ WXSIZEOF(buf) - 1
+ );
+
+ if ( !len )
+ {
+ wxLogLastError(_T("MultiByteToWideChar()"));
+ }
-#endif // Unicode/!Unicode
+ buf[len] = L'\0';
+ ttText->lpszText = (LPSTR) buf;
+ }
+ else // TTN_NEEDTEXTA
+#endif // !wxUSE_UNICODE
+ {
+ // we get here if we got TTN_NEEDTEXTA (only happens in ANSI build) or
+ // if we got TTN_NEEDTEXTW in Unicode build: in this case we just have
+ // to copy the string we have into the buffer
+ static wxChar buf[513];
+ wxStrncpy(buf, ttip.c_str(), WXSIZEOF(buf) - 1);
+ buf[WXSIZEOF(buf) - 1] = _T('\0');
+ ttText->lpszText = buf;
}
- return TRUE;
+ return true;
}
#endif // wxUSE_TOOLTIPS
if ( HandleTooltipNotify(hdr->code, lParam, m_tooltip->GetTip()))
{
// processed
- return TRUE;
+ return true;
}
}
#endif // wxUSE_TOOLTIPS
- return FALSE;
+ return false;
}
#endif // __WIN95__
#ifndef __WXWINCE__
wxCloseEvent event(wxEVT_QUERY_END_SESSION, -1);
event.SetEventObject(wxTheApp);
- event.SetCanVeto(TRUE);
+ event.SetCanVeto(true);
event.SetLoggingOff(logOff == (long)ENDSESSION_LOGOFF);
bool rc = wxTheApp->ProcessEvent(event);
return rc;
#else
- return FALSE;
+ return false;
#endif
}
#ifndef __WXWINCE__
// do nothing if the session isn't ending
if ( !endSession )
- return FALSE;
+ return false;
// only send once
if ( (this != wxTheApp->GetTopWindow()) )
- return FALSE;
+ return false;
wxCloseEvent event(wxEVT_END_SESSION, -1);
event.SetEventObject(wxTheApp);
- event.SetCanVeto(FALSE);
+ event.SetCanVeto(false);
event.SetLoggingOff( (logOff == (long)ENDSESSION_LOGOFF) );
return wxTheApp->ProcessEvent(event);
#else
- return FALSE;
+ return false;
#endif
}
wxWindowCreateEvent event((wxWindow *)this);
(void)GetEventHandler()->ProcessEvent(event);
- *mayCreate = TRUE;
+ *mayCreate = true;
- return TRUE;
+ return true;
}
bool wxWindowMSW::HandleDestroy()
#endif // wxUSE_DRAG_AND_DROP
// WM_DESTROY handled
- return TRUE;
+ return true;
}
// ---------------------------------------------------------------------------
// after the control gets to process it from EN_FOCUS handler
if ( wxDynamicCastThis(wxTextCtrl) )
{
- return FALSE;
+ return false;
}
#endif // wxUSE_TEXTCTRL
wxTextCtrl *ctrl = wxDynamicCastThis(wxTextCtrl);
if ( ctrl )
{
- return FALSE;
+ return false;
}
#endif
// only cause problems if the event handler tries to access the object.
if ( m_isBeingDeleted )
{
- return FALSE;
+ return false;
}
wxFocusEvent event(wxEVT_KILL_FOCUS, m_windowId);
bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam)
{
#if defined (__WXMICROWIN__) || defined(__WXWINCE__)
- return FALSE;
+ return false;
#else // __WXMICROWIN__
HDROP hFilesInfo = (HDROP) wParam;
if ( nHitTest != HTCLIENT )
{
- return FALSE;
+ return false;
}
HCURSOR hcursor = 0;
::SetCursor(hcursor);
// cursor set, stop here
- return TRUE;
+ return true;
}
#endif // __WXMICROWIN__
// pass up the window chain
- return FALSE;
+ return false;
}
// ---------------------------------------------------------------------------
{
wxMenuItem *pMenuItem = (wxMenuItem *)(pDrawStruct->itemData);
- wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
+ wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), false );
// prepare to call OnDrawItem(): notice using of wxDCTemp to prevent
// the DC from being released
#endif // wxUSE_CONTROLS
- return FALSE;
+ return false;
}
bool
{
wxMenuItem *pMenuItem = (wxMenuItem *)(pMeasureStruct->itemData);
- wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
+ wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), false );
+
+ size_t w, h;
+ bool rc = pMenuItem->OnMeasureItem(&w, &h);
- return pMenuItem->OnMeasureItem(&pMeasureStruct->itemWidth,
- &pMeasureStruct->itemHeight);
+ pMeasureStruct->itemWidth = w;
+ pMeasureStruct->itemHeight = h;
+
+ return rc;
}
wxControl *item = wxDynamicCast(FindItem(id), wxControl);
}
#endif // wxUSE_OWNER_DRAWN
- return FALSE;
+ return false;
}
// ---------------------------------------------------------------------------
// always let the system carry on the default processing to allow the
// native controls to react to the colours update
- return FALSE;
+ return false;
}
bool wxWindowMSW::HandleDisplayChange()
WXHBRUSH hBrush = 0;
#ifdef __WXWINCE__
- if (FALSE)
+ if (false)
#else
if ( nCtlColor == CTLCOLOR_DLG )
#endif
#if wxUSE_CONTROLS
else
{
- wxControl *item = (wxControl *)FindItemByHWND(pWnd, TRUE);
+ wxControl *item = (wxControl *)FindItemByHWND(pWnd, true);
if ( item )
hBrush = item->OnCtlColor(pDC, pWnd, nCtlColor, message, wParam, lParam);
}
return hBrush != 0;
#else // __WXMICROWIN__
- return FALSE;
+ return false;
#endif
}
// now check for the need to redraw
if (result > 0)
- InvalidateRect((HWND) hWndPalChange, NULL, TRUE);
+ ::InvalidateRect((HWND) hWndPalChange, NULL, TRUE);
}
}
if ( IsTopLevel() )
{
// FIXME-MT
- gs_hasStdCmap = FALSE;
+ gs_hasStdCmap = false;
}
wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
while ( node )
// update the colours we use if they were not set explicitly by the user:
// this must be done or OnCtlColor() would continue to use the old colours
- if ( !m_hasFgCol )
+ if ( !m_hasFgCol || !m_hasBgCol )
{
- m_foregroundColour = wxSystemSettings::
- GetSystemColour(wxSYS_COLOUR_WINDOWTEXT);
- }
+ wxVisualAttributes attrs = GetDefaultAttributes();
+ if ( !m_hasFgCol )
+ m_foregroundColour = attrs.colFg;
- if ( !m_hasBgCol )
- {
- m_backgroundColour = wxSystemSettings::
- GetSystemColour(wxSYS_COLOUR_BTNFACE);
+ if ( !m_hasBgCol )
+ m_backgroundColour = attrs.colBg;
}
}
if ( !gs_hasStdCmap )
{
- static bool s_coloursInit = FALSE;
+ static bool s_coloursInit = false;
if ( !s_coloursInit )
{
//s_stdColours[5] = RGB(255,000,255); // magenta
}
- s_coloursInit = TRUE;
+ s_coloursInit = true;
}
- gs_hasStdCmap = TRUE;
+ gs_hasStdCmap = true;
// create the colour map
#define INIT_CMAP_ENTRY(col) \
{
// Prevents flicker when dragging
if ( ::IsIconic(GetHwnd()) )
- return TRUE;
+ return true;
#if 0
if (GetParent() && GetParent()->GetExtraStyle() & wxWS_EX_THEMED_BACKGROUND)
{
- return FALSE;
+ return false;
}
if (GetExtraStyle() & wxWS_EX_THEMED_BACKGROUND)
::GetClientRect((HWND) GetHWND(), (RECT*) & rect);
wxUxThemeEngine::Get()->m_pfnDrawThemeBackground(hTheme, hdc, 10 /* TABP_BODY */, 0, &rect, &rect);
wxUxThemeEngine::Get()->m_pfnCloseThemeData(hTheme);
- return TRUE;
+ return true;
}
}
}
bool wxWindowMSW::HandleGetMinMaxInfo(void *mmInfo)
{
#ifdef __WXWINCE__
- return FALSE;
+ return false;
#else
MINMAXINFO *info = (MINMAXINFO *)mmInfo;
- bool rc = FALSE;
+ bool rc = false;
int minWidth = GetMinWidth(),
minHeight = GetMinHeight(),
if ( minWidth != -1 )
{
info->ptMinTrackSize.x = minWidth;
- rc = TRUE;
+ rc = true;
}
if ( minHeight != -1 )
{
info->ptMinTrackSize.y = minHeight;
- rc = TRUE;
+ rc = true;
}
if ( maxWidth != -1 )
{
info->ptMaxTrackSize.x = maxWidth;
- rc = TRUE;
+ rc = true;
}
if ( maxHeight != -1 )
{
info->ptMaxTrackSize.y = maxHeight;
- rc = TRUE;
+ rc = true;
}
return rc;
// wxSpinCtrl
wxSpinCtrl *spin = wxSpinCtrl::GetSpinForTextCtrl(control);
if ( spin && spin->ProcessTextCommand(cmd, id) )
- return TRUE;
+ return true;
}
#endif // wxUSE_SPINCTRL
- return FALSE;
+ return false;
}
bool wxWindowMSW::HandleSysCommand(WXWPARAM wParam, WXLPARAM WXUNUSED(lParam))
}
#endif
- return FALSE;
+ return false;
}
// ---------------------------------------------------------------------------
if ( !HasCapture() || IsMouseInWindow() )
{
// Generate an ENTER event
- m_mouseInWindow = TRUE;
-
+ m_mouseInWindow = true;
+#if _WIN32_WINNT >= 0x0400
+#ifndef __WXWINCE__
+ TRACKMOUSEEVENT trackinfo;
+
+ trackinfo.cbSize = sizeof(trackinfo);
+ trackinfo.dwFlags = TME_LEAVE;
+ trackinfo.hwndTrack = GetHwnd();
+ //Use the commctrl.h _TrackMouseEvent, which will call the
+ // appropriate TrackMouseEvent or emulate it ( win95 )
+ // else we need _WIN32_WINNT >= 0x0400
+ _TrackMouseEvent(&trackinfo);
+#endif
+#endif
wxMouseEvent event(wxEVT_ENTER_WINDOW);
InitMouseEvent(event, x, y, flags);
{
m_lastMouseEvent = wxEVT_MOTION;
- return FALSE;
+ return false;
}
#endif // wxUSE_MOUSEEVENT_HACK
(void) wParam;
(void) lParam;
- return FALSE;
+ return false;
#endif
}
return event;
}
-// isASCII is TRUE only when we're called from WM_CHAR handler and not from
+// isASCII is true only when we're called from WM_CHAR handler and not from
// WM_KEYDOWN one
bool wxWindowMSW::HandleChar(WXWPARAM wParam, WXLPARAM lParam, bool isASCII)
{
{
// If 1 -> 26, translate to either special keycode or just set
// ctrlDown. IOW, Ctrl-C should result in keycode == 3 and
- // ControlDown() == TRUE.
+ // ControlDown() == true.
id = wParam;
if ( (id > 0) && (id < 27) )
{
break;
default:
- //ctrlDown = TRUE;
+ //ctrlDown = true;
break;
}
}
}
else // we're called from WM_KEYDOWN
{
- id = wxCharCodeMSWToWX(wParam);
+ id = wxCharCodeMSWToWX(wParam, lParam);
if ( id == 0 )
{
// it's ASCII and will be processed here only when called from
- // WM_CHAR (i.e. when isASCII = TRUE), don't process it now
- return FALSE;
+ // WM_CHAR (i.e. when isASCII = true), don't process it now
+ return false;
}
}
(id >= 32 && id < 256) )
{
event.m_controlDown =
- event.m_altDown = FALSE;
+ event.m_altDown = false;
}
return GetEventHandler()->ProcessEvent(event);
bool wxWindowMSW::HandleKeyDown(WXWPARAM wParam, WXLPARAM lParam)
{
- int id = wxCharCodeMSWToWX(wParam);
+ int id = wxCharCodeMSWToWX(wParam, lParam);
if ( !id )
{
wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_DOWN, id, lParam, wParam));
if ( GetEventHandler()->ProcessEvent(event) )
{
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam, WXLPARAM lParam)
{
- int id = wxCharCodeMSWToWX(wParam);
+ int id = wxCharCodeMSWToWX(wParam, lParam);
if ( !id )
{
{
wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_UP, id, lParam, wParam));
if ( GetEventHandler()->ProcessEvent(event) )
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
int wxWindowMSW::HandleMenuChar(int chAccel, WXLPARAM lParam)
default:
wxFAIL_MSG(wxT("no such joystick event"));
- return FALSE;
+ return false;
}
wxJoystickEvent event(eventType, buttons, joystick, change);
return GetEventHandler()->ProcessEvent(event);
#else
- return FALSE;
+ return false;
#endif
}
bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam,
WXWORD pos, WXHWND control)
-{
- if ( control )
+{
+ if ( control && control != m_hWnd ) // Prevent infinite recursion
{
wxWindow *child = wxFindWinFromHandle(control);
if ( child )
break;
default:
- return FALSE;
+ return false;
}
return GetEventHandler()->ProcessEvent(event);
// Returns 0 if was a normal ASCII value, not a special key. This indicates that
// the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead.
-int wxCharCodeMSWToWX(int keySym)
+int wxCharCodeMSWToWX(int keySym, WXLPARAM lParam)
{
int id;
switch (keySym)
case VK_BACK: id = WXK_BACK; break;
case VK_TAB: id = WXK_TAB; break;
case VK_CLEAR: id = WXK_CLEAR; break;
- case VK_RETURN: id = WXK_RETURN; break;
case VK_SHIFT: id = WXK_SHIFT; break;
case VK_CONTROL: id = WXK_CONTROL; break;
case VK_MENU : id = WXK_MENU; break;
case VK_APPS: id = WXK_WINDOWS_MENU; break;
#endif // VK_APPS defined
+ case VK_RETURN:
+ // the same key is sent for both the "return" key on the main
+ // keyboard and the numeric keypad but we want to distinguish
+ // between them: we do this using the "extended" bit (24) of lParam
+ id = lParam & (1 << 24) ? WXK_NUMPAD_ENTER : WXK_RETURN;
+ break;
+
default:
id = 0;
}
int wxCharCodeWXToMSW(int id, bool *isVirtual)
{
- *isVirtual = TRUE;
+ *isVirtual = true;
int keySym;
switch (id)
{
case WXK_SCROLL: keySym = VK_SCROLL; break;
default:
{
- *isVirtual = FALSE;
+ *isVirtual = false;
keySym = id;
break;
}
return keySym;
}
+bool wxGetKeyState(wxKeyCode key)
+{
+ bool bVirtual;
+ int vkey = wxCharCodeWXToMSW(key, &bVirtual);
+
+ //there aren't WXK_ macros for non-virtual key codes
+ if (bVirtual == false)
+ return false;
+
+ return GetKeyState(vkey) < 0;
+}
+
wxWindow *wxGetActiveWindow()
{
HWND hWnd = GetActiveWindow();
// do it as well, win would be already non NULL
if ( ::SendMessage(hwnd, WM_GETDLGCODE, 0, 0) & DLGC_RADIOBUTTON )
{
- win = (wxWindow *)::GetWindowLong(hwnd, GWL_USERDATA);
+ win = (wxWindow *)wxGetWindowUserData(hwnd);
}
//else: it's a wxRadioButton, not a radiobutton from wxRadioBox
#endif // wxUSE_RADIOBOX
DWORD hiWord = HIWORD(lParam);
if ( nCode != HC_NOREMOVE && ((hiWord & KF_UP) == 0) )
{
- int id = wxCharCodeMSWToWX(wParam);
+ int id = wxCharCodeMSWToWX(wParam, lParam);
if ( id != 0 )
{
wxKeyEvent event(wxEVT_CHAR_HOOK);
if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN )
- event.m_altDown = TRUE;
+ event.m_altDown = true;
event.m_eventObject = NULL;
event.m_keyCode = id;
{
wxLogLastError(_T("RegisterHotKey"));
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
bool wxWindowMSW::UnregisterHotKey(int hotkeyId)
{
wxLogLastError(_T("UnregisterHotKey"));
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
bool wxWindowMSW::HandleHotKey(WXWPARAM wParam, WXLPARAM lParam)
#endif // wxUSE_HOTKEY
-// Not verified for WinCE
+// Not tested under WinCE
#ifndef __WXWINCE__
-/*
- * wxEventFixModule (needs a better name) allows message handling to continute while a menu
- * is being shown - ie, to continue processing messages from a worker thread.
- *
- * Code originally by Jason W. from wx-dev, reworked into a wxModule by Chris Mellon
- */
-
-class wxEventFixModule : public wxModule {
+
+// this class installs a message hook which really wakes up our idle processing
+// each time a WM_NULL is received (wxWakeUpIdle does this), even if we're
+// sitting inside a local modal loop (e.g. a menu is opened or scrollbar is
+// being dragged or even inside ::MessageBox()) and so don't control message
+// dispatching otherwise
+class wxIdleWakeUpModule : public wxModule
+{
public:
- //base class virtuals
- virtual bool OnInit() {
- wxEventFixModule::s_hMsgHookProc = SetWindowsHookEx(
- WH_GETMESSAGE,
- &wxEventFixModule::MsgHookProc,
- NULL,
- GetCurrentThreadId());
- wxLogDebug(_T("Loaded event fix module"));
- return true;
- };
- virtual void OnExit() {
- UnhookWindowsHookEx(wxEventFixModule::s_hMsgHookProc);
+ virtual bool OnInit()
+ {
+ ms_hMsgHookProc = ::SetWindowsHookEx
+ (
+ WH_GETMESSAGE,
+ &wxIdleWakeUpModule::MsgHookProc,
+ NULL,
+ GetCurrentThreadId()
+ );
- };
- static LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam) {
+ if ( !ms_hMsgHookProc )
+ {
+ wxLogLastError(_T("SetWindowsHookEx(WH_GETMESSAGE)"));
+
+ return false;
+ }
+
+ return true;
+ }
+
+ virtual void OnExit()
+ {
+ ::UnhookWindowsHookEx(wxIdleWakeUpModule::ms_hMsgHookProc);
+ }
+
+ static LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam)
+ {
MSG *msg = (MSG*)lParam;
- switch (msg->message)
+ if ( msg->message == WM_NULL )
{
- case WM_NULL:
- static bool bInHookProc = false;
- if (!bInHookProc)
- {
- bInHookProc = true;
- wxTheApp->ProcessPendingEvents();
- bInHookProc = false;
- }
- break;
+ wxTheApp->ProcessPendingEvents();
}
- return CallNextHookEx(wxEventFixModule::s_hMsgHookProc, nCode, wParam, lParam);
+
+ return CallNextHookEx(ms_hMsgHookProc, nCode, wParam, lParam);
};
+
private:
- static HHOOK s_hMsgHookProc;
-DECLARE_DYNAMIC_CLASS(wxEventFixModule)
+ static HHOOK ms_hMsgHookProc;
+
+ DECLARE_DYNAMIC_CLASS(wxIdleWakeUpModule)
};
-HHOOK wxEventFixModule::s_hMsgHookProc = 0;
-IMPLEMENT_DYNAMIC_CLASS(wxEventFixModule, wxModule)
-#endif
- // __WXWINCE__
+HHOOK wxIdleWakeUpModule::ms_hMsgHookProc = 0;
+
+IMPLEMENT_DYNAMIC_CLASS(wxIdleWakeUpModule, wxModule)
+
+#endif // __WXWINCE__