X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/3f480da37ca0840ddbe48b908d511d2e9fc20bf4..9fea1a5d6282d0925c15fc21e33c6236febcdecf:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index a1423f78e7..380abf22fe 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -29,6 +29,10 @@ #endif #ifndef WX_PRECOMP + #include + #include "wx/msw/winundef.h" + #include "wx/window.h" + #include "wx/accel.h" #include "wx/setup.h" #include "wx/menu.h" #include "wx/dc.h" @@ -58,6 +62,8 @@ #include "wx/menuitem.h" #include "wx/log.h" +#include "wx/msw/private.h" + #if wxUSE_TOOLTIPS #include "wx/tooltip.h" #endif @@ -69,13 +75,12 @@ #include "wx/intl.h" #include "wx/log.h" -#include "wx/msw/private.h" #include "wx/textctrl.h" #include -#ifndef __GNUWIN32__ +#if !defined(__GNUWIN32__)|| defined(wxUSE_NORLANDER_HEADERS) #include #include #endif @@ -84,26 +89,26 @@ #include #endif -#if ( defined(__WIN95__) && !defined(__GNUWIN32__)) || defined(__TWIN32__ ) +#if ( defined(__WIN95__) && !defined(__GNUWIN32__)) || defined(__TWIN32__ ) || defined(wxUSE_NORLANDER_HEADERS) #include #endif #ifndef __TWIN32__ #ifdef __GNUWIN32__ - #include + #ifndef wxUSE_NORLANDER_HEADERS + #include + #endif #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 // --------------------------------------------------------------------------- @@ -115,7 +120,7 @@ extern MSG s_currentMsg; wxMenu *wxCurrentPopupMenu = NULL; extern wxList WXDLLEXPORT wxPendingDelete; -extern char wxCanvasClassName[]; +extern wxChar wxCanvasClassName[]; // --------------------------------------------------------------------------- // private functions @@ -157,7 +162,7 @@ END_EVENT_TABLE() // --------------------------------------------------------------------------- // Find an item given the MS Windows id -wxWindow *wxWindow::FindItem(int id) const +wxWindow *wxWindow::FindItem(long id) const { wxWindowList::Node *current = GetChildren().GetFirst(); while (current) @@ -244,6 +249,11 @@ void wxWindow::Init() // wxWnd m_hMenu = 0; + m_hWnd = 0; + + // pass WM_GETDLGCODE to DefWindowProc() + m_lDlgCode = 0; + m_xThumbSize = 0; m_yThumbSize = 0; m_backgroundTransparent = FALSE; @@ -274,11 +284,10 @@ wxWindow::~wxWindow() { if ( !::DestroyWindow(GetHwnd()) ) wxLogLastError("DestroyWindow"); - } - // Restore old Window proc, if required and remove hWnd <-> wxWindow - // association - UnsubclassWin(); + // remove hWnd <-> wxWindow association + wxRemoveHandleAssociation(this); + } } // real construction (Init() must have been called before!) @@ -288,9 +297,10 @@ 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); + if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) ) + return FALSE; parent->AddChild(this); @@ -315,6 +325,14 @@ 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; + } + MSWCreate(m_windowId, parent, wxCanvasClassName, this, NULL, pos.x, pos.y, WidthDefault(size.x), HeightDefault(size.y), @@ -432,7 +450,7 @@ bool wxWindow::SetFont(const wxFont& font) wxASSERT_MSG( hFont, _T("should have valid font") ); - ::SendMessage(hWnd, WM_SETFONT, (WPARAM)hFont, TRUE); + ::SendMessage(hWnd, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0)); } return TRUE; @@ -783,12 +801,15 @@ 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); + HWND hwnd = (HWND)hWnd; + wxCHECK_RET( ::IsWindow(hwnd), _T("invalid HWND in SubclassWin") ); - m_oldWndProc = (WXFARPROC) GetWindowLong((HWND) hWnd, GWL_WNDPROC); - SetWindowLong((HWND) hWnd, GWL_WNDPROC, (LONG) wxWndProc); + wxAssociateWinWithHandle(hwnd, this); + + m_oldWndProc = (WXFARPROC) GetWindowLong(hwnd, GWL_WNDPROC); + SetWindowLong(hwnd, GWL_WNDPROC, (LONG) wxWndProc); } void wxWindow::UnsubclassWin() @@ -796,16 +817,19 @@ void wxWindow::UnsubclassWin() wxRemoveHandleAssociation(this); // Restore old Window proc - if ( GetHwnd() ) + HWND hwnd = GetHwnd(); + if ( hwnd ) { - FARPROC farProc = (FARPROC) GetWindowLong(GetHwnd(), GWL_WNDPROC); + m_hWnd = 0; + + wxCHECK_RET( ::IsWindow(hwnd), _T("invalid HWND in UnsubclassWin") ); + + FARPROC farProc = (FARPROC) GetWindowLong(hwnd, GWL_WNDPROC); if ( (m_oldWndProc != 0) && (farProc != (FARPROC) m_oldWndProc) ) { - SetWindowLong(GetHwnd(), GWL_WNDPROC, (LONG) m_oldWndProc); + SetWindowLong(hwnd, GWL_WNDPROC, (LONG) m_oldWndProc); m_oldWndProc = 0; } - - m_hWnd = 0; } } @@ -835,7 +859,8 @@ WXDWORD wxWindow::MakeExtendedStyle(long style, bool eliminateBorders) // 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 wxWindow::Determine3DEffects(WXDWORD defaultBorderStyle, bool *want3D) +WXDWORD wxWindow::Determine3DEffects(WXDWORD defaultBorderStyle, + bool *want3D) const { // If matches certain criteria, then assume no 3D effects // unless specifically requested (dealt with in MakeExtendedStyle) @@ -890,7 +915,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. @@ -1005,7 +1030,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) { @@ -1066,28 +1091,33 @@ void wxWindow::DoGetSize(int *x, int *y) const void wxWindow::DoGetPosition(int *x, int *y) const { HWND hWnd = GetHwnd(); - HWND hParentWnd = 0; - if ( GetParent() ) - hParentWnd = (HWND) GetParent()->GetHWND(); RECT rect; GetWindowRect(hWnd, &rect); - // Since we now have the absolute screen coords, if there's a parent we - // must subtract its top left corner POINT point; point.x = rect.left; point.y = rect.top; - if ( hParentWnd ) - { - ::ScreenToClient(hParentWnd, &point); - } - // We may be faking the client origin. So a window that's really at (0, - // 30) may appear (to wxWin apps) to be at (0, 0). - if ( GetParent() ) + // we do the adjustments with respect to the parent only for the "real" + // children, not for the dialogs/frames + if ( !IsTopLevel() ) { - wxPoint pt(GetParent()->GetClientAreaOrigin()); + HWND hParentWnd = 0; + wxWindow *parent = GetParent(); + if ( parent ) + hParentWnd = GetWinHwnd(parent); + + // Since we now have the absolute screen coords, if there's a parent we + // must subtract its top left corner + if ( hParentWnd ) + { + ::ScreenToClient(hParentWnd, &point); + } + + // We may be faking the client origin. So a window that's really at (0, + // 30) may appear (to wxWin apps) to be at (0, 0). + wxPoint pt(parent->GetClientAreaOrigin()); point.x -= pt.x; point.y -= pt.y; } @@ -1144,35 +1174,80 @@ void wxWindow::DoGetClientSize(int *x, int *y) const *y = rect.bottom; } +// set the size of the window: if the dimensions are positive, just use them, +// but if any of them is equal to -1, it means that we must find the value for +// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in +// which case -1 is a valid value for x and y) +// +// If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate +// the width/height to best suit our contents, otherwise we reuse the current +// width/height void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags) { + // get the current size and position... int currentX, currentY; GetPosition(¤tX, ¤tY); int currentW,currentH; GetSize(¤tW, ¤tH); - if ( x == currentX && y == currentY && width == currentW && height == currentH ) + // ... and don't do anything (avoiding flicker) if it's already ok + if ( x == currentX && y == currentY && + width == currentW && height == currentH ) + { return; + } - int actualWidth = width; - int actualHeight = height; - int actualX = x; - int actualY = y; if ( x == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE) ) - actualX = currentX; + x = currentX; if ( y == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE) ) - actualY = currentY; + y = currentY; - AdjustForParentClientOrigin(actualX, actualY, sizeFlags); + AdjustForParentClientOrigin(x, y, sizeFlags); + wxSize size(-1, -1); if ( width == -1 ) - actualWidth = currentW; + { + if ( sizeFlags && wxSIZE_AUTO_WIDTH ) + { + size = DoGetBestSize(); + width = size.x; + } + else + { + // just take the current one + width = currentW; + } + } + if ( height == -1 ) - actualHeight = currentH; + { + if ( sizeFlags && wxSIZE_AUTO_HEIGHT ) + { + if ( size.x == -1 ) + { + size= DoGetBestSize(); + } + //else: already called DoGetBestSize() above - HWND hWnd = GetHwnd(); - if ( hWnd ) - MoveWindow(hWnd, actualX, actualY, actualWidth, actualHeight, (BOOL)TRUE); + height = size.y; + } + else + { + // just take the current one + height = currentH; + } + } + + if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) ) + { + wxLogLastError("MoveWindow"); + } +} + +// for a generic window there is no natural best size - just use the current one +wxSize wxWindow::DoGetBestSize() +{ + return GetSize(); } void wxWindow::DoSetClientSize(int width, int height) @@ -1224,10 +1299,16 @@ wxPoint wxWindow::GetClientAreaOrigin() const // a toolbar that it manages itself). void wxWindow::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags) { - if ( ((sizeFlags & wxSIZE_NO_ADJUSTMENTS) == 0) && GetParent() ) + // don't do it for the dialogs/frames - they float independently of their + // parent + if ( !IsTopLevel() ) { - wxPoint pt(GetParent()->GetClientAreaOrigin()); - x += pt.x; y += pt.y; + wxWindow *parent = GetParent(); + if ( !(sizeFlags & wxSIZE_NO_ADJUSTMENTS) && parent ) + { + wxPoint pt(parent->GetClientAreaOrigin()); + x += pt.x; y += pt.y; + } } } @@ -1259,7 +1340,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 { @@ -1281,7 +1363,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, string, (int)string.Length(), &sizeRect); GetTextMetrics(dc, &tm); if ( fontToUse && fnt && hfontOld ) @@ -1289,13 +1371,17 @@ void wxWindow::GetTextExtent(const wxString& string, int *x, int *y, ReleaseDC(hWnd, dc); - if ( x ) *x = sizeRect.cx; - if ( y ) *y = sizeRect.cy; - if ( descent ) *descent = tm.tmDescent; - if ( externalLeading ) *externalLeading = tm.tmExternalLeading; + if ( x ) + *x = sizeRect.cx; + if ( y ) + *y = sizeRect.cy; + if ( descent ) + *descent = tm.tmDescent; + if ( externalLeading ) + *externalLeading = tm.tmExternalLeading; } -#if wxUSE_CARET +#if wxUSE_CARET && WXWIN_COMPATIBILITY // --------------------------------------------------------------------------- // Caret manipulation // --------------------------------------------------------------------------- @@ -1337,6 +1423,31 @@ void wxWindow::GetCaretPos(int *x, int *y) const } #endif // wxUSE_CARET +// --------------------------------------------------------------------------- +// popup menu +// --------------------------------------------------------------------------- + +bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y) +{ + menu->SetInvokingWindow(this); + menu->UpdateUI(); + + HWND hWnd = GetHwnd(); + HMENU hMenu = GetHmenuOf(menu); + POINT point; + point.x = x; + point.y = y; + ::ClientToScreen(hWnd, &point); + wxCurrentPopupMenu = menu; + ::TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, point.x, point.y, 0, hWnd, NULL); + wxYield(); + wxCurrentPopupMenu = NULL; + + menu->SetInvokingWindow(NULL); + + return TRUE; +} + // =========================================================================== // pre/post message processing // =========================================================================== @@ -1365,6 +1476,7 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg) if ( bProcess ) { bool bCtrlDown = (::GetKeyState(VK_CONTROL) & 0x100) != 0; + bool bShiftDown = (::GetKeyState(VK_SHIFT) & 0x100) != 0; // WM_GETDLGCODE: ask the control if it wants the key for itself, // don't process it if it's the case (except for Ctrl-Tab/Enter @@ -1381,13 +1493,16 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg) switch ( msg->wParam ) { case VK_TAB: - if ( lDlgCode & DLGC_WANTTAB ) { + // 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; } else { // Ctrl-Tab cycles thru notebook pages bWindowChange = bCtrlDown; - bForward = !(::GetKeyState(VK_SHIFT) & 0x100); + bForward = !bShiftDown; } break; @@ -1407,27 +1522,40 @@ 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 ) + else if ( lDlgCode & DLGC_BUTTON ) { - // if there is a default button, Enter should - // press it - (void)::SendMessage((HWND)btnDefault->GetHWND(), - BM_CLICK, 0, 0); - return TRUE; + // buttons want process Enter themselevs + bProcess = FALSE; + } + else + { + wxPanel *panel = wxDynamicCast(this, wxPanel); + wxButton *btn = NULL; + if ( panel ) + { + // panel may have a default button which should + // be activated by Enter + btn = panel->GetDefaultItem(); + } + + if ( btn && btn->IsEnabled() ) + { + // if we do have a default button, do press it + btn->MSWCommand(BN_CLICKED, 0 /* unused */); + + return TRUE; + } + // 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. } - // else: but if there is 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; @@ -1443,7 +1571,16 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg) event.SetEventObject(this); if ( GetEventHandler()->ProcessEvent(event) ) + { + wxButton *btn = wxDynamicCast(FindFocus(), wxButton); + if ( btn ) + { + // the button which has focus should be default + btn->SetDefault(); + } + return TRUE; + } } } @@ -1466,10 +1603,7 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg) bool wxWindow::MSWTranslateMessage(WXMSG* pMsg) { - return m_acceleratorTable.Ok() && - ::TranslateAccelerator(GetHwnd(), - GetTableHaccel(m_acceleratorTable), - (MSG *)pMsg); + return m_acceleratorTable.Translate(this, pMsg); } // --------------------------------------------------------------------------- @@ -1547,7 +1681,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; } @@ -1575,7 +1709,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__ @@ -1585,6 +1719,12 @@ LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA // it with wxWindow stored in wxWndHook if ( !wnd && wxWndHook ) { +#if 0 // def __WXDEBUG__ + char buf[512]; + ::GetClassNameA((HWND) hWnd, buf, 512); + wxString className(buf); +#endif + wxAssociateWinWithHandle(hWnd, wxWndHook); wnd = wxWndHook; wxWndHook = NULL; @@ -1699,8 +1839,8 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) case WM_MBUTTONUP: case WM_MBUTTONDBLCLK: { - int x = LOWORD(lParam); - int y = HIWORD(lParam); + short x = LOWORD(lParam); + short y = HIWORD(lParam); processed = HandleMouseEvent(message, x, y, wParam); } @@ -1763,6 +1903,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). @@ -1790,7 +1939,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; @@ -1921,7 +2073,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: @@ -1942,7 +2094,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); @@ -1978,19 +2130,44 @@ wxWindow *wxFindWinFromHandle(WXHWND hWnd) return (wxWindow *)node->Data(); } +#if 0 // def __WXDEBUG__ +static int gs_AssociationCount = 0; +#endif + 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") ); + + + wxWindow *oldWin = wxFindWinFromHandle((WXHWND) hWnd); + if ( oldWin && (oldWin != win) ) + { + wxString str(win->GetClassInfo()->GetClassName()); + wxLogError("Bug! Found existing HWND %X for new window of class %s", (int) hWnd, (const char*) str); + } + else if (!oldWin) + { +#if 0 // def __WXDEBUG__ + gs_AssociationCount ++; + wxLogDebug("+ Association %d", gs_AssociationCount); +#endif - if ( !wxWinHandleList->Find((long)hWnd) ) wxWinHandleList->Append((long)hWnd, win); + } } void wxRemoveHandleAssociation(wxWindow *win) { +#if 0 // def __WXDEBUG__ + if (wxWinHandleList->Member(win)) + { + wxLogDebug("- Association %d", gs_AssociationCount); + gs_AssociationCount --; + } +#endif wxWinHandleList->DeleteObject(win); } @@ -2010,16 +2187,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); @@ -2031,15 +2208,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; @@ -2063,7 +2240,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(); @@ -2091,14 +2272,14 @@ bool wxWindow::MSWCreate(int id, if ( !::SetWindowPos(GetHwnd(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE) ) { - wxLogLastError("SetWindowPos"); + wxLogLastError(_T("SetWindowPos")); } } // move the dialog to its initial position without forcing repainting if ( !::MoveWindow(GetHwnd(), x1, y1, width1, height1, FALSE) ) { - wxLogLastError("MoveWindow"); + wxLogLastError(_T("MoveWindow")); } } else @@ -2107,9 +2288,15 @@ bool wxWindow::MSWCreate(int id, if ( style & WS_CHILD ) controlId = id; + wxString className(wclass); + if ( GetWindowStyleFlag() & wxNO_FULL_REPAINT_ON_RESIZE ) + { + className += _T("NR"); + } + m_hWnd = (WXHWND)CreateWindowEx(extendedStyle, wclass, - title ? title : "", + title ? title : _T(""), style, x1, y1, width1, height1, @@ -2128,7 +2315,18 @@ bool wxWindow::MSWCreate(int id, } wxWndHook = NULL; - wxWinHandleList->Append((long)m_hWnd, this); +#ifdef __WXDEBUG__ + wxNode* node = wxWinHandleList->Member(this); + if (node) + { + HWND hWnd = (HWND) node->GetKeyInteger(); + if (hWnd != (HWND) m_hWnd) + { + wxLogError("A second HWND association is being added for the same window!"); + } + } +#endif + wxAssociateWinWithHandle((HWND) m_hWnd, this); return TRUE; } @@ -2183,7 +2381,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; @@ -2296,10 +2494,10 @@ bool wxWindow::HandleSetFocus(WXHWND WXUNUSED(hwnd)) #endif // wxUSE_CARET // panel wants to track the window which was the last to have focus in it - wxWindow *parent = GetParent(); - if ( parent && parent->IsKindOf(CLASSINFO(wxPanel)) ) + wxPanel *panel = wxDynamicCast(GetParent(), wxPanel); + if ( panel ) { - ((wxPanel *)parent)->SetLastFocus(GetId()); + panel->SetLastFocus(this); } wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId); @@ -2360,7 +2558,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); @@ -2430,13 +2628,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 ) { @@ -2466,11 +2664,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 ) { @@ -2488,10 +2689,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 @@ -3071,7 +3271,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; } @@ -3164,8 +3364,11 @@ void wxGetCharSize(WXHWND wnd, int *x, int *y,wxFont *the_font) SelectObject(dc,was); } ReleaseDC((HWND)wnd, dc); - *x = tm.tmAveCharWidth; - *y = tm.tmHeight + tm.tmExternalLeading; + + if ( x ) + *x = tm.tmAveCharWidth; + if ( y ) + *y = tm.tmHeight + tm.tmExternalLeading; // if ( the_font ) // the_font->ReleaseResource(); @@ -3352,11 +3555,12 @@ void wxSetKeyboardHook(bool doIt) { wxTheKeyboardHookProc = MakeProcInstance((FARPROC) wxKeyboardHook, wxGetInstance()); wxTheKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC) wxTheKeyboardHookProc, wxGetInstance(), + #if defined(__WIN32__) && !defined(__TWIN32__) GetCurrentThreadId()); // (DWORD)GetCurrentProcess()); // This is another possibility. Which is right? #else - GetCurrentTask()); + GetCurrentTask()); #endif } else