1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        msw/caret.cpp
3 // Purpose:     MSW implementation of wxCaret
4 // Author:      Vadim Zeitlin
5 // Modified by:
6 // Created:     23.05.99
7 // RCS-ID:      $Id: caret.cpp 35650 2005-09-23 12:56:45Z MR $
8 // Copyright:   (c) wxWidgets team
9 // Licence:     wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11 
12 // ===========================================================================
13 // declarations
14 // ===========================================================================
15 
16 // ---------------------------------------------------------------------------
17 // headers
18 // ---------------------------------------------------------------------------
19 
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22 
23 #ifdef __BORLANDC__
24     #pragma hdrstop
25 #endif
26 
27 #ifndef WX_PRECOMP
28     #include "wx/window.h"
29     #include "wx/log.h"
30 #endif // WX_PRECOMP
31 
32 #include "wx/caret.h"
33 
34 #if wxUSE_CARET
35 
36 #include "wx/msw/private.h"
37 
38 // ---------------------------------------------------------------------------
39 // macros
40 // ---------------------------------------------------------------------------
41 
42 #define CALL_CARET_API(api, args)   \
43         if ( !api args )                \
44             wxLogLastError(_T(#api))
45 
46 // ===========================================================================
47 // implementation
48 // ===========================================================================
49 
50 // ---------------------------------------------------------------------------
51 // blink time
52 // ---------------------------------------------------------------------------
53 
54 //static
GetBlinkTime()55 int wxCaretBase::GetBlinkTime()
56 {
57     int blinkTime = ::GetCaretBlinkTime();
58     if ( !blinkTime )
59     {
60         wxLogLastError(wxT("GetCaretBlinkTime"));
61     }
62 
63     return blinkTime;
64 }
65 
66 //static
SetBlinkTime(int milliseconds)67 void wxCaretBase::SetBlinkTime(int milliseconds)
68 {
69     CALL_CARET_API(SetCaretBlinkTime, (milliseconds));
70 }
71 
72 // ---------------------------------------------------------------------------
73 // creating/destroying the caret
74 // ---------------------------------------------------------------------------
75 
MSWCreateCaret()76 bool wxCaret::MSWCreateCaret()
77 {
78     wxASSERT_MSG( GetWindow(), wxT("caret without window cannot be created") );
79     wxASSERT_MSG( IsOk(),  wxT("caret of zero size cannot be created") );
80 
81     if ( !m_hasCaret )
82     {
83         CALL_CARET_API(CreateCaret, (GetWinHwnd(GetWindow()), 0,
84                                      m_width, m_height));
85 
86         m_hasCaret = true;
87     }
88 
89     return m_hasCaret;
90 }
91 
OnSetFocus()92 void wxCaret::OnSetFocus()
93 {
94     if ( m_countVisible > 0 )
95     {
96         if ( MSWCreateCaret() )
97         {
98             // the caret was recreated but it doesn't remember its position and
99             // it's not shown
100 
101             DoMove();
102             DoShow();
103         }
104     }
105     //else: caret is invisible, don't waste time creating it
106 }
107 
OnKillFocus()108 void wxCaret::OnKillFocus()
109 {
110     if ( m_hasCaret )
111     {
112         m_hasCaret = false;
113 
114         CALL_CARET_API(DestroyCaret, ());
115     }
116 }
117 
118 // ---------------------------------------------------------------------------
119 // showing/hiding the caret
120 // ---------------------------------------------------------------------------
121 
DoShow()122 void wxCaret::DoShow()
123 {
124     wxASSERT_MSG( GetWindow(), wxT("caret without window cannot be shown") );
125     wxASSERT_MSG( IsOk(), wxT("caret of zero size cannot be shown") );
126 
127     // we might not have created the caret yet if we had got the focus first
128     // and the caret was shown later - so do it now if we have the focus but
129     // not the caret
130     if ( !m_hasCaret && (wxWindow::FindFocus() == GetWindow()) )
131     {
132         if ( MSWCreateCaret() )
133         {
134             DoMove();
135         }
136     }
137 
138     if ( m_hasCaret )
139     {
140         CALL_CARET_API(ShowCaret, (GetWinHwnd(GetWindow())));
141     }
142     //else: will be shown when we get the focus
143 }
144 
DoHide()145 void wxCaret::DoHide()
146 {
147     if ( m_hasCaret )
148     {
149         CALL_CARET_API(HideCaret, (GetWinHwnd(GetWindow())));
150     }
151 }
152 
153 // ---------------------------------------------------------------------------
154 // moving the caret
155 // ---------------------------------------------------------------------------
156 
DoMove()157 void wxCaret::DoMove()
158 {
159     if ( m_hasCaret )
160     {
161         wxASSERT_MSG( wxWindow::FindFocus() == GetWindow(),
162                       wxT("how did we lose focus?") );
163 
164         // for compatibility with the generic version, the coordinates are
165         // client ones
166         wxPoint pt = GetWindow()->GetClientAreaOrigin();
167         CALL_CARET_API(SetCaretPos, (m_x + pt.x, m_y + pt.y));
168     }
169     //else: we don't have caret right now, nothing to do (this does happen)
170 }
171 
172 
173 // ---------------------------------------------------------------------------
174 // resizing the caret
175 // ---------------------------------------------------------------------------
176 
DoSize()177 void wxCaret::DoSize()
178 {
179     if ( m_hasCaret )
180     {
181         m_hasCaret = false;
182         CALL_CARET_API(DestroyCaret, ());
183         MSWCreateCaret();
184         OnSetFocus();
185     }
186 }
187 
188 #endif
189