window.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 2,123 行 · 第 1/5 页
CPP
2,123 行
// Do a recursive search.
wxWindow *wnd = parent->FindItemByHWND(hWnd);
if ( wnd )
return wnd;
if ( !controlOnly
#if wxUSE_CONTROLS
|| parent->IsKindOf(CLASSINFO(wxControl))
#endif // wxUSE_CONTROLS
)
{
wxWindow *item = current->GetData();
if ( item->GetHWND() == hWnd )
return item;
else
{
if ( item->ContainsHWND(hWnd) )
return item;
}
}
current = current->GetNext();
}
return NULL;
}
// Default command handler
bool wxWindowMSW::MSWCommand(WXUINT WXUNUSED(param), WXWORD WXUNUSED(id))
{
return false;
}
// ----------------------------------------------------------------------------
// constructors and such
// ----------------------------------------------------------------------------
void wxWindowMSW::Init()
{
// MSW specific
m_isBeingDeleted = false;
m_oldWndProc = NULL;
m_mouseInWindow = false;
m_lastKeydownProcessed = false;
m_childrenDisabled = NULL;
m_frozenness = 0;
m_hWnd = 0;
m_hDWP = 0;
m_xThumbSize = 0;
m_yThumbSize = 0;
#if wxUSE_MOUSEEVENT_HACK
m_lastMouseX =
m_lastMouseY = -1;
m_lastMouseEvent = -1;
#endif // wxUSE_MOUSEEVENT_HACK
m_pendingPosition = wxDefaultPosition;
m_pendingSize = wxDefaultSize;
#ifdef __POCKETPC__
m_contextMenuEnabled = false;
#endif
}
// Destructor
wxWindowMSW::~wxWindowMSW()
{
m_isBeingDeleted = true;
#ifndef __WXUNIVERSAL__
// VS: make sure there's no wxFrame with last focus set to us:
for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
{
wxTopLevelWindow *frame = wxDynamicCast(win, wxTopLevelWindow);
if ( frame )
{
if ( frame->GetLastFocus() == this )
{
frame->SetLastFocus(NULL);
}
// apparently sometimes we can end up with our grand parent
// pointing to us as well: this is surely a bug in focus handling
// code but it's not clear where it happens so for now just try to
// fix it here by not breaking out of the loop
//break;
}
}
#endif // __WXUNIVERSAL__
// VS: destroy children first and _then_ detach *this from its parent.
// If we'd do it the other way around, children wouldn't be able
// find their parent frame (see above).
DestroyChildren();
if ( m_hWnd )
{
// VZ: test temp removed to understand what really happens here
//if (::IsWindow(GetHwnd()))
{
if ( !::DestroyWindow(GetHwnd()) )
wxLogLastError(wxT("DestroyWindow"));
}
// remove hWnd <-> wxWindow association
wxRemoveHandleAssociation(this);
}
delete m_childrenDisabled;
}
// real construction (Init() must have been called before!)
bool wxWindowMSW::Create(wxWindow *parent,
wxWindowID id,
const wxPoint& pos,
const wxSize& size,
long style,
const wxString& name)
{
wxCHECK_MSG( parent, false, wxT("can't create wxWindow without parent") );
if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
return false;
parent->AddChild(this);
WXDWORD exstyle;
DWORD msflags = MSWGetCreateWindowFlags(&exstyle);
#ifdef __WXUNIVERSAL__
// no borders, we draw them ourselves
exstyle &= ~(WS_EX_DLGMODALFRAME |
WS_EX_STATICEDGE |
WS_EX_CLIENTEDGE |
WS_EX_WINDOWEDGE);
msflags &= ~WS_BORDER;
#endif // wxUniversal
if ( IsShown() )
{
msflags |= WS_VISIBLE;
}
if ( !MSWCreate(wxCanvasClassName, NULL, pos, size, msflags, exstyle) )
return false;
InheritAttributes();
return true;
}
// ---------------------------------------------------------------------------
// basic operations
// ---------------------------------------------------------------------------
void wxWindowMSW::SetFocus()
{
HWND hWnd = GetHwnd();
wxCHECK_RET( hWnd, _T("can't set focus to invalid window") );
#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
::SetLastError(0);
#endif
if ( !::SetFocus(hWnd) )
{
#if defined(__WXDEBUG__) && !defined(__WXMICROWIN__)
// was there really an error?
DWORD dwRes = ::GetLastError();
if ( dwRes )
{
HWND hwndFocus = ::GetFocus();
if ( hwndFocus != hWnd )
{
wxLogApiError(_T("SetFocus"), dwRes);
}
}
#endif // Debug
}
}
void wxWindowMSW::SetFocusFromKbd()
{
// when the focus is given to the control with DLGC_HASSETSEL style from
// keyboard its contents should be entirely selected: this is what
// ::IsDialogMessage() does and so we should do it as well to provide the
// same LNF as the native programs
if ( ::SendMessage(GetHwnd(), WM_GETDLGCODE, 0, 0) & DLGC_HASSETSEL )
{
::SendMessage(GetHwnd(), EM_SETSEL, 0, -1);
}
// do this after (maybe) setting the selection as like this when
// wxEVT_SET_FOCUS handler is called, the selection would have been already
// set correctly -- this may be important
wxWindowBase::SetFocusFromKbd();
}
// Get the window with the focus
wxWindow *wxWindowBase::DoFindFocus()
{
HWND hWnd = ::GetFocus();
if ( hWnd )
{
return wxGetWindowFromHWND((WXHWND)hWnd);
}
return NULL;
}
bool wxWindowMSW::Enable(bool enable)
{
if ( !wxWindowBase::Enable(enable) )
return false;
HWND hWnd = GetHwnd();
if ( hWnd )
::EnableWindow(hWnd, (BOOL)enable);
// the logic below doesn't apply to the top level windows -- otherwise
// showing a modal dialog would result in total greying out (and ungreying
// out later) of everything which would be really ugly
if ( IsTopLevel() )
return true;
// when the parent is disabled, all of its children should be disabled as
// well but when it is enabled back, only those of the children which
// hadn't been already disabled in the beginning should be enabled again,
// so we have to keep the list of those children
for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
node;
node = node->GetNext() )
{
wxWindow *child = node->GetData();
if ( child->IsTopLevel() )
{
// the logic below doesn't apply to top level children
continue;
}
if ( enable )
{
// enable the child back unless it had been disabled before us
if ( !m_childrenDisabled || !m_childrenDisabled->Find(child) )
child->Enable();
}
else // we're being disabled
{
if ( child->IsEnabled() )
{
// disable it as children shouldn't stay enabled while the
// parent is not
child->Disable();
}
else // child already disabled, remember it
{
// have we created the list of disabled children already?
if ( !m_childrenDisabled )
m_childrenDisabled = new wxWindowList;
m_childrenDisabled->Append(child);
}
}
}
if ( enable && m_childrenDisabled )
{
// we don't need this list any more, don't keep unused memory
delete m_childrenDisabled;
m_childrenDisabled = NULL;
}
return true;
}
bool wxWindowMSW::Show(bool show)
{
if ( !wxWindowBase::Show(show) )
return false;
HWND hWnd = GetHwnd();
int cshow = show ? SW_SHOW : SW_HIDE;
::ShowWindow(hWnd, cshow);
if ( show && IsTopLevel() )
{
wxBringWindowToTop(hWnd);
}
return true;
}
// Raise the window to the top of the Z order
void wxWindowMSW::Raise()
{
wxBringWindowToTop(GetHwnd());
}
// Lower the window to the bottom of the Z order
void wxWindowMSW::Lower()
{
::SetWindowPos(GetHwnd(), HWND_BOTTOM, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
void wxWindowMSW::SetTitle( const wxString& title)
{
SetWindowText(GetHwnd(), title.c_str());
}
wxString wxWindowMSW::GetTitle() const
{
return wxGetWindowText(GetHWND());
}
void wxWindowMSW::DoCaptureMouse()
{
HWND hWnd = GetHwnd();
if ( hWnd )
{
::SetCapture(hWnd);
}
}
void wxWindowMSW::DoReleaseMouse()
{
if ( !::ReleaseCapture() )
{
wxLogLastError(_T("ReleaseCapture"));
}
}
/* static */ wxWindow *wxWindowBase::GetCapture()
{
HWND hwnd = ::GetCapture();
return hwnd ? wxFindWinFromHandle((WXHWND)hwnd) : (wxWindow *)NULL;
}
bool wxWindowMSW::SetFont(const wxFont& font)
{
if ( !wxWindowBase::SetFont(font) )
{
// nothing to do
return false;
}
HWND hWnd = GetHwnd();
if ( hWnd != 0 )
{
WXHANDLE hFont = m_font.GetResourceHandle();
wxASSERT_MSG( hFont, wxT("should have valid font") );
::SendMessage(hWnd, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0));
}
return true;
}
bool wxWindowMSW::SetCursor(const wxCursor& cursor)
{
if ( !wxWindowBase::SetCursor(cursor) )
{
// no change
return false;
}
if ( m_cursor.Ok() )
{
HWND hWnd = GetHwnd();
// Change the cursor NOW if we're within the correct window
POINT point;
#ifdef __WXWINCE__
::GetCursorPosWinCE(&point);
#else
::GetCursorPos(&point);
#endif
RECT rect = wxGetWindowRect(hWnd);
if ( ::PtInRect(&rect, point) && !wxIsBusy() )
::SetCursor(GetHcursorOf(m_cursor));
}
return true;
}
void wxWindowMSW::WarpPointer(int x, int y)
{
ClientToScreen(&x, &y);
if ( !::SetCursorPos(x, y) )
{
wxLogLastError(_T("SetCursorPos"));
}
}
void wxWindowMSW::MSWUpdateUIState()
{
// WM_CHANGEUISTATE only appeared in Windows 2000 so it can do us no good
// to use it on older systems -- and could possibly do some harm
static int s_needToUpdate = -1;
if ( s_needToUpdate == -1 )
{
int verMaj, verMin;
s_needToUpdate = wxGetOsVersion(&verMaj, &verMin) == wxWINDOWS_NT &&
verMaj >= 5;
}
if ( s_needToUpdate )
{
// we send WM_CHANGEUISTATE so if nothing needs changing then the system
// won't send WM_UPDATEUISTATE
::SendMessage(GetHwnd(), WM_CHANGEUISTATE,
MAKEWPARAM(UIS_CLEAR, UISF_HIDEFOCUS), 0);
}
}
// ---------------------------------------------------------------------------
// scrolling stuff
// ---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?