1 /////////////////////////////////////////////////////////////////////////////
8 // Copyright: (c) AUTHOR
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "window.h"
20 #include "wx/window.h"
25 #include "wx/dcclient.h"
29 #include "wx/layout.h"
30 #include "wx/dialog.h"
32 #include "wx/listbox.h"
33 #include "wx/button.h"
34 #include "wx/msgdlg.h"
40 #include "wx/ownerdrw.h"
43 #if wxUSE_DRAG_AND_DROP
47 #include "wx/menuitem.h"
51 #include "wx/tooltip.h"
62 #include "wx/textctrl.h"
66 // place compiler, OS specific includes here
69 // standard macros -- these are for OS/2 PM, but most GUI's have something similar
71 // SHORT1FROMMP -- LOWORD
72 #define GET_X_LPARAM(mp) ((unsigned short)(unsigned long)(mp))
73 // SHORT2FROMMP -- HIWORD
74 #define GET_Y_LPARAM(mp) ((unsigned short)(unsigned long)(mp >> 16))
75 #endif // GET_X_LPARAM
77 // ---------------------------------------------------------------------------
79 // ---------------------------------------------------------------------------
81 // the last Windows message we got (MT-UNSAFE)
82 extern WXMSGID s_currentMsg
;
83 extern wxList WXDLLEXPORT wxPendingDelete
;
84 extern wxChar wxCanvasClassName
[];
86 wxMenu
*wxCurrentPopupMenu
= NULL
;
87 wxList
*wxWinHandleList
= NULL
;
89 // ---------------------------------------------------------------------------
91 // ---------------------------------------------------------------------------
92 // the window proc for all our windows; most gui's have something similar
93 MRESULT
wxWndProc( HWND hWnd
98 void wxRemoveHandleAssociation(wxWindow
*win
);
99 void wxAssociateWinWithHandle(HWND hWnd
, wxWindow
*win
);
100 wxWindow
*wxFindWinFromHandle(WXHWND hWnd
);
102 // ---------------------------------------------------------------------------
104 // ---------------------------------------------------------------------------
106 #if !USE_SHARED_LIBRARY
107 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
110 BEGIN_EVENT_TABLE(wxWindow
, wxWindowBase
)
111 EVT_ERASE_BACKGROUND(wxWindow::OnEraseBackground
)
112 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
113 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
114 EVT_IDLE(wxWindow::OnIdle
)
117 // ===========================================================================
119 // ===========================================================================
121 void wxWindow::Init()
127 m_winCaptured
= FALSE
;
128 m_isBeingDeleted
= FALSE
;
129 m_mouseInWindow
= FALSE
;
130 m_backgroundTransparent
= FALSE
;
137 // pass WM_GETDLGCODE to DefWindowProc()
143 // as all windows are created with WS_VISIBLE style...
148 bool wxWindow::Create(wxWindow
*parent
, wxWindowID id
,
152 const wxString
& name
)
154 wxCHECK_MSG( parent
, FALSE
, T("can't create wxWindow without parent") );
156 if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) )
159 // TODO: PM Specific initialization
160 parent
->AddChild(this);
165 wxWindow::~wxWindow()
167 m_isBeingDeleted
= TRUE
;
169 PMDetachWindowMenu();
172 m_parent
->RemoveChild(this);
176 if(!WinDestroyWindow(GetHWND()))
177 wxLogLastError(T("DestroyWindow"));
178 // remove hWnd <-> wxWindow association
179 wxRemoveHandleAssociation(this);
183 // ---------------------------------------------------------------------------
185 // ---------------------------------------------------------------------------
187 void wxWindow::Raise()
192 void wxWindow::Lower()
197 void wxWindow::SetFocus()
202 void wxWindow::WarpPointer(int x_pos
, int y_pos
)
207 void wxWindow::CaptureMouse()
212 void wxWindow::ReleaseMouse()
217 void wxWindow::Refresh(bool eraseBack
, const wxRect
*rect
)
222 void wxWindow::Clear()
227 bool wxWindow::SetFont(const wxFont
& f
)
233 int wxWindow::GetCharHeight() const
239 int wxWindow::GetCharWidth() const
245 void wxWindow::GetTextExtent( const wxString
& string
249 ,int* externalLeading
250 ,const wxFont
* theFont
256 void wxWindow::SetScrollbar( int orient
266 void wxWindow::SetScrollPos( int orient
274 int wxWindow::GetScrollPos(int orient
) const
280 int wxWindow::GetScrollRange(int orient
) const
286 int wxWindow::GetScrollThumb(int orient
) const
292 void wxWindow::ScrollWindow( int dx
300 #if wxUSE_DRAG_AND_DROP
301 void wxWindow::SetDropTarget(wxDropTarget
*pDropTarget
)
307 void wxWindow::DoClientToScreen( int *x
, int *y
) const
312 void wxWindow::DoScreenToClient( int *x
, int *y
) const
317 void wxWindow::DoGetPosition( int *x
, int *y
) const
322 void wxWindow::DoGetSize( int *width
, int *height
) const
327 void wxWindow::DoGetClientSize( int *width
, int *height
) const
332 void wxWindow::DoSetSize(int x
, int y
,
333 int width
, int height
,
339 void wxWindow::DoSetClientSize(int width
, int height
)
344 bool wxWindow::DoPopupMenu( wxMenu
*menu
, int x
, int y
)
355 bool wxWindow::Show(bool show
) // check if base implementation is OK
361 bool wxWindow::Enable(bool enable
) // check if base implementation is OK
367 bool wxWindow::SetCursor(const wxCursor
& cursor
) // check if base implementation is OK
373 bool wxWindow::Validate()
379 wxWindow
* wxWindow::FindFocus()
381 wxWindow
* window
= NULL
;
386 void wxWindow::DragAcceptFiles(bool accept
)
391 #if wxUSE_CARET && WXWIN_COMPATIBILITY
392 void wxWindow::CreateCaret(int w
, int h
)
397 void wxWindow::CreateCaret(const wxBitmap
*bitmap
)
402 void wxWindow::DestroyCaret()
407 void wxWindow::ShowCaret(bool show
)
412 void wxWindow::SetCaretPos(int x
, int y
)
417 void wxWindow::GetCaretPos(int *x
, int *y
) const
424 void wxWindow::OnCommand(wxWindow
& win
, wxCommandEvent
& event
)
429 void wxWindow::OnDefaultAction(wxControl
*initiatingItem
)
434 void wxWindow::OnEraseBackground(wxEraseEvent
& event
)
439 void wxWindow::OnChar(wxKeyEvent
& event
)
444 void wxWindow::OnKeyDown(wxKeyEvent
& event
)
449 void wxWindow::OnKeyUp(wxKeyEvent
& event
)
454 void wxWindow::OnPaint(wxPaintEvent
& event
)
459 void wxWindow::OnIdle(wxIdleEvent
& event
)
464 void wxWindow::OnInitDialog(wxInitDialogEvent
& event
)
470 wxPoint
wxWindow::GetClientAreaOrigin() const
473 return wxPoint(0, 0);
476 void wxWindow::AdjustForParentClientOrigin(int& x
, int& y
, int sizeFlags
)
481 long wxWindow::Default()
487 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
492 wxObject
* wxWindow::GetChild(int number
) const
495 return((wxObject
*)this);
498 void wxWindow::PMDetachWindowMenu()
502 HMENU hMenu
= (HMENU
)m_hMenu
;
504 int N
= (int)WinSendMsg(hMenu
, MM_QUERYITEMCOUNT
, 0, 0);
506 for (i
= 0; i
< N
; i
++)
509 int chars
= (int)WinSendMsg(hMenu
, MM_QUERYITEMTEXT
, MPFROM2SHORT(i
, N
), buf
);
512 wxLogLastError(T("GetMenuString"));
517 if ( wxStrcmp(buf
, T("&Window")) == 0 )
519 WinSendMsg(hMenu
, MM_DELETEITEM
, MPFROM2SHORT(i
, TRUE
), 0);
526 void wxAssociateWinWithHandle(HWND hWnd
, wxWindow
*win
)
528 // adding NULL hWnd is (first) surely a result of an error and
529 // (secondly) breaks menu command processing
530 wxCHECK_RET( hWnd
!= (HWND
)NULL
,
531 T("attempt to add a NULL hWnd to window list ignored") );
533 if ( !wxWinHandleList
->Find((long)hWnd
) )
534 wxWinHandleList
->Append((long)hWnd
, win
);
537 wxWindow
*wxFindWinFromHandle(WXHWND hWnd
)
539 wxNode
*node
= wxWinHandleList
->Find((long)hWnd
);
542 return (wxWindow
*)node
->Data();
545 void wxRemoveHandleAssociation(wxWindow
*win
)
547 wxWinHandleList
->DeleteObject(win
);
550 void wxWindow::SubclassWin(WXHWND hWnd
)
552 wxASSERT_MSG( !m_oldWndProc
, T("subclassing window twice?") );
554 HWND hwnd
= (HWND
)hWnd
;
556 * TODO: implement something like this:
557 * wxCHECK_RET( ::IsWindow(hwnd), T("invalid HWND in SubclassWin") );
559 * wxAssociateWinWithHandle(hwnd, this);
561 * m_oldWndProc = (WXFARPROC) GetWindowLong(hwnd, GWL_WNDPROC);
562 * SetWindowLong(hwnd, GWL_WNDPROC, (LONG) wxWndProc);
566 void wxWindow::UnsubclassWin()
571 wxRemoveHandleAssociation(this);
573 // Restore old Window proc
574 HWND hwnd = GetHwnd();
579 wxCHECK_RET( ::IsWindow(hwnd), T("invalid HWND in UnsubclassWin") );
581 FARPROC farProc = (FARPROC) GetWindowLong(hwnd, GWL_WNDPROC);
582 if ( (m_oldWndProc != 0) && (farProc != (FARPROC) m_oldWndProc) )
584 SetWindowLong(hwnd, GWL_WNDPROC, (LONG) m_oldWndProc);
591 WXDWORD
wxWindow::Determine3DEffects(WXDWORD defaultBorderStyle
,
594 DWORD exStyle
; // remove after implementation doe
595 /* TODO: this ought to be fun
597 // If matches certain criteria, then assume no 3D effects
598 // unless specifically requested (dealt with in MakeExtendedStyle)
599 if ( !GetParent() || !IsKindOf(CLASSINFO(wxControl)) || (m_windowStyle & wxNO_BORDER) )
602 return MakeExtendedStyle(m_windowStyle, FALSE);
605 // Determine whether we should be using 3D effects or not.
606 bool nativeBorder = FALSE; // by default, we don't want a Win95 effect
608 // 1) App can specify global 3D effects
609 *want3D = wxTheApp->GetAuto3D();
611 // 2) If the parent is being drawn with user colours, or simple border specified,
612 // switch effects off. TODO: replace wxUSER_COLOURS with wxNO_3D
613 if ( GetParent() && (GetParent()->GetWindowStyleFlag() & wxUSER_COLOURS) || (m_windowStyle & wxSIMPLE_BORDER) )
616 // 3) Control can override this global setting by defining
617 // a border style, e.g. wxSUNKEN_BORDER
618 if ( m_windowStyle & wxSUNKEN_BORDER )
621 // 4) If it's a special border, CTL3D can't cope so we want a native border
622 if ( (m_windowStyle & wxDOUBLE_BORDER) || (m_windowStyle & wxRAISED_BORDER) ||
623 (m_windowStyle & wxSTATIC_BORDER) )
629 // 5) If this isn't a Win95 app, and we are using CTL3D, remove border
630 // effects from extended style
633 nativeBorder = FALSE;
636 DWORD exStyle = MakeExtendedStyle(m_windowStyle, !nativeBorder);
638 // If we want 3D, but haven't specified a border here,
639 // apply the default border style specified.
640 // TODO what about non-Win95 WIN32? Does it have borders?
641 #if defined(__WIN95__) && !wxUSE_CTL3D
642 if ( defaultBorderStyle && (*want3D) && ! ((m_windowStyle & wxDOUBLE_BORDER) || (m_windowStyle & wxRAISED_BORDER ) ||
643 (m_windowStyle & wxSTATIC_BORDER) || (m_windowStyle & wxSIMPLE_BORDER) ))
644 exStyle |= defaultBorderStyle; // WS_EX_CLIENTEDGE;