#include "wx/menu.h"
#include "wx/dc.h"
#include "wx/dcclient.h"
+ #include "wx/dcmemory.h"
#include "wx/utils.h"
#include "wx/app.h"
#include "wx/layout.h"
// global variables
// ---------------------------------------------------------------------------
-// the last Windows message we got (MT-UNSAFE)
+// the last Windows message we got (FIXME-MT)
extern MSG s_currentMsg;
#if wxUSE_MENUS_NATIVE
extern const wxChar *wxCanvasClassName;
+// true if we had already created the std colour map, used by
+// wxGetStdColourMap() and wxWindow::OnSysColourChanged() (FIXME-MT)
+static bool gs_hasStdCmap = FALSE;
+
// ---------------------------------------------------------------------------
// private functions
// ---------------------------------------------------------------------------
{
m_isBeingDeleted = TRUE;
- MSWDetachWindowMenu();
-
#ifndef __WXUNIVERSAL__
// VS: make sure there's no wxFrame with last focus set to us:
for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
//
// the correct solution is to create the controls as siblings of the
// static box
- wxASSERT_MSG( !wxDynamicCastThis(wxStaticBox),
+ wxASSERT_MSG( !wxDynamicCast(parent, wxStaticBox),
_T("wxStaticBox can't be used as a window parent!") );
#endif // wxUSE_STATBOX
if ( !::SetFocus(hWnd) )
{
+#if defined(__WXDEBUG__) && !defined(__WXMICROWIN__)
// was there really an error?
-#ifndef __WXMICROWIN__
DWORD dwRes = ::GetLastError();
-#else
-
- DWORD dwRes = 0;
-#endif
if ( dwRes )
{
- wxLogApiError(_T("SetFocus"), dwRes);
+ HWND hwndFocus = ::GetFocus();
+ if ( hwndFocus != hWnd )
+ {
+ wxLogApiError(_T("SetFocus"), dwRes);
+ }
}
-
- // VZ: just why does this happen sometimes?? any idea?
-#if 0
- HWND hwndFocus = ::GetFocus();
- wxASSERT_MSG( hwndFocus == hWnd, _T("SetFocus() didn't work?") );
-#endif // 0
+#endif // Debug
}
}
void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height)
{
+ // TODO: is this consistent with other platforms?
+ // Still, negative width or height shouldn't be allowed
+ if (width < 0)
+ width = 0;
+ if (height < 0)
+ height = 0;
if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) )
{
wxLogLastError(wxT("MoveWindow"));
// will not be correct as the difference between the total and client size
// changes - so we keep changing it until we get it right
//
- // normally this loop shouldn't take more than 2 iterations (usually 1 but
- // if scrollbars [dis]appear as the result of the first call, then 2) but
- // just to be on the safe side we check for it instead of making it an
+ // normally this loop shouldn't take more than 3 iterations (usually 1 but
+ // if scrollbars [dis]appear as the result of the first call, then 2 and it
+ // may become 3 if the window had 0 size originally and so we didn't
+ // calculate the scrollbar correction correctly during the first iteration)
+ // but just to be on the safe side we check for it instead of making it an
// "infinite" loop (i.e. leaving break inside as the only way to get out)
- for ( int i = 0; i < 3; i++ )
+ for ( int i = 0; i < 4; i++ )
{
RECT rectClient;
::GetClientRect(GetHwnd(), &rectClient);
break;
}
- if ( i == 2 )
+ if ( i == 3 )
{
// how did it happen? maybe OnSize() handler does something really
// strange in this class?
break;
#endif // !__WXMICROWIN__
- // the return value for this message is ignored
case WM_SYSCOLORCHANGE:
+ // the return value for this message is ignored
processed = HandleSysColorChange();
break;
{
}
-void wxWindowMSW::MSWDetachWindowMenu()
-{
-#ifndef __WXUNIVERSAL__
- if ( m_hMenu )
- {
- wxChar buf[1024];
- HMENU hMenu = (HMENU)m_hMenu;
-
- int N = ::GetMenuItemCount(hMenu);
- for ( int i = 0; i < N; i++ )
- {
- if ( !::GetMenuString(hMenu, i, buf, WXSIZEOF(buf), MF_BYPOSITION) )
- {
- wxLogLastError(wxT("GetMenuString"));
-
- continue;
- }
-
- if ( wxStrcmp(buf, _("&Window")) == 0 )
- {
- if ( !::RemoveMenu(hMenu, i, MF_BYPOSITION) )
- {
- wxLogLastError(wxT("RemoveMenu"));
- }
-
- break;
- }
- }
- }
-#endif // __WXUNIVERSAL__
-}
-
bool wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint& pos,
const wxSize& size,
int& x, int& y,
SubclassWin(m_hWnd);
- SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT));
+ SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
return TRUE;
}
// Responds to colour changes: passes event on to children.
void wxWindowMSW::OnSysColourChanged(wxSysColourChangedEvent& event)
{
+ // the top level window also reset the standard colour map as it might have
+ // changed (there is no need to do it for the non top level windows as we
+ // only have to do it once)
+ if ( IsTopLevel() )
+ {
+ // FIXME-MT
+ gs_hasStdCmap = FALSE;
+ }
wxWindowList::Node *node = GetChildren().GetFirst();
while ( node )
{
}
}
+extern wxCOLORMAP *wxGetStdColourMap()
+{
+ static COLORREF s_stdColours[wxSTD_COL_MAX];
+ static wxCOLORMAP s_cmap[wxSTD_COL_MAX];
+
+ if ( !gs_hasStdCmap )
+ {
+ static bool s_coloursInit = FALSE;
+
+ if ( !s_coloursInit )
+ {
+ // When a bitmap is loaded, the RGB values can change (apparently
+ // because Windows adjusts them to care for the old programs always
+ // using 0xc0c0c0 while the transparent colour for the new Windows
+ // versions is different). But we do this adjustment ourselves so
+ // we want to avoid Windows' "help" and for this we need to have a
+ // reference bitmap which can tell us what the RGB values change
+ // to.
+ wxBitmap stdColourBitmap(_T("wxBITMAP_STD_COLOURS"));
+ if ( stdColourBitmap.Ok() )
+ {
+ // the pixels in the bitmap must correspond to wxSTD_COL_XXX!
+ wxASSERT_MSG( stdColourBitmap.GetWidth() == wxSTD_COL_MAX,
+ _T("forgot to update wxBITMAP_STD_COLOURS!") );
+
+ wxMemoryDC memDC;
+ memDC.SelectObject(stdColourBitmap);
+
+ wxColour colour;
+ for ( size_t i = 0; i < WXSIZEOF(s_stdColours); i++ )
+ {
+ memDC.GetPixel(i, 0, &colour);
+ s_stdColours[i] = wxColourToRGB(colour);
+ }
+ }
+ else // wxBITMAP_STD_COLOURS couldn't be loaded
+ {
+ s_stdColours[0] = RGB(000,000,000); // black
+ s_stdColours[1] = RGB(128,128,128); // dark grey
+ s_stdColours[2] = RGB(192,192,192); // light grey
+ s_stdColours[3] = RGB(255,255,255); // white
+ //s_stdColours[4] = RGB(000,000,255); // blue
+ //s_stdColours[5] = RGB(255,000,255); // magenta
+ }
+
+ s_coloursInit = TRUE;
+ }
+
+ gs_hasStdCmap = TRUE;
+
+ // create the colour map
+#define INIT_CMAP_ENTRY(col) \
+ s_cmap[wxSTD_COL_##col].from = s_stdColours[wxSTD_COL_##col]; \
+ s_cmap[wxSTD_COL_##col].to = ::GetSysColor(COLOR_##col)
+
+ INIT_CMAP_ENTRY(BTNTEXT);
+ INIT_CMAP_ENTRY(BTNSHADOW);
+ INIT_CMAP_ENTRY(BTNFACE);
+ INIT_CMAP_ENTRY(BTNHIGHLIGHT);
+
+#undef INIT_CMAP_ENTRY
+ }
+
+ return s_cmap;
+}
+
// ---------------------------------------------------------------------------
// painting
// ---------------------------------------------------------------------------