// Modified by: VZ on 13.05.99: no more Default(), MSWOnXXX() reorganisation
// Created: 04/01/98
// RCS-ID: $Id$
-// Copyright: (c) Julian Smart and Markus Holzem
-// Licence: wxWindows license
+// Copyright: (c) Julian Smart
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ===========================================================================
#include "wx/dnd.h"
#endif
+#if wxUSE_ACCESSIBILITY
+ #include "wx/access.h"
+ #include <oleacc.h>
+ #ifndef WM_GETOBJECT
+ #define WM_GETOBJECT 0x003D
+ #endif
+ #ifndef OBJID_CLIENT
+ #define OBJID_CLIENT 0xFFFFFFFC
+ #endif
+#endif
+
#include "wx/menuitem.h"
#include "wx/log.h"
#ifndef VK_OEM_1
#define VK_OEM_1 0xBA
- #define VK_OEM_PLUS 0xBB
- #define VK_OEM_COMMA 0xBC
- #define VK_OEM_MINUS 0xBD
- #define VK_OEM_PERIOD 0xBE
#define VK_OEM_2 0xBF
#define VK_OEM_3 0xC0
#define VK_OEM_4 0xDB
#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
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// the window proc for all our windows
+#ifdef __DIGITALMARS__
+extern "C" LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message,
+ WPARAM wParam, LPARAM lParam);
+#else
LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
+#endif
+
#ifdef __WXDEBUG__
const char *wxGetMessageName(int message);
#endif //__WXDEBUG__
void wxRemoveHandleAssociation(wxWindowMSW *win);
-void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win);
+#ifdef __DIGITALMARS__
+extern "C" void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win);
+#else
+extern void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win);
+#endif
wxWindow *wxFindWinFromHandle(WXHWND hWnd);
// this magical function is used to translate VK_APPS key presses to right
{
wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") );
-#if wxUSE_STATBOX
- // wxGTK doesn't allow to create controls with static box as the parent so
- // this will result in a crash when the program is ported to wxGTK - warn
- // about it
- //
- // the correct solution is to create the controls as siblings of the
- // static box
- wxASSERT_MSG( !wxDynamicCast(parent, wxStaticBox),
- _T("wxStaticBox can't be used as a window parent!") );
-#endif // wxUSE_STATBOX
-
if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
return FALSE;
if ( hWnd )
::EnableWindow(hWnd, (BOOL)enable);
+ // the logic below doesn't apply to the top level windows -- otherwise
+ // 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;
+
// 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
// hadn't been already disabled in the beginning should be enabled again,
// so we have to keep the list of those children
- wxWindowList::Node *node = GetChildren().GetFirst();
- while ( node )
+ for ( wxWindowList::Node *node = GetChildren().GetFirst();
+ node;
+ node = node->GetNext() )
{
wxWindow *child = node->GetData();
+ if ( child->IsTopLevel() )
+ {
+ // the logic below doesn't apply to top level children
+ continue;
+ }
if ( enable )
{
m_childrenDisabled->Append(child);
}
}
-
- node = node->GetNext();
}
if ( enable && m_childrenDisabled )
// scrolling stuff
// ---------------------------------------------------------------------------
+// convert wxHORIZONTAL/wxVERTICAL to SB_HORZ/SB_VERT
+static inline int wxDirToWinStyle(int orient)
+{
+ return orient == wxHORIZONTAL ? SB_HORZ : SB_VERT;
+}
+
#if WXWIN_COMPATIBILITY
void wxWindowMSW::SetScrollRange(int orient, int range, bool refresh)
{
-#if defined(__WIN95__)
-
int range1 = range;
// Try to adjust the range to cope with page size > 1
range1 += (pageSize - 1);
}
- SCROLLINFO info;
- int dir;
-
- if ( orient == wxHORIZONTAL ) {
- dir = SB_HORZ;
- } else {
- dir = SB_VERT;
- }
-
- info.cbSize = sizeof(SCROLLINFO);
+ WinStruct<SCROLLINFO> info;
info.nPage = pageSize; // Have to set this, or scrollbar goes awry
info.nMin = 0;
info.nMax = range1;
- info.nPos = 0;
info.fMask = SIF_RANGE | SIF_PAGE;
HWND hWnd = GetHwnd();
if ( hWnd )
- ::SetScrollInfo(hWnd, dir, &info, refresh);
-#else
- int wOrient;
- if ( orient == wxHORIZONTAL )
- wOrient = SB_HORZ;
- else
- wOrient = SB_VERT;
-
- HWND hWnd = GetHwnd();
- if ( hWnd )
- ::SetScrollRange(hWnd, wOrient, 0, range, refresh);
-#endif
+ ::SetScrollInfo(hWnd, wxDirToWinStyle(orient), &info, refresh);
}
void wxWindowMSW::SetScrollPage(int orient, int page, bool refresh)
{
-#if defined(__WIN95__)
- SCROLLINFO info;
- int dir;
-
- if ( orient == wxHORIZONTAL ) {
- dir = SB_HORZ;
- m_xThumbSize = page;
- } else {
- dir = SB_VERT;
- m_yThumbSize = page;
- }
-
- info.cbSize = sizeof(SCROLLINFO);
+ WinStruct<SCROLLINFO> info;
info.nPage = page;
- info.nMin = 0;
info.fMask = SIF_PAGE;
HWND hWnd = GetHwnd();
if ( hWnd )
- ::SetScrollInfo(hWnd, dir, &info, refresh);
-#else
- if ( orient == wxHORIZONTAL )
- m_xThumbSize = page;
- else
- m_yThumbSize = page;
-#endif
-}
-
-int wxWindowMSW::OldGetScrollRange(int orient) const
-{
- int wOrient;
- if ( orient == wxHORIZONTAL )
- wOrient = SB_HORZ;
- else
- wOrient = SB_VERT;
-
-#if __WATCOMC__ && defined(__WINDOWS_386__)
- short minPos, maxPos;
-#else
- int minPos, maxPos;
-#endif
- HWND hWnd = GetHwnd();
- if ( hWnd )
- {
- ::GetScrollRange(hWnd, wOrient, &minPos, &maxPos);
-#if defined(__WIN95__)
- // Try to adjust the range to cope with page size > 1
- // - a Windows API quirk
- int pageSize = GetScrollPage(orient);
- if ( pageSize > 1 )
- {
- maxPos -= (pageSize - 1);
- }
-#endif
- return maxPos;
- }
- else
- return 0;
+ ::SetScrollInfo(hWnd, wxDirToWinStyle(orient), &info, refresh);
}
int wxWindowMSW::GetScrollPage(int orient) const
{
- if ( orient == wxHORIZONTAL )
- return m_xThumbSize;
- else
- return m_yThumbSize;
+ return orient == wxHORIZONTAL ? m_xThumbSize : m_yThumbSize;
}
#endif // WXWIN_COMPATIBILITY
int wxWindowMSW::GetScrollPos(int orient) const
{
- int wOrient;
- if ( orient == wxHORIZONTAL )
- wOrient = SB_HORZ;
- else
- wOrient = SB_VERT;
-
HWND hWnd = GetHwnd();
wxCHECK_MSG( hWnd, 0, _T("no HWND in GetScrollPos") );
- return GetScrollPosition(hWnd, wOrient);
+ return GetScrollPosition(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT);
}
// This now returns the whole range, not just the number
// of positions that we can scroll.
int wxWindowMSW::GetScrollRange(int orient) const
{
- int wOrient;
- if ( orient == wxHORIZONTAL )
- wOrient = SB_HORZ;
- else
- wOrient = SB_VERT;
-
-#if __WATCOMC__ && defined(__WINDOWS_386__)
- short minPos, maxPos;
-#else
int minPos, maxPos;
-#endif
HWND hWnd = GetHwnd();
- if ( hWnd )
- {
- ::GetScrollRange(hWnd, wOrient, &minPos, &maxPos);
-#if defined(__WIN95__)
- // Try to adjust the range to cope with page size > 1
- // - a Windows API quirk
- int pageSize = GetScrollThumb(orient);
- if ( pageSize > 1 )
- {
- maxPos -= (pageSize - 1);
- }
- // October 10th: new range concept.
- maxPos += pageSize;
-#endif
-
- return maxPos;
- }
- else
+ if ( !hWnd )
return 0;
+
+ ::GetScrollRange(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
+ &minPos, &maxPos);
+
+ // undo "range - 1" done in SetScrollbar()
+ return maxPos + 1;
}
int wxWindowMSW::GetScrollThumb(int orient) const
{
- if ( orient == wxHORIZONTAL )
- return m_xThumbSize;
- else
- return m_yThumbSize;
+ return orient == wxHORIZONTAL ? m_xThumbSize : m_yThumbSize;
}
void wxWindowMSW::SetScrollPos(int orient, int pos, bool refresh)
HWND hWnd = GetHwnd();
wxCHECK_RET( hWnd, _T("SetScrollPos: no HWND") );
- int dir = orient == wxHORIZONTAL ? SB_HORZ : SB_VERT;
-
-#if defined(__WIN95__)
- SCROLLINFO info;
- info.cbSize = sizeof(SCROLLINFO);
+ WinStruct<SCROLLINFO> info;
info.nPage = 0;
info.nMin = 0;
info.nPos = pos;
info.fMask = SIF_POS;
- ::SetScrollInfo(hWnd, dir, &info, refresh);
-#else // !__WIN95__
- ::SetScrollPos(hWnd, dir, pos, refresh);
-#endif // __WIN95__/!__WIN95__
+ ::SetScrollInfo(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
+ &info, refresh);
}
// New function that will replace some of the above.
-void wxWindowMSW::SetScrollbar(int orient, int pos, int thumbVisible,
- int range, bool refresh)
-{
-#if defined(__WIN95__)
- int oldRange = range - thumbVisible;
-
- int range1 = oldRange;
-
- // Try to adjust the range to cope with page size > 1
- // - a Windows API quirk
- int pageSize = thumbVisible;
- if ( pageSize > 1 && range > 0)
- {
- range1 += (pageSize - 1);
- }
-
- SCROLLINFO info;
- int dir;
-
- if ( orient == wxHORIZONTAL ) {
- dir = SB_HORZ;
- } else {
- dir = SB_VERT;
- }
-
- info.cbSize = sizeof(SCROLLINFO);
- info.nPage = pageSize; // Have to set this, or scrollbar goes awry
- info.nMin = 0;
- info.nMax = range1;
+void wxWindowMSW::SetScrollbar(int orient,
+ int pos,
+ int pageSize,
+ int range,
+ bool refresh)
+{
+ WinStruct<SCROLLINFO> info;
+ info.nPage = pageSize;
+ info.nMin = 0; // range is nMax - nMin + 1
+ info.nMax = range - 1; // as both nMax and nMax are inclusive
info.nPos = pos;
info.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
- HWND hWnd = GetHwnd();
- if ( hWnd )
- ::SetScrollInfo(hWnd, dir, &info, refresh);
-#else
- int wOrient;
- if ( orient == wxHORIZONTAL )
- wOrient = SB_HORZ;
- else
- wOrient = SB_VERT;
-
HWND hWnd = GetHwnd();
if ( hWnd )
{
- ::SetScrollRange(hWnd, wOrient, 0, range, FALSE);
- ::SetScrollPos(hWnd, wOrient, pos, refresh);
- }
-#endif
- if ( orient == wxHORIZONTAL ) {
- m_xThumbSize = thumbVisible;
- } else {
- m_yThumbSize = thumbVisible;
+ ::SetScrollInfo(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
+ &info, refresh);
}
+
+ *(orient == wxHORIZONTAL ? &m_xThumbSize : &m_yThumbSize) = pageSize;
}
void wxWindowMSW::ScrollWindow(int dx, int dy, const wxRect *prect)
WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
{
// translate the style
- WXDWORD style = WS_CHILD;
+ WXDWORD style = WS_CHILD | WS_VISIBLE;
if ( flags & wxCLIP_CHILDREN )
style |= WS_CLIPCHILDREN;
style |= WS_CLIPSIBLINGS;
wxBorder border = (wxBorder)(flags & wxBORDER_MASK);
- if ( border != wxBORDER_NONE && border != wxBORDER_DEFAULT )
+
+ // Check if we want to automatically give it a sunken style.
+ // Note than because 'sunken' actually maps to WS_EX_CLIENTEDGE, which
+ // is a more neutral term, we don't necessarily get a sunken effect in
+ // Windows XP. Instead we get the appropriate style for the theme.
+
+ if (border == wxBORDER_DEFAULT && wxTheApp->GetAuto3D() &&
+ GetParent() && (GetParent()->IsKindOf(CLASSINFO(wxPanel)) ||
+ GetParent()->IsKindOf(CLASSINFO(wxDialog))) &&
+ ((GetParent()->GetWindowStyleFlag() & wxUSER_COLOURS) != wxUSER_COLOURS))
+ {
+ border = (wxBorder)((flags & wxBORDER_MASK) | wxBORDER_SUNKEN);
+ }
+
+ // Only give it WS_BORDER for wxBORDER_SIMPLE
+ if (border & wxBORDER_SIMPLE)
style |= WS_BORDER;
-
+
// now deal with ext style if the caller wants it
if ( exstyle )
{
if ( flags & wxTRANSPARENT_WINDOW )
*exstyle |= WS_EX_TRANSPARENT;
- switch ( flags & wxBORDER_MASK )
+ switch ( border )
{
default:
wxFAIL_MSG( _T("unknown border style") );
break;
case wxBORDER_RAISED:
- *exstyle |= WS_EX_WINDOWEDGE;
+ *exstyle |= WS_EX_DLGMODALFRAME;
break;
case wxBORDER_SUNKEN:
*exstyle |= WS_EX_CLIENTEDGE;
+ style &= ~WS_BORDER;
break;
case wxBORDER_DOUBLE:
return style;
}
-// Make a Windows extended style from the given wxWindows window style
-WXDWORD wxWindowMSW::MakeExtendedStyle(long style, bool eliminateBorders)
-{
- WXDWORD exStyle = 0;
- if ( style & wxTRANSPARENT_WINDOW )
- exStyle |= WS_EX_TRANSPARENT;
-
- if ( !eliminateBorders )
- {
- if ( style & wxSUNKEN_BORDER )
- exStyle |= WS_EX_CLIENTEDGE;
- if ( style & wxDOUBLE_BORDER )
- exStyle |= WS_EX_DLGMODALFRAME;
-#if defined(__WIN95__)
- if ( style & wxRAISED_BORDER )
- // It seems that WS_EX_WINDOWEDGE doesn't work, but WS_EX_DLGMODALFRAME does
- exStyle |= WS_EX_DLGMODALFRAME; /* WS_EX_WINDOWEDGE */;
- if ( style & wxSTATIC_BORDER )
- exStyle |= WS_EX_STATICEDGE;
-#endif
- }
-
- return exStyle;
-}
-
-// Determines whether native 3D effects or CTL3D should be used,
-// applying a default border style if required, and returning an extended
-// style to pass to CreateWindowEx.
-WXDWORD wxWindowMSW::Determine3DEffects(WXDWORD defaultBorderStyle,
- bool *want3D) const
-{
- // If matches certain criteria, then assume no 3D effects
- // unless specifically requested (dealt with in MakeExtendedStyle)
- if ( !GetParent()
-#if wxUSE_CONTROLS
- || !IsKindOf(CLASSINFO(wxControl))
-#endif // wxUSE_CONTROLS
- || (m_windowStyle & wxNO_BORDER) )
- {
- *want3D = FALSE;
- return MakeExtendedStyle(m_windowStyle);
- }
-
- // Determine whether we should be using 3D effects or not.
- bool nativeBorder = FALSE; // by default, we don't want a Win95 effect
-
- // 1) App can specify global 3D effects
- *want3D = wxTheApp->GetAuto3D();
-
- // 2) If the parent is being drawn with user colours, or simple border specified,
- // switch effects off. TODO: replace wxUSER_COLOURS with wxNO_3D
- if ( GetParent() && (GetParent()->GetWindowStyleFlag() & wxUSER_COLOURS) || (m_windowStyle & wxSIMPLE_BORDER) )
- *want3D = FALSE;
-
- // 3) Control can override this global setting by defining
- // a border style, e.g. wxSUNKEN_BORDER
- if ( m_windowStyle & wxSUNKEN_BORDER )
- *want3D = TRUE;
-
- // 4) If it's a special border, CTL3D can't cope so we want a native border
- if ( (m_windowStyle & wxDOUBLE_BORDER) || (m_windowStyle & wxRAISED_BORDER) ||
- (m_windowStyle & wxSTATIC_BORDER) )
- {
- *want3D = TRUE;
- nativeBorder = TRUE;
- }
-
- // 5) If this isn't a Win95 app, and we are using CTL3D, remove border
- // effects from extended style
-#if wxUSE_CTL3D
- if ( *want3D )
- nativeBorder = FALSE;
-#endif
-
- DWORD exStyle = MakeExtendedStyle(m_windowStyle, !nativeBorder);
-
- // 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__) && !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;
-#endif
-
- return exStyle;
-}
-
#if WXWIN_COMPATIBILITY
// If nothing defined for this, try the parent.
// E.g. we may be a button loaded from a resource, with no callback function
// drag and drop
// ---------------------------------------------------------------------------
-#if wxUSE_DRAG_AND_DROP
+#if wxUSE_DRAG_AND_DROP
void wxWindowMSW::SetDropTarget(wxDropTarget *pDropTarget)
{
if ( m_dropTarget != 0 ) {
if ( m_dropTarget != 0 )
m_dropTarget->Register(m_hWnd);
}
-
#endif // wxUSE_DRAG_AND_DROP
// old style file-manager drag&drop support: we retain the old-style
wxWindowBase::DoSetToolTip(tooltip);
if ( m_tooltip )
- m_tooltip->SetWindow(this);
+ m_tooltip->SetWindow((wxWindow *)this);
}
#endif // wxUSE_TOOLTIPS
{
wxTheApp->DoMessage((WXMSG *)&msg);
}
+
+ // If we retrieved a WM_QUIT, insert back into the message queue.
+ if (msg.message == WM_QUIT)
+ ::PostQuitMessage(0);
}
bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
long wxWindowMSW::MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
{
if ( m_oldWndProc )
+#ifdef __DIGITALMARS__
+ return ::CallWindowProc( (FARPROC) m_oldWndProc, GetHwnd(), (UINT) nMsg, (WPARAM) wParam, (LPARAM) lParam);
+#else
return ::CallWindowProc(CASTWNDPROC m_oldWndProc, GetHwnd(), (UINT) nMsg, (WPARAM) wParam, (LPARAM) lParam);
+#endif
else
return ::DefWindowProc(GetHwnd(), nMsg, wParam, lParam);
}
if ( !bCtrlDown )
{
lDlgCode = ::SendMessage(msg->hwnd, WM_GETDLGCODE, 0, 0);
+
+ // surprizingly, DLGC_WANTALLKEYS bit mask doesn't contain the
+ // DLGC_WANTTAB nor DLGC_WANTARROWS bits although, logically,
+ // it, of course, implies them
+ if ( lDlgCode & DLGC_WANTALLKEYS )
+ {
+ lDlgCode |= DLGC_WANTTAB | DLGC_WANTARROWS;
+ }
}
bool bForward = TRUE,
// eat the Enter events sometimes
return FALSE;
}
+ else if (!IsTopLevel())
+ {
+ // if not a top level window, let parent
+ // handle it
+ return FALSE;
+ }
//else: treat Enter as TAB: pass to the next
// control as this is the best thing to do
// if the text doesn't handle Enter itself
{
// trace all messages - useful for the debugging
#ifdef __WXDEBUG__
+#if wxUSE_LOG
wxLogTrace(wxTraceMessages, wxT("Processing %s(wParam=%8lx, lParam=%8lx)"),
wxGetMessageName(message), (long) wParam, lParam);
+#endif // wxUSE_LOG
#endif // __WXDEBUG__
wxWindowMSW *wnd = wxFindWinFromHandle((WXHWND) hWnd);
break;
#endif // __WXMICROWIN__
- // VZ: if you find a situation when this is needed, tell
- // me about it, do *not* uncomment this code as it
- // causes other strange problems
-#if 0
- if ( message == WM_LBUTTONDOWN && AcceptsFocus() )
- SetFocus();
-#endif // 0
-
int x = GET_X_LPARAM(lParam),
y = GET_Y_LPARAM(lParam);
else
{
win = FindWindowForMouseEvent(this, &x, &y);
+
+ // this should never happen
+ wxCHECK_MSG( win, 0,
+ _T("FindWindowForMouseEvent() returned NULL") );
+
+ // for the standard classes their WndProc sets the focus to
+ // them anyhow and doing it from here results in some weird
+ // problems, but for our windows we want them to acquire
+ // focus when clicked
+ if ( !win->IsOfStandardClass() )
+ {
+ if ( message == WM_LBUTTONDOWN && win->AcceptsFocus() )
+ win->SetFocus();
+ }
}
processed = win->HandleMouseEvent(message, x, y, wParam);
if ( m_lastKeydownProcessed )
{
processed = TRUE;
- break;
}
- switch ( wParam )
+ if ( !processed )
{
- // we consider these message "not interesting" to OnChar, so
- // just don't do anything more with them
- case VK_SHIFT:
- case VK_CONTROL:
- case VK_MENU:
- case VK_CAPITAL:
- case VK_NUMLOCK:
- case VK_SCROLL:
- processed = TRUE;
- break;
-
- // 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:
- case VK_ADD:
- case VK_SUBTRACT:
- case VK_MULTIPLY:
- case VK_DIVIDE:
- case VK_OEM_1:
- case VK_OEM_2:
- case VK_OEM_3:
- case VK_OEM_4:
- case VK_OEM_5:
- case VK_OEM_6:
- case VK_OEM_7:
- case VK_OEM_PLUS:
- case VK_OEM_COMMA:
- case VK_OEM_MINUS:
- case VK_OEM_PERIOD:
- // 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;
+ switch ( wParam )
+ {
+ // we consider these message "not interesting" to OnChar, so
+ // just don't do anything more with them
+ case VK_SHIFT:
+ case VK_CONTROL:
+ case VK_MENU:
+ case VK_CAPITAL:
+ case VK_NUMLOCK:
+ case VK_SCROLL:
+ processed = TRUE;
+ break;
- break;
+ // 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:
+ case VK_ADD:
+ case VK_SUBTRACT:
+ case VK_MULTIPLY:
+ case VK_DIVIDE:
+ case VK_OEM_1:
+ case VK_OEM_2:
+ case VK_OEM_3:
+ case VK_OEM_4:
+ case VK_OEM_5:
+ case VK_OEM_6:
+ case VK_OEM_7:
+ case VK_OEM_PLUS:
+ case VK_OEM_COMMA:
+ case VK_OEM_MINUS:
+ case VK_OEM_PERIOD:
+ // 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;
+ break;
#ifdef VK_APPS
- // special case of VK_APPS: treat it the same as right mouse
- // click because both usually pop up a context menu
- case VK_APPS:
- {
- WPARAM flags;
- int x, y;
+ // special case of VK_APPS: treat it the same as right mouse
+ // click because both usually pop up a context menu
+ case VK_APPS:
+ {
+ WPARAM flags;
+ int x, y;
- TranslateKbdEventToMouse(this, &x, &y, &flags);
- processed = HandleMouseEvent(WM_RBUTTONDOWN, x, y, flags);
- }
- break;
+ TranslateKbdEventToMouse(this, &x, &y, &flags);
+ processed = HandleMouseEvent(WM_RBUTTONDOWN, x, y, flags);
+ }
+ break;
#endif // VK_APPS
- default:
- // do generate a CHAR event
- processed = HandleChar((WORD)wParam, lParam);
-
+ default:
+ // do generate a CHAR event
+ processed = HandleChar((WORD)wParam, lParam);
+ }
}
+ if (message == WM_SYSKEYDOWN) // Let Windows still handle the SYSKEYs
+ processed = FALSE;
break;
case WM_SYSKEYUP:
}
break;
+#if wxUSE_ACCESSIBILITY
+ case WM_GETOBJECT:
+ {
+ //WPARAM dwFlags = (WPARAM) (DWORD) wParam;
+ LPARAM dwObjId = (LPARAM) (DWORD) lParam;
+
+ if (dwObjId == OBJID_CLIENT && GetOrCreateAccessible())
+ {
+ return LresultFromObject(IID_IAccessible, wParam, (IUnknown*) GetAccessible()->GetIAccessible());
+ }
+ break;
+ }
+#endif
+
#if defined(__WIN32__) && defined(WM_HELP)
case WM_HELP:
{
processed = GetEventHandler()->ProcessEvent(evtCtx);
}
break;
+
+ case WM_MENUCHAR:
+ // we're only interested in our own menus, not MF_SYSMENU
+ if ( HIWORD(wParam) == MF_POPUP )
+ {
+ // handle menu chars for ownerdrawn menu items
+ int i = HandleMenuChar(toupper(LOWORD(wParam)), lParam);
+ if ( i != wxNOT_FOUND )
+ {
+ rc.result = MAKELRESULT(i, MNC_EXECUTE);
+ processed = TRUE;
+ }
+ }
+ break;
#endif // __WIN32__
}
if ( !processed )
{
#ifdef __WXDEBUG__
+#if wxUSE_LOG
wxLogTrace(wxTraceMessages, wxT("Forwarding %s to DefWindowProc."),
wxGetMessageName(message));
+#endif // wxUSE_LOG
#endif // __WXDEBUG__
rc.result = MSWDefWindowProc(message, wParam, lParam);
}
LPTOOLTIPTEXT ttText = (LPTOOLTIPTEXT)lParam;
+#if !wxUSE_UNICODE
if ( code == (WXUINT) TTN_NEEDTEXTA )
{
- ttText->lpszText = (wxChar *)ttip.c_str();
+ // we pass just the pointer as we store the string internally anyhow
+ ttText->lpszText = (char *)ttip.c_str();
}
- else
+ 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
- size_t lenAnsi = ttip.length();
-
- // some compilers (MetroWerks and Cygwin) don't like calling mbstowcs
- // with NULL argument
- #if defined( __MWERKS__ ) || defined( __CYGWIN__ )
- size_t lenUnicode = 2*lenAnsi;
- #else
- size_t lenUnicode = mbstowcs(NULL, ttip, lenAnsi);
- #endif
-
- // using the pointer of right type avoids us doing all sorts of
- // pointer arithmetics ourselves
- wchar_t *dst = (wchar_t *)ttText->szText,
- *pwz = new wchar_t[lenUnicode + 1];
- mbstowcs(pwz, ttip, lenAnsi + 1);
- memcpy(dst, pwz, lenUnicode*sizeof(wchar_t));
-
- // put the terminating wide NUL
- dst[lenUnicode] = L'\0';
-
- delete [] pwz;
+ MultiByteToWideChar(CP_ACP, 0, ttip, ttip.length()+1,
+ (wchar_t *)ttText->szText,
+ sizeof(ttText->szText) / sizeof(wchar_t));
#endif // Unicode/!Unicode
}
bool wxWindowMSW::HandleDestroy()
{
- wxWindowDestroyEvent event((wxWindow *)this);
- (void)GetEventHandler()->ProcessEvent(event);
+ SendDestroyEvent();
// delete our drop target if we've got one
#if wxUSE_DRAG_AND_DROP
bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam)
{
-#ifndef __WXMICROWIN__
+#if defined (__WXMICROWIN__)
+ return FALSE;
+#else // __WXMICROWIN__
HDROP hFilesInfo = (HDROP) wParam;
// Get the total number of files dropped
event.m_pos.y = dropPoint.y;
return GetEventHandler()->ProcessEvent(event);
-#else // __WXMICROWIN__
- return FALSE;
#endif
}
+#ifdef __DIGITALMARS__
+extern "C" HCURSOR wxGetCurrentBusyCursor();
+#endif
+
bool wxWindowMSW::HandleSetCursor(WXHWND WXUNUSED(hWnd),
short nHitTest,
int WXUNUSED(mouseMsg))
if ( hcursor )
{
+// wxLogDebug("HandleSetCursor: Setting cursor %ld", (long) hcursor);
+
::SetCursor(hcursor);
// cursor set, stop here
}
wxKeyEvent event(CreateKeyEvent(wxEVT_CHAR, id, lParam, wParam));
- if ( ctrlDown )
+
+ // the alphanumeric keys produced by pressing AltGr+something on European
+ // keyboards have both Ctrl and Alt modifiers which may confuse the user
+ // code as, normally, keys with Ctrl and/or Alt don't result in anything
+ // alphanumeric, so pretend that there are no modifiers at all (the
+ // KEY_DOWN event would still have the correct modifiers if they're really
+ // needed)
+ if ( event.m_controlDown && event.m_altDown &&
+ (id >= 32 && id < 256) )
{
- event.m_controlDown = TRUE;
+ event.m_controlDown =
+ event.m_altDown = FALSE;
}
return GetEventHandler()->ProcessEvent(event);
return FALSE;
}
+#ifdef __WIN32__
+
+int wxWindowMSW::HandleMenuChar(int chAccel, WXLPARAM lParam)
+{
+ const HMENU hmenu = (HMENU)lParam;
+
+ MENUITEMINFO mii;
+ wxZeroMemory(mii);
+ mii.cbSize = sizeof(MENUITEMINFO);
+ mii.fMask = MIIM_TYPE | MIIM_DATA;
+
+ // find if we have this letter in any owner drawn item
+ const int count = ::GetMenuItemCount(hmenu);
+ for ( int i = 0; i < count; i++ )
+ {
+ if ( ::GetMenuItemInfo(hmenu, i, TRUE, &mii) )
+ {
+ if ( mii.fType == MFT_OWNERDRAW )
+ {
+ // dwItemData member of the MENUITEMINFO is a
+ // pointer to the associated wxMenuItem -- see the
+ // menu creation code
+ wxMenuItem *item = (wxMenuItem*)mii.dwItemData;
+
+ const wxChar *p = wxStrchr(item->GetText(), _T('&'));
+ while ( p++ )
+ {
+ if ( *p == _T('&') )
+ {
+ // this is not the accel char, find the real one
+ p = wxStrchr(p + 1, _T('&'));
+ }
+ else // got the accel char
+ {
+ // FIXME-UNICODE: this comparison doesn't risk to work
+ // for non ASCII accelerator characters I'm afraid, but
+ // what can we do?
+ if ( wxToupper(*p) == chAccel )
+ {
+ return i;
+ }
+ else
+ {
+ // this one doesn't match
+ break;
+ }
+ }
+ }
+ }
+ }
+ else // failed ot get the menu text?
+ {
+ // it's not fatal, so don't show error, but still log
+ // it
+ wxLogLastError(_T("GetMenuItemInfo"));
+ }
+ }
+
+ return wxNOT_FOUND;
+}
+
+#endif // __WIN32__
+
// ---------------------------------------------------------------------------
// joystick
// ---------------------------------------------------------------------------
// be done only for these two SB_ events as they are the only one
// carrying the scrollbar position)
{
- SCROLLINFO scrollInfo;
- wxZeroMemory(scrollInfo);
- scrollInfo.cbSize = sizeof(SCROLLINFO);
+ WinStruct<SCROLLINFO> scrollInfo;
scrollInfo.fMask = SIF_TRACKPOS;
if ( !::GetScrollInfo(GetHwnd(),
case VK_OEM_6: id = ']'; break;
case VK_OEM_7: id = '\''; break;
+#ifdef VK_APPS
+ case VK_LWIN: id = WXK_WINDOWS_LEFT; break;
+ case VK_RWIN: id = WXK_WINDOWS_RIGHT; break;
+ case VK_APPS: id = WXK_WINDOWS_MENU; break;
+#endif // VK_APPS defined
+
default:
id = 0;
}
// avoids warning about statement with no effect (FreeProcInstance
// doesn't do anything under Win32)
-#if !defined(WIN32) && !defined(_WIN32) && !defined(__WIN32__) && !defined(__NT__) && !defined(__GNUWIN32__)
+#if !defined(__WIN32__) && !defined(__NT__)
FreeProcInstance(wxTheKeyboardHookProc);
#endif
}
// Find the wxWindow at the current mouse position, returning the mouse
// position.
-wxWindow* wxFindWindowAtPointer(wxPoint& WXUNUSED(pt))
+wxWindow* wxFindWindowAtPointer(wxPoint& pt)
{
- return wxFindWindowAtPoint(wxGetMousePosition());
+ pt = wxGetMousePosition();
+ return wxFindWindowAtPoint(pt);
}
wxWindow* wxFindWindowAtPoint(const wxPoint& pt)