Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / xfa / src / fwl / src / basewidget / fwl_spinbuttonimp.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4 \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #include "../../../foxitlib.h"\r
8 #include "../core/include/fwl_targetimp.h"\r
9 #include "../core/include/fwl_noteimp.h"\r
10 #include "../core/include/fwl_widgetimp.h"\r
11 #include "include/fwl_spinbuttonimp.h"\r
12 #define  FWL_SPN_MinWidth   18\r
13 #define  FWL_SPN_MinHeight  32\r
14 #define  FWL_SPIN_Elapse        200\r
15 IFWL_SpinButton* IFWL_SpinButton::Create()\r
16 {\r
17     return new IFWL_SpinButton;\r
18 }\r
19 IFWL_SpinButton::IFWL_SpinButton()\r
20 {\r
21     m_pData = NULL;\r
22 }\r
23 IFWL_SpinButton::~IFWL_SpinButton()\r
24 {\r
25     if (m_pData) {\r
26         delete (CFWL_SpinButtonImp*)m_pData;\r
27         m_pData = NULL;\r
28     }\r
29 }\r
30 FWL_ERR IFWL_SpinButton::Initialize(IFWL_Widget *pOuter)\r
31 {\r
32     m_pData = FX_NEW CFWL_SpinButtonImp;\r
33     ((CFWL_SpinButtonImp*)m_pData)->SetInterface(this);\r
34     return ((CFWL_SpinButtonImp*)m_pData)->Initialize();\r
35 }\r
36 FWL_ERR IFWL_SpinButton::Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)\r
37 {\r
38     m_pData = FX_NEW CFWL_SpinButtonImp(properties);\r
39     ((CFWL_SpinButtonImp*)m_pData)->SetInterface(this);\r
40     return ((CFWL_SpinButtonImp*)m_pData)->Initialize();\r
41 }\r
42 FWL_ERR IFWL_SpinButton::EnableButton(FX_BOOL bEnable, FX_BOOL bUp)\r
43 {\r
44     return ((CFWL_SpinButtonImp*)m_pData)->EnableButton(bEnable, bUp);\r
45 }\r
46 FX_BOOL IFWL_SpinButton::IsButtonEnable(FX_BOOL bUp)\r
47 {\r
48     return ((CFWL_SpinButtonImp*)m_pData)->IsButtonEnable(bUp);\r
49 }\r
50 CFWL_SpinButtonImp::CFWL_SpinButtonImp(IFWL_Widget* pOuter )\r
51     : CFWL_WidgetImp(pOuter)\r
52     , m_dwUpState(FWL_PARTSTATE_SPB_Normal)\r
53     , m_dwDnState(FWL_PARTSTATE_SPB_Normal)\r
54     , m_bLButtonDwn(FALSE)\r
55     , m_iButtonIndex(0)\r
56     , m_hTimer(NULL)\r
57 {\r
58     m_rtClient.Reset();\r
59     m_rtUpButton.Reset();\r
60     m_rtDnButton.Reset();\r
61     m_pProperties->m_dwStyleExes |= FWL_STYLEEXE_SPB_Vert;\r
62 }\r
63 CFWL_SpinButtonImp::CFWL_SpinButtonImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)\r
64     : CFWL_WidgetImp(properties, pOuter)\r
65     , m_dwUpState(FWL_PARTSTATE_SPB_Normal)\r
66     , m_dwDnState(FWL_PARTSTATE_SPB_Normal)\r
67     , m_bLButtonDwn(FALSE)\r
68     , m_iButtonIndex(0)\r
69     , m_hTimer(NULL)\r
70 {\r
71     m_rtClient.Reset();\r
72     m_rtUpButton.Reset();\r
73     m_rtDnButton.Reset();\r
74     m_pProperties->m_dwStyleExes |= FWL_STYLEEXE_SPB_Vert;\r
75 }\r
76 CFWL_SpinButtonImp::~CFWL_SpinButtonImp()\r
77 {\r
78 }\r
79 FWL_ERR CFWL_SpinButtonImp::GetClassName(CFX_WideString &wsClass) const\r
80 {\r
81     wsClass = FWL_CLASS_SpinButton;\r
82     return FWL_ERR_Succeeded;\r
83 }\r
84 FX_DWORD CFWL_SpinButtonImp::GetClassID() const\r
85 {\r
86     return FWL_CLASSHASH_SpinButton;\r
87 }\r
88 FWL_ERR CFWL_SpinButtonImp::Initialize()\r
89 {\r
90     _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_WidgetImp::Initialize(), FWL_ERR_Indefinite);\r
91     m_pDelegate = (IFWL_WidgetDelegate*) FX_NEW CFWL_SpinButtonImpDelegate(this);\r
92     return FWL_ERR_Succeeded;\r
93 }\r
94 FWL_ERR CFWL_SpinButtonImp::Finalize()\r
95 {\r
96     if ( m_pDelegate) {\r
97         delete (CFWL_SpinButtonImpDelegate*)m_pDelegate;\r
98         m_pDelegate = NULL;\r
99     }\r
100     return CFWL_WidgetImp::Finalize();\r
101 }\r
102 FWL_ERR CFWL_SpinButtonImp::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize)\r
103 {\r
104     if (bAutoSize) {\r
105         rect.Set(0, 0, FWL_SPN_MinWidth, FWL_SPN_MinHeight);\r
106         CFWL_WidgetImp::GetWidgetRect(rect, TRUE);\r
107     } else {\r
108         rect = m_pProperties->m_rtWidget;\r
109     }\r
110     return FWL_ERR_Succeeded;\r
111 }\r
112 FWL_ERR CFWL_SpinButtonImp::Update()\r
113 {\r
114     if (IsLocked()) {\r
115         return FWL_ERR_Indefinite;\r
116     }\r
117     GetClientRect(m_rtClient);\r
118     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXE_SPB_Vert) {\r
119         m_rtUpButton.Set(m_rtClient.top, m_rtClient.left, m_rtClient.width, m_rtClient.height / 2);\r
120         m_rtDnButton.Set(m_rtClient.left, m_rtClient.top + m_rtClient.height / 2, m_rtClient.width, m_rtClient.height / 2);\r
121     } else {\r
122         m_rtUpButton.Set(m_rtClient.left, m_rtClient.top, m_rtClient.width / 2, m_rtClient.height);\r
123         m_rtDnButton.Set(m_rtClient.left + m_rtClient.width / 2, m_rtClient.top, m_rtClient.width / 2, m_rtClient.height);\r
124     }\r
125     return FWL_ERR_Succeeded;\r
126 }\r
127 FX_DWORD CFWL_SpinButtonImp::HitTest(FX_FLOAT fx, FX_FLOAT fy)\r
128 {\r
129     if (m_rtClient.Contains(fx, fy)) {\r
130         return FWL_WGTHITTEST_Client;\r
131     }\r
132     if (HasBorder() && (m_rtClient.Contains(fx, fy))) {\r
133         return FWL_WGTHITTEST_Border;\r
134     }\r
135     if (HasEdge()) {\r
136         CFX_RectF rtEdge;\r
137         GetEdgeRect(rtEdge);\r
138         if (rtEdge.Contains(fx, fy)) {\r
139             return FWL_PART_SPB_Edge;\r
140         }\r
141     }\r
142     if (m_rtUpButton.Contains(fx, fy)) {\r
143         return FWL_WGTHITTEST_SPB_UpButton;\r
144     }\r
145     if (m_rtDnButton.Contains(fx, fy)) {\r
146         return FWL_WGTHITTEST_SPB_DownButton;\r
147     }\r
148     return FWL_WGTHITTEST_Unknown;\r
149 }\r
150 FWL_ERR CFWL_SpinButtonImp::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix)\r
151 {\r
152     _FWL_RETURN_VALUE_IF_FAIL(pGraphics, FWL_ERR_Indefinite);\r
153     CFX_RectF rtClip(m_rtClient);\r
154     if (pMatrix != NULL) {\r
155         pMatrix->TransformRect(rtClip);\r
156     }\r
157     IFWL_ThemeProvider *pTheme = GetAvailableTheme();\r
158     if (HasBorder()) {\r
159         DrawBorder(pGraphics, FWL_PART_SPB_Border, pTheme, pMatrix);\r
160     }\r
161     if (HasEdge()) {\r
162         DrawEdge(pGraphics, FWL_PART_SPB_Edge, pTheme, pMatrix);\r
163     }\r
164     DrawUpButton(pGraphics, pTheme, pMatrix);\r
165     DrawDownButton(pGraphics, pTheme, pMatrix);\r
166     return FWL_ERR_Succeeded;\r
167 }\r
168 FX_INT32 CFWL_SpinButtonImp::Run(FWL_HTIMER hTimer)\r
169 {\r
170     if (m_hTimer) {\r
171         CFWL_EvtSpbClick wmPosChanged;\r
172         wmPosChanged.m_pSrcTarget = m_pInterface;\r
173         wmPosChanged.m_bUp = m_iButtonIndex == 0;\r
174         DispatchEvent(&wmPosChanged);\r
175     }\r
176     return 1;\r
177 }\r
178 FWL_ERR CFWL_SpinButtonImp::EnableButton(FX_BOOL bEnable, FX_BOOL bUp)\r
179 {\r
180     if (bUp) {\r
181         if (bEnable) {\r
182             m_dwUpState = FWL_PARTSTATE_SPB_Normal;\r
183         } else {\r
184             m_dwUpState = FWL_PARTSTATE_SPB_Disabled;\r
185         }\r
186     } else {\r
187         if (bEnable) {\r
188             m_dwDnState = FWL_PARTSTATE_SPB_Normal;\r
189         } else {\r
190             m_dwDnState = FWL_PARTSTATE_SPB_Disabled;\r
191         }\r
192     }\r
193     return FWL_ERR_Succeeded;\r
194 }\r
195 FX_BOOL CFWL_SpinButtonImp::IsButtonEnable(FX_BOOL bUp)\r
196 {\r
197     if (bUp) {\r
198         return (m_dwUpState != FWL_PARTSTATE_SPB_Disabled);\r
199     }\r
200     return (m_dwDnState != FWL_PARTSTATE_SPB_Disabled);\r
201 }\r
202 void CFWL_SpinButtonImp::DrawUpButton(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)\r
203 {\r
204     CFWL_ThemeBackground params;\r
205     params.m_pWidget = m_pInterface;\r
206     params.m_iPart = FWL_PART_SPB_UpButton;\r
207     params.m_pGraphics = pGraphics;\r
208     params.m_dwStates = m_dwUpState + 1;\r
209     if (pMatrix) {\r
210         params.m_matrix.Concat(*pMatrix);\r
211     }\r
212     params.m_rtPart = m_rtUpButton;\r
213     pTheme->DrawBackground(&params);\r
214 }\r
215 void CFWL_SpinButtonImp::DrawDownButton(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)\r
216 {\r
217     CFWL_ThemeBackground params;\r
218     params.m_pWidget = m_pInterface;\r
219     params.m_iPart = FWL_PART_SPB_DownButton;\r
220     params.m_pGraphics = pGraphics;\r
221     params.m_dwStates = m_dwDnState + 1;\r
222     if (pMatrix) {\r
223         params.m_matrix.Concat(*pMatrix);\r
224     }\r
225     params.m_rtPart = m_rtDnButton;\r
226     pTheme->DrawBackground(&params);\r
227 }\r
228 CFWL_SpinButtonImpDelegate::CFWL_SpinButtonImpDelegate(CFWL_SpinButtonImp *pOwner)\r
229     : m_pOwner(pOwner)\r
230 {\r
231 }\r
232 FX_INT32 CFWL_SpinButtonImpDelegate::OnProcessMessage(CFWL_Message *pMessage)\r
233 {\r
234     _FWL_RETURN_VALUE_IF_FAIL(pMessage, 0);\r
235     FX_INT32 iRet = 1;\r
236     FX_DWORD dwMsgCode = pMessage->GetClassID();\r
237     switch (dwMsgCode) {\r
238         case FWL_MSGHASH_SetFocus:\r
239         case FWL_MSGHASH_KillFocus: {\r
240                 OnFocusChanged(pMessage, dwMsgCode == FWL_MSGHASH_SetFocus);\r
241                 break;\r
242             }\r
243         case FWL_MSGHASH_Mouse: {\r
244                 CFWL_MsgMouse *pMsg = (CFWL_MsgMouse*)pMessage;\r
245                 FX_DWORD dwCmd = pMsg->m_dwCmd;\r
246                 switch (dwCmd) {\r
247                     case FWL_MSGMOUSECMD_LButtonDown: {\r
248                             OnLButtonDown(pMsg);\r
249                             break;\r
250                         }\r
251                     case FWL_MSGMOUSECMD_LButtonUp: {\r
252                             OnLButtonUp(pMsg);\r
253                             break;\r
254                         }\r
255                     case FWL_MSGMOUSECMD_MouseMove: {\r
256                             OnMouseMove(pMsg);\r
257                             break;\r
258                         }\r
259                     case FWL_MSGMOUSECMD_MouseLeave: {\r
260                             OnMouseLeave(pMsg);\r
261                             break;\r
262                         }\r
263                     default: {\r
264                         }\r
265                 }\r
266                 break;\r
267             }\r
268         case FWL_MSGHASH_Key: {\r
269                 CFWL_MsgKey *pKey = (CFWL_MsgKey*)pMessage;\r
270                 if (pKey->m_dwCmd == FWL_MSGKEYCMD_KeyDown) {\r
271                     OnKeyDown((CFWL_MsgKey*)pKey);\r
272                 }\r
273                 break;\r
274             }\r
275         default: {\r
276                 iRet = 0;\r
277                 break;\r
278             }\r
279     }\r
280     CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);\r
281     return iRet;\r
282 }\r
283 FWL_ERR CFWL_SpinButtonImpDelegate::OnProcessEvent(CFWL_Event *pEvent)\r
284 {\r
285     return FWL_ERR_Succeeded;\r
286 }\r
287 FWL_ERR CFWL_SpinButtonImpDelegate::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )\r
288 {\r
289     return m_pOwner->DrawWidget(pGraphics, pMatrix);\r
290 }\r
291 void CFWL_SpinButtonImpDelegate::OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet )\r
292 {\r
293     if (bSet) {\r
294         m_pOwner->m_pProperties->m_dwStates |= (FWL_WGTSTATE_Focused);\r
295     } else {\r
296         m_pOwner->m_pProperties->m_dwStates &= ~(FWL_WGTSTATE_Focused);\r
297     }\r
298     m_pOwner->Repaint(&m_pOwner->m_rtClient);\r
299 }\r
300 void CFWL_SpinButtonImpDelegate::OnLButtonDown(CFWL_MsgMouse *pMsg)\r
301 {\r
302     m_pOwner->m_bLButtonDwn = TRUE;\r
303     m_pOwner->SetGrab(TRUE);\r
304     m_pOwner->SetFocus(TRUE);\r
305     _FWL_RETURN_IF_FAIL(m_pOwner->m_pProperties->m_pDataProvider);\r
306     FX_BOOL bUpPress = (m_pOwner->m_rtUpButton.Contains(pMsg->m_fx, pMsg->m_fy) &&\r
307                         m_pOwner->IsButtonEnable(TRUE));\r
308     FX_BOOL bDnPress = (m_pOwner->m_rtDnButton.Contains(pMsg->m_fx, pMsg->m_fy) &&\r
309                         m_pOwner->IsButtonEnable(FALSE));\r
310     if (!bUpPress && !bDnPress) {\r
311         return;\r
312     }\r
313     if (bUpPress) {\r
314         m_pOwner->m_iButtonIndex = 0;\r
315         m_pOwner->m_dwUpState = FWL_PARTSTATE_SPB_Pressed;\r
316     }\r
317     if (bDnPress) {\r
318         m_pOwner->m_iButtonIndex = 1;\r
319         m_pOwner->m_dwDnState = FWL_PARTSTATE_SPB_Pressed;\r
320     }\r
321     CFWL_EvtSpbClick wmPosChanged;\r
322     wmPosChanged.m_pSrcTarget = m_pOwner->m_pInterface;\r
323     wmPosChanged.m_bUp = bUpPress;\r
324     m_pOwner->DispatchEvent(&wmPosChanged);\r
325     m_pOwner->Repaint(bUpPress ? &m_pOwner->m_rtUpButton : &m_pOwner->m_rtDnButton);\r
326     m_pOwner->m_hTimer = FWL_StartTimer(m_pOwner, FWL_SPIN_Elapse);\r
327 }\r
328 void CFWL_SpinButtonImpDelegate::OnLButtonUp(CFWL_MsgMouse *pMsg)\r
329 {\r
330     if (m_pOwner->m_pProperties->m_dwStates & FWL_PARTSTATE_SPB_Disabled) {\r
331         return;\r
332     }\r
333     m_pOwner->m_bLButtonDwn = FALSE;\r
334     m_pOwner->SetGrab(FALSE);\r
335     m_pOwner->SetFocus(FALSE);\r
336     if (m_pOwner->m_hTimer) {\r
337         FWL_StopTimer(m_pOwner->m_hTimer);\r
338         m_pOwner->m_hTimer = NULL;\r
339     }\r
340     FX_BOOL bRepaint = FALSE;\r
341     CFX_RectF rtInvalidate;\r
342     if (m_pOwner->m_dwUpState == FWL_PARTSTATE_SPB_Pressed && m_pOwner->IsButtonEnable(TRUE)) {\r
343         m_pOwner->m_dwUpState = FWL_PARTSTATE_SPB_Normal;\r
344         bRepaint = TRUE;\r
345         rtInvalidate = m_pOwner->m_rtUpButton;\r
346     } else if (m_pOwner->m_dwDnState == FWL_PARTSTATE_SPB_Pressed && m_pOwner->IsButtonEnable(FALSE)) {\r
347         m_pOwner->m_dwDnState = FWL_PARTSTATE_SPB_Normal;\r
348         bRepaint = TRUE;\r
349         rtInvalidate = m_pOwner->m_rtDnButton;\r
350     }\r
351     if (bRepaint) {\r
352         m_pOwner->Repaint(&rtInvalidate);\r
353     }\r
354 }\r
355 void CFWL_SpinButtonImpDelegate::OnMouseMove(CFWL_MsgMouse *pMsg)\r
356 {\r
357     _FWL_RETURN_IF_FAIL(m_pOwner->m_pProperties->m_pDataProvider);\r
358     if (m_pOwner->m_bLButtonDwn) {\r
359         return;\r
360     }\r
361     FX_BOOL bRepaint = FALSE;\r
362     CFX_RectF rtInvlidate;\r
363     rtInvlidate.Reset();\r
364     if (m_pOwner->m_rtUpButton.Contains(pMsg->m_fx, pMsg->m_fy)) {\r
365         if (m_pOwner->IsButtonEnable(TRUE)) {\r
366             if (m_pOwner->m_dwUpState == FWL_PARTSTATE_SPB_Hovered) {\r
367                 m_pOwner->m_dwUpState = FWL_PARTSTATE_SPB_Hovered;\r
368                 bRepaint = TRUE;\r
369                 rtInvlidate = m_pOwner->m_rtUpButton;\r
370             }\r
371             if (m_pOwner->m_dwDnState != FWL_PARTSTATE_SPB_Normal && m_pOwner->IsButtonEnable(FALSE)) {\r
372                 m_pOwner->m_dwDnState = FWL_PARTSTATE_SPB_Normal;\r
373                 if (bRepaint) {\r
374                     rtInvlidate.Union(m_pOwner->m_rtDnButton);\r
375                 } else {\r
376                     rtInvlidate = m_pOwner->m_rtDnButton;\r
377                 }\r
378                 bRepaint = TRUE;\r
379             }\r
380         }\r
381         if (!m_pOwner->IsButtonEnable(FALSE)) {\r
382             m_pOwner->EnableButton(FALSE, FALSE);\r
383         }\r
384     } else if (m_pOwner->m_rtDnButton.Contains(pMsg->m_fx, pMsg->m_fy)) {\r
385         if (m_pOwner->IsButtonEnable(FALSE)) {\r
386             if (m_pOwner->m_dwDnState != FWL_PARTSTATE_SPB_Hovered) {\r
387                 m_pOwner->m_dwDnState = FWL_PARTSTATE_SPB_Hovered;\r
388                 bRepaint = TRUE;\r
389                 rtInvlidate = m_pOwner->m_rtDnButton;\r
390             }\r
391             if (m_pOwner->m_dwUpState != FWL_PARTSTATE_SPB_Normal && m_pOwner->IsButtonEnable(TRUE)) {\r
392                 m_pOwner->m_dwUpState = FWL_PARTSTATE_SPB_Normal;\r
393                 if (bRepaint) {\r
394                     rtInvlidate.Union(m_pOwner->m_rtUpButton);\r
395                 } else {\r
396                     rtInvlidate = m_pOwner->m_rtUpButton;\r
397                 }\r
398                 bRepaint = TRUE;\r
399             }\r
400         }\r
401     } else if (m_pOwner->m_dwUpState != FWL_PARTSTATE_SPB_Normal || m_pOwner->m_dwDnState != FWL_PARTSTATE_SPB_Normal) {\r
402         if (m_pOwner->m_dwUpState != FWL_PARTSTATE_SPB_Normal) {\r
403             m_pOwner->m_dwUpState = FWL_PARTSTATE_SPB_Normal;\r
404             bRepaint = TRUE;\r
405             rtInvlidate = m_pOwner->m_rtUpButton;\r
406         }\r
407         if (m_pOwner->m_dwDnState != FWL_PARTSTATE_SPB_Normal) {\r
408             m_pOwner->m_dwDnState = FWL_PARTSTATE_SPB_Normal;\r
409             if (bRepaint) {\r
410                 rtInvlidate.Union(m_pOwner->m_rtDnButton);\r
411             } else {\r
412                 rtInvlidate = m_pOwner->m_rtDnButton;\r
413             }\r
414             bRepaint = TRUE;\r
415         }\r
416     }\r
417     if (bRepaint) {\r
418         m_pOwner->Repaint(&rtInvlidate);\r
419     }\r
420 }\r
421 void CFWL_SpinButtonImpDelegate::OnMouseLeave(CFWL_MsgMouse *pMsg)\r
422 {\r
423     _FWL_RETURN_IF_FAIL(pMsg);\r
424     if (m_pOwner->m_dwUpState != FWL_PARTSTATE_SPB_Normal && m_pOwner->IsButtonEnable(TRUE)) {\r
425         m_pOwner->m_dwUpState = FWL_PARTSTATE_SPB_Normal;\r
426     }\r
427     if (m_pOwner->m_dwDnState != FWL_PARTSTATE_SPB_Normal && m_pOwner->IsButtonEnable(FALSE)) {\r
428         m_pOwner->m_dwDnState = FWL_PARTSTATE_SPB_Normal;\r
429     }\r
430     m_pOwner->Repaint(&m_pOwner->m_rtClient);\r
431 }\r
432 void CFWL_SpinButtonImpDelegate::OnKeyDown(CFWL_MsgKey *pMsg)\r
433 {\r
434     _FWL_RETURN_IF_FAIL(m_pOwner->m_pProperties->m_pDataProvider);\r
435     FX_BOOL bUp = pMsg->m_dwKeyCode == FWL_VKEY_Up || pMsg->m_dwKeyCode == FWL_VKEY_Left;\r
436     FX_BOOL bDown = pMsg->m_dwKeyCode == FWL_VKEY_Down || pMsg->m_dwKeyCode == FWL_VKEY_Right;\r
437     if (!bUp && !bDown) {\r
438         return;\r
439     }\r
440     FX_BOOL bUpEnable = m_pOwner->IsButtonEnable(TRUE);\r
441     FX_BOOL bDownEnable = m_pOwner->IsButtonEnable(FALSE);\r
442     if (!bUpEnable && !bDownEnable) {\r
443         return;\r
444     }\r
445     CFWL_EvtSpbClick wmPosChanged;\r
446     wmPosChanged.m_pSrcTarget = m_pOwner->m_pInterface;\r
447     wmPosChanged.m_bUp = bUpEnable;\r
448     m_pOwner->DispatchEvent(&wmPosChanged);\r
449     m_pOwner->Repaint(bUpEnable ? &m_pOwner->m_rtUpButton : &m_pOwner->m_rtDnButton);\r
450 }\r