]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
better wxGetUserId/Name
[wxWidgets.git] / src / msw / window.cpp
index 88a43b6b3314672f22c4befbf8cf4072512ae999..5a5d8f643488ca57eb25fa858a4efcf5dc8e7a00 100644 (file)
@@ -29,6 +29,9 @@
 #endif
 
 #ifndef WX_PRECOMP
+    #include <windows.h>
+    #include "wx/msw/winundef.h"
+    #include "wx/accel.h"
     #include "wx/setup.h"
     #include "wx/menu.h"
     #include "wx/dc.h"
 #endif
 
 #if     wxUSE_DRAG_AND_DROP
+    #include "wx/dataobj.h"
     #include "wx/msw/ole/droptgt.h"
 #endif
 
 #include "wx/menuitem.h"
 #include "wx/log.h"
 
+#include "wx/msw/private.h"
+
 #if wxUSE_TOOLTIPS
     #include "wx/tooltip.h"
 #endif
 
+#if wxUSE_CARET
+    #include "wx/caret.h"
+#endif // wxUSE_CARET
+
 #include "wx/intl.h"
 #include "wx/log.h"
 
-#include "wx/msw/private.h"
 
 #include "wx/textctrl.h"
 
     #endif
 #endif
 
-#include "wx/msw/winundef.h"
-
 // ---------------------------------------------------------------------------
 // macros
 // ---------------------------------------------------------------------------
 
 // standard macros missing from some compilers headers
 #ifndef GET_X_LPARAM
-        #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
-        #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
+    #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
+    #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
 #endif // GET_X_LPARAM
 
 // ---------------------------------------------------------------------------
@@ -110,7 +117,7 @@ extern MSG s_currentMsg;
 
 wxMenu *wxCurrentPopupMenu = NULL;
 extern wxList WXDLLEXPORT wxPendingDelete;
-extern char wxCanvasClassName[];
+extern wxChar wxCanvasClassName[];
 
 // ---------------------------------------------------------------------------
 // private functions
@@ -231,12 +238,6 @@ void wxWindow::Init()
     m_doubleClickAllowed = 0;
     m_winCaptured = FALSE;
 
-    // caret stuff: initially there is no caret at all
-    m_caretWidth =
-    m_caretHeight = 0;
-    m_caretEnabled =
-    m_caretShown = FALSE;
-
     m_isBeingDeleted = FALSE;
     m_oldWndProc = 0;
     m_useCtl3D = FALSE;
@@ -289,7 +290,7 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id,
                       long style,
                       const wxString& name)
 {
-    wxCHECK_MSG( parent, FALSE, "can't create wxWindow without parent" );
+    wxCHECK_MSG( parent, FALSE, _T("can't create wxWindow without parent") );
 
     CreateBase(parent, id, pos, size, style, name);
 
@@ -316,6 +317,20 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id,
         msflags |= WS_BORDER;
     }
 
+    // calculate the value to return from WM_GETDLGCODE handler
+    if ( GetWindowStyleFlag() & wxWANTS_CHARS )
+    {
+        // want everything: i.e. all keys and WM_CHAR message
+        m_lDlgCode = DLGC_WANTARROWS | DLGC_WANTCHARS |
+                     DLGC_WANTTAB | DLGC_WANTMESSAGE;
+        
+    }
+    else
+    {
+        // default behaviour
+        m_lDlgCode = 0;
+    }
+
     MSWCreate(m_windowId, parent, wxCanvasClassName, this, NULL,
               pos.x, pos.y,
               WidthDefault(size.x), HeightDefault(size.y),
@@ -784,7 +799,7 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect)
 
 void wxWindow::SubclassWin(WXHWND hWnd)
 {
-    wxASSERT_MSG( !m_oldWndProc, "subclassing window twice?" );
+    wxASSERT_MSG( !m_oldWndProc, _T("subclassing window twice?") );
 
     wxAssociateWinWithHandle((HWND)hWnd, this);
 
@@ -891,7 +906,7 @@ WXDWORD wxWindow::Determine3DEffects(WXDWORD defaultBorderStyle, bool *want3D)
     return exStyle;
 }
 
-#if WXWIN_COMPATIBILITY_2
+#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
 // defined.
@@ -1006,7 +1021,7 @@ void wxWindow::Refresh(bool eraseBack, const wxRect *rect)
 // drag and drop
 // ---------------------------------------------------------------------------
 
-#if    wxUSE_DRAG_AND_DROP
+#if wxUSE_DRAG_AND_DROP
 
 void wxWindow::SetDropTarget(wxDropTarget *pDropTarget)
 {
@@ -1260,7 +1275,8 @@ int wxWindow::GetCharWidth() const
     return lpTextMetric.tmAveCharWidth;
 }
 
-void wxWindow::GetTextExtent(const wxString& string, int *x, int *y,
+void wxWindow::GetTextExtent(const wxString& string,
+                             int *x, int *y,
                              int *descent, int *externalLeading,
                              const wxFont *theFont) const
 {
@@ -1282,7 +1298,7 @@ void wxWindow::GetTextExtent(const wxString& string, int *x, int *y,
 
     SIZE sizeRect;
     TEXTMETRIC tm;
-    GetTextExtentPoint(dc, (const char *)string, (int)string.Length(), &sizeRect);
+    GetTextExtentPoint(dc, (const wxChar *)string, (int)string.Length(), &sizeRect);
     GetTextMetrics(dc, &tm);
 
     if ( fontToUse && fnt && hfontOld )
@@ -1296,51 +1312,47 @@ void wxWindow::GetTextExtent(const wxString& string, int *x, int *y,
     if ( externalLeading ) *externalLeading = tm.tmExternalLeading;
 }
 
+#if wxUSE_CARET && WXWIN_COMPATIBILITY
 // ---------------------------------------------------------------------------
 // Caret manipulation
 // ---------------------------------------------------------------------------
 
 void wxWindow::CreateCaret(int w, int h)
 {
-    m_caretWidth = w;
-    m_caretHeight = h;
-    m_caretEnabled = TRUE;
+    SetCaret(new wxCaret(this, w, h));
 }
 
 void wxWindow::CreateCaret(const wxBitmap *WXUNUSED(bitmap))
 {
-    // Not implemented
+    wxFAIL_MSG("not implemented");
 }
 
 void wxWindow::ShowCaret(bool show)
 {
-    if ( m_caretEnabled )
-    {
-        if ( show )
-            ::ShowCaret(GetHwnd());
-        else
-            ::HideCaret(GetHwnd());
-        m_caretShown = show;
-    }
+    wxCHECK_RET( m_caret, "no caret to show" );
+
+    m_caret->Show(show);
 }
 
 void wxWindow::DestroyCaret()
 {
-    m_caretEnabled = FALSE;
+    SetCaret(NULL);
 }
 
 void wxWindow::SetCaretPos(int x, int y)
 {
-    ::SetCaretPos(x, y);
+    wxCHECK_RET( m_caret, "no caret to move" );
+
+    m_caret->Move(x, y);
 }
 
 void wxWindow::GetCaretPos(int *x, int *y) const
 {
-    POINT point;
-    ::GetCaretPos(&point);
-    *x = point.x;
-    *y = point.y;
+    wxCHECK_RET( m_caret, "no caret to get position of" );
+
+    m_caret->GetPosition(x, y);
 }
+#endif // wxUSE_CARET
 
 // ===========================================================================
 // pre/post message processing
@@ -1383,7 +1395,7 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg)
             bool bForward = TRUE,
                  bWindowChange = FALSE;
 
-            switch ( msg->wParam ) 
+            switch ( msg->wParam )
             {
                 case VK_TAB:
                     if ( lDlgCode & DLGC_WANTTAB ) {
@@ -1412,27 +1424,16 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg)
 
                 case VK_RETURN:
                     {
-                        if ( lDlgCode & DLGC_WANTMESSAGE )
+                        if ( (lDlgCode & DLGC_WANTMESSAGE) && !bCtrlDown )
                         {
                             // control wants to process Enter itself, don't
                             // call IsDialogMessage() which would interpret
                             // it
                             return FALSE;
                         }
-#ifndef __WIN16__
-                        wxButton *btnDefault = GetDefaultItem();
-                        if ( btnDefault && !bCtrlDown )
-                        {
-                            // if there is a default button, Enter should
-                            // press it
-                            (void)::SendMessage((HWND)btnDefault->GetHWND(),
-                                                BM_CLICK, 0, 0);
-                            return TRUE;
-                        }
-                        // else: but if there is not it makes sense to make it
+                        // else: but if it does not it makes sense to make it
                         //       work like a TAB - and that's what we do.
                         //       Note that Ctrl-Enter always works this way.
-#endif
                     }
                     break;
 
@@ -1552,7 +1553,7 @@ void wxWindow::UnpackScroll(WXWPARAM wParam, WXLPARAM lParam,
 void wxWindow::UnpackCtlColor(WXWPARAM wParam, WXLPARAM lParam,
                               WXWORD *nCtlColor, WXHDC *hdc, WXHWND *hwnd)
 {
-    *control = (WXHWND)LOWORD(lParam);
+    *hwnd = (WXHWND)LOWORD(lParam);
     *nCtlColor = (int)HIWORD(lParam);
     *hdc = (WXHDC)wParam;
 }
@@ -1580,7 +1581,7 @@ LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA
 {
     // trace all messages - useful for the debugging
 #ifdef __WXDEBUG__
-    wxLogTrace(wxTraceMessages, "Processing %s(wParam=%8lx, lParam=%8lx)",
+    wxLogTrace(wxTraceMessages, _T("Processing %s(wParam=%8lx, lParam=%8lx)"),
                wxGetMessageName(message), wParam, lParam);
 #endif // __WXDEBUG__
 
@@ -1768,6 +1769,15 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
             }
             break;
 
+        case WM_GETDLGCODE:
+            if ( m_lDlgCode )
+            {
+                rc.result = m_lDlgCode;
+                processed = TRUE;
+            }
+            //else: get the dlg code from the DefWindowProc()
+            break;
+
         case WM_KEYDOWN:
             // If this has been processed by an event handler,
             // return 0 now (we've handled it).
@@ -1795,7 +1805,10 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
                 case VK_RETURN:
                 case VK_BACK:
                 case VK_TAB:
-                    processed = TRUE;
+                    // 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;
 
@@ -1926,7 +1939,7 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
             break;
 
         case WM_GETMINMAXINFO:
-            processed = HandleGetMinMaxInfo((LPMINMAXINFO)lParam);
+            processed = HandleGetMinMaxInfo((MINMAXINFO*)lParam);
             break;
 
         case WM_SETCURSOR:
@@ -1947,7 +1960,7 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
     if ( !processed )
     {
 #ifdef __WXDEBUG__
-        wxLogTrace(wxTraceMessages, "Forwarding %s to DefWindowProc.",
+        wxLogTrace(wxTraceMessages, _T("Forwarding %s to DefWindowProc."),
                    wxGetMessageName(message));
 #endif // __WXDEBUG__
         rc.result = MSWDefWindowProc(message, wParam, lParam);
@@ -1988,7 +2001,7 @@ void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win)
     // adding NULL hWnd is (first) surely a result of an error and
     // (secondly) breaks menu command processing
     wxCHECK_RET( hWnd != (HWND)NULL,
-                 "attempt to add a NULL hWnd to window list ignored" );
+                 _T("attempt to add a NULL hWnd to window list ignored") );
 
     if ( !wxWinHandleList->Find((long)hWnd) )
         wxWinHandleList->Append((long)hWnd, win);
@@ -2015,16 +2028,16 @@ void wxWindow::MSWDetachWindowMenu()
         int i;
         for (i = 0; i < N; i++)
         {
-            char buf[100];
+            wxChar buf[100];
             int chars = GetMenuString(hMenu, i, buf, 100, MF_BYPOSITION);
             if ( !chars )
             {
-                wxLogLastError("GetMenuString");
+                wxLogLastError(_T("GetMenuString"));
 
                 continue;
             }
 
-            if ( strcmp(buf, "&Window") == 0 )
+            if ( wxStrcmp(buf, _T("&Window")) == 0 )
             {
                 RemoveMenu(hMenu, i, MF_BYPOSITION);
 
@@ -2036,15 +2049,15 @@ void wxWindow::MSWDetachWindowMenu()
 
 bool wxWindow::MSWCreate(int id,
                          wxWindow *parent,
-                         const char *wclass,
+                         const wxChar *wclass,
                          wxWindow *wx_win,
-                         const char *title,
+                         const wxChar *title,
                          int x,
                          int y,
                          int width,
                          int height,
                          WXDWORD style,
-                         const char *dialog_template,
+                         const wxChar *dialog_template,
                          WXDWORD extendedStyle)
 {
     int x1 = CW_USEDEFAULT;
@@ -2068,7 +2081,11 @@ bool wxWindow::MSWCreate(int id,
     if ( width > -1 ) width1 = width;
     if ( height > -1 ) height1 = height;
 
+#ifdef __WXWINE__
+    HWND hParent = (HWND)NULL;
+#else
     HWND hParent = NULL;
+#endif
     if ( parent )
         hParent = (HWND) parent->GetHWND();
 
@@ -2089,7 +2106,22 @@ bool wxWindow::MSWCreate(int id,
             return FALSE;
         }
 
-        ::MoveWindow(GetHwnd(), x1, y1, width1, height1, FALSE);
+        // ::SetWindowLong(GWL_EXSTYLE) doesn't work for the dialogs, so try
+        // to take care of (at least some) extended style flags ourselves
+        if ( extendedStyle & WS_EX_TOPMOST )
+        {
+            if ( !::SetWindowPos(GetHwnd(), HWND_TOPMOST, 0, 0, 0, 0,
+                                 SWP_NOSIZE | SWP_NOMOVE) )
+            {
+                wxLogLastError(_T("SetWindowPos"));
+            }
+        }
+
+        // move the dialog to its initial position without forcing repainting
+        if ( !::MoveWindow(GetHwnd(), x1, y1, width1, height1, FALSE) )
+        {
+            wxLogLastError(_T("MoveWindow"));
+        }
     }
     else
     {
@@ -2099,7 +2131,7 @@ bool wxWindow::MSWCreate(int id,
 
         m_hWnd = (WXHWND)CreateWindowEx(extendedStyle,
                                         wclass,
-                                        title ? title : "",
+                                        title ? title : _T(""),
                                         style,
                                         x1, y1,
                                         width1, height1,
@@ -2173,7 +2205,7 @@ bool wxWindow::MSWOnNotify(int WXUNUSED(idCtrl),
     if ( hdr->code == TTN_NEEDTEXT && m_tooltip )
     {
         TOOLTIPTEXT *ttt = (TOOLTIPTEXT *)lParam;
-        ttt->lpszText = (char *)m_tooltip->GetTip().c_str();
+        ttt->lpszText = (wxChar *)m_tooltip->GetTip().c_str();
 
         // processed
         return TRUE;
@@ -2277,20 +2309,13 @@ bool wxWindow::HandleActivate(int state,
 
 bool wxWindow::HandleSetFocus(WXHWND WXUNUSED(hwnd))
 {
+#if wxUSE_CARET
     // Deal with caret
-    if ( m_caretEnabled && (m_caretWidth > 0) && (m_caretHeight > 0) )
+    if ( m_caret )
     {
-        if ( ::CreateCaret(GetHwnd(), NULL, m_caretWidth, m_caretHeight) )
-        {
-            if ( m_caretShown )
-            {
-                if ( !::ShowCaret(GetHwnd()) )
-                    wxLogLastError("ShowCaret");
-            }
-        }
-        else
-            wxLogLastError("CreateCaret");
+        m_caret->OnSetFocus();
     }
+#endif // wxUSE_CARET
 
     // panel wants to track the window which was the last to have focus in it
     wxWindow *parent = GetParent();
@@ -2307,12 +2332,13 @@ bool wxWindow::HandleSetFocus(WXHWND WXUNUSED(hwnd))
 
 bool wxWindow::HandleKillFocus(WXHWND WXUNUSED(hwnd))
 {
+#if wxUSE_CARET
     // Deal with caret
-    if ( m_caretEnabled )
+    if ( m_caret )
     {
-        if ( !::DestroyCaret() )
-            wxLogLastError("DestroyCaret");
+        m_caret->OnKillFocus();
     }
+#endif // wxUSE_CARET
 
     wxFocusEvent event(wxEVT_KILL_FOCUS, m_windowId);
     event.SetEventObject(this);
@@ -2356,7 +2382,7 @@ bool wxWindow::HandleDropFiles(WXWPARAM wParam)
     int wIndex;
     for (wIndex=0; wIndex < (int)gwFilesDropped; wIndex++)
     {
-        DragQueryFile (hFilesInfo, wIndex, (LPSTR) wxBuffer, 1000);
+        DragQueryFile (hFilesInfo, wIndex, (LPTSTR) wxBuffer, 1000);
         files[wIndex] = wxBuffer;
     }
     DragFinish (hFilesInfo);
@@ -2426,13 +2452,13 @@ bool wxWindow::HandleSetCursor(WXHWND hWnd,
     return FALSE;
 }
 
-#if wxUSE_OWNER_DRAWN
 // ---------------------------------------------------------------------------
 // owner drawn stuff
 // ---------------------------------------------------------------------------
 
 bool wxWindow::MSWOnDrawItem(int id, WXDRAWITEMSTRUCT *itemStruct)
 {
+#if wxUSE_OWNER_DRAWN
     // is it a menu item?
     if ( id == 0 )
     {
@@ -2462,11 +2488,14 @@ bool wxWindow::MSWOnDrawItem(int id, WXDRAWITEMSTRUCT *itemStruct)
         return ((wxControl *)item)->MSWOnDraw(itemStruct);
     }
     else
+#endif
         return FALSE;
+
 }
 
 bool wxWindow::MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct)
 {
+#if wxUSE_OWNER_DRAWN
     // is it a menu item?
     if ( id == 0 )
     {
@@ -2484,10 +2513,9 @@ bool wxWindow::MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct)
     {
         return ((wxControl *)item)->MSWOnMeasure(itemStruct);
     }
-
+#endif  // owner-drawn menus
     return FALSE;
 }
-#endif  // owner-drawn menus
 
 // ---------------------------------------------------------------------------
 // colours and palettes
@@ -3067,7 +3095,7 @@ bool wxWindow::HandleJoystickEvent(WXUINT msg, int x, int y, WXUINT flags)
             break;
 
         default:
-            wxFAIL_MSG("no such joystick event");
+            wxFAIL_MSG(_T("no such joystick event"));
 
             return FALSE;
     }
@@ -3093,7 +3121,7 @@ bool wxWindow::MSWOnScroll(int orientation, WXWORD wParam,
             return child->MSWOnScroll(orientation, wParam, pos, control);
     }
 
-    wxScrollEvent event;
+    wxScrollWinEvent event;
     event.SetPosition(pos);
     event.SetOrientation(orientation);
     event.m_eventObject = this;
@@ -3101,32 +3129,32 @@ bool wxWindow::MSWOnScroll(int orientation, WXWORD wParam,
     switch ( wParam )
     {
     case SB_TOP:
-        event.m_eventType = wxEVT_SCROLL_TOP;
+        event.m_eventType = wxEVT_SCROLLWIN_TOP;
         break;
 
     case SB_BOTTOM:
-        event.m_eventType = wxEVT_SCROLL_BOTTOM;
+        event.m_eventType = wxEVT_SCROLLWIN_BOTTOM;
         break;
 
     case SB_LINEUP:
-        event.m_eventType = wxEVT_SCROLL_LINEUP;
+        event.m_eventType = wxEVT_SCROLLWIN_LINEUP;
         break;
 
     case SB_LINEDOWN:
-        event.m_eventType = wxEVT_SCROLL_LINEDOWN;
+        event.m_eventType = wxEVT_SCROLLWIN_LINEDOWN;
         break;
 
     case SB_PAGEUP:
-        event.m_eventType = wxEVT_SCROLL_PAGEUP;
+        event.m_eventType = wxEVT_SCROLLWIN_PAGEUP;
         break;
 
     case SB_PAGEDOWN:
-        event.m_eventType = wxEVT_SCROLL_PAGEDOWN;
+        event.m_eventType = wxEVT_SCROLLWIN_PAGEDOWN;
         break;
 
     case SB_THUMBTRACK:
     case SB_THUMBPOSITION:
-        event.m_eventType = wxEVT_SCROLL_THUMBTRACK;
+        event.m_eventType = wxEVT_SCROLLWIN_THUMBTRACK;
         break;
 
     default: