#ifndef WX_PRECOMP
#include <windows.h>
#include "wx/msw/winundef.h"
+ #include "wx/window.h"
#include "wx/accel.h"
#include "wx/setup.h"
#include "wx/menu.h"
#include "wx/ownerdrw.h"
#endif
-#if wxUSE_DRAG_AND_DROP
- #include "wx/dataobj.h"
- #include "wx/msw/ole/droptgt.h"
+#if wxUSE_DRAG_AND_DROP
+ #include "wx/dnd.h"
#endif
#include "wx/menuitem.h"
#include <string.h>
-#ifndef __GNUWIN32__
+#if !defined(__GNUWIN32__)|| defined(wxUSE_NORLANDER_HEADERS)
#include <shellapi.h>
#include <mmsystem.h>
#endif
#include <windowsx.h>
#endif
-#if ( defined(__WIN95__) && !defined(__GNUWIN32__)) || defined(__TWIN32__ )
+#if ( defined(__WIN95__) && !defined(__GNUWIN32__)) || defined(__TWIN32__ ) || defined(wxUSE_NORLANDER_HEADERS)
#include <commctrl.h>
#endif
#ifndef __TWIN32__
#ifdef __GNUWIN32__
- #include <wx/msw/gnuwin32/extra.h>
+ #ifndef wxUSE_NORLANDER_HEADERS
+ #include "wx/msw/gnuwin32/extra.h"
+ #endif
#endif
#endif
// ---------------------------------------------------------------------------
// the window proc for all our windows
-LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message,
+LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
#ifdef __WXDEBUG__
// ---------------------------------------------------------------------------
// 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)
long style,
const wxString& name)
{
- wxCHECK_MSG( parent, FALSE, _T("can't create wxWindow without parent") );
+ wxCHECK_MSG( parent, FALSE, wxT("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);
if ( hWnd )
::EnableWindow(hWnd, (BOOL)enable);
+ wxWindowList::Node *node = GetChildren().GetFirst();
+ while ( node )
+ {
+ wxWindow *child = node->GetData();
+ child->Enable(enable);
+
+ node = node->GetNext();
+ }
+
return TRUE;
}
{
WXHANDLE hFont = m_font.GetResourceHandle();
- wxASSERT_MSG( hFont, _T("should have valid font") );
+ wxASSERT_MSG( hFont, wxT("should have valid font") );
::SendMessage(hWnd, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0));
}
}
wxASSERT_MSG( m_cursor.Ok(),
- _T("cursor must be valid after call to the base version"));
+ wxT("cursor must be valid after call to the base version"));
HWND hWnd = GetHwnd();
void wxWindow::SubclassWin(WXHWND hWnd)
{
- wxASSERT_MSG( !m_oldWndProc, _T("subclassing window twice?") );
+ wxASSERT_MSG( !m_oldWndProc, wxT("subclassing window twice?") );
HWND hwnd = (HWND)hWnd;
- wxCHECK_RET( ::IsWindow(hwnd), _T("invalid HWND in SubclassWin") );
+ wxCHECK_RET( ::IsWindow(hwnd), wxT("invalid HWND in SubclassWin") );
wxAssociateWinWithHandle(hwnd, this);
{
m_hWnd = 0;
- wxCHECK_RET( ::IsWindow(hwnd), _T("invalid HWND in SubclassWin") );
+ wxCHECK_RET( ::IsWindow(hwnd), wxT("invalid HWND in UnsubclassWin") );
FARPROC farProc = (FARPROC) GetWindowLong(hwnd, GWL_WNDPROC);
if ( (m_oldWndProc != 0) && (farProc != (FARPROC) m_oldWndProc) )
// 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)
// 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 ( parent )
- {
- wxPoint pt(parent->GetClientAreaOrigin());
- point.x -= pt.x;
- point.y -= pt.y;
- }
+ wxPoint pt(parent->GetClientAreaOrigin());
+ point.x -= pt.x;
+ point.y -= pt.y;
}
if ( x )
*y = rect.bottom;
}
+void wxWindow::DoMoveWindow(int x, int y, int width, int height)
+{
+ if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) )
+ {
+ wxLogLastError("MoveWindow");
+ }
+}
+
+// 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;
+ }
+ }
+
+ DoMoveWindow(x, y, width, height);
+}
+
+// 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)
::ScreenToClient(hParentWnd, &point);
}
- MoveWindow(hWnd, point.x, point.y, actual_width, actual_height, (BOOL)TRUE);
+ DoMoveWindow(point.x, point.y, actual_width, actual_height);
wxSizeEvent event(wxSize(width, height), m_windowId);
event.SetEventObject(this);
SIZE sizeRect;
TEXTMETRIC tm;
- GetTextExtentPoint(dc, (const wxChar *)string, (int)string.Length(), &sizeRect);
+ GetTextExtentPoint(dc, string, (int)string.Length(), &sizeRect);
GetTextMetrics(dc, &tm);
if ( fontToUse && fnt && hfontOld )
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 && WXWIN_COMPATIBILITY
// popup menu
// ---------------------------------------------------------------------------
-bool wxWindow::PopupMenu(wxMenu *menu, int x, int y)
+bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y)
{
menu->SetInvokingWindow(this);
menu->UpdateUI();
btn = panel->GetDefaultItem();
}
- if ( btn )
+ if ( btn && btn->IsEnabled() )
{
// if we do have a default button, do press it
btn->MSWCommand(BN_CLICKED, 0 /* unused */);
wxWindow *wxWndHook = NULL;
// Main window proc
-LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
// trace all messages - useful for the debugging
#ifdef __WXDEBUG__
- wxLogTrace(wxTraceMessages, _T("Processing %s(wParam=%8lx, lParam=%8lx)"),
+ wxLogTrace(wxTraceMessages, wxT("Processing %s(wParam=%8lx, lParam=%8lx)"),
wxGetMessageName(message), wParam, lParam);
#endif // __WXDEBUG__
// 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;
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);
}
if ( !processed )
{
#ifdef __WXDEBUG__
- wxLogTrace(wxTraceMessages, _T("Forwarding %s to DefWindowProc."),
+ wxLogTrace(wxTraceMessages, wxT("Forwarding %s to DefWindowProc."),
wxGetMessageName(message));
#endif // __WXDEBUG__
rc.result = MSWDefWindowProc(message, wParam, lParam);
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,
- _T("attempt to add a NULL hWnd to window list ignored") );
+ wxT("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);
}
int chars = GetMenuString(hMenu, i, buf, 100, MF_BYPOSITION);
if ( !chars )
{
- wxLogLastError(_T("GetMenuString"));
+ wxLogLastError(wxT("GetMenuString"));
continue;
}
- if ( wxStrcmp(buf, _T("&Window")) == 0 )
+ if ( wxStrcmp(buf, wxT("&Window")) == 0 )
{
RemoveMenu(hMenu, i, MF_BYPOSITION);
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();
if ( !::SetWindowPos(GetHwnd(), HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE) )
{
- wxLogLastError(_T("SetWindowPos"));
+ wxLogLastError(wxT("SetWindowPos"));
}
}
// move the dialog to its initial position without forcing repainting
if ( !::MoveWindow(GetHwnd(), x1, y1, width1, height1, FALSE) )
{
- wxLogLastError(_T("MoveWindow"));
+ wxLogLastError(wxT("MoveWindow"));
}
}
else
if ( style & WS_CHILD )
controlId = id;
+ wxString className(wclass);
+ if ( GetWindowStyleFlag() & wxNO_FULL_REPAINT_ON_RESIZE )
+ {
+ className += wxT("NR");
+ }
+
m_hWnd = (WXHWND)CreateWindowEx(extendedStyle,
- wclass,
- title ? title : _T(""),
+ className,
+ title ? title : wxT(""),
style,
x1, y1,
width1, height1,
}
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;
}
{
#if wxUSE_TOOLTIPS
NMHDR* hdr = (NMHDR *)lParam;
- if ( hdr->code == TTN_NEEDTEXT && m_tooltip )
+ if ( (int)hdr->code == TTN_NEEDTEXT && m_tooltip )
{
TOOLTIPTEXT *ttt = (TOOLTIPTEXT *)lParam;
ttt->lpszText = (wxChar *)m_tooltip->GetTip().c_str();
wxCloseEvent event(wxEVT_QUERY_END_SESSION, -1);
event.SetEventObject(wxTheApp);
event.SetCanVeto(TRUE);
- event.SetLoggingOff(logOff == ENDSESSION_LOGOFF);
+ event.SetLoggingOff(logOff == (long)ENDSESSION_LOGOFF);
bool rc = wxTheApp->ProcessEvent(event);
wxCloseEvent event(wxEVT_END_SESSION, -1);
event.SetEventObject(wxTheApp);
event.SetCanVeto(FALSE);
- event.SetLoggingOff( (logOff == ENDSESSION_LOGOFF) );
+ event.SetLoggingOff( (logOff == (long)ENDSESSION_LOGOFF) );
if ( (this == wxTheApp->GetTopWindow()) && // Only send once
wxTheApp->ProcessEvent(event))
{
break;
default:
- wxFAIL_MSG(_T("no such joystick event"));
+ wxFAIL_MSG(wxT("no such joystick event"));
return FALSE;
}
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();
{
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
{
UnhookWindowsHookEx(wxTheKeyboardHook);
+ // avoids mingw warning about statement with no effect (FreeProcInstance
+ // doesn't do anything under Win32)
+#ifndef __GNUWIN32__
FreeProcInstance(wxTheKeyboardHookProc);
+#endif
}
}