From afafd942a1f9d0f683a95bb72f8bc1e128543749 Mon Sep 17 00:00:00 2001
From: Julian Smart <julian@anthemion.co.uk>
Date: Fri, 18 Mar 2005 14:26:57 +0000
Subject: [PATCH] Added WXK_SPECIAL... keycodes for special hardware buttons
 Made (Un)RegisterHotKey WinCE-aware. Added wxEVT_HIBERNATE event. Now fakes
 wxEVT_ACTIVATE_APP to be symmetrical with wxEVT_HIBERNATE. Added
 wxTE_CAPITALIZE for CAPEDIT controls.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@32893 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/changes.txt           | 14 ++++++----
 docs/latex/wx/activevt.tex |  7 +++--
 docs/latex/wx/keycode.tex  | 25 +++++++++++++++++-
 docs/latex/wx/window.tex   |  3 ++-
 docs/latex/wx/wxmsw.tex    | 34 +++++++++++++++++++++---
 include/wx/defs.h          | 26 +++++++++++++++++--
 include/wx/event.h         |  3 +++
 include/wx/msw/frame.h     |  3 +++
 include/wx/textctrl.h      |  7 +++++
 src/common/event.cpp       |  1 +
 src/msw/app.cpp            |  8 ++++++
 src/msw/frame.cpp          | 53 ++++++++++++++++++++++++++++++++++++++
 src/msw/textctrl.cpp       |  6 +++++
 src/msw/window.cpp         | 30 +++++++++++++++++++++
 14 files changed, 206 insertions(+), 14 deletions(-)

diff --git a/docs/changes.txt b/docs/changes.txt
index b4adc9969f..0f6ce4a398 100644
--- a/docs/changes.txt
+++ b/docs/changes.txt
@@ -9,9 +9,10 @@ All:
 
 - wxURI::GetUser() only returns the user name now, use GetUserInfo() to get
   user and password as in 2.5.4; wxURI::GetPassword() added.
-- added wxDebugReport class.
-- added wxTempFileOutputStream by Stas Sergeev
-- fixed wxDateTime::SetToWeekDayInSameWeek(Sun, Monday_First)
+- Added wxDebugReport class.
+- Added wxTempFileOutputStream by Stas Sergeev.
+- Fixed wxDateTime::SetToWeekDayInSameWeek(Sun, Monday_First).
+- Added WXK_SPECIAL keycodes for special hardware buttons.
 
 All (GUI):
 
@@ -42,7 +43,7 @@ wxMac:
 
 wxPalmOS:
 
-- native wxRadioBox implementation.
+- Native wxRadioBox implementation.
 
 wxWinCE:
 
@@ -56,7 +57,10 @@ wxWinCE:
 - Frames have Ctrl+Q accelerator set automatically, as per the
   PocketPC guidelines
 - Documented issues in manual under wxWinCE topic.
-
+- Made (Un)RegisterHotKey WinCE-aware.
+- Sends wxEVT_HIBERNATE event.
+- Now fakes wxEVT_ACTIVATE_APP to be symmetrical with wxEVT_HIBERNATE.
+- Added wxTE_CAPITALIZE for CAPEDIT controls.
 
 2.5.4
 -----
diff --git a/docs/latex/wx/activevt.tex b/docs/latex/wx/activevt.tex
index 285ac8fbb0..40902dc5e8 100644
--- a/docs/latex/wx/activevt.tex
+++ b/docs/latex/wx/activevt.tex
@@ -21,6 +21,10 @@ function that takes a wxActivateEvent argument.
 \begin{twocollist}\itemsep=0pt
 \twocolitem{{\bf EVT\_ACTIVATE(func)}}{Process a wxEVT\_ACTIVATE event.}
 \twocolitem{{\bf EVT\_ACTIVATE\_APP(func)}}{Process a wxEVT\_ACTIVATE\_APP event.}
+\twocolitem{{\bf EVT\_HIBERNATE(func)}}{Process a hibernate event, supplying the member function.
+This event applies to wxApp only, and only on Windows SmartPhone and PocketPC. It is generated when the
+system is low on memory; the application should free up as much memory as possible, and restore
+full working when it receives a wxEVT\_ACTIVATE or wxEVT\_ACTIVATE\_APP event.}
 \end{twocollist}%
 
 \wxheading{Remarks}
@@ -33,8 +37,7 @@ An application is activated or deactivated when one of its frames becomes activa
 or a frame becomes inactivate resulting in all application frames being inactive. (Windows only)
 
 Please note that usually you should call \helpref{event.Skip()}{wxeventskip} in
-your handlers for these events as not doing so can result in strange effects,
-especially on Mac platform.
+your handlers for these events as not doing so can result in strange effects.
 
 \wxheading{See also}
 
diff --git a/docs/latex/wx/keycode.tex b/docs/latex/wx/keycode.tex
index 08f4f2ac5f..12c2b3a8d8 100644
--- a/docs/latex/wx/keycode.tex
+++ b/docs/latex/wx/keycode.tex
@@ -113,7 +113,30 @@ values are the ASCII character codes, plus the following:
     // the following key codes are only generated under Windows currently
     WXK_WINDOWS_LEFT,
     WXK_WINDOWS_RIGHT,
-    WXK_WINDOWS_MENU
+    WXK_WINDOWS_MENU,
+    WXK_COMMAND,
+
+    // Hardware-specific buttons
+    WXK_SPECIAL1 = 193,
+    WXK_SPECIAL2,
+    WXK_SPECIAL3,
+    WXK_SPECIAL4,
+    WXK_SPECIAL5,
+    WXK_SPECIAL6,
+    WXK_SPECIAL7,
+    WXK_SPECIAL8,
+    WXK_SPECIAL9,
+    WXK_SPECIAL10,
+    WXK_SPECIAL11,
+    WXK_SPECIAL12,
+    WXK_SPECIAL13,
+    WXK_SPECIAL14,
+    WXK_SPECIAL15,
+    WXK_SPECIAL16,
+    WXK_SPECIAL17,
+    WXK_SPECIAL18,
+    WXK_SPECIAL19,
+    WXK_SPECIAL20
 \end{verbatim}
 }
 
diff --git a/docs/latex/wx/window.tex b/docs/latex/wx/window.tex
index f7047df259..09f2f5d37b 100644
--- a/docs/latex/wx/window.tex
+++ b/docs/latex/wx/window.tex
@@ -2280,7 +2280,8 @@ hotkey with this modifier/virtualKeyCode combination.
 \wxheading{Remarks}
 
 Use EVT\_HOTKEY(hotkeyId, fnc) in the event table to capture the event.
-This function is currently only implemented under MSW.
+This function is currently only implemented under Windows. It is used
+in the \helpref{Windows CE port}{wxwince} for detecting hardware button presses.
 
 \wxheading{See also}
 
diff --git a/docs/latex/wx/wxmsw.tex b/docs/latex/wx/wxmsw.tex
index 59937fee83..4f22b9b3ae 100644
--- a/docs/latex/wx/wxmsw.tex
+++ b/docs/latex/wx/wxmsw.tex
@@ -102,6 +102,37 @@ according to the orientation, which you could detect in idle time, for example).
 However, if the input panel (SIP) is shown, windows do not yet resize accordingly. This will
 be implemented soon.
 
+\subsubsection{Closing top-level windows in wxWinCE}
+
+You won't get a wxCloseEvent when the user clicks on the X in the titlebar
+on Smartphone and PocketPC; the window is simply hidden instead. However the system may send the
+event to force the application to close down.
+
+\subsubsection{Hibernation in wxWinCE}
+
+Smartphone and PocketPC will send a wxEVT\_HIBERNATE to the application object in low
+memory conditions. Your application should release memory and close dialogs,
+and wake up again when the next wxEVT\_ACTIVATE or wxEVT\_ACTIVATE\_APP message is received.
+(wxEVT\_ACTIVATE\_APP is generated whenever a wxEVT\_ACTIVATE event is received
+in Smartphone and PocketPC, since these platforms do not support WM\_ACTIVATEAPP.)
+
+\subsubsection{Hardware buttons in wxWinCE}
+
+Special hardware buttons are sent to a window via the wxEVT\_HOTKEY event
+under Smartphone and PocketPC. You should first register each required button with \helpref{wxWindow::RegisterHotKey}{wxwindowregisterhotkey},
+and unregister the button when you're done with it. For example:
+
+\begin{verbatim}
+  win->RegisterHotKey(0, wxMOD_WIN, WXK_SPECIAL1);
+  win->UnregisterHotKey(0);
+\end{verbatim}
+
+You may have to register the buttons in a wxEVT_ACTIVATE event handler
+since other applications will grab the buttons.
+
+There is currently no method of finding out the names of the special
+buttons or how many there are.
+
 \subsubsection{Dialogs in wxWinCE}
 
 PocketPC dialogs have an OK button on the caption, and so you should generally
@@ -210,9 +241,6 @@ needs to be simplified (and speeded up).
 layout seems slow. Some analysis is required.
 \item {\bf Notification boxes.} The balloon-like notification messages, and their
 icons, should be implemented. This will be quite straightforward.
-\item {\bf WM\_SETTINGCHANGE.} This message needs to be handled by calling SHHandleWMSettingChange.
-\item {\bf WM\_ACTIVATE.} This message needs to be handled by calling SHHandleWMActivate.
-\item {\bf WM\_HIBERNATE.} We need to handle this message.
 \item {\bf SIP size.} We need to be able to get the area taken up by the SIP (input panel),
 and the remaining area, by calling SHSipInfo. We also may need to be able to show and hide
 the SIP programmatically, with SHSipPreference. See also the {\it Input Dialogs} topic in
diff --git a/include/wx/defs.h b/include/wx/defs.h
index 6291efca99..daa43a38a2 100644
--- a/include/wx/defs.h
+++ b/include/wx/defs.h
@@ -1941,7 +1941,7 @@ enum wxKeyCode
     WXK_SPACE   =    32,
     WXK_DELETE  =    127,
 
-    /* These are, by design, not compatable with unicode characters.
+    /* These are, by design, not compatible with unicode characters.
        If you want to get a unicode character from a key event, use
        wxKeyEvent::GetUnicodeKey instead.                           */
     WXK_START   = 300,
@@ -2046,7 +2046,29 @@ enum wxKeyCode
     WXK_WINDOWS_LEFT,
     WXK_WINDOWS_RIGHT,
     WXK_WINDOWS_MENU ,
-    WXK_COMMAND
+    WXK_COMMAND,
+
+    // Hardware-specific buttons
+    WXK_SPECIAL1 = 193,
+    WXK_SPECIAL2,
+    WXK_SPECIAL3,
+    WXK_SPECIAL4,
+    WXK_SPECIAL5,
+    WXK_SPECIAL6,
+    WXK_SPECIAL7,
+    WXK_SPECIAL8,
+    WXK_SPECIAL9,
+    WXK_SPECIAL10,
+    WXK_SPECIAL11,
+    WXK_SPECIAL12,
+    WXK_SPECIAL13,
+    WXK_SPECIAL14,
+    WXK_SPECIAL15,
+    WXK_SPECIAL16,
+    WXK_SPECIAL17,
+    WXK_SPECIAL18,
+    WXK_SPECIAL19,
+    WXK_SPECIAL20
 };
 
 #if wxUSE_HOTKEY
diff --git a/include/wx/event.h b/include/wx/event.h
index d056318fa7..e488280322 100644
--- a/include/wx/event.h
+++ b/include/wx/event.h
@@ -273,6 +273,7 @@ BEGIN_DECLARE_EVENT_TYPES()
     DECLARE_EVENT_TYPE(wxEVT_UPDATE_UI, 440)
     DECLARE_EVENT_TYPE(wxEVT_SIZING, 441)
     DECLARE_EVENT_TYPE(wxEVT_MOVING, 442)
+    DECLARE_EVENT_TYPE(wxEVT_HIBERNATE, 443)
 
         // Generic command events
         // Note: a click is a higher-level event than button down/up
@@ -1288,6 +1289,7 @@ private:
 /*
  wxEVT_ACTIVATE
  wxEVT_ACTIVATE_APP
+ wxEVT_HIBERNATE
  */
 
 class WXDLLIMPEXP_CORE wxActivateEvent : public wxEvent
@@ -2686,6 +2688,7 @@ typedef void (wxEvtHandler::*wxMouseCaptureChangedEventFunction)(wxMouseCaptureC
 #define EVT_CHILD_FOCUS(func)  wx__DECLARE_EVT0(wxEVT_CHILD_FOCUS, wxChildFocusEventHandler(func))
 #define EVT_ACTIVATE(func)  wx__DECLARE_EVT0(wxEVT_ACTIVATE, wxActivateEventHandler(func))
 #define EVT_ACTIVATE_APP(func)  wx__DECLARE_EVT0(wxEVT_ACTIVATE_APP, wxActivateEventHandler(func))
+#define EVT_HIBERNATE(func)  wx__DECLARE_EVT0(wxEVT_HIBERNATE, wxActivateEventHandler(func))
 #define EVT_END_SESSION(func)  wx__DECLARE_EVT0(wxEVT_END_SESSION, wxCloseEventHandler(func))
 #define EVT_QUERY_END_SESSION(func)  wx__DECLARE_EVT0(wxEVT_QUERY_END_SESSION, wxCloseEventHandler(func))
 #define EVT_DROP_FILES(func)  wx__DECLARE_EVT0(wxEVT_DROP_FILES, wxDropFilesEventHandler(func))
diff --git a/include/wx/msw/frame.h b/include/wx/msw/frame.h
index c7fb8ed76c..a925030e4a 100644
--- a/include/wx/msw/frame.h
+++ b/include/wx/msw/frame.h
@@ -153,6 +153,9 @@ private:
 #if wxUSE_TOOLTIPS
     WXHWND                m_hwndToolTip;
 #endif // tooltips
+#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
+    void* m_activateInfo;
+#endif
 
     // used by IconizeChildFrames(), see comments there
     bool m_wasMinimized;
diff --git a/include/wx/textctrl.h b/include/wx/textctrl.h
index f56d0197ad..43c6cfda0a 100644
--- a/include/wx/textctrl.h
+++ b/include/wx/textctrl.h
@@ -123,6 +123,13 @@ const wxTextCoord wxInvalidTextCoord    = -2;
 // wxTE_RICH controls - can be used together with or instead of wxTE_RICH
 #define wxTE_RICH2          0x8000
 
+// reuse wxTE_RICH2's value for CAPEDIT control on Windows CE
+#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
+#define wxTE_CAPITALIZE     wxTE_RICH2
+#else
+#define wxTE_CAPITALIZE     0
+#endif
+
 // ----------------------------------------------------------------------------
 // wxTextCtrl::HitTest return values
 // ----------------------------------------------------------------------------
diff --git a/src/common/event.cpp b/src/common/event.cpp
index bda30d8451..7bb9ba699d 100644
--- a/src/common/event.cpp
+++ b/src/common/event.cpp
@@ -265,6 +265,7 @@ DEFINE_EVENT_TYPE(wxEVT_MOVING)
 DEFINE_EVENT_TYPE(wxEVT_CLOSE_WINDOW)
 DEFINE_EVENT_TYPE(wxEVT_END_SESSION)
 DEFINE_EVENT_TYPE(wxEVT_QUERY_END_SESSION)
+DEFINE_EVENT_TYPE(wxEVT_HIBERNATE)
 DEFINE_EVENT_TYPE(wxEVT_ACTIVATE_APP)
 DEFINE_EVENT_TYPE(wxEVT_POWER)
 DEFINE_EVENT_TYPE(wxEVT_ACTIVATE)
diff --git a/src/msw/app.cpp b/src/msw/app.cpp
index 64ea131143..84a91f04d7 100644
--- a/src/msw/app.cpp
+++ b/src/msw/app.cpp
@@ -68,6 +68,10 @@
     #define  wxUSE_OLE 0
 #endif // broken compilers
 
+#if defined(__POCKETPC__) || defined(__SMARTPHONE__)
+#include <aygshell.h>
+#endif
+
 #if wxUSE_OLE
     #include <ole2.h>
 #endif
@@ -300,6 +304,10 @@ bool wxApp::Initialize(int& argc, wxChar **argv)
     InitCommonControls();
 #endif // __WIN95__
 
+#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
+    SHInitExtraControls();
+#endif
+
     wxOleInitialize();
 
     RegisterWindowClasses();
diff --git a/src/msw/frame.cpp b/src/msw/frame.cpp
index 22bebcacc6..777f5ea1f6 100644
--- a/src/msw/frame.cpp
+++ b/src/msw/frame.cpp
@@ -46,6 +46,12 @@
 #include <commctrl.h>
 #endif
 
+#if defined(__POCKETPC__) || defined(__SMARTPHONE__)
+#include "wx/msw/ole/oleutils.h"
+#include <aygshell.h>
+#include "wx/msw/winundef.h"
+#endif
+
 #if wxUSE_STATUSBAR
     #include "wx/statusbr.h"
     #include "wx/generic/statusbr.h"
@@ -177,6 +183,14 @@ void wxFrame::Init()
     m_hwndToolTip = 0;
 #endif
 
+#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
+    SHACTIVATEINFO* info = new SHACTIVATEINFO;
+    memset(info, 0, sizeof(SHACTIVATEINFO));
+    info->cbSize = sizeof(SHACTIVATEINFO);
+
+    m_activateInfo = (void*) info;
+#endif
+
     m_wasMinimized = false;
 }
 
@@ -213,6 +227,12 @@ wxFrame::~wxFrame()
 {
     m_isBeingDeleted = true;
     DeleteAllBars();
+
+#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
+    SHACTIVATEINFO* info = (SHACTIVATEINFO*) m_activateInfo;
+    delete info;
+    m_activateInfo = NULL;
+#endif
 }
 
 // ----------------------------------------------------------------------------
@@ -932,6 +952,39 @@ WXLRESULT wxFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lPara
 
     switch ( message )
     {
+#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
+        case WM_ACTIVATE:
+        {
+            SHACTIVATEINFO* info = (SHACTIVATEINFO*) m_activateInfo;
+            if (info)
+                SHHandleWMActivate(GetHwnd(), wParam, lParam, info, FALSE);
+            
+            // This implicitly sends a wxEVT_ACTIVATE_APP event
+            if (wxTheApp)
+                wxTheApp->SetActive(wParam != 0, FindFocus());
+            break;
+        }
+        case WM_SETTINGCHANGE:
+        {
+            SHACTIVATEINFO* info = (SHACTIVATEINFO*) m_activateInfo;
+            if (info)
+                SHHandleWMSettingChange(GetHwnd(), wParam, lParam, info);
+            processed = true;
+            break;
+        }
+        case WM_HIBERNATE:
+        {
+            wxActivateEvent event(wxEVT_HIBERNATE, true, wxID_ANY);
+            event.SetEventObject(wxTheApp);
+
+            if (wxTheApp)
+            {
+                processed = wxTheApp->ProcessEvent(event);
+            }
+            break;
+        }
+#endif
+
         case WM_CLOSE:
             // if we can't close, tell the system that we processed the
             // message - otherwise it would close us
diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp
index 2f4136d212..87d8ada59e 100644
--- a/src/msw/textctrl.cpp
+++ b/src/msw/textctrl.cpp
@@ -280,6 +280,12 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id,
 
     // do create the control - either an EDIT or RICHEDIT
     wxString windowClass = wxT("EDIT");
+    
+#if defined(__POCKETPC__) || defined(__SMARTPHONE__)
+    // A control that capitalizes the first letter
+    if (style & wxTE_CAPITALIZE)
+        windowClass = wxT("CAPEDIT");
+#endif    
 
 #if wxUSE_RICHEDIT
     if ( m_windowStyle & wxTE_AUTO_URL )
diff --git a/src/msw/window.cpp b/src/msw/window.cpp
index 0e04fab578..d196f61203 100644
--- a/src/msw/window.cpp
+++ b/src/msw/window.cpp
@@ -2278,6 +2278,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
 
 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
         case WM_ACTIVATEAPP:
+            // This implicitly sends a wxEVT_ACTIVATE_APP event
             wxTheApp->SetActive(wParam != 0, FindFocus());
             break;
 #endif
@@ -5794,6 +5795,25 @@ wxPoint wxGetMousePosition()
 
 #if wxUSE_HOTKEY
 
+#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
+static void WinCEUnregisterHotKey(int modifiers, int id)
+{
+    // Register hotkeys for the hardware buttons
+    HINSTANCE hCoreDll;
+    typedef BOOL (WINAPI *UnregisterFunc1Proc)(UINT, UINT);
+
+    UnregisterFunc1Proc procUnregisterFunc;
+    hCoreDll = LoadLibrary(_T("coredll.dll"));
+    if (hCoreDll)
+    {
+        procUnregisterFunc = (UnregisterFunc1Proc)GetProcAddress(hCoreDll, _T("UnregisterFunc1"));
+        if (procUnregisterFunc)
+            procUnregisterFunc(modifiers, id);
+        FreeLibrary(hCoreDll);
+    }
+}
+#endif
+
 bool wxWindowMSW::RegisterHotKey(int hotkeyId, int modifiers, int keycode)
 {
     UINT win_modifiers=0;
@@ -5806,6 +5826,12 @@ bool wxWindowMSW::RegisterHotKey(int hotkeyId, int modifiers, int keycode)
     if ( modifiers & wxMOD_WIN )
         win_modifiers |= MOD_WIN;
 
+#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
+    // Required for PPC and Smartphone hardware buttons
+    if (keycode >= WXK_SPECIAL1 && keycode <= WXK_SPECIAL20)
+        WinCEUnregisterHotKey(win_modifiers, hotkeyId);
+#endif
+
     if ( !::RegisterHotKey(GetHwnd(), hotkeyId, win_modifiers, keycode) )
     {
         wxLogLastError(_T("RegisterHotKey"));
@@ -5818,6 +5844,10 @@ bool wxWindowMSW::RegisterHotKey(int hotkeyId, int modifiers, int keycode)
 
 bool wxWindowMSW::UnregisterHotKey(int hotkeyId)
 {
+#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
+    WinCEUnregisterHotKey(MOD_WIN, hotkeyId);
+#endif
+
     if ( !::UnregisterHotKey(GetHwnd(), hotkeyId) )
     {
         wxLogLastError(_T("UnregisterHotKey"));
-- 
2.50.0

