soui 5.0.0.1
Soui5 Doc
 
Loading...
Searching...
No Matches
SwndContainerImpl.cpp
1//////////////////////////////////////////////////////////////////////////
2// Class Name: SwndContainerImpl
3//////////////////////////////////////////////////////////////////////////
4#include "souistd.h"
6
7SNSBEGIN
8
9#define WM_NCMOUSEFIRST WM_NCMOUSEMOVE
10#define WM_NCMOUSELAST WM_NCMBUTTONDBLCLK
11
12//////////////////////////////////////////////////////////////////////////
14 : m_hCapture(0)
15 , m_hHover(0)
16 , m_bNcHover(FALSE)
17 , m_bZorderDirty(TRUE)
18 , m_pRoot(NULL)
19{
20}
21
23{
24 m_pRoot = pRoot;
25 m_dropTarget.SetOwner(pRoot);
26 m_focusMgr.SetOwner(pRoot);
27}
28
29LRESULT SwndContainerImpl::DoFrameEvent(UINT uMsg, WPARAM wParam, LPARAM lParam)
30{
31 LRESULT lRet = 0;
32 SWindow *pRoot = m_pRoot; // use a local value to avoid m_pRoot changed while handle message
33 pRoot->AddRef();
34 pRoot->SetMsgHandled(TRUE);
35
36 switch (uMsg)
37 {
38 case WM_MOUSEMOVE:
39 OnFrameMouseMove((UINT)wParam, CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
40 break;
41 case WM_MOUSEHOVER:
42 OnFrameMouseEvent(uMsg, wParam, lParam);
43 break;
44 case WM_MOUSELEAVE:
46 break;
47 case WM_SETCURSOR:
48 lRet = OnFrameSetCursor(CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
49 if (!lRet)
50 {
51 HCURSOR hCursor = GETRESPROVIDER->LoadCursor(IDC_ARROW);
52 SetCursor(hCursor);
53 }
54 break;
55 case WM_KEYDOWN:
56 OnFrameKeyDown((UINT)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16));
57 break;
58 case WM_SETFOCUS:
59 OnActivate(WA_ACTIVE);
60 break;
61 case WM_KILLFOCUS:
62 OnActivate(WA_INACTIVE);
63 break;
64 case WM_ACTIVATE:
65 OnActivate(LOWORD(wParam));
66 break;
67 case WM_ACTIVATEAPP:
68 OnActivateApp((BOOL)wParam, (DWORD)lParam);
69 break;
70 case WM_IME_STARTCOMPOSITION:
71 case WM_IME_ENDCOMPOSITION:
72 case WM_IME_COMPOSITION:
73 case WM_IME_CHAR:
74 case WM_IME_REQUEST:
75 lRet = OnFrameKeyEvent(uMsg, wParam, lParam);
76 break;
77 case WM_MOUSEWHEEL:
78 case 0x20E: // WM_MOUSEHWHEEL
79 OnFrameMouseWheel(uMsg, wParam, lParam);
80 break;
81 default:
82 if (uMsg >= WM_KEYFIRST && uMsg <= WM_KEYLAST)
83 OnFrameKeyEvent(uMsg, wParam, lParam);
84 else if (uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST)
85 OnFrameMouseEvent(uMsg, wParam, lParam);
86 else
87 pRoot->SetMsgHandled(FALSE);
88 break;
89 }
90
91 pRoot->Release();
92 return lRet;
93}
94
96{
98 if (pWnd)
99 {
100 pWnd->OnCaptureChanged(FALSE);
101 }
102 m_hCapture = 0;
103 return TRUE;
104}
105
107{
108 if (m_hCapture == swnd)
109 return swnd;
110 SWindow *pWnd = SWindowMgr::GetWindow(swnd);
111 SASSERT(pWnd);
112 if (pWnd->IsDisabled(TRUE))
113 return 0;
114
115 SWND hRet = m_hCapture;
116 m_hCapture = swnd;
117 pWnd->OnCaptureChanged(TRUE);
118 return hRet;
119}
120
122{
123 if (swnd && ::GetFocus() != GetHostHwnd() && !(::GetWindowLong(GetHostHwnd(), GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
124 {
125 ::SetFocus(GetHostHwnd());
126 }
127 m_focusMgr.SetFocusedHwnd(swnd);
128}
129
131{
132 return m_hCapture;
133}
134
136{
137 return m_focusMgr.GetFocusedHwnd();
138}
139
141{
142 return m_hHover;
143}
144
145void SwndContainerImpl::OnFrameMouseMove(UINT uFlag, CPoint pt)
146{
148 if (pCapture)
149 { //有窗口设置了鼠标捕获,不需要判断是否有TrackMouseEvent属性,也不需要判断客户区与非客户区的变化
150 pCapture->TransformPointEx(pt);
151 SWindow *pHover = pCapture->IsContainPoint(pt, FALSE) ? pCapture : NULL;
152 SWND hHover = pHover ? pHover->GetSwnd() : 0;
153 if (hHover != m_hHover)
154 { //检测鼠标是否在捕获窗口间移动
156 m_hHover = hHover;
157 if (pOldHover)
158 {
159 if (m_bNcHover)
160 pOldHover->SSendMessage(WM_NCMOUSELEAVE);
161 pOldHover->SSendMessage(WM_MOUSELEAVE);
162 }
163 if (pHover && !(pHover->GetState() & WndState_Hover))
164 {
165 if (m_bNcHover)
166 pHover->SSendMessage(WM_NCMOUSEHOVER, uFlag, MAKELPARAM(pt.x, pt.y));
167 pHover->SSendMessage(WM_MOUSEHOVER, uFlag, MAKELPARAM(pt.x, pt.y));
168 }
169 }
170 pCapture->SSendMessage(m_bNcHover ? WM_NCMOUSEMOVE : WM_MOUSEMOVE, uFlag, MAKELPARAM(pt.x, pt.y));
171 }
172 else
173 { //没有设置鼠标捕获
174 CPoint pt2 = pt;
175 SWND hHover = m_pRoot->SwndFromPoint(pt2);
176 SWindow *pHover = SWindowMgr::GetWindow(hHover);
177 if (m_hHover != hHover)
178 { // hover窗口发生了变化
180 m_hHover = hHover;
181 if (pOldHover)
182 {
183 BOOL bLeave = TRUE;
184 if (pOldHover->GetStyle().m_bTrackMouseEvent)
185 { //对于有监视鼠标事件的窗口做特殊处理
186 CPoint pt3 = pt;
187 pOldHover->TransformPointEx(pt3);
188 bLeave = !pOldHover->IsContainPoint(pt3, FALSE);
189 }
190 if (bLeave)
191 {
192 if (m_bNcHover)
193 pOldHover->SSendMessage(WM_NCMOUSELEAVE);
194 pOldHover->SSendMessage(WM_MOUSELEAVE);
195 }
196 }
197 if (pHover && !pHover->IsDisabled(TRUE) && !(pHover->GetState() & WndState_Hover))
198 {
199 m_bNcHover = pHover->OnNcHitTest(pt2);
200 if (m_bNcHover)
201 pHover->SSendMessage(WM_NCMOUSEHOVER, uFlag, MAKELPARAM(pt2.x, pt2.y));
202 pHover->SSendMessage(WM_MOUSEHOVER, uFlag, MAKELPARAM(pt2.x, pt2.y));
203 }
204 }
205 else if (pHover && !pHover->IsDisabled(TRUE))
206 { //窗口内移动,检测客户区和非客户区的变化
207 BOOL bNcHover = pHover->OnNcHitTest(pt2);
208 if (bNcHover != m_bNcHover)
209 {
210 m_bNcHover = bNcHover;
211 if (m_bNcHover)
212 {
213 pHover->SSendMessage(WM_NCMOUSEHOVER, uFlag, MAKELPARAM(pt2.x, pt2.y));
214 }
215 else
216 {
217 pHover->SSendMessage(WM_NCMOUSELEAVE);
218 }
219 }
220 }
221 if (pHover && !pHover->IsDisabled(TRUE))
222 pHover->SSendMessage(m_bNcHover ? WM_NCMOUSEMOVE : WM_MOUSEMOVE, uFlag, MAKELPARAM(pt2.x, pt2.y));
223 }
224
225 //处理trackMouseEvent属性
226 SPOSITION pos = m_lstTrackMouseEvtWnd.GetHeadPosition();
227 while (pos)
228 {
229 SWND swnd = m_lstTrackMouseEvtWnd.GetNext(pos);
230 SWindow *pWnd = SWindowMgr::GetWindow(swnd);
231 if (!pWnd)
232 {
234 }
235 else if (pWnd->IsVisible(TRUE))
236 {
237 CPoint pt4(pt);
238 pWnd->TransformPointEx(pt4);
239 BOOL bInWnd = pWnd->IsContainPoint(pt4, FALSE);
240 if (bInWnd && !(pWnd->GetState() & WndState_Hover))
241 {
242 pWnd->SSendMessage(WM_MOUSEHOVER);
243 }
244 else if (!bInWnd && (pWnd->GetState() & WndState_Hover))
245 {
246 pWnd->SSendMessage(WM_MOUSELEAVE);
247 }
248 }
249 }
250}
251
253{
255 if (pCapture)
256 {
257 pCapture->SSendMessage(WM_MOUSELEAVE);
258 }
259 else if (m_hHover)
260 {
262 if (pHover && !pHover->IsDisabled(TRUE))
263 {
264 pHover->AddRef();
265 pHover->SSendMessage(WM_MOUSELEAVE);
266 if (m_bNcHover)
267 pHover->SSendMessage(WM_NCMOUSELEAVE);
268 pHover->Release();
269 }
270 }
271
272 //处理trackMouseEvent属性
273 SPOSITION pos = m_lstTrackMouseEvtWnd.GetHeadPosition();
274 while (pos)
275 {
276 SWND swnd = m_lstTrackMouseEvtWnd.GetNext(pos);
277 SWindow *pWnd = SWindowMgr::GetWindow(swnd);
278 if (!pWnd)
279 {
281 }
282 else if (pWnd->IsVisible(TRUE) && pWnd->GetState() & WndState_Hover)
283 {
284 pWnd->SSendMessage(WM_MOUSELEAVE);
285 }
286 }
287 m_hHover = 0;
288}
289
291{
293 if (pCapture)
294 return pCapture->OnSetCursor(pt);
295 else
296 {
298 if (pHover && !pHover->IsDisabled(TRUE))
299 return pHover->OnSetCursor(pt);
300 }
301 return FALSE;
302}
303
304void SwndContainerImpl::OnFrameMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam)
305{
307 if (pCapture)
308 {
309 if (m_bNcHover)
310 uMsg += (UINT)WM_NCMOUSEFIRST - WM_MOUSEFIRST; //转换成NC对应的消息
311 BOOL bMsgHandled = FALSE;
312 CPoint pt(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
313 pCapture->TransformPointEx(pt);
314 lParam = MAKELPARAM(pt.x, pt.y);
315 pCapture->SSendMessage(uMsg, wParam, lParam, &bMsgHandled);
316 m_pRoot->SetMsgHandled(bMsgHandled);
317 }
318 else
319 {
320 CPoint pt(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
321 m_hHover = m_pRoot->SwndFromPoint(pt);
323 if (pHover && !pHover->IsDisabled(TRUE))
324 {
325 BOOL bMsgHandled = FALSE;
326 if (m_bNcHover)
327 uMsg += (UINT)WM_NCMOUSEFIRST - WM_MOUSEFIRST; //转换成NC对应的消息
328 lParam = MAKELPARAM(pt.x, pt.y);
329 pHover->SSendMessage(uMsg, wParam, lParam, &bMsgHandled);
330 m_pRoot->SetMsgHandled(bMsgHandled);
331 }
332 else
333 {
334 m_pRoot->SetMsgHandled(FALSE);
335 }
336 }
337}
338
339void SwndContainerImpl::OnFrameMouseWheel(UINT uMsg, WPARAM wParam, LPARAM lParam)
340{
342 if (!pWndTarget)
343 {
344 if (IsSendWheel2Hover())
345 {
346 CPoint pt(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
347 m_hHover = m_pRoot->SwndFromPoint(pt);
348 pWndTarget = SWindowMgr::GetWindow(m_hHover);
349 }
350 else
351 {
352 pWndTarget = SWindowMgr::GetWindow(m_focusMgr.GetFocusedHwnd());
353 }
354 }
355
356 if (pWndTarget && !pWndTarget->IsDisabled(TRUE))
357 {
358 BOOL bMsgHandled = FALSE;
359 pWndTarget->SSendMessage(uMsg, wParam, lParam, &bMsgHandled);
360 m_pRoot->SetMsgHandled(bMsgHandled);
361 }
362 else
363 {
364 m_pRoot->SetMsgHandled(FALSE);
365 }
366}
367
368LRESULT SwndContainerImpl::OnFrameKeyEvent(UINT uMsg, WPARAM wParam, LPARAM lParam)
369{
370 LRESULT lRet = 0;
371 if ((uMsg == WM_KEYDOWN || uMsg == WM_KEYUP) && GetKeyState(VK_MENU) & 0x80)
372 {
373 UINT vKey = (UINT)wParam;
374 if (vKey >= 'a' && vKey <= 'z')
375 vKey -= 0x20; //转换成VK
376 if (m_focusMgr.OnKeyDown(vKey))
377 return lRet; //首先处理焦点切换
378 }
379
380 SWindow *pFocus = SWindowMgr::GetWindow(m_focusMgr.GetFocusedHwnd());
381 if (pFocus)
382 {
383 BOOL bMsgHandled = FALSE;
384 lRet = pFocus->SSendMessage(uMsg, wParam, lParam, &bMsgHandled);
385 m_pRoot->SetMsgHandled(bMsgHandled);
386 }
387 else
388 {
389 m_pRoot->SetMsgHandled(FALSE);
390 }
391 return lRet;
392}
393
394void SwndContainerImpl::OnFrameKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
395{
396 if (m_focusMgr.OnKeyDown(nChar))
397 return; //首先处理焦点切换
398
399 SWindow *pFocus = SWindowMgr::GetWindow(m_focusMgr.GetFocusedHwnd());
400 if (pFocus)
401 {
402 BOOL bMsgHandled = FALSE;
403 pFocus->SSendMessage(WM_KEYDOWN, nChar, MAKELPARAM(nRepCnt, nFlags), &bMsgHandled);
404 m_pRoot->SetMsgHandled(bMsgHandled);
405 }
406 else
407 {
408 m_pRoot->SetMsgHandled(FALSE);
409 }
410}
411
412BOOL SwndContainerImpl::RegisterDragDrop(SWND swnd, IDropTarget *pDropTarget)
413{
414 return m_dropTarget.RegisterDragDrop(swnd, pDropTarget);
415}
416
418{
419 return m_dropTarget.UnregisterDragDrop(swnd);
420}
421
423{
424 if (nState == WA_INACTIVE)
425 {
426 m_focusMgr.StoreFocusedView();
427 }
428 else if (nState == WA_ACTIVE)
429 {
430 m_focusMgr.RestoreFocusedView();
431 }
432}
433
434void SwndContainerImpl::OnActivateApp(BOOL bActive, DWORD dwThreadID)
435{
436 m_pRoot->SDispatchMessage(WM_ACTIVATEAPP, (WPARAM)bActive, (LPARAM)dwThreadID);
437}
438
440{
441 if (m_lstTrackMouseEvtWnd.Find(swnd))
442 return FALSE;
443 m_lstTrackMouseEvtWnd.AddTail(swnd);
444 return TRUE;
445}
446
448{
449 SPOSITION pos = m_lstTrackMouseEvtWnd.Find(swnd);
450 if (!pos)
451 return FALSE;
452 m_lstTrackMouseEvtWnd.RemoveAt(pos);
453 return TRUE;
454}
455
460
462{
463 if (m_bZorderDirty)
464 {
465 UINT uInitZorder = 0;
466 _BuildWndTreeZorder(m_pRoot, uInitZorder);
467 m_bZorderDirty = FALSE;
468 }
469}
470
471void SwndContainerImpl::_BuildWndTreeZorder(IWindow *pWnd, UINT &iOrder)
472{
473 ((SWindow *)pWnd)->m_uZorder = iOrder++;
474 IWindow *pChild = pWnd->GetIWindow(GSW_FIRSTCHILD);
475 while (pChild)
476 {
477 _BuildWndTreeZorder(pChild, iOrder);
478 pChild = pChild->GetIWindow(GSW_NEXTSIBLING);
479 }
480}
481
483{
484 return m_timelineHandlerMgr.RegisterTimelineHandler(pHandler);
485}
486
488{
489 return m_timelineHandlerMgr.UnregisterTimelineHandler(pHandler);
490}
491
493{
494 if (!m_pRoot->IsVisible(FALSE))
495 return;
496 m_timelineHandlerMgr.OnNextFrame();
497}
498
500{
501 SPOSITION pos = m_lstVideoCanvas.Find(swnd);
502 if (pos)
503 return FALSE;
504 m_lstVideoCanvas.AddTail(swnd);
505 return TRUE;
506}
507
509{
510 SPOSITION pos = m_lstVideoCanvas.Find(swnd);
511 if (!pos)
512 return FALSE;
513
514 m_lstVideoCanvas.RemoveAt(pos);
515 return TRUE;
516}
517
518SNSEND
@ GSW_FIRSTCHILD
Definition SWnd.h:195
@ GSW_NEXTSIBLING
Definition SWnd.h:198
@ WndState_Hover
Definition SWnd.h:76
SOUI窗口容器的实现
Base class for SOUI DUI windows.
Definition SWnd.h:286
SWND GetSwnd() SCONST OVERRIDE
Retrieves the window handle.
Definition Swnd.cpp:489
DWORD GetState() SCONST OVERRIDE
Retrieves the current state of the window.
Definition Swnd.cpp:437
virtual void OnCaptureChanged(BOOL bCaptured)
Called when the capture state of the window changes.
Definition Swnd.cpp:2477
BOOL IsVisible(BOOL bCheckParent=FALSE) SCONST OVERRIDE
Checks if the window is visible.
Definition Swnd.cpp:646
void TransformPointEx(CPoint &pt) const
Extends the transformation of a point.
Definition Swnd.cpp:1395
LRESULT SSendMessage(UINT uMsg, WPARAM wParam=0, LPARAM lParam=0, BOOL *pbMsgHandled=NULL) OVERRIDE
Sends a message to the window.
Definition Swnd.cpp:364
BOOL IsContainPoint(POINT pt, BOOL bClientOnly) SCONST OVERRIDE
Checks if the window contains a specified point.
Definition Swnd.cpp:3100
BOOL IsDisabled(BOOL bCheckParent=FALSE) SCONST OVERRIDE
Checks if the window is disabled.
Definition Swnd.cpp:638
virtual BOOL OnSetCursor(const CPoint &pt)
Sets the cursor when the mouse hovers over the window.
Definition Swnd.cpp:429
void SetMsgHandled(BOOL bHandled)
Sets the message handled flag.
Definition Swnd.cpp:212
const SwndStyle & GetStyle() const
Retrieves the style of the window.
Definition Swnd.cpp:716
virtual BOOL OnNcHitTest(CPoint pt)
Non-client area hit test.
Definition Swnd.cpp:2647
static SWindow * GetWindow(SWND swnd)
Retrieves the SWindow pointer from a given handle.
SWND GetHover() SCONST OVERRIDE
Retrieves the window handle that is hovered.
void BuildWndTreeZorder() OVERRIDE
Rebuilds the window tree's z-order.
SDropTargetDispatcher m_dropTarget
STimerlineHandlerMgr m_timelineHandlerMgr
BOOL RegisterTrackMouseEvent(SWND swnd) OVERRIDE
Registers a window for tracking mouse events.
void OnFrameMouseLeave()
Handles mouse leave events within the frame.
SWND GetFocus() SCONST OVERRIDE
Retrieves the window handle that has focus.
void OnSetSwndFocus(SWND swnd) OVERRIDE
Sets the window focus.
BOOL OnFrameSetCursor(const CPoint &pt)
Sets the cursor based on the mouse position.
void OnFrameMouseWheel(UINT uMsg, WPARAM wParam, LPARAM lParam)
Handles mouse wheel events within the frame.
void MarkWndTreeZorderDirty() OVERRIDE
Marks the window tree's z-order as dirty.
SList< SWND > m_lstTrackMouseEvtWnd
void OnActivate(UINT nState)
Handles window activation events.
BOOL RegisterTimelineHandler(ITimelineHandler *pHandler) OVERRIDE
Registers a timeline handler.
SFocusManager m_focusMgr
BOOL RegisterDragDrop(SWND swnd, IDropTarget *pDropTarget) OVERRIDE
Registers a drop target for a window.
void SetRoot(SWindow *pRoot)
Sets the root window of the container.
void OnFrameKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
Handles key down events within the frame.
void OnNextFrame() OVERRIDE
Called when the next frame is ready.
SList< SWND > m_lstVideoCanvas
virtual LRESULT DoFrameEvent(UINT uMsg, WPARAM wParam, LPARAM lParam)
Processes frame events.
BOOL OnReleaseSwndCapture() OVERRIDE
Releases the window capture.
BOOL UnregisterVideoCanvas(SWND swnd) OVERRIDE
Unregisters a window as a video canvas.
LRESULT OnFrameKeyEvent(UINT uMsg, WPARAM wParam, LPARAM lParam)
Handles key events within the frame.
SWND OnSetSwndCapture(SWND swnd) OVERRIDE
Sets the window capture.
SWND OnGetSwndCapture() SCONST OVERRIDE
Retrieves the window handle that has capture.
BOOL UnregisterTimelineHandler(ITimelineHandler *pHandler) OVERRIDE
Unregisters a timeline handler.
BOOL UnregisterTrackMouseEvent(SWND swnd) OVERRIDE
Unregisters a window for tracking mouse events.
void _BuildWndTreeZorder(IWindow *pWnd, UINT &iOrder)
Recursively builds the z-order of the window tree.
SwndContainerImpl()
Constructor.
void OnFrameMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam)
Handles mouse events within the frame.
void OnActivateApp(BOOL bActive, DWORD dwThreadID)
Handles application activation events.
void OnFrameMouseMove(UINT uFlag, CPoint pt)
Handles mouse move events within the frame.
BOOL RegisterVideoCanvas(SWND swnd) OVERRIDE
Registers a window as a video canvas.
BOOL UnregisterDragDrop(SWND swnd) OVERRIDE
Unregisters a drop target for a window.
DWORD m_bTrackMouseEvent
Definition SWndStyle.h:64
long AddRef() override
Increments the reference count.
long Release() override
Decrements the reference count and deletes the object if the count reaches zero.
HWND GetHostHwnd() PURE
Retrieves the handle to the host window.
BOOL IsSendWheel2Hover() SCONST PURE
Checks if mouseWheel messages are sent to the hover window.
时间轴处理接口