// UNUSED.TXT // // Stuff that is not used anymore but could be useful for // cut & paste. // /* switch (uMsg) { case WM_SETCURSOR: if (MouseTargetter.m_dwTargetMode == CMouseTargetter::tgTargetTreeView) { HTREEITEM hti; MOUSETARGETINFO mti = { hwnd }; Assert(TreeView.m_hWnd == hwnd); // Fill out structure with mouse position GetCursorPos(&tvHitTest.pt); if (hti == s_htiOld) { if (hcursorOld) { SetCursor(hcursorOld); return TRUE; } } if (s_htiOld != NULL) InvalidateRect(hwnd, &rcOld, TRUE); if (hti) { (void)MouseTracker.HwndGrabCapture(hwnd); TreeView_GetItemRect(hwnd, hti, &rcOld, TRUE); rcOld.right++; HDC hdc = GetDC(hwnd); FrameRect(hdc, &rcOld, hbrWindowText); ReleaseDC(hwnd, hdc); tvItem.mask = TVIF_PARAM; tvItem.hItem = hti; SideAssert(TreeView_GetItem(hwnd, OUT &tvItem)); Assert((ITreeItem *)tvItem.lParam != NULL); mti.hcursorTarget = hcursorFinger; mti.tv.hti = hti; mti.tv.pTreeItem = (ITreeItem *)tvItem.lParam; s_htiOld = hti; } else { s_htiOld = NULL; } (void)MouseTargetter.OnNotify(INOUT &mti); hcursorOld = mti.hcursorTarget; if (mti.hcursorTarget) { SetCursor(mti.hcursorTarget); return TRUE; } } break; case UN_MOUSETIMERCAPTURE: if (lParam == NULL && s_htiOld != NULL) { s_htiOld = NULL; hcursorOld = NULL; InvalidateRect(TreeView.m_hWnd, &rcOld, TRUE); } return 0; } // switch */ case WM_SETCURSOR: if (MouseTargetter.m_dwTargetMode != CMouseTargetter::tgTargetNone) { if ((HWND)wParam == hwndMain) { SetCursor(MouseTargetter.m_dwTargetMode == CMouseTargetter::tgTargetStandBy ? hcursorArrow : hcursorNo); return TRUE; } } goto DoDefault; ///////////////////////////////////////////////////////////////////////////// VOID CALLBACK MouseTrackerTimerProc(HWND, UINT, UINT, DWORD); ///////////////////////////////////////////////////////////////////////////// // class CMouseTracker // // CMouseTracker require a timer in order to determine if the mouse // has gone out of a window client's rectangle. A window receives // WM_MOUSEMOVE only when the mouse is inside its client area, but // never receives any notification when the mouse is about to move // to another window. // A simple way would to capture the mouse on the first mouse move // message and keep the capture as long as the mouse is inside the // client area. Capturing the mouse has a bad side effect: It // is impossible for the user to activate the menu via the Alt key. // // Therefore, we need to check manually if the cursor is on top of // our window on every timer event. If the cursor is outside the // window client's rectangle, it sends a UN_MOUSETIMERCAPTURE message // with lParam==NULL, otherwise lParam==&ptMouse and wParam is the // number of milliseconds that have elapsed since you grap the capture. // ptMouse specifies the coordinates relative to the upper left // corner of the client area. // // Once you grab the capture, you get UN_MOUSETIMERCAPTURE messages // every dtTimerTick (currently 200 milliseconds) until you loose // the capture. // class CMouseTracker { public: enum { dtTimerTick = 200 }; protected: UINT m_uTimerId; HWND m_hwndCapture; DWORD m_dwTimeCapture; public: CMouseTracker(); ~CMouseTracker(); HWND HwndGrabCapture(HWND hwndCaptureNew); HWND HwndReleaseCapture(HWND hwnd); void OnWmTimer(DWORD dwCurrentTime); inline HWND HwndGetCapture() const { return m_hwndCapture; } DebugCode( UINT GetTimerId() const { return m_uTimerId; } ) }; // CMouseTracker ///////////////////////////////////////////////////////////////////////////// // UN_MOUSETARGETCHANGED // // Notification message indicating the mouse has moved and the // target has changed. // // wParam = 0; // pMTI = (MOUSETARGETINFO *)lParam; // #define UN_MOUSETARGETCHANGED (WM_FIRST+30) class ITreeItem; struct MOUSETARGETINFO // mti { HWND hwndFrom; // IN: Window sending the message DWORD dwFlags; // IN: Extra Flags HCURSOR hcursorTarget; // OPTIONAL: Change the shape of the cursor union { struct TREEVIEW_INFO { HTREEITEM hti; ITreeItem * pTreeItem; } tv; }; }; ///////////////////////////////////////////////////////////////////////////// class CMouseTargetter { public: enum { tgTargetNone, tgTargetStandBy, tgTargetTreeView }; public: DWORD m_dwTargetMode; // What kind of target we want HWND m_hwndNotify; // Window receiving UN_MOUSETARGETCHANGED public: void SetTargetMode(DWORD dwTargetMode, HWND hwndNotify = NULL); LRESULT OnNotify(INOUT MOUSETARGETINFO * pMTI); }; // CMouseTargetter extern CMouseTargetter MouseTargetter; ///////////////////////////////////////////////////////////////////////////// // UN_MOUSETIMERCAPTURE // // Notification message indicating the window has lost the mouse capture and/or // the mouse cursor is no longer in its client area. // // dwTimeElapsed = (DWORD)wParam; // fLostCapture = (BOOL)(lParam == NULL); // pptMouse = (POINT *)lParam; // // dwTimeElapsed: Time elapsed (in milliseconds) since the capture // fLostCapture: The mouse is no longer in your client area // pptMouse: Mouse coordinates in client coordinates // #define UN_MOUSETIMERCAPTURE (WM_FIRST+31) ///////////////////////////////////////////////////////////////////////////// // CMouseTracker() // // Initialize the mouse tracker timer. // CMouseTracker::CMouseTracker() { DebugCode( static int cRefCount = 0; ) Assert(cRefCount++ == 0); m_hwndCapture = NULL; m_uTimerId = SetTimer(NULL, 0, dtTimerTick, (TIMERPROC)MouseTrackerTimerProc); ReportFSz(m_uTimerId != 0, "CMouseTracker: Unable to set a timer."); } // CMouseTracker ///////////////////////////////////////////////////////////////////////////// // ~CMouseTracker() // // Kill the mouse tracker timer. // CMouseTracker::~CMouseTracker() { SideReport(KillTimer(NULL, m_uTimerId)); } // ~CMouseTracker ///////////////////////////////////////////////////////////////////////////// // HwndGrabCapture() // // Set the mouse capture to the window hwndCaptureNew. If the capture // was already set set to hwndCaptureNew, the function simply does // nothing. If you want to release the capture, set hwndCaptureNew to // NULL. This will send you a message UN_MOUSETIMERCAPTURE with // lParam==NULL indicating you have lost the capture. // // Return Value: // The function always returns the handle of the previous window having // the capture. If no window had the capture, the function will return // NULL. To find if you just captured the mouse, you may do the following: // // // Find if you just got the mouse capture // if (MouseTracker.HwndGrabCapture(hwnd) != hwnd) // { // // Initialization code for the capture // } // HWND CMouseTracker::HwndGrabCapture(HWND hwndCaptureNew) { HWND hwndCaptureOld; DWORD dwCurrentTime; Assert(IsWindow(hwndCaptureNew)); if (hwndCaptureNew == m_hwndCapture) return m_hwndCapture; // A new window is about to receive the mouse capture hwndCaptureOld = m_hwndCapture; m_hwndCapture = hwndCaptureNew; // Get the current time dwCurrentTime = GetTickCount(); // If the previous window having the capture still exists if (IsWindow(hwndCaptureOld)) { // Send a notification message that the window has lost the capture SendMessage(hwndCaptureOld, UN_MOUSETIMERCAPTURE, dwCurrentTime - m_dwTimeCapture, NULL); } m_dwTimeCapture = dwCurrentTime; return hwndCaptureOld; } // HwndGrabCapture ///////////////////////////////////////////////////////////////////////////// // HwndReleaseCapture() // // Release the capture previously set by HwndGrabCapture. hwnd is the // handle of the window releasing the capture (ie, the same handle // as for HwndGrabCapture. // If your window had the capture, the function will send a // UN_MOUSETIMERCAPTURE message to your window to indicate you has // lost the capture. // The function will return the handle of the window having the capture. // Typically the return value is NULL because the capture has been // released, however there is always the possibility of another // window having the capture. In this case, no UN_MOUSETIMERCAPTURE will // be send to your window and the function will return a non-NULL handle. // NOTE: A window should not worry about releasing the capture because // as soon as someone else grab the capture, HwndGrabCapture will // automatically release the capture of the previous window. This // function should be used only if you want explicitly release the capture // while you have the focus and/or receiving WM_MOUSEMOVE messages. // HWND CMouseTracker::HwndReleaseCapture(HWND hwnd) { Assert(IsWindow(hwnd)); if (hwnd == m_hwndCapture) { // Send a notification message to our the window to // notify we have released/lost the capture SendMessage(hwnd, UN_MOUSETIMERCAPTURE, 0, NULL); m_hwndCapture = NULL; } return(m_hwndCapture); } // HwndReleaseCapture ///////////////////////////////////////////////////////////////////////////// // HwndGetCapture() // // Retrieves the handle of the window (if any) that has grabbed the // capture. This may be useful if you want to do something special // on your WM_PAINT message if you have the mouse capture. // ///////////////////////////////////////////////////////////////////////////// // OnWmTimer() // // Process the WM_TIMER message and forward a UN_MOUSETIMERCAPTURE to // the window having the capture. // void CMouseTracker::OnWmTimer(DWORD dwCurrentTime) { HWND hwnd; POINT ptMouse; if (m_hwndCapture == NULL) return; if (!IsWindow(m_hwndCapture)) { m_hwndCapture = NULL; return; } hwnd = GetCapture(); if (hwnd == m_hwndCapture) return; if (hwnd) { // Someone else got the capture // Send a notification message that the window has lost the capture SendMessage(m_hwndCapture, UN_MOUSETIMERCAPTURE, dwCurrentTime - m_dwTimeCapture, NULL); m_hwndCapture = NULL; return; } GetCursorPos(&ptMouse); hwnd = WindowFromPoint(ptMouse); if (hwnd != m_hwndCapture) { // Mouse is no longer on top of our window // Send a notification message that the window has lost the capture SendMessage(m_hwndCapture, UN_MOUSETIMERCAPTURE, dwCurrentTime - m_dwTimeCapture, NULL); m_hwndCapture = NULL; } else { ScreenToClient(m_hwndCapture, &ptMouse); SendMessage(m_hwndCapture, UN_MOUSETIMERCAPTURE, dwCurrentTime - m_dwTimeCapture, (LPARAM)&ptMouse); } } // OnWmTimer ///////////////////////////////////////////////////////////////////////////// void CMouseTargetter::SetTargetMode(DWORD dwTargetMode, HWND hwndNotify) { switch (dwTargetMode) { case tgTargetNone: EnableWindow(hwndMain, TRUE); HelperMgr.EnableWindow(TRUE); break; case tgTargetStandBy: EnableWindow(hwndMain, FALSE); break; case tgTargetTreeView: Assert(IsWindow(hwndNotify)); EnableWindow(hwndMain, TRUE); HelperMgr.EnableWindow(FALSE); break; default: Assert(FALSE); } // switch m_dwTargetMode = dwTargetMode; m_hwndNotify = hwndNotify; } // SetTargetMode ///////////////////////////////////////////////////////////////////////////// LRESULT CMouseTargetter::OnNotify(INOUT MOUSETARGETINFO * pMTI) { Assert(IsWindow(m_hwndNotify)); Assert(pMTI); return SendMessage(m_hwndNotify, UN_MOUSETARGETCHANGED, 0, (LPARAM)pMTI); } // OnNotify ///////////////////////////////////////////////////////////////////////////// VOID CALLBACK MouseTrackerTimerProc( HWND hwnd, // Handle of window for timer messages UINT uMsg, // WM_TIMER message UINT idTimer, // Timer identifier DWORD dwTime) // Current system time { Assert(hwnd == NULL); Assert(uMsg == WM_TIMER); Assert(idTimer == MouseTracker.GetTimerId()); MouseTracker.OnWmTimer(dwTime); } // MouseTrackerTimerProc // To store an array of pointers // Behavior of a list class CDynArray { private: enum { nDataGranularity = 64 }; // Allocate storage for 64 elements private: PVOID m_rgpvData[100]; int m_cData; // Number of elements in array int m_cDataAlloc; // Number of elements allocated public: CDynArray() { // Initialize the array to zeroes ZeroInit(m_rgpvData, sizeof(m_rgpvData)); m_cData = 0; } // Insert an element at position iIndex // - iIndex is a zero based index // - If iIndex==-1, append at end of array // - The array grows automatically if necessary // void Add(PVOID pvData) { // if (iIndex == -1) // iIndex = m_cData; // Points to the end of array // Assert(iIndex >= 0 && iIndex < 10); // REVIEW: Temporary Assert(m_cData < 10); m_rgpvData[m_cData++] = pvData; } PVOID GetAt(int iIndex) { Assert(iIndex >= 0 && iIndex < 10); // REVIEW: Temporary return (m_rgpvData[iIndex]); } int GetSize() { return m_cData; } }; // CDynArray #endif // NOT_USED #ifdef OBSOLETE Trace3(mskTraceUnused3, "\nTreeView::OnNotify() [code=0x%X (%d), action=0x%X] ", pNmTreeView->hdr.code, pNmTreeView->hdr.code, pNmTreeView->action); switch (pNmTreeView->hdr.code) { case TVN_SETDISPINFO: case TVN_GETDISPINFO: Trace0(mskTraceUnused3, "TVN_GETDISPINFO/TVN_SETDISPINFO"); break; case TVN_SELCHANGING: Trace0(mskTraceUnused3, "TVN_SELCHANGING"); break; case TVN_SELCHANGED: Trace0(mskTraceUnused3, "TVN_SELCHANGED"); break; case TVN_ITEMEXPANDING: Trace0(mskTraceUnused3, "TVN_ITEMEXPANDING"); break; case NM_RCLICK: Trace0(mskTraceUnused3, "NM_RCLICK"); break; case NM_CLICK: Trace0(mskTraceUnused3, "NM_CLICK"); break; case NM_DBLCLK: Trace0(mskTraceUnused3, "NM_DBLCLK"); break; case NM_RETURN: break; case NM_SETFOCUS: Trace0(mskTraceUnused3, "NM_SETFOCUS"); } // switch #endif // OBSOLETE