#pragma hdrstop
#endif
+#include "wx/window.h"
+
#ifndef WX_PRECOMP
#include "wx/msw/wrapwin.h"
- #include "wx/window.h"
#include "wx/accel.h"
#include "wx/menu.h"
#include "wx/dc.h"
#include "wx/settings.h"
#include "wx/statbox.h"
#include "wx/sizer.h"
+ #include "wx/intl.h"
+ #include "wx/log.h"
#endif
#if wxUSE_OWNER_DRAWN && !defined(__WXUNIVERSAL__)
#include "wx/evtloop.h"
#include "wx/module.h"
+#include "wx/power.h"
#include "wx/sysopt.h"
#if wxUSE_DRAG_AND_DROP
#endif
#include "wx/menuitem.h"
-#include "wx/log.h"
#include "wx/msw/private.h"
#include "wx/spinctrl.h"
#endif // wxUSE_SPINCTRL
-#include "wx/intl.h"
-#include "wx/log.h"
-
#include "wx/textctrl.h"
#include "wx/notebook.h"
#include "wx/listctrl.h"
#include <commctrl.h>
+#ifndef __WXWINCE__
+ #include <pbt.h>
+#endif
+
#include "wx/msw/missing.h"
#if defined(__WXWINCE__)
#include "wx/msw/wince/missing.h"
+#ifdef __POCKETPC__
+ #include <windows.h>
+ #include <shellapi.h>
+ #include <ole2.h>
+ #include <aygshell.h>
+#endif
#endif
#if defined(TME_LEAVE) && defined(WM_MOUSELEAVE)
m_pendingPosition = wxDefaultPosition;
m_pendingSize = wxDefaultSize;
+
+#ifdef __POCKETPC__
+ m_contextMenuEnabled = false;
+#endif
}
// Destructor
return false;
}
- if ( m_cursor.Ok() )
+ // don't "overwrite" busy cursor
+ if ( m_cursor.Ok() && !wxIsBusy() )
{
- HWND hWnd = GetHwnd();
-
- // Change the cursor NOW if we're within the correct window
- POINT point;
-#ifdef __WXWINCE__
- ::GetCursorPosWinCE(&point);
-#else
- ::GetCursorPos(&point);
-#endif
-
- RECT rect = wxGetWindowRect(hWnd);
-
- if ( ::PtInRect(&rect, point) && !wxIsBusy() )
- ::SetCursor(GetHcursorOf(m_cursor));
+ ::SetCursor(GetHcursorOf(m_cursor));
}
return true;
// simply check m_oldWndProc
m_oldWndProc = NULL;
}
+
+ // we're officially created now, send the event
+ wxWindowCreateEvent event((wxWindow *)this);
+ (void)GetEventHandler()->ProcessEvent(event);
}
void wxWindowMSW::UnsubclassWin()
if ( !GetHwnd() )
return;
+ // we may need to call SetWindowPos() when we change some styles
+ bool callSWP = false;
+
WXDWORD exstyle, exstyleOld;
long style = MSWGetStyle(flags, &exstyle),
styleOld = MSWGetStyle(flagsOld, &exstyleOld);
styleReal |= style;
::SetWindowLong(GetHwnd(), GWL_STYLE, styleReal);
+
+ // If any of the style changes changed any of the frame styles:
+ // MSDN: SetWindowLong:
+ // Certain window data is cached, so changes you make using
+ // SetWindowLong will not take effect until you call the
+ // SetWindowPos function. Specifically, if you change any of
+ // the frame styles, you must call SetWindowPos with the
+ // SWP_FRAMECHANGED flag for the cache to be updated properly.
+
+ callSWP = ((styleOld ^ style ) & (WS_BORDER |
+ WS_THICKFRAME |
+ WS_CAPTION |
+ WS_DLGFRAME |
+ WS_MAXIMIZEBOX |
+ WS_MINIMIZEBOX |
+ WS_SYSMENU) ) != 0;
}
// and the extended style
+ long exstyleReal = ::GetWindowLong(GetHwnd(), GWL_EXSTYLE);
+
if ( exstyle != exstyleOld )
{
- long exstyleReal = ::GetWindowLong(GetHwnd(), GWL_EXSTYLE);
exstyleReal &= ~exstyleOld;
exstyleReal |= exstyle;
::SetWindowLong(GetHwnd(), GWL_EXSTYLE, exstyleReal);
+ // ex style changes don't take effect without calling SetWindowPos
+ callSWP = true;
+ }
+
+ if ( callSWP )
+ {
// we must call SetWindowPos() to flush the cached extended style and
// also to make the change to wxSTAY_ON_TOP style take effect: just
// setting the style simply doesn't work
exstyleReal & WS_EX_TOPMOST ? HWND_TOPMOST
: HWND_NOTOPMOST,
0, 0, 0, 0,
- SWP_NOMOVE | SWP_NOSIZE) )
+ SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED) )
{
wxLogLastError(_T("SetWindowPos"));
}
{
wxASSERT_MSG( m_frozenness > 0, _T("Thaw() without matching Freeze()") );
- if ( !--m_frozenness )
+ if ( --m_frozenness == 0 )
{
if ( IsShown() )
{
#if defined(__WXWINCE__)
UINT flags = 0;
#else
- UINT flags = TPM_RIGHTBUTTON;
+ UINT flags = TPM_RIGHTBUTTON | TPM_RECURSE;
#endif
::TrackPopupMenu(hMenu, flags, point.x, point.y, 0, hWnd, NULL);
// relay mouse move events to the tooltip control
MSG *msg = (MSG *)pMsg;
if ( msg->message == WM_MOUSEMOVE )
- m_tooltip->RelayEvent(pMsg);
+ wxToolTip::RelayEvent(pMsg);
}
#endif // wxUSE_TOOLTIPS
wxCHECK_MSG( win, 0,
_T("FindWindowForMouseEvent() returned NULL") );
}
+#ifdef __POCKETPC__
+ if (IsContextMenuEnabled() && message == WM_LBUTTONDOWN)
+ {
+ SHRGINFO shrgi = {0};
+
+ shrgi.cbSize = sizeof(SHRGINFO);
+ shrgi.hwndClient = (HWND) GetHWND();
+ shrgi.ptDown.x = x;
+ shrgi.ptDown.y = y;
+
+ shrgi.dwFlags = SHRG_RETURNCMD;
+ // shrgi.dwFlags = SHRG_NOTIFYPARENT;
+
+ if (GN_CONTEXTMENU == ::SHRecognizeGesture(&shrgi))
+ {
+ wxPoint pt(x, y);
+ pt = ClientToScreen(pt);
+
+ wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU, GetId(), pt);
+
+ evtCtx.SetEventObject(this);
+ if (GetEventHandler()->ProcessEvent(evtCtx))
+ {
+ processed = true;
+ return true;
+ }
+ }
+ }
+#endif
+
#else // !__WXWINCE__
wxWindowMSW *win = this;
#endif // __WXWINCE__/!__WXWINCE__
case VK_SUBTRACT:
case VK_MULTIPLY:
case VK_DIVIDE:
+ case VK_NUMPAD0:
+ case VK_NUMPAD1:
+ case VK_NUMPAD2:
+ case VK_NUMPAD3:
+ case VK_NUMPAD4:
+ case VK_NUMPAD5:
+ case VK_NUMPAD6:
+ case VK_NUMPAD7:
+ case VK_NUMPAD8:
+ case VK_NUMPAD9:
case VK_OEM_1:
case VK_OEM_2:
case VK_OEM_3:
processed = HandleCaptureChanged((WXHWND) (HWND) lParam);
break;
+ case WM_SETTINGCHANGE:
+ processed = HandleSettingChange(wParam, lParam);
+ break;
+
case WM_QUERYNEWPALETTE:
processed = HandleQueryNewPalette();
break;
}
}
break;
+
+#ifndef __WXWINCE__
+ case WM_POWERBROADCAST:
+ {
+ bool vetoed;
+ processed = HandlePower(wParam, lParam, &vetoed);
+ rc.result = processed && vetoed ? BROADCAST_QUERY_DENY : TRUE;
+ }
+ break;
+#endif // __WXWINCE__
}
if ( !processed )
EnsureParentHasControlParentStyle(GetParent());
#endif // !__WXWINCE__
- // TODO: should generate this event from WM_NCCREATE
- wxWindowCreateEvent event((wxWindow *)this);
- (void)GetEventHandler()->ProcessEvent(event);
-
*mayCreate = true;
return true;
return false;
}
+bool wxWindowMSW::HandlePower(WXWPARAM WXUNUSED_IN_WINCE(wParam),
+ WXLPARAM WXUNUSED(lParam),
+ bool *WXUNUSED_IN_WINCE(vetoed))
+{
+#ifdef __WXWINCE__
+ // FIXME
+ return false;
+#else
+ wxEventType evtType;
+ switch ( wParam )
+ {
+ case PBT_APMQUERYSUSPEND:
+ evtType = wxEVT_POWER_SUSPENDING;
+ break;
+
+ case PBT_APMQUERYSUSPENDFAILED:
+ evtType = wxEVT_POWER_SUSPEND_CANCEL;
+ break;
+
+ case PBT_APMSUSPEND:
+ evtType = wxEVT_POWER_SUSPENDED;
+ break;
+
+ case PBT_APMRESUMESUSPEND:
+ evtType = wxEVT_POWER_RESUME;
+ break;
+
+ default:
+ wxLogDebug(_T("Unknown WM_POWERBROADCAST(%d) event"), wParam);
+ // fall through
+
+ // these messages are currently not mapped to wx events
+ case PBT_APMQUERYSTANDBY:
+ case PBT_APMQUERYSTANDBYFAILED:
+ case PBT_APMSTANDBY:
+ case PBT_APMRESUMESTANDBY:
+ case PBT_APMBATTERYLOW:
+ case PBT_APMPOWERSTATUSCHANGE:
+ case PBT_APMOEMEVENT:
+#ifdef PBT_APMRESUMEAUTOMATIC
+ case PBT_APMRESUMEAUTOMATIC:
+#endif
+ case PBT_APMRESUMECRITICAL:
+ evtType = wxEVT_NULL;
+ break;
+ }
+
+ // don't handle unknown messages
+ if ( evtType == wxEVT_NULL )
+ return false;
+
+ // TODO: notify about PBTF_APMRESUMEFROMFAILURE in case of resume events?
+
+ wxPowerEvent event(evtType);
+ if ( !GetEventHandler()->ProcessEvent(event) )
+ return false;
+
+ *vetoed = event.IsVetoed();
+
+ return true;
+#endif
+}
+
// ---------------------------------------------------------------------------
// owner drawn stuff
// ---------------------------------------------------------------------------
return GetEventHandler()->ProcessEvent(event);
}
+bool wxWindowMSW::HandleSettingChange(WXWPARAM wParam, WXLPARAM lParam)
+{
+ // despite MSDN saying "(This message cannot be sent directly to a window.)"
+ // we need to send this to child windows (it is only sent to top-level
+ // windows) so {list,tree}ctrls can adjust their font size if necessary
+ // this is exactly how explorer does it to enable the font size changes
+
+ wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
+ while ( node )
+ {
+ // top-level windows already get this message from the system
+ wxWindow *win = node->GetData();
+ if ( !win->IsTopLevel() )
+ {
+ ::SendMessage(GetHwndOf(win), WM_SETTINGCHANGE, wParam, lParam);
+ }
+
+ node = node->GetNext();
+ }
+
+ // let the system handle it
+ return false;
+}
+
bool wxWindowMSW::HandleQueryNewPalette()
{
int id;
if ( isASCII )
{
- // If 1 -> 26, translate to either special keycode or just set
- // ctrlDown. IOW, Ctrl-C should result in keycode == 3 and
- // ControlDown() == true.
id = wParam;
- if ( (id > 0) && (id < 27) )
- {
- switch (id)
- {
- case 13:
- id = WXK_RETURN;
- break;
-
- case 8:
- id = WXK_BACK;
- break;
-
- case 9:
- id = WXK_TAB;
- break;
-
- default:
- //ctrlDown = true;
- break;
- }
- }
}
else // we're called from WM_KEYDOWN
{
- id = wxCharCodeMSWToWX(wParam, lParam);
+ // don't pass lParam to wxCharCodeMSWToWX() here because we don't want
+ // to get numpad key codes: CHAR events should use the logical keys
+ // such as WXK_HOME instead of WXK_NUMPAD_HOME which is for KEY events
+ id = wxCharCodeMSWToWX(wParam);
if ( id == 0 )
{
// it's ASCII and will be processed here only when called from
id = wParam;
}
- if ( id != -1 ) // VZ: does this ever happen (FIXME)?
- {
- wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_DOWN, id, lParam, wParam));
- if ( GetEventHandler()->ProcessEvent(event) )
- {
- return true;
- }
- }
-
- return false;
+ wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_DOWN, id, lParam, wParam));
+ return GetEventHandler()->ProcessEvent(event);
}
bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam, WXLPARAM lParam)
id = wParam;
}
- if ( id != -1 ) // VZ: does this ever happen (FIXME)?
- {
- wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_UP, id, lParam, wParam));
- if ( GetEventHandler()->ProcessEvent(event) )
- return true;
- }
-
- return false;
+ wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_UP, id, lParam, wParam));
+ return GetEventHandler()->ProcessEvent(event);
}
int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel),
return wxNOT_FOUND;
}
+bool wxWindowMSW::HandleClipboardEvent( WXUINT nMsg )
+{
+ const wxEventType type = ( nMsg == WM_CUT ) ? wxEVT_COMMAND_TEXT_CUT :
+ ( nMsg == WM_COPY ) ? wxEVT_COMMAND_TEXT_COPY :
+ /*( nMsg == WM_PASTE ) ? */ wxEVT_COMMAND_TEXT_PASTE;
+ wxClipboardTextEvent evt(type, GetId());
+
+ evt.SetEventObject(this);
+
+ return GetEventHandler()->ProcessEvent(evt);
+}
+
// ---------------------------------------------------------------------------
// joystick
// ---------------------------------------------------------------------------
// use the "extended" bit (24) of lParam to distinguish extended keys
// from normal keys as the same key is sent
-static inline int ChooseNormalOrExtended(int lParam, int keyNormal, int keyExtended)
+static inline
+int ChooseNormalOrExtended(int lParam, int keyNormal, int keyExtended)
{
- return lParam & (1 << 24) ? keyExtended : keyNormal;
+ // except that if lParam is 0, it means we don't have real lParam from
+ // WM_KEYDOWN but are just translating just a VK constant (e.g. done from
+ // msw/treectrl.cpp when processing TVN_KEYDOWN) -- then assume this is a
+ // non-numpad (hence extended) key as this is a more common case
+ return !lParam || (lParam & (1 << 24)) ? keyExtended : keyNormal;
}
// Returns 0 if was a normal ASCII value, not a special key. This indicates that
// handle extended keys
case VK_PRIOR:
- id = ChooseNormalOrExtended(lParam, WXK_NUMPAD_PRIOR, WXK_PRIOR);
+ id = ChooseNormalOrExtended(lParam, WXK_NUMPAD_PAGEUP, WXK_PAGEUP);
break;
case VK_NEXT:
- id = ChooseNormalOrExtended(lParam, WXK_NUMPAD_NEXT, WXK_NEXT);
+ id = ChooseNormalOrExtended(lParam, WXK_NUMPAD_PAGEDOWN, WXK_PAGEDOWN);
break;
case VK_END:
id = ChooseNormalOrExtended(lParam, WXK_NUMPAD_END, WXK_END);
case VK_DELETE:
id = ChooseNormalOrExtended(lParam, WXK_NUMPAD_DELETE, WXK_DELETE);
break;
- // this order is correct as the numpad enter is the extended key
case VK_RETURN:
- id = ChooseNormalOrExtended(lParam, WXK_RETURN, WXK_NUMPAD_ENTER);
+ // don't use ChooseNormalOrExtended() here as the keys are reversed
+ // here: numpad enter is the extended one
+ id = lParam && (lParam & (1 << 24)) ? WXK_NUMPAD_ENTER : WXK_RETURN;
break;
default:
case WXK_ALT: keySym = VK_MENU; break;
case WXK_PAUSE: keySym = VK_PAUSE; break;
case WXK_CAPITAL: keySym = VK_CAPITAL; break;
- case WXK_PRIOR: keySym = VK_PRIOR; break;
- case WXK_NEXT : keySym = VK_NEXT; break;
+ case WXK_PAGEUP: keySym = VK_PRIOR; break;
+ case WXK_PAGEDOWN: keySym = VK_NEXT; break;
case WXK_END: keySym = VK_END; break;
case WXK_HOME : keySym = VK_HOME; break;
case WXK_LEFT : keySym = VK_LEFT; break;