window.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 2,123 行 · 第 1/5 页
CPP
2,123 行
/////////////////////////////////////////////////////////////////////////////
// Name: src/msw/windows.cpp
// Purpose: wxWindow
// Author: Julian Smart
// Modified by: VZ on 13.05.99: no more Default(), MSWOnXXX() reorganisation
// Created: 04/01/98
// RCS-ID: $Id: window.cpp,v 1.638.2.17 2006/03/04 18:18:28 JS Exp $
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ===========================================================================
// declarations
// ===========================================================================
// ---------------------------------------------------------------------------
// headers
// ---------------------------------------------------------------------------
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "window.h"
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/msw/wrapwin.h"
#include "wx/window.h"
#include "wx/accel.h"
#include "wx/setup.h"
#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"
#include "wx/dialog.h"
#include "wx/frame.h"
#include "wx/listbox.h"
#include "wx/button.h"
#include "wx/msgdlg.h"
#include "wx/settings.h"
#include "wx/statbox.h"
#include "wx/sizer.h"
#endif
#if wxUSE_OWNER_DRAWN && !defined(__WXUNIVERSAL__)
#include "wx/ownerdrw.h"
#endif
#include "wx/evtloop.h"
#include "wx/module.h"
#include "wx/sysopt.h"
#if wxUSE_DRAG_AND_DROP
#include "wx/dnd.h"
#endif
#if wxUSE_ACCESSIBILITY
#include "wx/access.h"
#include <ole2.h>
#include <oleacc.h>
#ifndef WM_GETOBJECT
#define WM_GETOBJECT 0x003D
#endif
#ifndef OBJID_CLIENT
#define OBJID_CLIENT 0xFFFFFFFC
#endif
#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
#if wxUSE_SPINCTRL
#include "wx/spinctrl.h"
#endif // wxUSE_SPINCTRL
#include "wx/intl.h"
#include "wx/log.h"
#include "wx/textctrl.h"
#include "wx/notebook.h"
#include "wx/listctrl.h"
#include <string.h>
#if (!defined(__GNUWIN32_OLD__) && !defined(__WXMICROWIN__) /* && !defined(__WXWINCE__) */ ) || defined(__CYGWIN10__)
#include <shellapi.h>
#include <mmsystem.h>
#endif
#ifdef __WIN32__
#include <windowsx.h>
#endif
#include <commctrl.h>
#include "wx/msw/missing.h"
#if defined(__WXWINCE__)
#ifdef __POCKETPC__
#include <windows.h>
#include <shellapi.h>
#include <ole2.h>
#include <aygshell.h>
#endif
#include "wx/msw/wince/missing.h"
#endif
#if defined(TME_LEAVE) && defined(WM_MOUSELEAVE)
#define HAVE_TRACKMOUSEEVENT
#endif // everything needed for TrackMouseEvent()
// if this is set to 1, we use deferred window sizing to reduce flicker when
// resizing complicated window hierarchies, but this can in theory result in
// different behaviour than the old code so we keep the possibility to use it
// by setting this to 0 (in the future this should be removed completely)
#ifdef __WXWINCE__
#define USE_DEFERRED_SIZING 0
#else
#define USE_DEFERRED_SIZING 1
#endif
// ---------------------------------------------------------------------------
// global variables
// ---------------------------------------------------------------------------
#if wxUSE_MENUS_NATIVE
wxMenu *wxCurrentPopupMenu = NULL;
#endif // wxUSE_MENUS_NATIVE
#ifdef __WXWINCE__
extern wxChar *wxCanvasClassName;
#else
extern const wxChar *wxCanvasClassName;
#endif
// 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
// ---------------------------------------------------------------------------
// the window proc for all our windows
LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
#ifdef __WXDEBUG__
const wxChar *wxGetMessageName(int message);
#endif //__WXDEBUG__
void wxRemoveHandleAssociation(wxWindowMSW *win);
extern void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win);
wxWindow *wxFindWinFromHandle(WXHWND hWnd);
// get the text metrics for the current font
static TEXTMETRIC wxGetTextMetrics(const wxWindowMSW *win);
#ifdef __WXWINCE__
// find the window for the mouse event at the specified position
static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y);
#endif // __WXWINCE__
// wrapper around BringWindowToTop() API
static inline void wxBringWindowToTop(HWND hwnd)
{
#ifdef __WXMICROWIN__
// It seems that MicroWindows brings the _parent_ of the window to the top,
// which can be the wrong one.
// activate (set focus to) specified window
::SetFocus(hwnd);
#endif
// raise top level parent to top of z order
if (!::SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE))
{
wxLogLastError(_T("SetWindowPos"));
}
}
#ifndef __WXWINCE__
// ensure that all our parent windows have WS_EX_CONTROLPARENT style
static void EnsureParentHasControlParentStyle(wxWindow *parent)
{
/*
If we have WS_EX_CONTROLPARENT flag we absolutely *must* set it for our
parent as well as otherwise several Win32 functions using
GetNextDlgTabItem() to iterate over all controls such as
IsDialogMessage() or DefDlgProc() would enter an infinite loop: indeed,
all of them iterate over all the controls starting from the currently
focused one and stop iterating when they get back to the focus but
unless all parents have WS_EX_CONTROLPARENT bit set, they would never
get back to the initial (focused) window: as we do have this style,
GetNextDlgTabItem() will leave this window and continue in its parent,
but if the parent doesn't have it, it wouldn't recurse inside it later
on and so wouldn't have a chance of getting back to this window neither.
*/
while ( parent && !parent->IsTopLevel() )
{
LONG exStyle = ::GetWindowLong(GetHwndOf(parent), GWL_EXSTYLE);
if ( !(exStyle & WS_EX_CONTROLPARENT) )
{
// force the parent to have this style
::SetWindowLong(GetHwndOf(parent), GWL_EXSTYLE,
exStyle | WS_EX_CONTROLPARENT);
}
parent = parent->GetParent();
}
}
#endif // !__WXWINCE__
#ifdef __WXWINCE__
// On Windows CE, GetCursorPos can return an error, so use this function
// instead
bool GetCursorPosWinCE(POINT* pt)
{
if (!GetCursorPos(pt))
{
DWORD pos = GetMessagePos();
pt->x = LOWORD(pos);
pt->y = HIWORD(pos);
}
return true;
}
#endif
// ---------------------------------------------------------------------------
// event tables
// ---------------------------------------------------------------------------
// in wxUniv/MSW this class is abstract because it doesn't have DoPopupMenu()
// method
#ifdef __WXUNIVERSAL__
IMPLEMENT_ABSTRACT_CLASS(wxWindowMSW, wxWindowBase)
#else // __WXMSW__
#if wxUSE_EXTENDED_RTTI
// windows that are created from a parent window during its Create method, eg. spin controls in a calendar controls
// must never been streamed out separately otherwise chaos occurs. Right now easiest is to test for negative ids, as
// windows with negative ids never can be recreated anyway
bool wxWindowStreamingCallback( const wxObject *object, wxWriter * , wxPersister * , wxxVariantArray & )
{
const wxWindow * win = dynamic_cast<const wxWindow*>(object) ;
if ( win && win->GetId() < 0 )
return false ;
return true ;
}
IMPLEMENT_DYNAMIC_CLASS_XTI_CALLBACK(wxWindow, wxWindowBase,"wx/window.h", wxWindowStreamingCallback)
// make wxWindowList known before the property is used
wxCOLLECTION_TYPE_INFO( wxWindow* , wxWindowList ) ;
template<> void wxCollectionToVariantArray( wxWindowList const &theList, wxxVariantArray &value)
{
wxListCollectionToVariantArray<wxWindowList::compatibility_iterator>( theList , value ) ;
}
WX_DEFINE_FLAGS( wxWindowStyle )
wxBEGIN_FLAGS( wxWindowStyle )
// new style border flags, we put them first to
// use them for streaming out
wxFLAGS_MEMBER(wxBORDER_SIMPLE)
wxFLAGS_MEMBER(wxBORDER_SUNKEN)
wxFLAGS_MEMBER(wxBORDER_DOUBLE)
wxFLAGS_MEMBER(wxBORDER_RAISED)
wxFLAGS_MEMBER(wxBORDER_STATIC)
wxFLAGS_MEMBER(wxBORDER_NONE)
// old style border flags
wxFLAGS_MEMBER(wxSIMPLE_BORDER)
wxFLAGS_MEMBER(wxSUNKEN_BORDER)
wxFLAGS_MEMBER(wxDOUBLE_BORDER)
wxFLAGS_MEMBER(wxRAISED_BORDER)
wxFLAGS_MEMBER(wxSTATIC_BORDER)
wxFLAGS_MEMBER(wxBORDER)
// standard window styles
wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
wxFLAGS_MEMBER(wxCLIP_CHILDREN)
wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
wxFLAGS_MEMBER(wxWANTS_CHARS)
wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE)
wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
wxFLAGS_MEMBER(wxVSCROLL)
wxFLAGS_MEMBER(wxHSCROLL)
wxEND_FLAGS( wxWindowStyle )
wxBEGIN_PROPERTIES_TABLE(wxWindow)
wxEVENT_PROPERTY( Close , wxEVT_CLOSE_WINDOW , wxCloseEvent)
wxEVENT_PROPERTY( Create , wxEVT_CREATE , wxWindowCreateEvent )
wxEVENT_PROPERTY( Destroy , wxEVT_DESTROY , wxWindowDestroyEvent )
// Always constructor Properties first
wxREADONLY_PROPERTY( Parent,wxWindow*, GetParent, EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
wxPROPERTY( Id,wxWindowID, SetId, GetId, -1 /*wxID_ANY*/ , 0 /*flags*/ , wxT("Helpstring") , wxT("group") )
wxPROPERTY( Position,wxPoint, SetPosition , GetPosition, wxDefaultPosition , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // pos
wxPROPERTY( Size,wxSize, SetSize, GetSize, wxDefaultSize , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // size
wxPROPERTY( WindowStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
// Then all relations of the object graph
wxREADONLY_PROPERTY_COLLECTION( Children , wxWindowList , wxWindowBase* , GetWindowChildren , wxPROP_OBJECT_GRAPH /*flags*/ , wxT("Helpstring") , wxT("group"))
// and finally all other properties
wxPROPERTY( ExtraStyle , long , SetExtraStyle , GetExtraStyle , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // extstyle
wxPROPERTY( BackgroundColour , wxColour , SetBackgroundColour , GetBackgroundColour , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // bg
wxPROPERTY( ForegroundColour , wxColour , SetForegroundColour , GetForegroundColour , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // fg
wxPROPERTY( Enabled , bool , Enable , IsEnabled , wxxVariant((bool)true) , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
wxPROPERTY( Shown , bool , Show , IsShown , wxxVariant((bool)true) , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
#if 0
// possible property candidates (not in xrc) or not valid in all subclasses
wxPROPERTY( Title,wxString, SetTitle, GetTitle, wxEmptyString )
wxPROPERTY( Font , wxFont , SetFont , GetWindowFont , )
wxPROPERTY( Label,wxString, SetLabel, GetLabel, wxEmptyString )
// MaxHeight, Width , MinHeight , Width
// TODO switch label to control and title to toplevels
wxPROPERTY( ThemeEnabled , bool , SetThemeEnabled , GetThemeEnabled , )
//wxPROPERTY( Cursor , wxCursor , SetCursor , GetCursor , )
// wxPROPERTY( ToolTip , wxString , SetToolTip , GetToolTipText , )
wxPROPERTY( AutoLayout , bool , SetAutoLayout , GetAutoLayout , )
#endif
wxEND_PROPERTIES_TABLE()
wxBEGIN_HANDLERS_TABLE(wxWindow)
wxEND_HANDLERS_TABLE()
wxCONSTRUCTOR_DUMMY(wxWindow)
#else
IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
#endif
#endif // __WXUNIVERSAL__/__WXMSW__
BEGIN_EVENT_TABLE(wxWindowMSW, wxWindowBase)
EVT_SYS_COLOUR_CHANGED(wxWindowMSW::OnSysColourChanged)
EVT_ERASE_BACKGROUND(wxWindowMSW::OnEraseBackground)
#ifdef __WXWINCE__
EVT_INIT_DIALOG(wxWindowMSW::OnInitDialog)
#endif
END_EVENT_TABLE()
// ===========================================================================
// implementation
// ===========================================================================
// ---------------------------------------------------------------------------
// wxWindow utility functions
// ---------------------------------------------------------------------------
// Find an item given the MS Windows id
wxWindow *wxWindowMSW::FindItem(long id) const
{
#if wxUSE_CONTROLS
wxControl *item = wxDynamicCastThis(wxControl);
if ( item )
{
// is it we or one of our "internal" children?
if ( item->GetId() == id
#ifndef __WXUNIVERSAL__
|| (item->GetSubcontrols().Index(id) != wxNOT_FOUND)
#endif // __WXUNIVERSAL__
)
{
return item;
}
}
#endif // wxUSE_CONTROLS
wxWindowList::compatibility_iterator current = GetChildren().GetFirst();
while (current)
{
wxWindow *childWin = current->GetData();
wxWindow *wnd = childWin->FindItem(id);
if ( wnd )
return wnd;
current = current->GetNext();
}
return NULL;
}
// Find an item given the MS Windows handle
wxWindow *wxWindowMSW::FindItemByHWND(WXHWND hWnd, bool controlOnly) const
{
wxWindowList::compatibility_iterator current = GetChildren().GetFirst();
while (current)
{
wxWindow *parent = current->GetData();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?